Needs

로컬 환경에서도 쉽게 확인 가능한 이슈라면 상관없지만,

  • K8s 환경에 올라가야만 발생하고
  • pod 을 재시작하면 재현이 안될 것 같은 상황이라 현재 어플리케이션은 건드리지 않아야하는데 deployment 권한 수정이 필요한 경우 (ex. 리소스 프로파일링)

등등에 필연적으로 ephemeral container 을 구동하게 된다. 관련해서 나중에 재조회를 위해 간략히 정리.

Ephemeral container 구동 명령어

다른 프로세스의 CPU/Memory 등 리소스 정보 조회에는 privilege 가 요구된다. python 프로그램의 cpu profiling 에 일반적으로 사용되는 pyspy 도 K8s deployment 에서 SecurityContext 가 priviledged 가 true 로 설정되어있어야만 하는데,

일반적인 어플리케이션에서 해당 옵션이 true 로 요구되는 케이스는 거의 없다고 보면 된다.
(만약 True 로 설정되어있다면 보안적으로 문제는 없는지, 정말 필요한지 다시 고민해 볼 필요가 있다)

따라서 현재 구동 중인 pod / container 의 리소스 사용량을 보고 싶은 경우

  • privilede 가 false 로 설정된 컨테이너 내의 어플리케이션은 띄워져 있는 상태에서
  • 동일한 pod 내에 별도 컨테이너를 띄워서 pyspy 를 실행하여 구동중인 프로세스를 모니터링 하는 것.

다음 명령어를 통해 먼저 ephemeralContainers 를 원하는 namespace / pod에 구동한다.

kubectl debug -it pod/<pod> --image=python:3.12-slim --target=<container-name> --share-processes
kubectl -n <namespace> get pod <pod> -o json | \
jq '.spec.ephemeralContainers = ((.spec.ephmeralContainers // []) + [{
    "name": "spy",
    "image": "python:3.12-slim",
    "stdin": true,
    "tty": true,
    "targetContainerName": <container-name>,
    "SecurityContext": {
        "privileged": true
        "allowPrivilegeEscalation": true
        "capabilities": {"add": ["SYS_PTRACE"]},
        "seccompProfile": { "type": "Unconfined"}
    },
    "command": ["/bin/sh"]
}])' \
| kubectl -n <namespace> replace --raw /api/v1/namespaces/<namespace>/pods/<pod>/ephemeralcontainers -f -

container 가 생성되면서 command 를 /bin/sh 로 지정하였기 때문에 좀 기다리면 쉘로 진입이 되고, 해당 쉘에서 다음 순으로 작업을 진행한다.

  1. py-spy 설치
python -m pip install --no-cache-dir py-spy
  1. 프로세스 확인
for p in /proc/[0-9]*; do [ -r "$p/comm" ] && grep -Eq '^(python|uvicorn)' "$p/comm" && echo "${p##*/}" $(cat $p/comm); done
  1. py-spy 실행
py-spy record --nonblocking --pid <PID> --duration 30 --rate 99 --format speedscope --output /tmp/profile.speedscope.json
  1. output 파일 내 로컬로 복사하기
kubectl -n <namespace> cp -c spy <pod>:/tmp/profile.speedscope.json ./profile.speedscope.json

와 같이 하면 된다.