( 참고 : [교재] 핵심만 콕! 쿠버네티스 )
쿠버네티스 Pod
1. Pod 소개
Pod = 쿠버네티스의 최소 실행단위
( Pod를 통해 기본 가상환경을 제공함 )
가상환경 플랫폼 실행 단위
- 가상머신 : Instance
- 도커 : Container
- 쿠버네티스 : Pod
Pod의 특징
[1] 1개 이상의 container 실행
- 상황에 따라 2~3개의 컨테이너를 실행
[2] 동일 Node에 할당
- Pod 내에 실행되는 container들은, 반드시 동일한 node에 할당되며, 동일한 생명 주기를 가진다
- Pod가 삭제되면, Pod 내의 모든 container들이 삭제됨
[3] 고유의 Pod IP
- Pod 리소스는 cluster내에서 접근가능한 고유의 IP를 가진다
- NAT 통신 없이도, Pod의 고유 IP를 통해 접근 가능
[4] IP 공유
-
Pod내에 있는 “container들은 서로 IP를 공유”
( 따라서, 포트를 이용하여 구분함)
[5] Volume 공유
- Pod내에 있는 컨테이너들은, 동일한 Volume과 연결이 가능
구조 도식화
Node (192.168.0.6
)
- Pod 1 (
10.10.0.4
)- Container 1-1
- Container 1-2
- Pod 2 (
10.10.0.5
)- Container 2-1
- Container 2-2
YAML
- 쿠버네티스의 모든 리소스는 YAML 형태의 “선언형 명령 정의서”로 표현 가능
- ex) Pod의 YAML 정의서 파일 만들기 (
mynginx.yaml
)--dry-run
&-o yaml
을 조합하면, Pod를 실제로 생성하지 않고도 템플릿 파일 생성 가능
kubectl run mynginx --image nginx --dry-run=client -o yaml > mynginx.yaml
이렇게 해서 생성된 mynginx.yaml
:
# mynginx.yaml
apiVersion : v1
kind : Pod
metadata :
labels :
run : mynginx
name : mynbinx
spec :
containers :
- image : nginx
name : mynginx
restartPolicy : Never
Pod를 구성하기 위한 최소 property
apiVersion
: 리소스 동일 이름 충돌 피하기 위한 목적 ( 리소스의 scope를 정의 )- ex) V1
kind
: 리소스 타입- ex) Pod
metadata
: 리소스의 meta 정보- labels : 리소스의 label 정보
- name : 리소스의 name 정보
spec
: 리소스의 스펙 정보- containers : 1개 이상의 container 정의
- name : container의 이름
- image : container의 이미지 주소
- containers : 1개 이상의 container 정의
위에서 생성된 YAML파일를 사용하여, Pod를 생성하기
kubectl apply -f mynginx.yaml
생성 순서
-
step 1) 사용자가
kubectl
명령어를 통해, Pod 정의를 Master에 전달 -
step 2) Master는 YAML 정의의 유효성을 체크 &
특정 노드에 (사용자의 요청에 따라) container를 실행하도록 명령 내림
-
step 3) 명령 받은 node는 (요청사항에 따라) 컨테이너를 node에 실행
2. 라벨링 시스템
라벨 = 단순히 key,value 형태의 문자열
라벨링 시스템의 목적 :
-
특정 리소스를 참조하기 위해!
-
Pod에 트래픽을 전달하기 위해
Pod에 라벨을 부여한다
= (key,value) 형태의 문자열을 Pod의 meta data property에 추가한다
(1) 라벨 정보 부여
방법 1) kubectl label
kubectl label pod <NAME> <KEY>=<VALUE>
example )
- mynginx 이름의 pod에 hello(key) = world(value) 라벨을 추가
kubectl label pod mynginx hello=world
방법 2) 선언형 명령
- 애초에 YAML 정의서를 작성할 때, metadata property에 “직접 라벨 추가”
(2) 라벨 정보 확인
Pod에 부여된 라벨을 확인하기 위해, -L
옵션 사용
example) run이라는 key에 대한 value를 확인하려면?
kubectl get pod mynginx -L run
특정 라벨이 아닌, 전체 라벨을 확인하려면, --show-labels
옵션 사용
kubectl get pod mynginx --show-labels
(3) 라벨을 이용한 조건 필터링
특정한 라벨을 가진 Pod만 확인하려면, -l
옵션 사용
example) key가 run인 Pod 출력
kubectl get pod -l run
example) key가 run & value가 mynginx인 Pod 출력
kubectl get pod -l run=mynginx
(4) nodeSelector를 이용한 노드 선택
- Pod가 특정 Node에 할당되도록 스케줄링
- (default) Master가 알아서 어떤 Node에서 실행할지 스스로 판단하여 스케줄링
- (명시적) nodeSelector 통해서, Node 선택 가능
node들에게 달린 라벨 확인하기
kubectl get node --show-labels
라벨 추가하기 ( disktype )
- Master 노드에
disktype=ssd
라벨을 부여 - Worker 노드에
disktype=hdd
라벨을 부여
( pod와 마찬가지로, 동일하게 label 명령어 사용하면 됨 )
kubectl label node master disktype=ssd
kubectl label node worker disktype=hdd
노드의 라벨 확인하기
- 필터 :
disktype
라벨을 가진 노드의 라벨 정보만
kubectl get node --show-labels | grep distkype
실행하고자 하는 Pod의 YAML 정의서에, nodeSelector property 추가하기
example) node-selector.yaml
apiVersion :v1
kind : Pod
...
..
spec :
...
nodeSelector :
disktype : ssd
그런 뒤, 해당 YAML 파일을 선언하여 Pod 생성
kubectl apply -f node-selector.yaml
방금 생성한 Pod가 어느 node에서 생성되는지 확인
( 잘 되었다면, 우리가 지정한 Master node에서 생성되어야 함! )
kubectl get pod node-selector -o wide
노드 그룹
만약 2개 이상의 node에 동일한 라벨이 붙어있는 경우?
\(\rightarrow\) 노드의 상태에 따라 자동으로 “최적의 node”를 선택하여 할당함
3. 실행 명령 & 파라미터 지정
Pod 생성 시,실행 명령 &파라미터를 전달할 수 있음
ex) cmd.yaml
apiVersion : v1
...
spec :
restartPolicy : OnFailure
containers :
- name : nginx
image : nginx
command : ["/bin/echo"]
args : ["hello"]
-
command
: 컨테이너의 시작 실행 명령( = 도커의 ENTRYPOINT )
-
args
: 실행 명령에 넘겨줄 parameter( = 도커의 CMD )
-
restartPolicy
: Pod의 재시작 정책- Always : Pod 종료 시, 항상 재시작 시도 ( default )
- Never : 재시작 시도 X
- OnFailure : 실패 시에만!
이대로 실행하기~
kubectl apply -f cmd.yaml
4. 환경 변수 설정
Pod에 환경변수를 전달(설정)하는 방법
\(\rightarrow\) env property
활용하기
ex) env.yaml
# env.yaml
apiVersion : v1
...
spec :
containers :
- name : nginx
image : nginx
env :
- name : hello
value : "world!"
env
환경변수를 설정하는 property를 선언함- name : 환경변수의 key
- value : 환경변수의 value
위와 같은 환경변수를 가진 pod를 생성함
kubectl apply -f env.yaml
pod 생성 이후, exec 명령으로 env Pod에 printenv 명령 전달
- example) hello라는 key를 가진 환경변수 출력하기!
kubectl exec env -- printenv | grep hello
5. 볼륨 연결
Pod 내부 스토리지의 생명 주기 = Pod와 동일
( \(\therefore\) Pod 삭제 시, 저장된 데이터도 함께 삭제 )
따라서, 지속적으로 저장하고 싶다면, 볼륨을 따로 연결해야 함
-
여러 형태의 volume 존재
-
가장 기본이 되는 것은 “host Volume”
( 도커
-v
옵션과 유사하게, host 서버의 볼륨공간에 pod가 데이터를 저장 )
# volume.yaml
apiVersion : v1
..
spec :
containers :
- name :
...
volumeMounts:
- mountPath : /container-volume
name : my-volume
volumes :
- name : my-volume
hostPath :
path : /home
volumeMounts
: 컨테이너 내부에 사용될 볼륨 선언volumes
: Pod에서 사용할 volume 지정
위와 같이 volume이 연결된 pod를 실행하기
kubectl apply -f volume.yaml
volume 확인하기
\(\rightarrow\) 호스트 서버의 /home 디렉터리와 동일함을 확인함
kubectl exec volume --ls /container-volume
# ubuntu
ls /home
# ubuntu
6. 리소스 관리
여기서 말하는 리소스는..
- 쿠버네티스의 리소스 (X)
- 컴퓨팅 자원관리 (O)
container 실행에 필요한 리소스를 제약할 수 있음
( resources라는 property를 활용하여 )
- 최소 resource : requests
- 최대 resource : limits property
(1) requests : 최소 사용량
pod가 보장받을 수 있는 “최소 사용량”
ex) requests.yaml
# requests.yaml
apiVersion : v1
...
spec :
containers :
- name : nginx
image : nginx
resources :
requests :
cpu : "250m"
memory : "500Mi"
(2) limits : 최대 사용량
pod가 사용할 수 있는 “최대 사용량”
ex) limits.yaml
# limits.yaml
apiVersion : v1
...
spec :
containers :
- name : nginx
image : nginx
resources :
limits :
cpu : "500m"
memory : "1Gi"
최대 리소스 사용량을 넘어가면…
- CPU : throttling
- 메모리 : Out of Memory
무한 메모리 리소스를 반복하도록 하는 python script를 실행한 뒤 지켜보자
kubectl apply -f limits.yaml
watch kubectl get pod
7. 상태 확인
Pod가 정상적으로 동작하고 있는지 확인 ( health check )
(1) livenessProbe
컨테이너가 잘 살아있는지 확인
( + 자가치유를 위한 판단 기준으로 사용 )
ex) liveness.yaml
# liveness.yaml
apiVersion : v1
...
spec :
containers :
- name : nginx
image : nginx
livenessProbe :
httpGet :
path: /live
port: 80
해석 :
-
Pod의 상태를 확인하기 위해, HTTP 프로토콜의 GET method를 사용하여,
/live
위치의80
포트를 지속적으로 호출 -
리턴값이
-
200~300번대이면 : 정상
-
그 외 : 비정상
\(\rightarrow\) 종료 & 재시작
-
실행 후 확인하기
kubectl apply -f liveness.yaml
watch kubectl get pod liveness
# NAME READY STATUS RESTARTS AGE
# ...
-
계속해서 지켜 보면, RESTARTS값이 계속 증가하는 것을 확인할 수 있음
( 이유 :
/live
호출에서 404error을 받기 때문에, Pod가 강제로 재시작(자가치유) 되고 있으므로 )
(2) readinessProbe
Pod가 생성 직후, 트래픽을 받을 준비가 되었는지 확인
ex) readiness.yaml
# readiness.yaml
apiVersion : v1
...
spec :
containers :
- name : nginx
image : nginx
readinessProbe :
httpGet :
path: /ready
port: 80
실행 후 확인하기
kubectl apply -f liveness.yaml
kubectl get pod
# NAME READY STATUS RESTARTS AGE
# ... 0/1
# /ready URL 생성
kubectl exec readiness --touch /usr/share/nginx/html/ready
kubectl get pod
# NAME READY STATUS RESTARTS AGE
# ... 1/1
READY
칼럼의 0/1 표시를 통해 확인 가능- 0/1 : 준비 X
- 1/1 : 준비 O
(3) livenessProbe & readinessProbe
위 둘 다, HTTP 통신뿐만 아니라, 명령 실행을 통해서도 잘 작동하는지 확인 가능
ex) readiness-cmd.yaml
# readiness-cmd.yaml
apiVersion : v1
...
spec :
containers :
- name : nginx
image : nginx
readinessProbe :
exec :
command :
- cat
- /tmp/ready
exec
: 아래의 명령 실행command
: 사용자가 실행할 명령 지정
실행 후 확인하기
kubectl apply -f readiness-cmd.yaml
kubectl get pod
# NAME READY STATUS RESTARTS AGE
# ... 0/1
# /tmp/ready 파일 생성
kubectl exec readiness-cmd --touch /tmp/ready
kubectl get pod
# NAME READY STATUS RESTARTS AGE
# ... 1/1
READY
칼럼의 0/1 표시를 통해 확인 가능- 0/1 : 준비 X
- 1/1 : 준비 O
8. 2개 컨테이너 실행
Pod = 1개 이상의 컨테이너를 가질 수 있는 최소 실행 단위
\(\rightarrow\) 이번에는, 2개의 서로 다른 컨테이너를 실행해볼 것
ex) second.yaml
# second.yaml
apiVersion : v1
kind : Pod
metadata :
name : second
spec :
containers :
- name : nginx
image : nginx
- name : curl
image : curlimages/curl
command : ["/bin/sh"]
args : ["-c", "while true; do sleep 5; curl localhost; done"]
- 1번째 container : NGINX 웹서버
- 2번째 container : 쉘 스크립트를 실행하는 컨테이너
- 역할 : loop를 돌면서, 5초 간 대기 후 local host로 호출
실행 후 확인하기
kubctl apply -f second.yaml
kubectl logs second
\(\rightarrow\) log 확인하려 할 때, 에러 발생
( \(\because\) 2개 이상의 container이므로, “명시적으로 지정” 해줘야 )
kubectl logs second -c nginx
9. 초기화 컨테이너
container끼리는 실행 순서 보장 X
but, 명시적으로 지정해서 초기화 작업을 수행해야하는 경우에는?
\(\rightarrow\) initContainers property를 이용
# init-container.yaml
apiVersion : v1
kind : Pod
metadata :
name : init-container
spec :
restartPolicy : OnFailure
containers :
- name : busybox
image : k8s.gcr.io/busybox
command : ["ls"]
args : ["/tmp/moby"]
volumeMounts:
- name : workdir
mountPath : /tmp
initContainers :
- name : git
image : alpine/git
command : ["sh"]
args :
- "-c"
- "git clone https://github.com/moby/moby.git /tmp/moby"
volumeMounts :
- name : workdir
mountPath : "/tmp"
volumes :
- name : workdir
emptyDir : {}
ex) main container 실행 전에, 먼저 git repository에서 받아야 한다면?
- 초기화 container에서 미리 git pull을 받아서, container 끼리의 공유 공간인 “emptyDir” volume을 통해 gir repository 전달
실행 후 확인하기
kubctl apply -f init-container.yaml
kubectl get pod
# 1) initContainer의 log 확인
kubectl logs init-container -c git -f
# 2) main Container(=busybox)의 log 확인
kubectl logs init-container
\(\rightarrow\) log 확인하려 할 때, 에러 발생
( \(\because\) 2개 이상의 container이므로, “명
10. Config 설정
설정값들을 따로 모아두고, 필요할 떄 꺼내 쓰자!
\(\rightarrow\) 설정값들 모아놓은 통 = ConfigMap
ConfigMap에서 설정값들을 불러와서 Pod에 전달하자!
(1) ConfigMap 리소스 생성
ConfigMap 리소스
-
메타데이터(설정값)을 저장하는 리소스
( 지금까지는 Pod에서 “직접” 설정값들을 지정했었음 )
ConfigMap 생성하기
kubectl create configmap <key> <data-source>
방법 1 : --from-file
-
(1) 설정파일 작성하기
# game.properties weapon = gun health = 3 potion = 5
-
(2) ConfigMap 만들기
( ConfigMap의 이름은 “game-config”로 지정 )
kubectl create configmap game-config --from-file=game.properties
-
(3) 생성된 ConfigMap (cm) 조회하기
kubectl get cm game-config -o yaml kubectl get configmaps game-config -o yaml
방법 2 : --from-literal
--from-literal
을 사용해서도 Configmap 생성 가능
( --from-file
과는 다르게, 파일 사용 없이 직접! )
kubectl create configmap special-config\
--from--literal=special.power=10
--from--literal=special.strength=20
방법 3 : YAML 정의서
직접 ConfigMap 리소스를 YAML 정의서로 작성하여 생성 가능
# monster-config.yaml
apiVersion : v1
kind : ConfigMap
metadata :
name : monster-config
namespace : default
data :
monsterType : fire
monsterNum : "5"
monsterLife : "3"
실행 후 확인하기
kubctl apply -f monster-config.yaml
kubectl get cm monster-config -o yaml
(2) ConfigMap 활용
1) 볼륨 연결
ConfigMap을 볼륨으로 mount하여 파일처럼 사용 가능
ex) game-volume.yaml
# game-volume.yaml
apiVersion : v1
kind : Pod
metadata :
name : game-volume
spec :
restartPolicy : OnFailure
containers :
...
volumes :
- name : game-volume
configMap :
name : game-config
volumes
: Pod에서 사용할 볼륨 선언configMap
:- (기존) hostPath, emptyDir
- (신규) configMap라는 볼륨 사용 가능
실행 후 확인하기
kubctl apply -f game-volume.yaml
kubectl logs game-volume
2) 환경변수 - valueFrom
- 생략
3) 환경변수 - envFrom
- 생략