보통 Microservice구조에서 app이 두 개 있다면 pod를 두 개로 만드는 것이 일반적인 시스템이다.
그런데, 특정한 경우 pod안에 두 개의 container를 만들어 배포해야할 때가 있는데, 가령 다음과 같다.
----------------Pod---------------
| ----Log Agent Container---- |
| | | |
| --------------------------- |
| |
| ----Web Server Container---- |
| | | |
| --------------------------- |
----------------------------------
하나의 pod에 main이 되는 app은 web server container이고, 보조적으로 log를 모아주고 정제해주는 container가 log agent container이다.
이 두 service가 하나의 pod에 함께 배포되어야하기 때문에 하나의 pod에 두 개 이상의 container를 배포하는 것이다.
multi-container pod를 만드는 방법은, 이전의 pod 배포 방법에서 크게 다를 바 없다.
apiVersion: v1
kind: Pod
metadata:
name: simple-webapp
spec:
containers:
- name: simple-webapp
image: simple-webapp
ports:
- containerPort: 8080
- name: log-agent
image: log-agent
containers
에 두 개의 pod를 정의하는 것이 전부이다.
참고로 multi container에는 여러 pattern이 있는데, sidecar
, adapter
, ambassador
가 있다. CKA 영역이 아니라 CKAD 영역이기 때문에 따로 깊게 다루진 않는다.
위는 하나의 pod에서 main container와 부수적인 기능을 하는 sidecar container를 동작하는 방식이다. 그러나, 특정 경우에는 main container가 배포되기 이전에, 필요한 설정들이 먼저 실행되어야하는 경우가 있다. 이때 사용하는 것이 바로 InitContainer
이다.
InitContainer
는 main container
가 실행되기 이전에 필요한 설정들을 해주는데, 가령 DB connection을 먼저 확인해주거나, 특정 repository에서 package를 먼저 설치하거나 하는 기능들을 한다. 만약 InitContainer
에서 동작이 실패하는 경우 pod를 재시작하도록 할 수 있다. 또한, InitContainer
는 sidecar
container와는 달리, 기능을 다하면 종료된다. 정리하면 다음과 같다.
InitContainer
는 pod에서 container가 배포되는 방식과 똑같은 방식으로 배포되는데, pod에서 containers
부분이 아니라 InitContainers
에서 배포된다.
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
command: ['sh', '-c', 'git clone <some-repository-that-will-be-used-by-application> ; done;']
initContainers
에 container가 배포되는 것을 볼 수 있다. 이 init-myservice
의 command가 정상적으로 종료되어야 main container
인 myapp-container
가 실행되는 것이다. 만약 init-myservice
가 실패하면 myapp-container
는 실행되지 않고, pod를 재시작한다.
참고로 InitContainer
또한 여러 개의 container로 실행시킬 수 있다. 다만, 순서대로 실행되는 것에 주의하도록 하자.
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; do echo waiting for myservice; sleep 2; done;']
- name: init-mydb
image: busybox:1.28
command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']
init-myservice
가 먼저 실행되고 성공하면 init-mydb
이 실행되고 myapp-container
가 정상 실행되는 것이다.
참고로, pod를 재정의하고 싶다면 다음과 같이 사용하면 된다.
kubectl replace --force -f <pod.yaml>