[Kubernetes 시작하기] 05. 파드

2023. 12. 29. 16:25Infrastructure/Kubernetes

반응형
  1. 파드
    1. 파드?
    2. 파드 매니페스트
  2. 파드
    1. 명령어를 이용한 파드 생성/삭제
    2. 파드 매니페스트 적용을 통한 파드 실행
  3. 파드에 접근
    1. 파드 로그 출력
    2. 컨테이너에서 명령 실행하기
  4. Probe
    1. 활성 프로브(liveness probe)
    2. 준비 프로브(readiness probe)
    3. 시작 프로브 (startup probe)
    4. 상태 검사의 기타 타입

1. 파드

1.1. 파드?

컨테이너화 된 애플리케이션을 배포하고자 할때,
여러 애플리케이션을 한 머신 위에 단일 원자 단위(atimic unit)로 배포하고자 할 것입니다

쿠버네티스에서는, 이 단일 원자 단위를 Pod(파드)라고 부릅니다.

어떤 애플리케이션을 서비스하기 위해 웹서버Git 동기화 서버 가 필요하고, 그 두 서버는 _공통 파일 리소스_를 이용하고 있다고 할때

  • 웹서버와 Git동기화 서버는 각각 별도의 컨테이너에 담는다
  • 위의 두 컨테이너는 Volume(공통 파일 리소스 서버)에 접근할 수 있다
  • 두 서버는 하나의 기능을 위한 서버이자, 공유 파일시스템을 이용하며, 서로 공생관계이다.

이런 두 컨테이너를 Pod라는 하나의 단위로 그룹화 합니다.

파드는 동일한 실행환경에서 동작하는 애플리케이션 컨테이너와 볼륨의 집합 이고, 쿠버네티스 클러스터에서 배포할 수 있는 가장 작은 아티팩트 입니다.

동일한 파드 내에 실행되는 애플리케이션은

  • 같은 머신에 존재합니다.
  • 동일한 ip, port, network namespace를 공유하고, 동일한 호스트명(uts 네임스페이스)을 갖습니다.
  • 시스템 V IPC나 POSIX 메시지 큐 위의 프로세스 간 통신 채널을 통해 통신할 수 있습니다.

서로 다른 파드에 있는 애플리케이션은 서로 격리되어있고, 서로 다른 ip주소와 호스트 주소를 갖습니다.

어떤 애플리케이션을 하나에 다 두었을때와 각자 별도로 분리했을 때를 생각했을때
각기 다른 머신에 두어도 잘 동작이 되는 애플리케이션이라면 각기 다른 파드에 구성하는 것이 옳습니다.

또 필요에따라 서버의 scale out을 시행할 텐데,
파드로 묶어둘 경우 파드 내에 들어있는 모든 애플리케이션의 확장이 일어난다는 점도 염두해야 합니다.

1.2. 파드 매니페스트

파드는 파드 매니페스트(Pod manifest)에 기술됩니다.

파드 매니페스트는 쿠버네티스 API객체를 yaml 텍스트 파일 형태로 표현한 것으로, 파드 매니페스트 파일에 작성된 내용은 선언형 컨피규레이션 성질에 의해 쿠버네티스 서버에 적용됩니다.

아래 코드는 파드 매니페스트 예시입니다.

apiVersion: v1
kind: Pod
metadata:
  name: kuard
spec:
  containers:
    - image: gcr.io/kuar-demo/kuard-arm64:blue
      name: kuard
      ports:
        - containerPort: 8080
          name: http
          protocol: TCP

2. 파드 생성

2.1. 명령어를 이용한 파드 생성/삭제

파드 생성

kubectl run kuard --image=gcr.io/kuar-demo/kuard-arm64:blue
pod/kuard created

pod 상태 및 목록 조회

kubectl get pods
NAME    READY   STATUS    RESTARTS   AGE
kuard   1/1     Running   0          65s

파드를 생성한 후 바로 위의 명령어를 실행하면, Pending으로 조회되다가 Running으로 바뀝니다.
위의 명령어는 파드 목록 뿐만아니라, 준비된 컨테이너 수, 파드의 상태, 파드의 수명, 파드가 재시작된 수를 확인할 수 있습니다.


파드 삭제

파드 삭제 명령어 실행 후, 30s의 종료 유예시간 후 삭제됩니다.
유예 시간동안은 Terminating 상태로 출력되며, 이 상태에서는 더이 상 새로운 요청을 받지 않지만, 현재 처리중인 요청이 끝낼수 있도록 하기 때문에 신뢰성 측면에서 강점이 있습니다.

kubectl delete pod/kuard

파드가 삭제할 때에는 파드 내에 들어있는 컨테이너 및 데이터가 함께 삭제됩니다.
만약, 파드 삭제시 제거되면 안되는 데이터가 있다면, 그 데이터들은 Persistent Volume 에 설정해둬야 합니다.


2.2. 파드 매니페스트 적용을 통한 파드 실행

kuard-pod.yml 파일에 파드에 관한 설정을 정의해두고, apply를 통해 파드를 생성할 수 있습니다.

apiVersion: v1
kind: Pod
metadata:
  name: kuard
spec:
  containers:
    - image: gcr.io/kuar-demo/kuard-arm64:blue
      name: kuard
      ports:
        - containerPort: 8080
          name: http
          protocol: TCP

파드 실행

kubectl apply -f kuard-pod.yml
pod/kuard created

kubectl get pods 명령어를 실행하면 kuard 파드가 조회됩니다.

위와같이 파일을 통해 파드에 대한 정의를 하게된다면 장기적인 관점에서 편리하게 관리할 수 있습니다.


파드 세부사항 조회

파드에 대한 상세한 정보를 확인하고 싶다면 kubectl describe pods 파드명 을 사용하면 됩니다.

kubectl describe pods kuard
Name:             kuard
Namespace:        default
Priority:         0
Service Account:  default
Node:             minikube/192.168.49.2
Start Time:       Mon, 27 Nov 2023 00:02:09 +0900
Labels:           <none>
Annotations:      <none>
Status:           Running
IP:               10.244.0.6
IPs:
  IP:  10.244.0.6

파드 내에서 실행중인 컨테이너에 대한 정보

Containers:
  kuard:
    Container ID:   docker://364fd550f63c6e92805e41533ac72777c9af0a8b27ce630176f0bb9d41658120
    Image:          gcr.io/kuar-demo/kuard-arm64:blue
    Image ID:       docker-pullable://gcr.io/kuar-demo/kuard-arm64@sha256:4f500bd9af3813076b7672450fd060a51a5c98d6fea1772d48ae0447da66a26a
    Port:           8080/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Mon, 27 Nov 2023 00:02:09 +0900
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-sghjc (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  kube-api-access-sghjc:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s

스케줄링된 시간과 이미지를 가져온 시간, 상태검사 실패로인한 재시작 여부, 시간 등에 대한 이벤트 정보

Events:
  Type    Reason     Age    From               Message
  ----    ------     ----   ----               -------
  Normal  Scheduled  4m48s  default-scheduler  Successfully assigned default/kuard to minikube
  Normal  Pulled     4m48s  kubelet            Container image "gcr.io/kuar-demo/kuard-arm64:blue" already present on machine
  Normal  Created    4m48s  kubelet            Created container kuard
  Normal  Started    4m48s  kubelet            Started container kuard

3. 파드에 접근

파드 내부에서 실행되고 있는 코드 및 데이터와 상호작용하는 방법을 알아봅니다.


3.1. 파드 로그 출력

kubectl logs 파드명 명령어를 이용하면, 실행중인 파드로부터 현재 로그를 다운받을 수 있습니다.

  • -f
    • 연속 로그 스트림으로 실시간 로그를 확인
  • --previous
    • 컨테이너의 이전 인스턴스로 부터 로그를 가져옵니다
    • 컨테이너가 문제가 있어 계속해서 컨테이너 재시작하고 있는 경우에 활용하면 좋습니다
kubectl logs kuard
2023/11/26 15:02:09 Starting kuard version: v0.10.0-blue
2023/11/26 15:02:09 **********************************************************************
2023/11/26 15:02:09 * WARNING: This server may expose sensitive
2023/11/26 15:02:09 * and secret information. Be careful.
2023/11/26 15:02:09 **********************************************************************
2023/11/26 15:02:09 Config:
{
  "address": ":8080",
  "debug": false,
  "debug-sitedata-dir": "./sitedata",
  "keygen": {
    "enable": false,
    "exit-code": 0,
    "exit-on-complete": false,
    "memq-queue": "",
    "memq-server": "",
    "num-to-gen": 0,
    "time-to-run": 0
  },
  "liveness": {
    "fail-next": 0
  },
  "readiness": {
    "fail-next": 0
  },
  "tls-address": ":8443",
  "tls-dir": "/tls"
}
2023/11/26 15:02:09 Could not find certificates to serve TLS
2023/11/26 15:02:09 Serving on HTTP on :8080

3.2. 컨테이너에서 명령 실행하기

kubectl exec 명령어를 사용하여, 컨테이너 내부에서 명령을 실행할 수 있습니다.

kubectl exec kuard -- date
Sun Nov 26 15:27:00 UTC 2023

여기에 -it 옵션을 추가하면, 대화형으로 명령을 계속해서 실행할 수 있습니다.

kubectl exec -it kuard -- sh
~ $ls
bin    dev    etc    home   kuard  lib    media  mnt    opt    proc   root   run    sbin   srv    sys    tmp    usr    var

4. Probe(프로브)

쿠버네티스에서는 프로세스 health check를 통해 컨테이너가 살아있는지 체크하며, 문제가 있을시 쿠버네티스가 애플리케이션을 재시작 해줍니다.

하지만, 애플리케이션의 health check는 문제가 없지만, 프로세스 deadlock에 걸린 상태라 요청을 처리할 수 없는 상태라면 어떻게 해야할까

쿠버네티스에서는 이러한 문제를 해결하고자 liveness(활성) 상태 검사를 도입했습니다.
단순히 애플리케이션이 동작되고 있는 것 뿐만 아니라, 정상 기능 수행 여부를 검사하는 기능입니다.

이는, 애플리케이션마다 정의가 달라질 수 있는 부분이기 때문에 파드 매니페스트에 정의합니다.

쿠버네티스에서는 다양한 프로브 옵션을 제공하며, 별도로 지정하지 않을 경우 기본값으로 설정됩니다.
관련 링크: Configure Probes

제공하고 있는 고급 프로브 옵션에는 아래와 설정들이 있습니다.

  • 파드 구동 후 프로브를 시작하고자 대기하는 시간
  • 실패로 간주할 총 실패 수
  • 실패수를 재설정하는데에 필요한 성공 횟수

4.1. 활성 프로브 (liveness probe)

컨테이너 단위로 정의되며, 파드의 각 컨테이너별로 상태검사를 수행합니다.

kubectl apply -f kuard-pod-health.yml
pod/kuard created

포트포워딩 설정을 통해 호스트와 파드 내의 이미를 연결할 수 있습니다.

kubectl port-forward kuard 8080:8080
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080
Handling connection for 8080

포트포워딩 설정을 마쳤으면, kuard 웹 페이지에 접근이 가능합니다.
Liveness Probe 탭에 들어가면, 프로브 실행 결과를 확인할 수 있는데

01-2

Fail 링크를 클릭하여 임의로 상태 검사 실패를 시켜봅니다.
그러면, 아래와 같이 500 status가 노출되다가 재시작을 행하게 됩니다.

활성 상태 검사 실패에 대한 default 반응은 파드를 재시작하는 것입니다.
이 값은 restartPolicy(파드 재시작 정책) 설정으로 변경할 수 있습니다.

  • restartPolicy
    • Always
      • 기본값
      • 활성 검사 실패시 재시작
    • OnFailure
      • 활성 검사 실패 또는 0이 아닌 프로세스 정지 코드시 재시작
    • Never
      • 재시작하지 않는다

01-3


kubectl describe pods kuard 명령어를 이용하여 Event 섹션에서 재시작에 관련된 세부 정보를 확인할 수 있습니다.

Events:
  Type     Reason     Age                 From               Message
  ----     ------     ----                ----               -------
  Normal   Scheduled  5m1s                default-scheduler  Successfully assigned default/kuard to minikube
  Normal   Pulled     31s (x2 over 5m1s)  kubelet            Container image "gcr.io/kuar-demo/kuard-arm64:blue" already present on machine
  Normal   Created    31s (x2 over 5m1s)  kubelet            Created container kuard
  Normal   Started    31s (x2 over 5m1s)  kubelet            Started container kuard
  Warning  Unhealthy  31s (x3 over 51s)   kubelet            Liveness probe failed: HTTP probe failed with statuscode: 500
  Normal   Killing    31s                 kubelet            Container kuard failed liveness probe, will be restarted

4.2. 준비 프로브 (readiness probe)

준비 프로브는 상태 검사를 하는 프로프 중 하나 입니다.

liveness probe는 애플리케이션의 정상 동작 여부를 검사하고, 활성검사 실패시 컨테이너를 재시작한다면,

readiness probe는 컨테이너가 사용자 요청 처리에 대한 준비 유무를 검사합니다.
준비 상태 검사 실패시, 컨테이너는 서비스 로드밸런서에서 제거됩니다

준비프로브와 활성 프로브를 함께 사용하면 클러스터 내에서 정상 상태의 컨테이너만 실행되게 할 수 있습니다.


4.3. 시작 프로브 (startup probe)

느리게 구동되는 컨테이너(slow-starting container)를 관리하기 위한 대안으로 도입되었습니다.
느리게 구동되는 컨테이너에 대해 느리게 폴링하고, 그 컨테이너가 초기화된 후 응답 활성 검사를 가능하게 합니다.

파드 구동시, 파드의 다른 프로브가 구동되기 전에 시작 프로브가 실행됩니다.

시작프로브는 시간이 초과되거나 성공할때까지 진행됩니다.

  • 시간이 초과되면 파드를 다시 시작하고
  • 성공하면 활성 프로브로 인계됩니다.

4.3. 상태 검사의 기타 타입

상태검사는 HTTP 검사 외에도

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-http
spec:
  containers:
  - name: liveness
    image: registry.k8s.io/liveness
    args:
    - /server
    livenessProbe:
      httpGet:
        path: /healthz
        port: 8080
        httpHeaders:
        - name: Custom-Header
          value: Awesome
      initialDelaySeconds: 3
      periodSeconds: 3

TCP 소켓을 이용한 상태 검사도 지원하고

apiVersion: v1
kind: Pod
metadata:
  name: goproxy
  labels:
    app: goproxy
spec:
  containers:
  - name: goproxy
    image: registry.k8s.io/goproxy:0.1
    ports:
    - containerPort: 8080
    readinessProbe:
      tcpSocket:
        port: 8080
      initialDelaySeconds: 15
      periodSeconds: 10
    livenessProbe:
      tcpSocket:
        port: 8080
      initialDelaySeconds: 15
      periodSeconds: 10

exec 프로브도 지원합니다.
exec 프로브는 컨테이너 내부에서 스크립트나 프로그램을 실행합니다.
스크립트가 종료코드 0을 반환할 경우 해당 프로브를 성공으로, 그 외의 경우 실패로 간주합니다.
HTTP 호출에 적합하지 않은 사용자 정의 애플리케이션의 검증 로직에 이용하면 좋습니다.

apiVersion: v1
kind: Pod
metadata:
  labels:
    test: liveness
  name: liveness-exec
spec:
  containers:
  - name: liveness
    image: registry.k8s.io/busybox
    args:
    - /bin/sh
    - -c
    - touch /tmp/healthy; sleep 30; rm -f /tmp/healthy; sleep 600
    livenessProbe:
      exec:
        command:
        - cat
        - /tmp/healthy
      initialDelaySeconds: 5
      periodSeconds: 5

그밖에 gRPC 프로브도 지원하니, 필요하다면 Define a gRPC liveness probe를 참고하시면 됩니다.


5. 리소스 관리

TODO ++

애플리케이션이 필요로하는 리소스의 양을 정의

쿠버네티스에서 사용자가 설정할 수 있는 리소스에 관련된 2가지 매트릭

  • resource 요청(requests)
    • 애플리케이션 실행을 위해 필요한 최소 resource 양 설정
  • resource 제한(limits)
    • 애플리케이션이 사용할 수 있는 최대 resource 양 설정

6. 볼륨을 통한 데이터 보존

쿠버네티스에서 제공하는 persistent storage 로, 파드가 삭제되거나 컨테이너가 재시작되어도 데이터가 삭제되지 않습니다.

spec.volumes 섹션에 컨테이너 목록에서 접근해야할 볼륨 목록을 추가하고,
볼륨을 이용할 컨테이너들은 volumeMounts 설정을 추가해줍니다.

apiVersion: v1
kind: Pod
metadata:
  name: kuard
spec:
  volumes:
    - name: kuard-data
      hostPath:
        path: /var/lib/kuard
  containers:
    - image: gcr.io/kuar-demo/kuard-arm64:blue
      name: kuard
      volumeMounts:
        - mountPath: /data
          name: kuard-data
      ports:
        - containerPort: 8080
          name: http
          protocol: TCP

노드

파드는 언제나 노드 위에서 동작합니다.
노드는 쿠버네티스에서 워커머신을 의미하고, 클러스터에 따라 가상머신일 수도 있고 물리머신일 수도 있습니다.

각 노드는 컨트롤 플레인에 의해 관리됩니다.
컨트롤 플레인은 클러스터 내의 노드를 통해 파드에 대한 스케쥴링을 자동으로 처리합니다.

728x90
반응형