-
[따배쿠] Pod - init container & infra containerkubernetes 2024. 12. 1. 16:27
Init Container
- Main Container 실행 전에 미리 동작시킬 컨테이너
- 본 Container가 실행되기 전에 사전 작업이 필요할 경우 사용
- 즉, Init Container가 실행되어야, Main Container를 구동시킬 수 있다.
- 예시 1. node.js 이미지로 만들어진 로그인 지원 application을 담당 main container가 있다고 가정한다. 해당 main container에서 로그인을 지원하기 위해서는 db에서 로그인 관련 정보를 가져와야한다. 여기서 db에 접속을 해서 데이터를 가져오는 컨테이너가 init container가 된다.
- 이를 하나의 pod로 만들어 놓으면, init container에서 작업이 성공해야 main container를 동작시킬 수 있다
- init container에서 동작이 실패하면 main container도 동작이 실패한다.
예시
# yaml 파일 작성
root@master:~/Getting-Start-Kubernetes/5# vi init-container-exam.yaml apiVersion: v1 kind: Pod metadata: name: myapp-pod labels: app: myapp spec: containers: - name: myapp-container image: busybox:1.28 command: ['sh', '-c', 'echo The app is running! && sleep 3600'] initContainers: - name: init-myservice image: busybox:1.28 command: ['sh', '-c', "until nslookup myservice.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for myservice; sleep 2; done"] - name: init-mydb image: busybox:1.28 command: ['sh', '-c', "until nslookup mydb.$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace).svc.cluster.local; do echo waiting for mydb; sleep 2; done"]
여기서 containers가 main container, init containers가 init container로 작동한다.
[코드 설명]
더보기apiVersion: v1
- Kubernetes API의 버전을 지정합니다. 여기서는 v1을 사용하고 있습니다.
kind: Pod
- 생성할 리소스의 종류를 정의합니다. 여기서는 Pod을 생성합니다.
metadata
- Pod의 메타데이터를 정의합니다.name: Pod의 이름을 myapp-pod로 설정합니다.
labels: Pod에 대한 레이블을 설정합니다. 여기서는 app: myapp이라는 레이블이 있습니다.
spec
- Pod의 사양을 정의합니다.
containers : 일반 컨테이너를 정의합니다.
name: 컨테이너의 이름을 myapp-container로 설정합니다.
image: 사용할 Docker 이미지를 busybox:1.28로 설정합니다.
command: 컨테이너가 시작될 때 실행할 명령어를 정의합니다. 여기서는 "The app is running!"이라는 메시지를 출력하고 3600초(1시간) 동안 대기합니다.initContainers : Init 컨테이너를 정의합니다. Init 컨테이너는 일반 컨테이너가 시작되기 전에 실행되는 특별한 컨테이너입니다.
#첫 번째 Init 컨테이너 (init-myservice):name: Init 컨테이너의 이름을 init-myservice로 설정합니다.
image: 사용할 Docker 이미지를 busybox:1.28로 설정합니다.
command: myservice라는 서비스의 DNS 이름이 해결될 때까지 대기하는 명령어를 실행합니다. 이 명령어는 nslookup을 사용하여 서비스의 DNS를 확인하고, 서비스가 준비될 때까지 2초 간격으로 "waiting for myservice"라는 메시지를 출력합니다. 즉, myservice라는 서비스가 실행되지 않으면 무한루프고 myservice라는 서비스가 실행되면 완료
#두 번째 Init 컨테이너 (init-mydb):
name: Init 컨테이너의 이름을 init-mydb로 설정합니다.
image: 사용할 Docker 이미지를 busybox:1.28로 설정합니다.
command: mydb라는 서비스의 DNS 이름이 해결될 때까지 대기하는 명령어를 실행합니다. 이 명령어도 nslookup을 사용하여 서비스의 DNS를 확인하고, 서비스가 준비될 때까지 2초 간격으로 "waiting for mydb"라는 메시지를 출력합니다.
<요약>
이 YAML 파일은 myapp-pod라는 이름의 Pod을 정의하며, 두 개의 Init 컨테이너(init-myservice와 init-mydb)가 각각 myservice와 mydb 서비스가 준비될 때까지 대기한 후, 일반 컨테이너(myapp-container)가 실행됩니다. Init 컨테이너는 일반 컨테이너가 시작되기 전에 반드시 완료되어야 하며, 이를 통해 서비스의 의존성을 관리할 수 있습니다.# pod 생성
root@master:~/Getting-Start-Kubernetes/5# kubectl create -f init-container-exam.yaml pod/myapp-pod created
# 확인
root@master:~/Getting-Start-Kubernetes/5# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES myapp-pod 0/1 Init:0/2 0 6m 192.168.166.153 node1 <none> <none>
pod가 실행되지 않고 있는 것을 확인
아마 myservice와 mydb라는 service가 없어서 init container 또한 실행되지 않았고,자연스레 main container 또한 실행되지 않았다.
# myservice와 mydb라는 service 생성
root@master:~/Getting-Start-Kubernetes/5# vi init-container-svc.yaml --- apiVersion: v1 kind: Service metadata: name: myservice spec: ports: - protocol: TCP port: 80 targetPort: 9376 --- apiVersion: v1 kind: Service metadata: name: mydb spec: ports: - protocol: TCP port: 80 targetPort: 9377
root@master:~/Getting-Start-Kubernetes/5# kubectl create -f init-container-svc.yaml service/myservice created service/mydb created
# 재확인
root@master:~/Getting-Start-Kubernetes/5# kubectl get pods -o wide
Infra container (pause)
- Pod의 환경을 만들어주는 컨테이너 (Pod 대한 IP, hostname 관리 및 생성하는 컨테이너)
- Pod 생성 시, 자동으로 생성되고 삭제 시 자동으로 삭제 됨
- 보통 컨테이너 조회 명령어로 보이진 않지만, 실제로는 존재함 !
예시
# pod 생성 (nginx 이미지를 쓰는 webserver라는 이름의 컨테이너를 보유하고 있다)
root@master:~/Getting-Start-Kubernetes/5# kubectl run webserver --image=nginx:1.14 --port=80 pod/webserver created
*CLI로 pod를 생성하고 싶을 땐, kubectl run ~ 명령어 사용
root@master:~/Getting-Start-Kubernetes/5# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES webserver 1/1 Running 0 2m46s 192.168.166.156 node1 <none> <none>
node1에서 webserver pod가 생성되었다.
# node1 접속 (...을 하기 위해서) master 서버의 공개키를 node1 서버에 등록
[master]
root@master:~/Getting-Start-Kubernetes/5# ssh-keygen -t rsa
ssh 공개키 생성
root@master:~/.ssh# ls authorized_keys id_rsa id_rsa.pub known_hosts root@master:~/.ssh# cat id_rsa.pub ssh-rsa ~~~ root@master
~/.ssh 경로의 id_rsa.pub을 cat 명령어로 출력 후, 복사
[node1]
root@node1:~/.ssh# vi authorized_keys
~/.ssh 경로의 authorized_keys 파일에 master 서버 공개키 붙여넣기
[master > node1 SSH 접속]
root@master:~# ssh node1 Welcome to Ubuntu 24.04.1 LTS (GNU/Linux 6.8.0-1017-azure x86_64) * Documentation: https://help.ubuntu.com * Management: https://landscape.canonical.com * Support: https://ubuntu.com/pro System information as of Mon Dec 2 06:23:34 UTC 2024 System load: 0.0 Processes: 163 Usage of /: 21.5% of 28.02GB Users logged in: 1 Memory usage: 7% IPv4 address for eth0: 10.100.0.101 Swap usage: 0%
master 서버에서 node1으로 SSH 접속 시도해보면, 별도의 패스워드 인증 없이 SSH 접속 가능 확인
# ps aux 명령어로 확인
root@node1:~# ps aux root 26367 0.0 0.2 1238424 17656 ? Sl 06:13 0:00 /usr/bin/containerd-shim-runc-v2 -namespace k8s.io -id a377 65535 26388 0.0 0.0 996 512 ? Ss 06:13 0:00 /pause root 26417 0.0 0.0 32636 5632 ? Ss 06:13 0:00 nginx: master process nginx -g daemon off; message+ 26429 0.0 0.0 33084 2536 ? S 06:13 0:00 nginx: worker process
webserver pod 생성하면서 nginx 컨테이너가 생성됨과 동시에, pause 컨테이너도 생성된 것을 확인할 수 있다.
참고 영상
https://www.youtube.com/watch?v=ChArV14J6Ek&list=PLApuRlvrZKohaBHvXAOhUD-RxD0uQ3z0c&index=13
참고 문서
https://kubernetes.io/ko/docs/concepts/workloads/pods/init-containers/
'kubernetes' 카테고리의 다른 글
[따배쿠] Pod - static Pod(feat. kubelet daemon) (0) 2024.12.02 따배쿠 학습 용도 (0) 2024.12.01 [따배쿠] Pod - liveness Probe를 이용해서 Self-healing Pod 만들기 (1) 2024.12.01 [따배쿠] Pod (0) 2024.11.10 [따배쿠] namespace (0) 2024.11.10