guswns1659 / guswns1659.github.io

MIT License
1 stars 0 forks source link

24.06.28 k8s 자료 준비 #12

Open guswns1659 opened 3 weeks ago

guswns1659 commented 3 weeks ago

코멘트로 추가

guswns1659 commented 3 weeks ago

Service 객체에서 selector의 역할

Kubernetes에서 Service YAML 파일을 작성할 때 specselector의 역할은 매우 중요합니다. selector는 Service가 트래픽을 라우팅할 대상인 Pod을 식별하는 데 사용됩니다.

역할과 기능

예시

아래는 Service YAML 파일의 예시로, selectorapp: my-app 레이블을 가진 모든 Pod에게 트래픽을 라우팅합니다.

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: my-app
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080

동작 방식

  1. Pod 레이블: Pod이 생성될 때 다음과 같이 레이블을 지정할 수 있습니다:

    apiVersion: v1
    kind: Pod
    metadata:
     name: my-pod
     labels:
       app: my-app
    spec:
     containers:
     - name: my-container
       image: my-image
       ports:
       - containerPort: 8080
  2. Service 트래픽 라우팅: 위 Service는 selector에 지정된 레이블(app: my-app)을 가진 모든 Pod에게 트래픽을 분배합니다. Service는 클러스터 내부에서 해당 레이블을 가진 Pod을 자동으로 감지하고 연결합니다.

참고 자료

이 자료들은 spec.selector의 역할과 Kubernetes Service의 동작 방식을 이해하는 데 도움이 될 것입니다. selector는 Kubernetes에서 동적인 서비스 디스커버리와 로드 밸런싱을 가능하게 하는 핵심 요소입니다.

guswns1659 commented 3 weeks ago

service.yaml에서 ports의 역할

Kubernetes의 Service 정의에서 ports 섹션을 다음과 같이 설정하는 경우, 각 필드(port, targetPort, nodePort)가 가지는 의미와 동작을 자세히 설명하겠습니다:

spec:
  type: NodePort
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
    nodePort: 30007

각 필드의 역할

  1. protocol:

    • 역할: 서비스가 사용할 프로토콜을 지정합니다. 기본값은 TCP입니다.
    • 설명: 서비스가 TCP를 통해 통신하도록 설정되어 있습니다. 다른 프로토콜로는 UDP를 사용할 수 있습니다.
  2. port:

    • 역할: 서비스가 클러스터 내에서 사용하는 포트 번호입니다.
    • 설명: 클러스터 내부의 다른 Pod이나 서비스가 이 서비스에 접근할 때 사용하는 포트 번호입니다. 여기서는 80번 포트를 사용합니다.
    • 효과: 클러스터 내의 다른 Pod들이 nginx-service에 접근할 때 http://nginx-service:80와 같은 형식으로 접근할 수 있습니다.
  3. targetPort:

    • 역할: 서비스가 트래픽을 전달할 대상 Pod의 컨테이너 포트 번호입니다.
    • 설명: 서비스가 선택한 Pod의 컨테이너에서 실제로 열려 있는 포트 번호입니다. 여기서는 80번 포트를 지정하고 있습니다.
    • 효과: nginx 컨테이너가 80번 포트에서 웹 서버를 실행하고 있으므로, 서비스가 이 포트로 트래픽을 전달합니다.
  4. nodePort:

    • 역할: 클러스터 외부에서 이 서비스에 접근할 때 사용할 노드 포트 번호입니다.
    • 설명: Kubernetes는 이 포트를 각 노드의 IP 주소에서 개방하여 외부 트래픽을 해당 서비스로 라우팅합니다. 이 예시에서는 30007번 포트를 사용하고 있습니다.
    • 효과: 클러스터 외부에서 노드의 IP 주소와 30007번 포트를 통해 이 서비스에 접근할 수 있습니다. 예를 들어, http://<노드 IP>:30007 형식으로 접근 가능합니다.

동작 방식

  1. 클러스터 내부 접근:

    • 클러스터 내부의 다른 Pod들은 nginx-service를 통해 80번 포트로 접근합니다.
    • 서비스는 selector에 지정된 레이블(app: nginx)을 가진 Pod을 찾아 트래픽을 전달합니다.
    • 내부 트래픽은 port: 80에서 targetPort: 80으로 전달됩니다.
  2. 클러스터 외부 접근:

    • 클러스터 외부에서 노드의 IP 주소와 30007번 포트를 통해 이 서비스에 접근할 수 있습니다.
    • NodePort 서비스는 모든 클러스터 노드에서 30007번 포트를 열어 놓고, 이 포트로 들어오는 트래픽을 서비스로 전달합니다.
    • 외부 트래픽은 nodePort: 30007에서 시작하여, 내부의 port: 80을 거쳐 최종적으로 targetPort: 80으로 전달됩니다.

예시

  1. 클러스터 내부:

    • Pod에서 curl http://nginx-service:80를 실행하면, 트래픽이 80번 포트를 통해 서비스로 전달되고, 해당 서비스는 targetPort: 80으로 트래픽을 라우팅하여 nginx 웹 서버에 도달합니다.
  2. 클러스터 외부:

    • 클러스터 외부의 브라우저에서 http://<노드 IP>:30007를 입력하면, 노드의 30007번 포트를 통해 서비스로 트래픽이 전달되고, 서비스는 이를 내부의 port: 80을 거쳐 targetPort: 80으로 라우팅하여 nginx 웹 서버에 도달합니다.

요약

참고 자료

이 자료들을 통해 Kubernetes의 Service 타입과 각 필드의 동작 방식을 더 깊이 이해할 수 있습니다.

guswns1659 commented 3 weeks ago

NodePort Service를 지정했는데 로컬에서 요청 시 통신이 안될 때

kubectl port-forward 명령어에서 svc/ 접두사는 포트 포워딩 대상이 서비스(Service)라는 것을 지정하기 위해 사용됩니다. Kubernetes에서는 여러 가지 리소스 타입(Pod, Service, Deployment 등)을 관리할 수 있으며, kubectl 명령어는 이러한 리소스 타입을 명확히 지정해야 합니다.

kubectl port-forward 명령어의 구성

예시

kubectl port-forward svc/nginx-service 8080:80

위 명령어는 로컬 호스트의 포트 8080을 Kubernetes 클러스터 내의 nginx-service 서비스의 80번 포트에 포워딩합니다.

포트 포워딩 대상

리소스 타입 지정 이유

Kubernetes에서는 다양한 리소스 타입을 관리하고, 각 리소스 타입은 특정 용도와 기능을 가집니다. 포트 포워딩 대상이 되는 리소스를 명확히 지정함으로써 Kubernetes 명령어가 정확히 어떤 리소스에 대해 작업을 수행해야 하는지 알 수 있습니다.

이와 같이 리소스 타입을 명확히 지정함으로써 kubectl 명령어의 동작을 정확히 제어할 수 있습니다.

참고 자료

guswns1659 commented 3 weeks ago

로컬 머신에서 docker에 포트포워딩을 추가하지 않으면 컨테이너에 직접 통신할 수 없는 이유

로컬 머신에서 Docker 컨테이너에 포트 포워딩을 추가하지 않으면 컨테이너에 직접 통신할 수 없는 이유는 Docker의 네트워크 격리 및 보안 모델에 기인합니다. 다음은 이 문제의 원인과 관련된 몇 가지 주요 요인입니다.

1. 네트워크 격리

Docker는 기본적으로 각 컨테이너를 격리된 네트워크 환경에서 실행합니다. 이러한 네트워크 격리는 컨테이너 간의 간섭을 줄이고, 보안을 강화하며, 예측 가능한 네트워킹 동작을 제공합니다.

2. 포트 포워딩

포트 포워딩은 로컬 머신의 특정 포트를 Docker 컨테이너의 포트와 연결하는 과정입니다. 이를 통해 외부 네트워크에서 컨테이너에 접근할 수 있습니다.

3. 보안 및 제어

Docker의 네트워크 격리 모델은 보안을 강화하고 네트워크 트래픽을 제어하기 위해 설계되었습니다.

예시

# 포트 포워딩 없이 실행
docker run -d --name my-nginx nginx

# 포트 포워딩을 설정하여 실행
docker run -d -p 8080:80 --name my-nginx nginx

첫 번째 명령어는 포트 포워딩 없이 컨테이너를 실행합니다. 이 경우, 호스트 시스템에서 http://localhost:8080으로 접근해도 컨테이너에 도달하지 못합니다. 두 번째 명령어는 호스트의 8080 포트를 컨테이너의 80 포트로 포워딩하여, http://localhost:8080으로 접근할 수 있게 만듭니다.

참고 자료

이 자료들은 Docker 네트워크 설정과 포트 포워딩에 대한 추가 정보를 제공하며, Docker의 네트워크 격리 모델을 이해하는 데 도움이 됩니다.

guswns1659 commented 3 weeks ago

(덜 중요) LoadBalancer 타입 Service를 로컬에서 네트워킹 테스트하고 싶을 때

로컬 환경에서 LoadBalancer 타입의 서비스를 테스트하는 것은 클라우드 환경에서의 로드 밸런서와 같은 방식으로는 불가능합니다. 그러나 Minikube와 같은 로컬 Kubernetes 클러스터 도구를 사용하면 LoadBalancer 타입의 서비스를 로컬에서 테스트할 수 있는 몇 가지 방법이 있습니다.

1. Minikube Tunnel 사용

Minikube는 로컬 환경에서 LoadBalancer 타입의 서비스를 테스트할 수 있는 minikube tunnel 명령어를 제공합니다. 이 명령어는 클러스터 외부에서 접근할 수 있는 로드 밸런서를 시뮬레이션합니다.

단계별 방법

  1. Minikube 클러스터 시작

    Minikube 클러스터가 실행 중인지 확인합니다. 실행 중이 아니면 시작합니다.

    minikube start
  2. 서비스 YAML 파일 적용

    작성한 nginx-service.yaml 파일을 클러스터에 적용합니다.

    kubectl apply -f nginx-service.yaml
  3. Minikube Tunnel 실행

    Minikube 터널을 실행합니다. 이 명령어는 로컬 머신에서 클러스터 외부로 포트를 노출합니다.

    minikube tunnel

    이 명령어를 실행하면, 관리자 권한이 필요할 수 있습니다. 이 명령어는 Minikube 클러스터의 서비스에 외부 IP 주소를 할당하고, 트래픽을 로컬 머신으로 라우팅합니다.

  4. 서비스 상태 확인

    서비스가 올바르게 생성되었는지, 외부 IP가 할당되었는지 확인합니다.

    kubectl get services

    출력 예시:

    NAME            TYPE           CLUSTER-IP      EXTERNAL-IP      PORT(S)        AGE
    nginx-service   LoadBalancer   10.96.95.196    10.0.0.1         80:31984/TCP   1m

    EXTERNAL-IP 필드에 IP 주소가 할당된 것을 확인할 수 있습니다.

  5. 서비스 접근

    할당된 외부 IP를 사용하여 서비스에 접근합니다. 예를 들어, 브라우저나 curl 명령어를 사용합니다.

    curl http://10.0.0.1

참고 자료

이 방법을 통해 로컬 환경에서 LoadBalancer 타입의 서비스를 테스트할 수 있습니다. Minikube 터널을 사용하면 로컬에서 클라우드 환경과 유사한 테스트를 수행할 수 있습니다.

guswns1659 commented 3 weeks ago

그럼 LoadBalancer + Ingress 조합과 Service를 LoadBalancer 타입으로 설정하는 것의 차이는?

LoadBalancer 타입의 서비스와 Ingress 리소스를 사용하는 방식에는 몇 가지 중요한 차이점이 있습니다. 두 가지 모두 Kubernetes 클러스터 외부에서 내부 서비스로의 접근을 허용하지만, 사용 사례와 제공하는 기능이 다릅니다.

LoadBalancer 타입 서비스

특징:

사용 예시:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: my-app
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080
  type: LoadBalancer

장점:

단점:

Ingress 리소스

특징:

사용 예시:

# Service
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:
    app: my-app
  ports:
  - protocol: TCP
    port: 8080
  type: ClusterIP

# Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: my-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: my-service
            port:
              number: 8080

장점:

단점:

요약

참고 자료

이 자료들은 Kubernetes의 LoadBalancer 서비스와 Ingress 리소스를 더 깊이 이해하는 데 도움이 될 것입니다.

guswns1659 commented 3 weeks ago

Ingress에서 서비스로 오는 요청은 실제로 kube-proxy가 받는다.

맞습니다. Ingress에서 서비스로 전달된 요청은 Kube-Proxy에 의해 처리되어 적절한 Pod로 라우팅됩니다. 이 과정을 더 자세히 설명하면 다음과 같습니다:

Ingress에서 서비스로 요청 전달

  1. Ingress: 클라이언트 요청이 Ingress 엔드포인트로 들어옵니다. Ingress 컨트롤러(NGINX, HAProxy 등)는 Ingress 리소스에 정의된 규칙에 따라 요청을 처리합니다.
  2. Ingress 컨트롤러: Ingress 컨트롤러는 요청된 호스트와 경로에 따라 적절한 서비스로 요청을 전달합니다. 예를 들어, example.com/app 요청은 example-service로 라우팅될 수 있습니다.

서비스에서 Pod로 요청 전달

  1. 서비스: 서비스는 클러스터 내의 Pod에 대한 추상화된 네트워크 엔드포인트입니다. 각 서비스는 고유한 Cluster IP를 가지고 있으며, 해당 서비스로 들어오는 요청을 관리합니다.
  2. Kube-Proxy: Kube-Proxy는 각 노드에서 실행되며, 서비스로 들어오는 트래픽을 적절한 Pod로 라우팅합니다. 이는 iptables 또는 IPVS를 사용하여 수행됩니다.

Kube-Proxy의 역할

예시 흐름

  1. Ingress 요청: 클라이언트가 example.com/app으로 HTTP 요청을 보냅니다.
  2. Ingress 컨트롤러: Ingress 컨트롤러는 이 요청을 example-service로 전달합니다.
  3. Kube-Proxy: Kube-Proxy는 example-service의 Cluster IP로 들어오는 트래픽을 적절한 Pod으로 라우팅합니다. 이때, Kube-Proxy는 iptables 또는 IPVS 규칙을 사용하여 요청을 처리합니다.
  4. Pod: 최종적으로 요청은 example-app 레이블을 가진 Pod 중 하나로 전달되고, 해당 Pod는 요청을 처리하여 응답을 반환합니다.

참고 자료

이 자료들을 통해 Ingress에서 서비스로, 그리고 서비스에서 Pod로의 요청 전달 과정에서 Kube-Proxy가 하는 역할을 더 깊이 이해할 수 있습니다.

guswns1659 commented 3 weeks ago

Deployment 컨트롤러는 실제 프로세스로 뜨고, Deployments는 etcd에만 저장된다.

네, 맞습니다. Kubernetes에서 Deployment는 etcd에 저장되는 선언적 구성 요소이며, 실제로 실행되는 프로세스는 Deployment 컨트롤러입니다. 이를 조금 더 자세히 설명하겠습니다:

Deployment 객체

Deployment 컨트롤러

요약

참고 자료

이 자료들을 통해 Deployment 객체와 Deployment 컨트롤러의 역할을 명확하게 이해할 수 있습니다.

guswns1659 commented 3 weeks ago

실습