파드 간 통신이 활성화된 잡

이 예제에서는, 파드의 IP 주소 대신 호스트네임으로 상호 통신할 수 있도록 파드를 생성하는 잡을 색인된 완료 모드(Indexed completion mode)로 구성하여 실행한다.

잡 내부의 파드들이 서로 통신해야 하는 경우가 있다. 각 파드에서 실행되는 사용자 워크로드에서 쿠버네티스 API 서버에 질의하여 다른 파드의 IP를 알아낼 수도 있지만, 쿠버네티스에 내장된 DNS 변환(resolution)을 활용하는 것이 훨씬 간편하다.

색인된 완료 모드의 잡은 자동으로 파드의 호스트네임을 ${jobName}-${completionIndex} 형식으로 설정한다. 이 형식을 활용하면 파드 호스트네임을 결정론적(deterministically)으로 빌드하고 파드 간 통신을 활성화할 수 있다. 쿠버네티스 컨트롤 플레인에 대해 클라이언트 연결을 생성하고 API 요청으로 파드 호스트네임 및 IP를 알아낼 필요 없이 말이다.

이러한 설정은 파드 네트워킹이 필요하지만 쿠버네티스 API 서버와의 네트워크 연결에 의존하지 않고 싶은 경우에 유용하다.

시작하기 전에

기본적으로 사용 방법에 익숙하다는 것을 가정한다.

쿠버네티스 클러스터가 필요하고, kubectl 커맨드-라인 툴이 클러스터와 통신할 수 있도록 설정되어 있어야 한다. 이 튜토리얼은 컨트롤 플레인 호스트가 아닌 노드가 적어도 2개 포함된 클러스터에서 실행하는 것을 추천한다. 만약, 아직 클러스터를 가지고 있지 않다면, minikube를 사용해서 생성하거나 다음 쿠버네티스 플레이그라운드 중 하나를 사용할 수 있다.

쿠버네티스 서버의 버전은 다음과 같거나 더 높아야 함. 버전: v1.21. 버전 확인을 위해서, 다음 커맨드를 실행 kubectl version.

파드 간 통신이 활성화된 잡 시작하기

잡의 파드 호스트네임을 활용한 파드 간 통신을 활성화하기 위해서는 다음 작업을 진행해야 한다.

  1. 잡으로 생성되는 파드들에 대한 레이블 셀렉터를 지닌 헤드리스 서비스를 만든다. 헤드리스 서비스는 반드시 잡과 동일한 네임스페이스에 생성해야 한다. 쿠버네티스에 의해 job-name 레이블이 자동으로 생성되므로 job-name: <your-job-name> 셀렉터를 활용하면 간단하다. 해당 설정은 잡에서 실행 중인 파드들의 호스트네임에 대한 레코드를 생성하도록 DNS 시스템을 트리거할 것이다.

  2. 잡 템플릿 스펙에 아래 값을 추가함으로써 헤드리스 서비스를 잡의 파드들의 서브도메인 서비스로 설정한다.

    subdomain: <headless-svc-name>
    

예제

아래는 파드 호스트네임을 통해 파드 간 통신이 활성화된 잡의 예시이다. 해당 잡은 모든 파드들이 호스트네임으로 상호 핑(ping)을 성공한 경우에만 완료된다.


apiVersion: v1
kind: Service
metadata:
  name: headless-svc
spec:
  clusterIP: None # 헤드리스 서비스를 생성하기 위해서는 clusterIP가 반드시 None이어야 한다.
  selector:
    job-name: example-job # 잡의 name과 일치해야 한다.
---
apiVersion: batch/v1
kind: Job
metadata:
  name: example-job
spec:
  completions: 3
  parallelism: 3
  completionMode: Indexed
  template:
    spec:
      subdomain: headless-svc # 서비스의 name과 일치해야 한다.
      restartPolicy: Never
      containers:
      - name: example-workload
        image: bash:latest
        command:
        - bash
        - -c
        - |
          for i in 0 1 2
          do
            gotStatus="-1"
            wantStatus="0"             
            while [ $gotStatus -ne $wantStatus ]
            do                                       
              ping -c 1 example-job-${i}.headless-svc > /dev/null 2>&1
              gotStatus=$?                
              if [ $gotStatus -ne $wantStatus ]; then
                echo "Failed to ping pod example-job-${i}.headless-svc, retrying in 1 second..."
                sleep 1
              fi
            done                                                         
            echo "Successfully pinged pod: example-job-${i}.headless-svc"
          done          

위의 예제를 적용한 이후, <pod-hostname>.<headless-service-name>를 사용하여 네트워크 상으로 서로 통신해보자. 아래와 유사한 내용이 출력될 것이다.

kubectl logs example-job-0-qws42
Failed to ping pod example-job-0.headless-svc, retrying in 1 second...
Successfully pinged pod: example-job-0.headless-svc
Successfully pinged pod: example-job-1.headless-svc
Successfully pinged pod: example-job-2.headless-svc
최종 수정 June 20, 2024 at 12:44 PM PST: Sync changest from andygol/k8s-website (36d05bc8a1)