쿠버네티스에서 생성하고 관리할 수 있는 배포 가능한 가장 작은 단위
⇒ 하나 이상의 컨테이너의 그룹
Docker 개념 측면에서 Pod는 공유 네임스페이스와 공유 파일시스템 볼륨이 있는 Docker Container Group과 비슷하다.
개념 정리
cgroup : Control Group의 약자, 하드웨어 자원을 배분하는 기능
( CPU, RAM, .. 의 자원을 사용자가 원하는 만큼 격리된 프로세스에 할당해 줄 수 있음 )
Namespace : Process를 독립시켜주는 가상화 기술
( 독립된 프로세스는 PID, IPC, Network, UID, Mount, UTS 가 독립적으로 존재할 수 있다. )
Pod는 생성부터 삭제까지의 과정에 생명 주기(Lifecycle)가 있다.
Pending : 쿠버네티스 시스템에 파드를 생성중임을 뜻한다.
Running : Pod 안 모든 컨테이너가 실행 중인 상태
Succeeded : Pod 안 모든 컨테이너가 정상 실행 종료된 상태로 재시작되지 않는다.
Failed : Pod 안 모든 컨테이너 중 정상적으로 실행 종료되지 않은 컨테이너가 있는 상태
( 컨테이너 종료 코드가 0이 아니면 비정상 종료이거나 시스템이 직접 종료한 것 )
Unknown : 파드의 상태를 확인할 수 없는 상태이다.
Pod의 생명 주기는 kubectl describe pods <<파드 이름>> 명령을 실행한 후
Status 항목을 살펴보면 확인할 수 있다.
: 컨테이너가 실행되었는지 확인한다. 이 진단에 실패하면 Kubelet은 컨테이너를 종료시키고, 재시작 정책에 따라서 컨테이너를 재시작한다.
( 컨테이너에 livenessProbe를 어떻게 할지 명시하지 않았다면 기본값은 Success이다. )
: 컨테이너가 실행된 후 실제로 서비스 요청에 응답할 수 있는지를 진단한다.
이 진단에 실패하면 Endpoint controller는 해당 파드에 연결된 모든 서비스를 대상으로 엔드포인트 정보를 제거한다. 첫 번째 readinessProbe를 하기 전까지의 기본 상태 값은 Failure이다.
( readinessProbe를 지원하지 않는 컨테이너라면 기본 상태 값은 Success이다. )
컨테이너 진단은 컨테이너가 구현한 핸들러를 Kubelet이 호출하여 실행한다. 총 3가지가 있음
ExecAction
: 컨테이너 안에 지정된 명령을 실행하고 종료 코드가 0일때 Success라고 진단한다.
TCPSocketAction
: 컨테이너 안에 지정된 IP와 포트로 TCP 상태를 확인하고 포트가 열려있으면 Success라고 진단한다.
HTTPGetAction
: 컨테이너 안에 지정된 IP, Port, 경로로 HTTP Get 요청을 보낸다.
( 응답 상태 코드가 200 ~ 400 사이면 Success라고 진단한다. )
Init Container ?
: App Container가 실행되기 전 Pod를 초기화한다. 보안상 이유로 App Container 이미지와 같이 두면 안되는 App의 소스 코드를 별도로 관리할 때 유용하다.
여러 개를 구성할 수 있으며 여러 개 있다면 YAML 파드 템플릿에 명시된 순서대로 초기화 컨테이너가 실행된다.
초기화 컨테이너 실행이 실패한다면 성공할 때까지 재시작한다.
⇒ 선언적(Declarative) 특징에서 벗어날 수 있으며 필요한 명령들을 순서대로 실행하는 데 이용할 수 있다.
초기화 컨테이너가 모두 실행된 후 App Container가 실행된다.
readinessProbe를 지원하지 않는다.
spec:
initContainers:
# 첫 번째 초기화 컨테이너
- name: init-myservice
image: arisu1000/simple-container-app:latest
command: ['sh', '-c', 'sleep 2; echo helloworld01;']
# 두 번째 초기화 컨테이너
- name: init-mydb
image: arisu1000/simple-container-app:latest
command: ['sh', '-c', 'sleep 2; echo helloworld02;']
# 초기화 컨테이너가 모두 성공적으로 수행 시 메인 컨테이너 생성
containers:
- name:
image: arisu1000/simple-container-app:latest
command: ['sh', '-c', 'echo The app is running! && sleep 3600']
root@instance-1:~/kubernetes-sample/pod# kubectl get pods -w
NAME READY STATUS RESTARTS AGE
kubernetes-simple-pod 0/1 Init:1/2 0 10s
kubernetes-simple-pod 0/1 PodInitializing 0 11s
kubernetes-simple-pod 1/1 Running 0 12s
# kubectl describe pods kubernetes-simple-pod
..
..
Init Containers:
init-myservice:
Container ID: docker://f106ff7109d2118802f8d60e728748b6b5a131495dfc58a79a642a39972ed856
..
..
init-mydb:
Container ID: docker://4fed60d740bcb412a8a51f97b76cdf9df30b90951bbb48bf6e37d7f143eb224f
Image: arisu1000/simple-container-app:latest
..
..
Containers:
kubernetes-simple-pod:
Container ID: docker://c6c6f449a0077fc3719e836573e0452700ab8719c0d6d1acc53aec923569dcf6
Image: arisu1000/simple-container-app:latest
..
..
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 47s default-scheduler Successfully assigned default/kubernetes-simple-pod to instance-5
Normal Pulling 46s kubelet Pulling image "arisu1000/simple-container-app:latest"
Normal Pulled 43s kubelet Successfully pulled image "arisu1000/simple-container-app:latest" in 2.6273271s
Normal Created 43s kubelet Created container init-myservice
Normal Started 43s kubelet Started container init-myservice
Normal Pulling 40s kubelet Pulling image "arisu1000/simple-container-app:latest"
Normal Pulled 39s kubelet Successfully pulled image "arisu1000/simple-container-app:latest" in 349.05471ms
Normal Created 39s kubelet Created container init-mydb
Normal Started 39s kubelet Started container init-mydb
Normal Pulling 37s kubelet Pulling image "arisu1000/simple-container-app:latest"
Normal Pulled 36s kubelet Successfully pulled image "arisu1000/simple-container-app:latest" in 266.076585ms
Normal Created 36s kubelet Created container kubernetes-simple-pod
Normal Started 36s kubelet Started container kubernetes-simple-pod
Pod infra Container
Kubernetes에는 모든 Pod에서 항상 실행되는 Pause라는 컨테이너가 있다.
pause는 파드 안 기본 네트워크로 실행되며, PID가 1로 설정되므로 다른 컨테이너의 부모 컨테이너 역할을 한다. 파드 안 다른 컨테이너는 pause 컨테이너가 제공하는 네트워크를 공유하여 사용한다. 그래서 파드 안 다른 컨테이너가 재시작되었을 때는 파드의 IP를 유지하지만, pause 컨테이너가 재시작되면 파드 안 모든 컨테이너도 재시작한다.
kubelet에는 명령 옵션으로 - -pod-infra-container-image가 있다. pause가 아닌 다른 컨테이너를 파드 인프라 컨테이너로 지정할 때 사용한다.
관련되는 개념 : namespace, cgroups, PID, Zombie process, fork, exec, systemcall
Static Pod
: kube-apiserver를 통하지 않고 해당 Node의 Kubelet이 직접 실행하는 Pod
kubelet 설정의 - -pod-manifest-path라는 옵션에 지정한 디렉터리에 스태틱 파드를 실행하려는 YAML 템플릿 파일을 넣어두면 Kubelet이 그것을 감지하여 Pod로 실행한다.
보통 Static Pod는 Kube-apiserver 혹은 etcd 같은 시스템 파드를 실행하는 용도로 많이 사용한다. 쿠버네티스에서 Pod를 실행하려면 kube-apiserver가 필요한데 kube-apiserver 자체를 처음 실행하는 별도의 수단으로 스태틱 파드를 이용하는 것이다.
containers:
..
..
resources:
requests:
cpu: 0.1
memory: 200M
limits:
cpu: 0.5
memory: 1G
CPU
0.1로 설정 시 연산량을 100이라고 가정했을 때 최소 10%는 확보해놓고 있겠다는 뜻
0.5 : 최대 50% 사용하겠다는 것을 명시
Memory
최소 200M의 메모리 공간을 미리 확보
최대 1G의 메모리 공간을 사용
containers:
..
..
env:
#### 1
#### 가장 기초적인 방법으로 직접 name과 value를 지정해줄 수 있다.
- name: TESTENV01
value: "testvalue01"
#### 2
#### valueFrom : 어딘가로부터 key, value를 참조하겠음을 의미
#### fieldRef : 파드의 현재 설정 내용을 값으로 설정하겠다는 뜻
#### fieldPath : 값을 참조하려는 항목의 위치를 지정해준다.
- name: HOSTNAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
#### 3
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
#### 4
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
#### 5
#### 컨테이너에 CPU, Memory 사용량을 얼마나 할당했는지에 관한 정보이다.
- name: CPU_REQUEST
valueFrom:
resourceFieldRef:
containerName: kubernetes-simple-pod
resource: requests.cpu
#### 6
- name: CPU_LIMIT
valueFrom:
resourceFieldRef:
containerName: kubernetes-simple-pod
resource: limits.cpu
확인
제대로 환경 변수가 설정되었는지 확인하기 위해 kubectl exec 명령어로 직접 컨테이너 내부로 접속하여 확인하였다.
root@instance-1:~/kubernetes-sample/pod# kubectl exec -it kubernetes-simple-pod sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
~ #
~ # env
POD_IP=10.233.118.7
KUBERNETES_PORT=tcp://10.233.0.1:443
KUBERNETES_SERVICE_PORT=443
CPU_REQUEST=0
HOSTNAME=instance-5
TESTENV01=testvalue01
SHLVL=1
HOME=/root
TERM=xterm
POD_NAME=kubernetes-simple-pod
KUBERNETES_PORT_443_TCP_ADDR=10.233.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
CPU_LIMIT=2
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.233.0.1:443
KUBERNETES_SERVICE_HOST=10.233.0.1
PWD=/root
## kubectl describe pods <<POD_NAME>> 으로도 확인할 수 있다.
..
..
Environment:
TESTENV01: testvalue01
HOSTNAME: (v1:spec.nodeName)
POD_NAME: kubernetes-simple-pod (v1:metadata.name)
POD_IP: (v1:status.podIP)
CPU_REQUEST: 0 (requests.cpu)
CPU_LIMIT: node allocatable (limits.cpu)
..
..