Skip to content

Kubernetes:Pod

다른 컨테이너 오케스트레이션 툴과 달리, Kubernetes는 컨테이너를 직접 실행하지 않는다. 대신에 하나 이상의 컨테이너를 그룹으로 묶어서 구조화한 pod를 관리한다. 같은 pod에 포함된 컨테이너들은 네트워크, IPC, 볼륨등을 공유한다. Pod에 포함된 컨테이너들은 하나의 물리적 노드에 배치가 되는데, 때문에 이들 자원의 공유와 커뮤니케이션이 쉬워진다. 하나의 노드에는 여러 pod가 배치될 수 있는데, 이들 pod는 다른 pod와 완전히 격리(isolation)된다.

Example

스팩 파일로 적용하는 방법:

apiVersion: v1
kind: Pod
metadata:
  name: nginx-instance
  labels:
    app: simple-http
spec:
  containers:
    - name: nginx-app
      image: nginx

kubectl:apply 명령으로 실행:

$ kubectl apply -f ./test.yml
pod/nginx-instance created

kubectl:get 명령으로 확인:

$ kubectl get pods
NAME             READY   STATUS    RESTARTS   AGE
nginx-instance   1/1     Running   0          82s

kubectl:logs 명령으로 로그(표준출력) 확인:

$ kubectl logs nginx-instance
$ kubectl logs -f nginx-instance  ## --follow 옵션. 출력상태를 계속 유지

kubectl:exec 명령으로 Pod 에서 프로세스 실행.

$ kubectl exec -it nginx-instance -- bash
root@nginx-instance:/# ...

kubectl:delete 명령으로 제거.

$ kubectl delete -f ./test.yml
pod "nginx-instance" deleted

컨테이너 상태 모니터링

컨테이너 생성과 실제 서비스 준비는 약간의 차이가 있습니다. 서버를 실행하면 바로 접속할 수 없고 짧게는 수초, 길게는 수분 Java ㅂㄷㅂㄷ 의 초기화 시간이 필요한데 실제로 접속이 가능할 때 서비스가 준비되었다고 말할 수 있습니다.

Pod-monitoring.jpg

쿠버네티스는 컨테이너가 생성되고 서비스가 준비되었다는 것을 체크하는 옵션을 제공하여 초기화하는 동안 서비스되는 것을 막을 수 있습니다.

livenessProbe

컨테이너가 정상적으로 동작하는지 체크하고 정상적으로 동작하지 않는다면 컨테이너를 재시작하여 문제를 해결합니다.

정상이라는 것은 여러 가지 방식으로 체크할 수 있는데 여기서는 http get 요청을 보내 확인하는 방법을 사용합니다.

piVersion: v1
kind: Pod
metadata:
  name: echo-lp
  labels:
    app: echo
spec:
  containers:
    - name: app
      image: ghcr.io/subicura/echo:v1
      livenessProbe:
        httpGet:
          path: /not/exist
          port: 8080
        initialDelaySeconds: 5
        timeoutSeconds: 2 # Default 1
        periodSeconds: 5 # Defaults 10
        failureThreshold: 1 # Defaults 3

일부러 존재하지 않는 path(/not/exist)와 port(8080)를 입력하였습니다.

상태 확인:

NAME      READY   STATUS             RESTARTS      AGE
echo-lp   0/1     CrashLoopBackOff   4 (15s ago)   60s

정상적으로 응답하지 않았기 때문에 Pod이 여러 번 재시작되고 CrashLoopBackOff 상태로 변경되었습니다.

INFORMATION

httpGet 외에 tcpSocket, exec 방법으로 상태를 체크할 수 있습니다.

readinessProbe

컨테이너가 준비되었는지 체크하고 정상적으로 준비되지 않았다면 Pod으로 들어오는 요청을 제외합니다.

livenessProbe와 차이점은 문제가 있어도 Pod을 재시작하지 않고 요청만 제외한다는 점입니다.

apiVersion: v1
kind: Pod
metadata:
  name: echo-rp
  labels:
    app: echo
spec:
  containers:
    - name: app
      image: ghcr.io/subicura/echo:v1
      readinessProbe:
        httpGet:
          path: /not/exist
          port: 8080
        initialDelaySeconds: 5
        timeoutSeconds: 2 # Default 1
        periodSeconds: 5 # Defaults 10
        failureThreshold: 1 # Defaults 3

상태 확인

NAME      READY   STATUS    RESTARTS   AGE
echo-rp   0/1     Running   0          14s

READY상태가 0/1인 것을 확인할 수 있습니다.

livenessProbe + readinessProbe

보통 livenessProbe와 readinessProbe를 같이 적용합니다. 상세한 설정은 애플리케이션 환경에 따라 적절하게 조정합니다.

apiVersion: v1
kind: Pod
metadata:
  name: echo-health
  labels:
    app: echo
spec:
  containers:
    - name: app
      image: ghcr.io/subicura/echo:v1
      livenessProbe:
        httpGet:
          path: /
          port: 3000
      readinessProbe:
        httpGet:
          path: /
          port: 3000

3000번 포트와 / 경로는 정상적이기 때문에 Pod이 오류없이 생성된 것을 확인할 수 있습니다.

다중 컨테이너

대부분 1 Pod = 1 컨테이너지만 여러 개의 컨테이너를 가진 경우도 꽤 흔합니다.

하나의 Pod에 속한 컨테이너는 서로 네트워크를 localhost로 공유하고 동일한 디렉토리를 공유할 수 있습니다.

apiVersion: v1
kind: Pod
metadata:
  name: counter
  labels:
    app: counter
spec:
  containers:
    - name: app
      image: ghcr.io/subicura/counter:latest
      env:
        - name: REDIS_HOST
          value: "localhost"
    - name: db
      image: redis

요청횟수를 redis에 저장하는 간단한 웹 애플리케이션을 다중 컨테이너로 생성합니다.

다중 컨테이너를 포함한 Pod은 다음과 같습니다.

Pod-multi.jpg

같은 Pod에 컨테이너가 생성되었기 때문에 counter앱은 redis를 localhost로 접근할 수 있습니다.

아직 Service를 배우지 않아 브라우저 테스트는 어려우니 직접 컨테이너에 접속해서 테스트해보겠습니다.

# Pod 생성
kubectl apply -f counter-pod-redis.yml

# Pod 목록 조회
kubectl get pod

# Pod 로그 확인
kubectl logs counter # 오류 발생 (컨테이너 지정 필요)
kubectl logs counter app
kubectl logs counter db

# Pod의 app컨테이너 접속
kubectl exec -it counter -c app -- sh
# curl localhost:3000
# curl localhost:3000
# telnet localhost 6379
  dbsize
  KEYS *
  GET count
  quit

# Pod 제거
kubectl delete -f counter-pod-redis.yml

See also

Favorite site