Search

Ephemeral 컨테이너

Tags
k8s
container
ephemeral
debug
analysis
Created
2024/09/06 08:54
Created time
2024/09/05 23:54
category
kubernetes

개요

이전 글에서 Pod 내의 다중 컨테이너는 Pause 컨테이너를 통해 기동되고, net, uts, ipc가 공유된다는 것을 학습
이 때 Pause 컨테이너 내부에 임시 (Ephemeral) 컨테이너를 주입하여 디버깅 및 분석하는 방법을 소개

소개

간혹 이미 실행 중인 Pod의 상태를 분석해야 하는데, 문제 상황을 손쉽게 재현할 수 없는 상황들이 존재할 수 있음
이러한 상황에서 Ephemeral 컨테이너를 해당 Pod에 추가하여 기동함으로써 디버깅 및 분석하는 것이 가능
Pod는 의도 자체가 일회성으로 언제나 교체될 수 있는 리소스인데, 이러한 Pod는 한 번 생성되면 컨테이너를 추가하기 어렵게 설계되어 있음
대신에 Deployment 등과 같은 방법으로 Pod의 삭제와 교체를 통해 제어하는 것은 가능
Ephemeral 컨테이너에는 아래와 같은 특징들이 있음
Static Pod를 지원하지 않음
일반적인 Pod의 특징처럼 한 번 Ephemeral 컨테이너를 Pod에 추가하면, Pod에서 해당 컨테이너를 수정하거나 지우는 것은 불가능
kubectl edit으로 pod.spec을 수정하는 방식이 아니고, ephemeralcontainers 핸들러의 API를 이용하는 것이기 때문에 예외적으로 Pod에 컨테이너를 추가하는 것이 가능
Pod의 리소스 할당량은 불변이고, 이에 따라 리소스 설정 자체는 허용되지 않음
Port가 없기에 port, livenessProbe, readinessProbe 등의 필드 사용은 허용되지 않음

가정

Distroless Container Images 라는 어플리케이션과 런타임 의존성만 포함한 최소의 이미지를 이용하고 있다고 가정하고, 이를 디버깅하기 위해 Ephemeral 컨테이너를 활용
바이너리 코드
라이브러리 및 모듈
최소한의 런타임
예시 (쉘 및 기타 프로그램 그리고 패키지 매니저는 없음)

준비 사항

# 클러스터 생성 kind create cluster --name myk8s
Shell
복사

방법 1 : 디버깅 컨테이너 삽입

# 로컬 호스트 # nginx 파드 생성 kubectl run myweb1 --image jauderho/nginx-distroless # nginx 파드 확인 kubectl describe po/myweb1 kubectl get po/myweb1 -o wide # nginx 접속 확인 docker exec -it myk8s-control-plane curl -s $(kubectl get pod myweb1 -o jsonpath={.status.podIP}) | grep -o "<title>.*</title>" # 최소 이미지라 쉘 및 부가 명령어는 동작하지 않음을 확인 kubectl exec -it myweb1 -- sh kubectl exec -it myweb1 -- bash kubectl exec -it myweb1 -- ls -l / # 기존에 최소 이미지로 배포한 nginx에 문제가 생김을 가정 # 해당 Pod에 컨테이너를 삽입 배포 kubectl debug myweb1 -it --image=nicolaka/netshoot -c netdebug
Shell
복사
# 컨테이너 내부 # 다음 명령어들을 사용 가능 ip -c -4 addr show eth0 ps -ef curl localhost ss -tlpn tcpdump -i eth0 -nnq ngrep -d any -tW byline exit
Shell
복사
# 로컬 호스트 # nginx 파드 확인 kubectl describe po/myweb1 | grep netdebug -A 10 # nginx 리소스 삭제 kubectl delete po myweb1
Shell
복사

방법 2: 복제된 Pod 생성

# 로컬 호스트 # nginx 파드 생성 kubectl run myweb1 --image jauderho/nginx-distroless # 기존에 최소 이미지로 배포한 nginx에 문제가 생김을 가정 # 해당 Pod를 복제하고, 복제된 Pod에 컨테이너를 삽입 배포 # --share-process를 통해 Pod 내의 컨테이너들 간 PID 네임스페이스 공유 설정 ("shareProcessNamespace: true") # worker 노드에서 복제본 Pod의 2개 컨테이너 정보를 확인 시, cgroup, ipc, net, pid , user가 동일 kubectl debug myweb1 -it --image=nicolaka/netshoot -c netdebug --share-processes --copy-to=myweb-debug
Shell
복사
# 컨테이너 내부 # 다음 명령어들을 사용 가능 ip -c -4 addr show eth0 ps -ef curl localhost ss -tlpn tcpdump -i eth0 -nnq ngrep -d any -tW byline exit
Shell
복사
# 로컬 호스트 # 원본과 복제본 Pod가 존재함을 확인 kubectl get po -o wide # nginx 파드 확인 kubectl describe po/myweb-debug | grep netdebug -A 10 # nginx 리소스 삭제 kubectl delete po myweb1 myweb-debug
Shell
복사