Skip to main content

파드 운영하기

Pod

  • Pod란 컨테이너를 표현하는 k8s API의 최소 단위
  • Pod에는 하나 또는 여러 개의 컨테이너가 포함될 수 있음

nginx 웹 서버 컨테이너를 pod로 동작시키기

CLI

# web 파드 생성, 이미지는 nginx:1.14, 포트 80
kubectl run web --image=nginx:1.14 --port=80

kubectl get pods # 파드 생성 확인
kubectl get pods -o wide # 파드 상세 확인

kubectl delete pod web # web 파드 삭제

kubectl run web --image=nginx:1.14 --port=80 --dry-run=client # 동작 확인

YAML

# yaml 결과 출력 (output -> yaml)
kubectl run web --image=nginx:1.14 --port=80 --dry-run=client -o yaml

# yaml 결과를 web.yaml에 저장
kubectl run web --image=nginx:1.14 --port=80 --dry-run=client -o yaml > web.yaml

# vi web.yaml
apiVersion: v1
kind: Pod
metadata:
name: web
spec:
containers:
- image: nginx:1.14
name: web
ports:
- containerPort: 80

# 파드 생성
kubectl apply -f web.yaml

kubectl get pods web
kubectl get pods web -o wide

# 파드 삭제
kubectl delete -f web.yaml
note

cka-exam이라는 namespace를 만들고, 'cka-exam' namespace에 아래와 같은 Pod를 생성하세요.

  • Pod name: pod-01
  • image: busybox
  • env: CERT="CKA-cert"
  • command: /bin/sh
  • args: -c "while true; do echo $(CERT); sleep 10;done"
# 현재 context 확인
kubectl config current-context
# context k8s로 switching
kubectl config use-context k8s

# cka-exam 네임스페이스 생성
kubectl create namepsace cka-exam

kubectl run pod-01 --image=busybox --dry-run=client -o yaml > 3-1.yaml

# vi 3-1.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod-01
namespace: cka-exam # 네임스페이스 지정
spec:
containers:
- image: busybox
name: pod-01
env: # 환경변수 설정
- name: CERT
value: "CKA-cert"
command: ["/bin/sh"]
args: ["-c", "while true; do echo $(CERT); sleep 10;done"]

# 파드 생성
kubectl apply -f 3-1.yaml

# 네임스페이스가 cka-exam인 파드 확인
kubectl get pods -n cka-exam


note

Pod "custom-app"의 log를 모니터링하고 "file not found" 메세지를 포함하는 로그 라인을 추출하세요. 추출된 결과는 /opt/REPORT/2022/custom-app-log에 기록하세요.

kubectl config current-context
kubectl config use-context hk8s

kubectl get pods

# custom-app 파드의 로그 확인
kubectl logs custom-app | grep 'file not found'

# custom-app 파드의 로그를 /opt/REPORT/2022/custom-app-log에 저장
kubectl logs custom-app | grep 'file not found' > /opt/REPORT/2022/custom-app-log

Static Pod

  • API 서버 없이 특정 노드에 있는 kubelet에 의해 직접 관리
  • 해당 워커 노드에서 kubelet이 컨테이너 파드를 생성
  • /etc/kubernetes/manifests/ 디렉토리에 파드의 구성정보가 담긴 yaml 파일을 저장시 적용
  • static pod 디렉토리 구성
  • static pod를 삭제하기 위해서는 static pod가 구동되고 있는 노드의 /etc/kubernetes/manifests 디렉토리 아래 삭제하려는 파드의 구성정보가 명시된 yaml 파일을 삭제해야 한다.
# 워커노드 접속
ssh node1

# staticPodPath 확인
sudo cat /var/lib/kubelet/config.yaml | grep -i staticpodpath
cat /var/lib/kubelet/config.yaml
...
staticPodPath: /etc/kubernetes/manifests
...

# static pod path 이동
cd /etc/kubernetes/manifests

# pod yaml 파일 생성
kubectl run webserver --image=nginx:1.14 --port=80 --dry-run=client -o yaml > webserver.yaml

# 위에서 생성한 webserver 파드 yaml 파일로 인해 생성된 파드 확인
kubectl get pods -o wide
...
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
busybox-sleep 1/1 Running 2 (16h ago) 37h 192.168.104.26 node2 <none> <none>
campus-01 1/1 Running 2 (16h ago) 37h 192.168.166.150 node1 <none> <none>
cka-webserver 1/1 Running 2 (16h ago) 37h 192.168.104.28 node2 <none> <none>
custom-app 1/1 Running 2 (16h ago) 37h 192.168.166.152 node1 <none> <none>
eshop-cart-app 1/1 Running 2 (16h ago) 37h 192.168.166.151 node1 <none> <none>
fast-01 1/1 Running 2 (16h ago) 37h 192.168.104.24 node2 <none> <none>
front-end-6f49fd5bf9-dws4k 1/1 Running 0 16h 192.168.166.147 node1 <none> <none>
front-end-6f49fd5bf9-gqw8h 1/1 Running 0 16h 192.168.104.29 node2 <none> <none>
podtest 1/1 Running 0 15h 192.168.104.30 node2 <none> <none>
webserver-node1 1/1 Running 0 11s 192.168.166.157 node1 <none> <none>

# 파드 상세 확인
kubectl describe pod webserver-node1

# yaml 파일 삭제
sudo rm- rf webserver.yaml

# 파드 삭제 확인
kubectl get pods -o wide
note

node1 노드에 nginx-static-pod.yaml라는 이름의 Static Pod를 생성하세요.

  • Pod name: nginx-static-pod
  • image: nginx
  • port: 80
sudo -i

# static pod path 확인
cat /var/lib/kubelet/config.yaml | grep -i staticpodpath

# 실행 확인
kubectl run nginx-static-pod --image=nginx --port=80 --dry-run=client -o yaml

# 결과 yaml 파일 생성
kubectl run nginx-static-pod --image=nginx --port=80 --dry-run=client -o yaml > nginx-static-pod.yaml

# 파드 생성 확인
kubectl get pods -o wide

멀티 컨테이너

  • 하나의 파드에 여러 개의 컨테이너가 포함되어 함께 실행

4개의 컨테이너를 동작시키는 eshop-frontend Pod를 생성하세요.

  • pod image: nginx, redir, memcached, consul
# yaml 파일 생성
# 명령에서는 이미지 단일로만 선택 가능
kubectl run eshop-frontend --image=nginx --dry-run=client -o yaml > 3-2.yaml

# vi 3-1.yaml
apiVersion: v1
kind: Pod
metadata:
name: eshop-frontend
spec:
containers:
- image: nginx # nginx
name: nginx-container

- image: redis # redit
name: redis-container

- image: memcached # memcached
name: memcached-container

- image: consul # consul
name: consul-container

# 파드 생성
kubectl apply -f 3-2.yaml

# 파드 확인
kubectl get pods eshop-frontend

# 상세 확인
kubectl describe pod eshop-frontend

사이드카 컨테이너

  • 오토바이에 부착된 사이드카를 연상
  • 기존 컨테이너의 변경 없이 기능을 확장하고 향상시킬 수 있다.
  • 기본 컨테이너 기능을 확장하기 위해 사용하며 본래의 컨테이너는 기본 서비스에 충실하고, 추가 기능을 별도의 컨테이너를 이용해 적용
  • 웹서버는 기본 서비스에 충실하고, 추가로 생성되는 웹서버 로그는 별도의 사이드카 컨테이너가 수집하여 외부 log aggregator로 전송하는 형태의 서비스

사이드카 패턴 예시

  • 보안을 위해 사이드카로 NGINX reverse proxy 등을 붙여서 HTTPS 통신을 한다.
  • 성능을 위해 사이드카로 NGINX content cache 등을 붙인다.
  • 컨테이너 외부로 로그를 모으기 위해 logstash, fluentd 등을 붙인다. (로그 중앙화)

장점

  • 상호 의존성을 줄일 수 있다.
  • 사이드카 장애 시 애플리케이션이 영향을 받지 않는다.
  • 사이드카 적용/변경/제거 등의 경우 애플리케이션 수정이 필요하지 않다.
  • 애플리케이션과 사이드카를 각각 독립적인 환경에서 구성할 수 있다.
  • 동일한 스토리지를 공유할 수 있다.

단점

  • 프로세스간 통신이 많고 최적화 해야 한다면 애플리케이션에서 함께 처리하는 것이 더 용이하다.
  • 어플리케이션이 작은 경우 관리포인트가 늘어날 수 있다.

사이드카 프록시

쿠버네티스 환경에서의 사이드카는 특히 파드(pod)와 컨테이너 관계에 주목해야 합니다. 동일한 파드의 모든 컨테이너는 동일한 가상 네트워크 장치를 공유하므로 네트워크를 통해 서로 안전하게 상호작용할 수 있습니다. 이런 특성을 이용해서 사이드카 프록시만 외부에 노출하고 프록시와 애플리케이션 사이는 보안 네트워크로 연결할 수 있습니다.

만약 쿠버네티스가 아닌 환경이라면 Nginx와 같은 리버스 프록시를 통해 애플리케이션을 캡슐화하고 해당 애플리케이션에 대한 인증을 제공할 수도 있습니다. 하지만 쿠버네티스 환경에서 레플리카셋(ReplicaSet)이나 디플로이먼트(Deployment)로 배포한 경우 파드가 속한 노드가 지속해서 바뀔 수 있으며, 이때 네트워크 정보도 모두 바뀌게 됩니다. 스테이트풀셋(StatefulSets)으로 배포한다면 이런 염려가 없겠지만, HPA(Horizontal Pod Autoscale)나 확장/가용성이 필요한 일반적인 애플리케이션의 배포 형태는 레플리카셋이나 디플로이먼트입니다.

note

현재 운영중인 eshop-cart-app Pod의 로그를 Kubernetes built-in logging 아키텍처(예: kubectl logs)에 통합하는 로그 스트리밍 사이드카 컨테이너를 운영하세요.

  • busybox 이미지를 사용하여 price라는 이름의 사이드카 컨테이너를 기존 eshop-cart-app에 추가합니다.
  • 새 price 컨테이너는 다음과 같은 command를 실행해야 합니다.
  • Command: /bin/sh, -c, "tail -n+1 -f /var/log/cart-app.log"
  • /var/log에 마운트 된 볼륨을 사용하여 사이드카 컨테이너에서 로그 파일 cart-app.log를 사용해야 합니다.
  • eshop-cart-app Pod와 cart-app 컨테이너를 수정하지 마세요.
# 현재 구동중인 eshop-cart-app 파드의 구성 정보를 yaml 파일에 저장
kubectl get pod eshop-cart-app -o yaml > 3-3.yaml

# vi 3-3.yaml
apiVersion: v1
kind: Pod
metadata:
name: eshop-cart-app
spec:
containers:
- command:
- /bin/sh
- -c
- 'i=1;while :;do echo -e ": Price: $((RANDOM % 10000 + 1))" >> /var/log/cart-app.log; i=$((i+1)); sleep 2; done'
image: busybox
name: cart-app
volumeMounts:
- mountPath: /var/log
name: varlog

- name: price # price 사이드카 컨테이너 추가
image: busybox
args: [/bin/sh, -c, 'tail -n+1 -f /var/log/cart-app.log']
volumeMounts:
- name: varlog # cart-app 컨테이너와 볼륨 공유
mountPath: /var/log # 볼륨 마운트

volumes:
- emptyDir: {}
name: varlog

# 파드 삭제
kubectl delete pod eshop-cart-app

# 파드 생성
kubectl apply -f 3-3.yaml

# 파드 확인
kubectl get pods

# price 컨테이너 로그 확인
kubectl logs eshop-cart-app -c price