kubernetes

POD

쿠버네티스에서 POD는 배포가능한 가장 작은 단위입니다. 보통 컨테이너를 배포한다는 이야기를 하지만, 사실은 컨테이너가 아니라 POD를 배포한다는 용어가 맞습니다. 그리고 배포한 POD위에 여러개의 컨테이너를 포함시키는 것이 가능합니다.

쿠버네티스에서 POD 내부에 실행되는 컨테이너들은 같은 환경을 가집니다. 따라서 최소 배포단위인 POD간의 격리는 맞는 말이지만, 컨테이너 간의 격리는 맞지 않는 말입니다. 따라서 컨테이너가 파드에서 여러개 실행 될때는 각각의 다른 포트를 가져야 실행이 됩니다.

POD안에서 여러개의 컨테이너를 실행 시키는 것이 가능합니다. 하지만 일반적으로 하나의 POD에는 하나의 컨테이너를 가지도록 구성을 합니다. 왜냐하면 하나의 어플리케이션인 컨테이너마다 POD에 넣어서 배포하는 것이 쿠버네티스가 효율적으로 관리를 하는 것이 가능하기 때문입니다. 하나의 파드에 하나의 컨테이너를 가지게 설계를 주로하기 때문에, 파드와 컨테이너를 동일하게 부르기도 합니다. 하지만 파드 없이 컨테이너를 배치하는 것은 불가능 하다는 것은 알아두셔야 합니다.

파드 생성 방법

yaml 파일을 통해 간단히 생성이 가능하다. ex-pod.yaml 파일을 아래와 같이 만들어보자.

yaml
apiVersion: v1
kind: Pod
metadata:
  name: ex-pod
spec:
  containers:
    - name: ex-container
      image: nginx:1.29
  • kind : 정의하는 객체의 종류를 의미합니다. 우리는 Pod를 생성하므로 Pod라 적힌 것을 확인 할 수 있습니다.
  • metadata: 객체 식별이름으로, 이 부분을 통해 객체 식별 및 정보 조회를 하기 때문에 중복되지 않는 이름을 가져야 합니다.
  • spec은 어떤 객체를 만들지 정의하는 부분입니다. 이부분은 kind의 정의된 객체 종류에 따라 다른 값들이 포함될 수 있습니다.
    • spec:name : 단순히 이름을 적어주는 곳입니다.
    • spec:image : 생성할 이미지를 적여주는 부분입니다.

물론 yaml파일만 적고 저장한다고 바로 실행되는 것은 아니다.

bash
$ kubectl apply -f ex-pod.yaml

명령어를 통해 yaml파일을 쿠버네티스 spec 적용이 가능하다.

Pod Phase

기본적으로 Pod도 life cycle을 가집니다. 각각의 라이플 사이클을 Phase(페이즈)라고 부릅니다. 보통 Pending과 Running을 자주 사용하게 됩니다. 전체 Phase의 종류는 아래와 같습니다.

Pending

  • 파드 생성 후부터 실행되기 전까지의 상태입니다. (파드가 노드에 배치되는 단계)

Running

  • 컨테이너가 실행되고 종료되기 전 단계로 Application의 로그가 뜬다면 Running 상태입니다. 이때, 만약 DB 연결 안되면 Application 다시 종료될 겁니다. 그 후에도 다시 시작될텐데, 이때도 Running 상태가 됩니다. 따라서 Running 상태인 경우에, 100프로 정상 실행되었다고 확정지으면 안되고 로그 및 작동 확인이 필요합니다.

Failed

  • 컨테이너가 비정상 종료된 상태입니다. 비정상 종료 시 바로 재시작을 하기 때문에, Failed상태는 거의 보기 힘들다고 할 수 있습니다. 아래의 재시작 정책에서 조금 더 확인해 봅시다. (Restart Policy)

Succeeded

  • 컨테이너 정상 종료된 상태로 exit 0인 상태를 의미합니다.

Unknown

  • 파드의 상태를 알 수 없는 상태를 의미합니다. 이러한 경우는 보통 하나의 파드만 장애가 나는 경우는 거의 없습니다. 이런 이슈는 대부분 하드웨어 이슈가 많기 때문에 발생하면 Node에 속한 전체 파드가 이러한 이슈가 발생한다. (인프라 레벨 해결필요)

Restart Policy (재시작 정책)

Single Container의 경우에 재시작 정책(Always/OnFailure/Never)에 대해 알아봅시다. 기본적으로 다른 설정이 없으면 Always 상태입니다.

Always

  • 종료된 컨테이너를 항상 재시작 합니다. 따라서 Always의 경우에는 Phase가 Failed나 Succeeded로 잘 가지 안게 됩니다.

OnFailure

  • 실패한 컨테이너만 재시작 합니다.
OnFailure 정상종료 테스트
apiVersion: v1
kind: Pod
metadata:
  name: OnFailure-pod
spec:
  restartPolicy: OnFailure
  containers:
    - name: my-container
      image: busybox
      command: ['sh', '-c', 'sleep 2']
  • pod 실행 시 2초 멈춤 후에 정상 종료됩니다. 이때 재시작하지 않습니다.
  • 확인 $ kubectl describe pod OnFailure-pod
OnFailure 비정상 테스트
apiVersion: v1
kind: Pod
metadata:
  name: OnFailure-pod
spec:
  restartPolicy: OnFailure
  containers:
    - name: my-container
      image: busybox
      command: ['sh', '-c', 'exit 1']
  • 비정상 강제 종료를 하는 부분입니다. 실행 후에 에러가 발생하고 리스타트를 진행합니다.

Never

  • 어떠한 경우에도 컨테이너를 재시작 하지 않습니다.
Never 비정상 테스트
apiVersion: v1
kind: Pod
metadata:
  name: Never-pod
spec:
  restartPolicy: Never
  containers:
    - name: my-container
      image: busybox
      command: ['sh', '-c', 'exit 1']
  • 에러 발생 후에 재시작 하지 않습니다. describe로 조회를 해보면 Status가 Failed이고 재시작하지 않습니다.

Container Status

Waiting

  • 컨테이너가 실행을 준비하고 있는 상태입니다.

Running

  • 컨테이너가 실행중인 상태입니다.

Terminated

  • 컨테이너가 정삭 혹은 비정상 종료된 상태입니다.

Container Restart with backoff

쿠버네티스에서는 컨테이너 종료 시 상태에 따라 재시작합니다. 기본적으로 컨테이너의 재시작 주기는 10s입니다. 재시작을 실패했을 경우에는 2배 후인 20s에 재시작하게 됩니다. 이러한 방식으로 재시작 주기가 2배로 증가하고 최대 5분까지 재시간 주기가 늘어납니다. 그리고 5분 마다 정상 실행 될때까지 반복하게 됩니다.

Container Lifecycle Hook

컨테이너의 시작과 종료 시점에 실행되는 명령어입니다. 사용빈도는 높지 않지만 알아두면 도움이 됩니다.

  • 컨테이너의 시작 직전(postStart : created와 running 사이)
  • 컨테이너의 종료 직전(preStop : runing 과 terminated 사이)