Kubernetes(K8S): Multi Container POD
1. 멀티 컨테이너 파드(Multi Container POD):
1.1. POD내에 2개이상의 Container를 포함
1.2. 일반적으로는 하나의 POD안에는 하나의 Container를 지향
1.3. 필요에 따라서 Main Container에 도움을 줄 수 있는 보조적인 역할의 Container를 추가해서 운영가능
1.4. Main Process를 Network 또는 Storage의 밀접한 공유가 필요한 다른 Container와 함께 운영할 때 고려
2. Kubernetes 설계 방식 - 전체 서비스를 기능 단위로 분산, Pod를 최소의 배포 단위로 구성
2.1. 동일 Pod내의 Container들은 같은 네트워크 안에서 동작
2.2. 동일한 IP주소와 Port를 공유
2.3. 따라서 동일한 Port를 사용하는 Container를 묶어서 단일 Pod로 배포는 불가능
2.4. 동일 Pod안에 완전히 별개의 성격을 가진 다른 프로세스들은 묶여 배포하는 것 역시 권장되지 않음
구글의 Brendan Burns와 David Oppenheimer: "Design patterns for container-based distributed systems"
3. Multi-Container Pod Design Pattern
3.1. sidecar
apiVersion: v1
kind: Pod
metadata:
name: apache-sidecar
spec:
containers:
- name: apache
image: httpd
ports:
- containerPort: 80
volumeMounts:
- name: log
mountPath: /var/log/httpd
- name: access-sidecar
image: busybox
args: [/bin/sh, -c, 'tail -n+1 -f /var/log/httpd/access.log']
volumeMounts:
- name: log
mountPath: /var/log/httpd
- name: error-sidecar
image: busybox
args: [/bin/sh, -c, 'tail -n+1 -f /var/log/httpd/error.log']
volumeMounts:
- name: log
mountPath: /var/log/httpd
volumes:
- name: logs
emptyDir: {}
3.1.1. 기존 Pod의 기능 향상
3.1.2. Pod의 File System을 공유하는 형태의 보조 Container를 Sidecar Container
3.1.3. K8S 환경에서 실제 이용되는 대다수의 MultiContainer Pod Disign Pattern
3.1.4. 예: Nginx가 구동되는 Pod안에 Nginx Log를 수집하는 Sidecar Container 배치
3.2. Adapter
https://medium.com/bb-tutorials-and-thoughts/kubernetes-learn-adaptor-container-pattern-97674285983c 참조
apiVersion: v1
kind: Pod
metadata:
name: adapter-container-demo
spec:
containers:
- image: busybox
command: ["/bin/sh"]
args: ["-c", "while true; do echo $(date -u)'#This is log' >> /var/log/file.log; sleep 5;done"]
name: main-container
resources: {}
volumeMounts:
- name: var-logs
mountPath: /var/log
- image: bbachin1/adapter-node-server
name: adapter-container
imagePullPolicy: Always
resources: {}
ports:
- containerPort: 3080
volumeMounts:
- name: var-logs
mountPath: /var/log
dnsPolicy: Default
volumes:
- name: var-logs
emptyDir: {}
3.2.1. Pod에 배포된 특정 App의 출력물(log)를 규격에 맞게 수정할 때 사용
3.2.2. nginx와 apache 서버의 log 출력은 그 형태가 상이함. 이를 조정할 때 사용하는 Container
3.3. Ambassador
https://www.weave.works/blog참조
apiVersion: v1
kind: Pod
metadata:
name: ambassador-example
spec:
containers:
- name: redis-client
image: redis
- name: ambassador
image: malexer/twemproxy
env:
- name: REDIS_SERVERS
value: redis-st-0.redis-svc.default.svc.cluster.local:6379:1 redis-st-1.redis-svc.default.svc.cluster.local:6379:1
ports:
- containerPort: 6380
3.3.1. Pod 외부의 서비스에 대한 Access를 간소화
3.3.2. Main Conatiner가 수행할 Network 통신을 대신해 주는 역할
3.3.3. App Container는 오직 Ambassador Container를 통해서만 외부와 통신 가능
3.3.4. 외부에서의 접근 역시 Ambassador Container를 통해서만 가능
3.3.5. Ambassdor Container는 Main Container의 Network를 전담하는 Proxy 역할 수행
3.4. init Container
아래 코드는 myservice와 mydb라는 서비스가 존재해야 myapp-container가 구동되는 코드
kubernetes 공식 문서 자료
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"]
위 구성파일의 myapp-container가 동작하기 위해서는 아래의 service를 생성해 줘야만 한다.
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
3.4.1. 의존성을 갖는 Pod를 배포할 때 사전 조건의 충족 여부를 확인하는 용도
3.4.2. Main Container 실행 전 초기화 역할을 담당하는 Container
3.4.3. Main Container를 구동하는 데 필요한 사전작업이나 조건을 명시하고 확인이 되면 Main Container 시작
3.4.4. init container와 일반 container의 차이점
3.4.4.1. 모든 init Container는 의도된 작업이 끝나면 반드시 종료되어야 한다.
3.4.4.2. 따라서 init Container는 생명주기(lifecycle)옵션, 프로브(livenessProbe, readinessProbe, startupProbe)옵션 사용불가
3.4.4.3. 다수를 동시에 구동시 하나씩 순차적으로 실행, 먼저 시작된 Container가 정상 종료되면 다음 Container 실행
3.4.4.4. init Container 구동 실패 시 kubelet는 성공(정상종료)할 때까지 Container 계속 재시작
3.4.4.5. Pod의 restartPolicy가 Never로 명시된 경우 Pod전체가 실패한 것으로 간주하고 작업 종료
Have a nice day!