파드 간 통신이 있는 Job

파드 간 통신이 있는 Job (Job with Pod-to-Pod Communication)

이 예시에서는 Indexed 완료 모드의 Job을, Job이 만든 파드들이 파드 IP 주소가 아니라 파드 호스트 이름으로 서로 통신할 수 있도록 구성해서 실행해요.

Job 안의 파드들은 서로 통신해야 할 수도 있어요. 각 파드에서 실행되는 사용자 워크로드는 Kubernetes API 서버를 조회해 다른 파드의 IP를 알 수 있지만, Kubernetes의 내장 DNS 해석에 의존하는 것이 훨씬 간단해요.

Indexed 완료 모드의 Job은 파드의 호스트 이름을 ${jobName}-${completionIndex} 형식으로 자동 설정해요. 이 형식을 사용해 결정적으로 파드 호스트 이름을 만들고, API 요청으로 파드 호스트 이름/IP를 얻기 위해 Kubernetes 컨트롤 플레인에 클라이언트 연결을 만들 필요 없이 파드 통신을 활성화할 수 있어요.

이 구성은 파드 네트워킹이 필요하지만 Kubernetes API 서버와의 네트워크 연결에 의존하고 싶지 않은 사용 사례에 유용해요.

출처: 문서

본문

시작하기 전에

Job의 기본 사용법에 이미 익숙해야 해요.

Kubernetes 클러스터가 있어야 하고 kubectl 명령줄 도구가 클러스터와 통신하도록 구성되어 있어야 해요. 이 튜토리얼은 컨트롤 플레인 호스트가 아닌 노드가 최소 두 개 있는 클러스터에서 실행하는 것을 권장해요. 아직 클러스터가 없다면 minikube를 이용해 만들거나, 아래 Kubernetes 플레이그라운드 중 하나를 사용할 수 있어요.

버전을 확인하려면 kubectl version을 입력해요.

파드 간 통신이 있는 Job 시작

Job에서 파드 호스트 이름으로 파드 간 통신을 활성화하려면 다음을 수행해야 해요.

  • Job이 만든 파드에 대한 유효한 라벨 셀렉터를 가진 헤드리스 서비스(headless Service)를 설정해요. 헤드리스 서비스는 Job과 같은 네임스페이스에 있어야 해요. 쉽게 하는 한 가지 방법은 job-name: <your-job-name> 셀렉터를 사용하는 것이에요. Kubernetes가 job-name 라벨을 자동으로 추가하기 때문이에요. 이 구성은 DNS 시스템이 Job을 실행하는 파드의 호스트 이름 레코드를 만들도록 트리거해요.
  • Job 템플릿 spec에 다음 값을 포함해 헤드리스 서비스를 Job 파드의 서브도메인 서비스로 구성해요.

예시 (Example)

아래는 파드 호스트 이름을 통한 파드 간 통신이 활성화된 Job의 동작하는 예시예요. Job은 모든 파드가 호스트 이름으로 서로 ping에 성공한 후에만 완료돼요.

apiVersion: v1
kind: Service
metadata:
  name: headless-svc
spec:
  clusterIP: None # clusterIP must be None to create a headless service
  selector:
    job-name: example-job # must match Job name
---
apiVersion: batch/v1
kind: Job
metadata:
  name: example-job
spec:
  completions: 3
  parallelism: 3
  completionMode: Indexed
  template:
    spec:
      subdomain: headless-svc # has to match Service 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

더 알아보기 (Learn more)