7.2. Pod를 배포하기 전에 Init Container를 사용하여 작업 수행

OpenShift Container Platform에서는 애플리케이션 컨테이너보다 먼저 실행되고 앱 이미지에 없는 유틸리티 또는 설정 스크립트를 포함할 수 있는 특수 컨테이너인 Init Container를 제공합니다.

7.2.1. Init Container 이해

Init Container 리소스를 사용하여 나머지 Pod를 배포하기 전에 작업을 수행할 수 있습니다.

Pod에는 애플리케이션 컨테이너 외에도 Init Container가 있을 수 있습니다. Init Container를 사용하면 설정 스크립트 및 바인딩 코드를 재구성할 수 있습니다.

Init Container는 다음을 수행할 수 있습니다.

  • 보안상의 이유로 앱 컨테이너 이미지에 포함하지 않는 유틸리티를 포함 및 실행합니다.
  • 앱 이미지에 없는 설정에 대한 유틸리티 또는 사용자 정의 코드를 포함합니다. 예를 들어, 설치 중에 sed, awk, python 또는 dig와 같은 툴을 사용하기 위해 다른 이미지에서 이미지를 만들 필요가 없습니다.
  • 애플리케이션 컨테이너에서 액세스할 수 없는 보안에 대한 액세스 권한과 같이 파일 시스템 보기가 앱 컨테이너와 다르게 표시되도록 Linux 네임스페이스를 사용합니다.

각 Init Container는 다음 컨테이너를 시작하기 전에 성공적으로 완료해야 합니다. 이를 위해 Init Container에서는 몇 가지 사전 조건 집합이 충족될 때까지 앱 컨테이너의 시작을 차단하거나 지연할 수 있는 쉬운 방법을 제공합니다.

예를 들어 다음은 Init Container를 사용할 수 있는 몇 가지 방법입니다.

  • 다음과 같은 쉘 명령을 사용하여 서비스가 생성될 때까지 기다립니다.

    for i in {1..100}; do sleep 1; if dig myservice; then exit 0; fi; done; exit 1
  • 다음과 같은 명령을 사용하여 Downward API에서 원격 서버에 이 Pod를 등록합니다.

    $ curl -X POST http://$MANAGEMENT_SERVICE_HOST:$MANAGEMENT_SERVICE_PORT/register -d ‘instance=$()&ip=$()’
  • sleep 60과 같은 명령을 사용하여 앱 컨테이너를 시작하기 전에 잠시 기다립니다.
  • Git 리포지토리를 볼륨에 복제합니다.
  • 구성 파일에 값을 저장하고 템플릿 툴을 실행하여 기본 앱 컨테이너에 대한 구성 파일을 동적으로 생성합니다. 예를 들어 POD_IP 값을 구성에 저장하고 Jinja를 사용하여 기본 앱 구성 파일을 생성합니다.

자세한 내용은 Kubernetes 설명서를 참조하십시오.

7.2.2. Init Container 생성

다음 예제에서는 Init Container가 두 개 있는 간단한 Pod를 간략하게 설명합니다. 첫 번째 컨테이너는 myservice를 기다리고 두 번째 컨테이너는 mydb를 기다립니다. 두 컨테이너가 모두 완료되면 Pod가 시작됩니다.

절차

  1. Init Container의 Pod를 생성합니다.

    1. 다음과 유사한 YAML 파일을 생성합니다.

      apiVersion: v1
      kind: Pod
      metadata:
        name: myapp-pod
        labels:
          app: myapp
      spec:
        containers:
        - name: myapp-container
          image: registry.access.redhat.com/ubi8/ubi:latest
          command: ['sh', '-c', 'echo The app is running! && sleep 3600']
        initContainers:
        - name: init-myservice
          image: registry.access.redhat.com/ubi8/ubi:latest
          command: ['sh', '-c', 'until getent hosts myservice; do echo waiting for myservice; sleep 2; done;']
        - name: init-mydb
          image: registry.access.redhat.com/ubi8/ubi:latest
          command: ['sh', '-c', 'until getent hosts mydb; do echo waiting for mydb; sleep 2; done;']
      # ...
    2. Pod를 생성합니다.

      $ oc create -f myapp.yaml
    3. Pod 상태를 확인합니다.

      $ oc get pods

      출력 예

      NAME                          READY     STATUS              RESTARTS   AGE
      myapp-pod                     0/1       Init:0/2            0          5s

      포드 상태 Init:0/2 는 두 서비스를 대기 중임을 나타냅니다.

  2. myservice 서비스를 생성합니다.

    1. 다음과 유사한 YAML 파일을 생성합니다.

      kind: Service
      apiVersion: v1
      metadata:
        name: myservice
      spec:
        ports:
        - protocol: TCP
          port: 80
          targetPort: 9376
    2. Pod를 생성합니다.

      $ oc create -f myservice.yaml
    3. Pod 상태를 확인합니다.

      $ oc get pods

      출력 예

      NAME                          READY     STATUS              RESTARTS   AGE
      myapp-pod                     0/1       Init:1/2            0          5s

      Pod 상태 Init:1/2 는 하나의 서비스(이 경우 mydb 서비스)를 대기 중임을 나타냅니다.

  3. mydb 서비스를 생성합니다.

    1. 다음과 유사한 YAML 파일을 생성합니다.

      kind: Service
      apiVersion: v1
      metadata:
        name: mydb
      spec:
        ports:
        - protocol: TCP
          port: 80
          targetPort: 9377
    2. Pod를 생성합니다.

      $ oc create -f mydb.yaml
    3. Pod 상태를 확인합니다.

      $ oc get pods

      출력 예

      NAME                          READY     STATUS              RESTARTS   AGE
      myapp-pod                     1/1       Running             0          2m

      Pod 상태는 더 이상 서비스를 기다리지 않고 실행 중임을 나타냅니다.