ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Kubernetes] CrashLoopBackOff 이슈 트러블슈팅 (+Nginx)
    [IT] 공부하는 개발자/Open Source 2023. 4. 15. 12:23

    [Kubernetes] CrashLoopBackOff 이슈 트러블슈팅

     

     
    직접 도커파일을 작성하고 쿠버네티스로 배포하다 보면 CrashLoopBackOff 에러를 자주 만나게 된다.
    CrashLoopBackOff는 컨테이너가 시작되지 않고 종료되어 버릴 때 발생하기 때문에, 컨테이너에 직접 들어가서 명령어를 실행하거나 테스트를 하는 것이 불가능하다.  (kubectl exec... 실행 안 돼요!)
     
    그러므로 kubectl logs 명령어를 실행해서 컨테이너가 종료되기 직전의 로그를 확인해야 한다.
     

    kubectl logs <pod-name> <container-name>

     


    해결 사례

     
    내가 찾아낸 이슈는 2가지였다.
     

    1. 내가 이미지 Dockerfile에 작성한 app 실행 명령이 수행되지 않고 컨테이너가 종료되었다.

     
    - 발생 원인
    Dockerfile 에 작성된 ENTRYPOINT, CMD 가 k8s 스크립트에 작성한 command, args에 override 되고 있었다.
    k8s pod 안에서 도커 컨테이너를 실행하면서 넣은 command, args는 수행되었지만 도커파일에 작성한 실행 명령어들이 무시되었다.
     
    예시 1) Dockerfile

    FROM python:3.8-slim
    ENTRYPOINT ["bash"]
    CMD ["streamlit run app.py"]

    예시 2) Kubernetes config

    apiVersion: v1
    kind: Pod
    metadata:
      name: demo
    spec:
      containers:
        - name: app
          image: ubuntu:latest
          command: ["echo"] # 실행됨 !
          args: ["this is override test"] # 실행됨 !
        - name: nginx
          image: nginx:latest

     
    예시 1의 도커파일 안에 작성한 Streamlit 실행 명령은 무시되고 예시 2의 echo this is override test 만 실행된다.
     
     
    - 해결 방법
    k8s config 에 작성한 command, args 구문을 삭제하여 Dockerfile에 작성한 그대로 실행되게 유도했다.
    (반대로 Dockerfile 에 작성한 ENTRYPOINT, CMD를 k8s로 옮기는 것도 가능했을 것이다.)
     


     
     

    2. 컨테이너에 외부 마운트된 디스크에 폴더 생성을 시도해 권한 문제로 실패

     
    - 발생 원인
    나는 80포트로 들어오는 요청을 8501 포트(Streamlit)로 패스시켜 주기 위해서 Nginx 컨테이너를 사이드카로 달았다. 그런데 메인 app 인 Streamlit 컨테이너는 잘 뜨는데 Nginx 컨테이너만 계속 종료되어 버렸다... kubectl logs 커맨드로 확인해 보니
     

    open() /logs/nginx/nginx.pid failed (2: No such file or directory)

     
    라는.. Nginx pid를 찾을 수 없다는 내용의 에러로그가 남아있었다.
    nginx.pid 는 Nginx 프로세스의 pid를 저장하는 파일이고, 이 파일이 없으면 Nginx는 정상적으로 실행될 수 없다.
     
     
    - 해결 방법
    1. Nginx 설정 파일에서 pid 파일의 경로가 정확한지 확인했다.
    -> 존재하지 않는 폴더였다. 그래서 그 상위 폴더를 만드는 명령어를 Dockerfile에 작성해 주었다.

    RUN mkdir -p /logs/nginx

     
    2. 작성해 주었는데도 pid 가 생성이 되지 않았다.
    -> 혹시나 하여 마운트 디스크를 (cmd: df) 체크해 보니까... 문제의 폴더는 마운트 된 디스크였다;; RUN mkdir 수행되는 시점은 Dockerfile build 단계이므로 외부 디스크가 마운트되기 전이다. 그러니 그 폴더가 생길리가 없다...ㅠ mkdir 이 컨테이너 run 단계에서 수행되도록 k8s 스크립트의 command 에 작성했다.. 그랬더니 드디어 폴더가 생성이 되었고, Nginx pid 파일이 저장될 수 있었다. Dockerfile 에 작성한다면 RUN 이 아니라 entrypoint 에 넣어서 문제를 해결할 수도 있었을 것 같다.
     


     

    댓글

Copyright in 2020 (And Beyond)