본문 바로가기
쿠버네티스

[쿠버네티스] Init,Infra Container 및 Static Pod란?

by woo0doo 2025. 3. 2.

 

Init Container

app container가 구동되기 이전에 pod를 초기화해주는 container입니다.

pod의 환경설정 또는 기타 다른 부수적인 작업을 하기 위해 일회성으로 구동되는 것입니다

app container와 다른 특성이 있따면 반드시 init container -> app container로 구동된다는 점입니다.

그래서 init container에서 에러가 발생한 경우 app container가 구동되지 않고 에러가 발생합니다.

example

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app.kubernetes.io/name: MyApp
spec:
  containers:
  - name: myapp-container
    image: busybox:1.28
    command: ['sh', '-c', 'echo The app is running! && sleep 3600']
  initContainers:
  - name: init-myservice
    image: busybox:1.28
    command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"]
  - name: init-mydb
    image: busybox:1.28
    command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]

 

예제 설명

 

1. Init Containers

Init Container들은 메인 컨테이너가 실행되기 전에 반드시 완료되어야 하는 초기화 작업을 수행합니다. 여기서는 두 개의 Init Container가 정의되어 있습니다:

  • init-myservice:
    • 이미지: busybox:1.28
    • 명령:
      sh -c "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"
    • 역할:
      이 컨테이너는 nslookup을 사용해 클러스터 내에서 myservice라는 서비스의 DNS 레코드가 조회 가능한지 확인합니다.
      • $(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace) 명령은 현재 Pod가 속한 네임스페이스를 가져옵니다.
      • 즉, 완전한 서비스 FQDN은 myservice.<namespace>.svc.cluster.local이 됩니다.
      • 서비스가 아직 준비되지 않았다면 "waiting for myservice"를 출력하며 2초마다 재시도합니다.
  • init-mydb:
    • 이미지: busybox:1.28
    • 명령:
       
      sh -c "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"
    • 역할:
      이 컨테이너는 mydb 서비스가 DNS를 통해 조회 가능한지 확인합니다.
      • 마찬가지로 현재 네임스페이스 정보를 사용하여 FQDN을 구성합니다.
      • 서비스가 준비될 때까지 "waiting for mydb"를 출력하고 2초 간격으로 반복 확인합니다.

 

주의: Init Container들은 순차적으로 실행되며, 각각의 Init Container가 성공적으로 완료되어야 다음 Init Container나 메인 컨테이너가 시작됩니다.

2. 메인 컨테이너

  • myapp-container:
    • 이미지: busybox:1.28
    • 명령:
       
      sh -c 'echo The app is running! && sleep 3600'
    • 역할:
      Init Container들이 모두 완료된 후 실행되며, 단순히 "The app is running!" 메시지를 출력한 후 1시간(3600초) 동안 실행 상태를 유지합니다.

전체적인 흐름

  1. Init Container 실행:
    • init-myservice가 실행되어 myservice 서비스의 DNS 확인이 성공할 때까지 반복합니다.
    • 그 다음, init-mydb가 실행되어 mydb 서비스의 DNS 확인이 성공할 때까지 반복합니다.
  2. 메인 컨테이너 실행:
    • 두 Init Container 모두 정상적으로 완료되면, 메인 컨테이너인 myapp-container가 시작되어 애플리케이션의 주 기능(여기서는 단순 메시지 출력 후 대기)을 수행합니다.

이와 같이, 이 YAML은 Pod 내에서 외부 서비스(예: myservice, mydb)의 준비 상태를 확인한 후 애플리케이션 컨테이너가 실행되도록 보장하는 초기화 작업을 수행합니다.

 

init container를 왜 사용할까?

 

  • 환경 설정 및 초기화 작업: 애플리케이션 컨테이너가 시작되기 전에 설정 파일을 생성하거나, 데이터베이스 마이그레이션, 초기 데이터 로딩 등의 작업을 수행할 수 있습니다.
  • 종속성 확인: 메인 컨테이너가 실행되기 전에 다른 서비스나 리소스(예: 데이터베이스, 메시지 큐 등)가 준비되었는지 확인할 수 있습니다.

Infra Container

쿠버네티스로 클러스터링 된 노드에서, docker 나 contained 의 명령어를 이용하여 컨테이너를 조회하면 파드에 대한 컨테이너외에 추가 다음과 같은 컨테이너들이 존재함을 알 수 있다.

[root@localhost]# ctr --namespace k8s.io containers list
CONTAINER          IMAGE                                  RUNTIME                  
b17bab258...b27    nginx:v1.11.2                          io.containerd.runc.v2    
c4e93ac4f...0e3    calico-kube-controllers:latest         io.containerd.runc.v2    
cc775ac0a...b8e    calico-node:latest                     io.containerd.runc.v2    
...
ea76c4e66...781    k8s.gcr.io/pause:3.6                   io.containerd.runc.v2    
eadc02066...8c8    k8s.gcr.io/pause:3.6                   io.containerd.runc.v2    
f4e2793c1...dcd    k8s.gcr.io/pause:3.6                   io.containerd.runc.v2    
fd2fb45f5...ee8    k8s.gcr.io/pause:3.6                   io.containerd.runc.v2    
[root@localhost]#

 

상단 명령어의 결과로 보이는 컨테이너들 중 일부는 k8s.gcr.io/pause:3.6 이란 이미지를 공통으로 사용하고 있다. 이 컨테이너들은 Pod Infra container 라고 불린다.

  • Pod의 환경을 만들어주는 컨테이너
    • IP, Host name 등의 인프라를 관리하고 생성해주는 컨테이너
    • 인프라를 관리하는 컨테이너이므로 kubectl get pods에서 명시되지 않음

Kubernetes에서 Infra Container(보통 "pause container"라고도 불림)는 Pod 내의 다른 컨테이너들이 공유하는 네임스페이스(예: 네트워크, IPC, PID 등)를 유지하기 위해 사용되는 매우 경량의 컨테이너입니다. 주요 역할은 다음과 같습니다

  • 네임스페이스 유지: Infra container는 Pod의 네트워크 네임스페이스를 생성 및 유지합니다. 이로 인해 Pod 내의 모든 컨테이너가 동일한 IP 주소와 포트를 공유할 수 있습니다.
  • 라이프사이클 관리: Pod의 핵심 인프라로서, 다른 컨테이너들이 해당 네임스페이스에 연결되어 실행되므로, infra container가 계속 실행되는 한 Pod의 네임스페이스는 유지됩니다.
  • 네트워크 안정성 제공: 만약 애플리케이션 컨테이너가 재시작되거나 교체되더라도, Pod의 IP 주소나 네트워크 구성이 변경되지 않도록 보장합니다.

이처럼 Infra Container는 Pod 내부의 컨테이너들이 일관된 환경에서 실행될 수 있도록 기반을 마련해주며, Kubernetes의 Pod 관리와 네트워크 안정성에 중요한 역할을 합니다.


Static Pod

Static Pod는 Kubernetes 클러스터에서 kubelet이 직접 관리하는 Pod를 의미합니다. 일반적인 Pod는 API 서버를 통해 스케줄러에 의해 노드에 할당되지만, Static Pod는 아래와 같은 특징을 가집니다:

  • 직접 관리:
    Static Pod는 kubelet에 의해 직접 관리되며, 클러스터 API 서버에 의해 스케줄링되지 않습니다. 이를 위해 관리자는 노드의 특정 디렉토리(예: /etc/kubernetes/manifests)에 Pod 매니페스트 파일을 생성합니다.
  • 자동 재시작:
    kubelet은 해당 디렉토리를 감시하여 매니페스트 파일에 정의된 Pod를 자동으로 생성하고, 만약 Pod가 종료되거나 실패하면 매니페스트 파일에 따라 자동으로 재시작합니다.
  • 주로 시스템 구성요소에 사용:
    Control Plane의 구성 요소(kube-apiserver, kube-controller-manager, kube-scheduler, etcd 등)나 클러스터 초기화 시 필수적인 컴포넌트들을 Static Pod로 실행하는 경우가 많습니다. 이를 통해 API 서버와의 의존성을 줄이고, 각 노드에서 독립적으로 실행될 수 있도록 합니다.

이처럼 Static Pod는 Kubernetes 클러스터에서 특정 노드에 직접 배포하고 관리해야 하는 중요한 컴포넌트나 시스템 데몬을 안정적으로 운영하기 위한 메커니즘으로 활용됩니다.