본문 바로가기
BackEnd

도커와 쿠버네티스 -K8S(네트워크 통신_pod들의 통신)

by mizuiro 2024. 11. 24.

1. Ingress

Ingress 란

기본적으로 ingress라는 용어는 네트워크에서 나왔다

네트워크 트래픽에서 외부에서 내부로 들어오는 트래픽을 Ingress, 반대는 egress 라고 한다

쿠버네티스에서의 Ingress 는 외부로부터 접근을 관리하는 API 오브젝트이다

즉, URL을 통해 HTTP 접근 경로를 만들어서 외부 트래픽이 내부의 어디에 도달할 수 있는지에 대해 정의한 규칙 모음이다

추가 : 서비스(Service)

파드들은 각각 클러스터 안에서 새로운 IP를 발급 받고 관리를 하게 된다. 그러나 쿠버네티스에서 파드들은 하나의 노드(마스터, 워크)에 고정으로 존재하지 않고 다른 노드로 옮겨지거나 삭제 될 수 있다

이렇게 변화가 있을 때마다 파드의 IP주소가 변경되기 때문에 파드 간의 통신이나, 다른 노드 또는 외부와 통신을 할 때 파드의 IP 주소를 사용하면 관리가 힘들다

그래서 이러한 통신을 원활하게 할 수 있도록 클러스터 내부에서 고정적인 IP 를 가지는 서비스(Service)를 이용한다

이 서비스(Service)는 파드가 다른 것들과 통신하기 위해 꼭 거쳐야 하는 곳이 되면서 IP 주소의 관리도 원활하게 할 수 있다

  • 서비스(Service) 유형 : 노출의 범위에 따라 분류
    • ClusterIP : 클러스터 내부에서만 접근 가능한 IP
    • NodePort : port 번호를 통해 외부에서 접근
    • LoadBalancer : 외부의 Load Balancer 사용
    • ExternalName : kube-dns 컴포넌트로 DNS를 이용

더 자세한 내용은 아래의 링크를 참조

https://bumday.tistory.com/165

K8S에서의 Ingress

K8S의 Ingress는 Service의 기능( 네트워크 통신)의 기능을 지원할 뿐만 아니라 아래의 기능도 제공한다

  • 하나의 클러스터에 복수의 도메인을 연결하는 가상 호스팅
  • 클러스터에 접근하는 트래픽을 URL 별로 서로 다른 서비스에 로드밸런싱
  • 클러스터 내에서 구동되는 리소스에 접근할 수 있는 외부 URL을 제공
  • HTTPS사용을 위한 SSL 인증서 로직 처리

2. K8S 에서의 통신

K8S에서의 네트워크 통신 종류

  • 내부 pod를 이용한 통신

    1. 같은 pod 내에서 컨테이너들의 통신
    2. 서로 다른 pod 에 있는 컨테이너들의 통신
    3. 내부 pod에서 외부로 통신
  • spring boot를 이용한 통신(Ingress)

  1. Service를 이용한 애플리케이션(spring boot) 들의 통신
    1. Service(ClusterIP, ExternalName) 객체로 서비스명으로 통신 가능

3. K8S 에서의 내부 pod를 이용한 통신

3-1. 같은 pod 내에서 컨테이너들의 통신

환경 : multi container를 설정하여 pod 내의 두 conatiner가 통신 가능한지 확인

container : curl container, nginx container

통신 : curl → nginx

  • 설정 파일
apiVersion: v1
kind: Pod
metadata:
  name: my-localhost-pod
spec:
  containers:
    - name: nginx-container
      image: nginx
    - name: curl-container
      image: curlimages/curl
      command: ["sh", "-c", "sleep 180"]
  • spec.containers: 두 개의 컨테이너 생성(curl, nginx)

    • -name(curl-container),command:

      curl은 nginx 처럼 프로세스로 계속 실행되는 것이 아니기에 시작하자 마자 종료가 될 수 있다

      그러므로 바로 종료 되어 container가 exited 가 되는 것을 방지하기 위해 sleep을 설정하며 일시 중시 시켜 명령어를 받을 수 있도록 설정한다

  • 실행
  1. pod 설치
kubectl apply -f ex1_my_localhost_pod.yaml
kubectl describe pod my-localhost-pod

⇒ describe 의 결과 중 contianers 부분 발췌

  1. 컨테이너 통신

    통신을 위한 화면이 없기 때문에 CLI 로 통신(curl → nginx)

kubectl exec my-localhost-pod -c curl-container -- curl localhost:80
  • -c : 어떤 컨테이너에 대해 명령을 수행할 것인지 지정하기 위한 옵션
  • curl-container : 명령을 수행할 컨테이너
  • — : 이후에 실행할 명령어들

중요!! : 두 컨테이너(curl, nginx)가 서로 통신 할 수 있는 이유는?

  1. curl-containernginx-container를 어떻게 인지하는가?
    같은 pod안에 있는 컨테이너들은 localhost로 서로 통신이 가능하다

    kubernetes에서 같은 pod 내 컨테이너들은 네트워크 네임스페이스(컨테이너 이름으로 서로의 IP 주소를 알 수 있는 것) 를 공유하기 때문에 서로를 localhost로 접근 할 수 있다

  2. 포트 번호가 80번인 이유

    nginx 웹 서버는 기본적으로 80번 포트를 사용한다 HTTP 프로토콜의 기본 포트가 80번이기에 별도로 포트를 지정하지 않는 한, nginx는 자동으로 80번 포트를 열고 HTTP 요청을 처리한다

    만약, nginx가 다른 포트에서 실행 중이라면, 그 포트를 지정해 줘야 하지만, 특별히 설정하지 않는 한, 80번 포트에서 작동한다

  1. 위의 명령어의 의미

    Pod 내 컨테이너들은 네트워크 네임스페이스를 공유하고 있다. 이런 환경에서 curl-container에서 localhost:80curl 명령을 실행하는 것이고, localhost는 동일한 Pod 내의 모든 컨테이너들을 가리키기 때문에, 사실 nginx-container가 해당 포트(80)를 열고 있으면 curl 명령이 자연스럽게 연결이 되는 것이다

3-2. 서로 다른 pod 에 있는 컨테이너들의 통신

K8S 클러스터 내부에 서로 다른 IP로 할당된 상태 : 서로 다른 pod에 있는 컨테이너

  • 설정 환경

    • Deployment (ReplicaSet)을 이용하여 pod1(nginx-container1), pod2(nginx-container2) 생성

    • Service( ClusterIP ) 를 이용하여 클러스터 내부에서만 접근 가능 IP를 할당하여 외부 pod에서 내부로 통신하도록 설정

    • 구조

        [Client (curl)]
                |
                | curl my-service:9080
                |
        [Service (ClusterIP) - my-service]
                |
                | 로드 밸런싱 (Round Robin or Random)
                |
          -------------------------
          |          |           |
        [Pod 1]   [Pod 2]   [Pod 3]
         (nginx)   (nginx)   (nginx)
           80번      80번      80번
          포트      포트      포트
      
  • 설정 파일

    1. Deployment

      apiVersion: apps/v1
      kind: Deployment
      metadata:
      name: my-nginx-deploy
      spec:
      replicas: 3
      selector:
       matchLabels:
         app: my-nginx
      template:
       metadata:
         labels:
           app: my-nginx
       spec:
         containers:
           - name: nginx
             image: nginx
    • ReplicaSet을 3으로 설정하여 nginx pod 가 3개가 생성되도록 설정
  1. Service ( ClusterIP )
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: ClusterIP
  selector:
    app: my-nginx
  ports:
    - protocol: TCP
      port: 9080
      targetPort: 80
  • metadata.name : 외부에서 이 서비스를 호출 하는 기준 (현재 코드는 my-service 라고 호출)

  • spec

    • type: ClusterIP : ClusterIP 는 default 로 생략이 가능하지만 명시적으로 작성하는 것이 좋음

    • selector : 이 서비스의 대상이 되는 pod 들을 지정한다

      이 코드에서 생성한 my-service 가 호출하는 pod 들은 endpointslices 객체가 가지고 있다

      • app : 위에서 작성한 deployment의 pod들이 대상이 되므로 deployment의 selector 와 동일한 selector를 지정한다
    • ports : nginx container 의 내부 80 port(기본 설정) 가 my-service의 9080 port로 매핑이 된다

      • protocol : TCP : 기본 설정
      • port : 9080 : Service는 9080 port를 호출하도록 지정
      • targetPort : 80 : Deployment의 pod 들은 nginx 이므로 80 port를 지정한다
  • 실행

  1. Deployment 생성
kubectl apply -f ex2-1_my_nginx_deploy.yaml
kubectl get pods
  1. Service 생성
kubectl apply -f .\ex2-2_my_service.yaml
kubectl get service
  1. 생성된 pod 들의 IP 확인
kubectl get endpointslices
kubectl get pods
kubectl describe pod my-nginx-deploy-'자동 생성된pod 해쉬코드 이름'
  • my-service에 연결된 endpoint 3개를 확인한다

  • pod들의 전체 이름을 확인한다

  • 제일 마지막 pod의 정보를 조회해 보았을 때 IP가 10.244.0.8로 조회되었다

  • 다른 pod 들도 조회를 하면 연결된 IP 들과 같은 IP 들로 되어 있다

  1. pod 간의 컨테이너 호출
kubectl exec my-localhost-pod -c nginx-container -- curl my-service:9080
  • 통신 순서

    my-localhost-pod(nginx) -> my-service:9080 -> my-nginx-deploy(nginx)

3-3. 내부 pod 가 외부와 통신

k8s 클러스터 내부에서 외부로 접근하는 방법

  • Service
apiVersion: v1
kind: Service
metadata:
  name: google-service
spec:
  type: ExternalName
  externalName: www.google.com
  • 외부 (구글) 과 통신하기

  • 실행

kubectl apply -f .\ex3_my_google_service.yaml
kubectl exec my-localhost-pod -c nginx-container -- curl --header "Host:www.google.com" google-service
  • 통신 순서

    my-localhost-pod(nginx) : K8S 내부 -> google-service -> www.google.com : K8S 외부