Amazon EKS에서 포드 상태 문제를 해결하려면 어떻게 해야 하나요?
Amazon Elastic Compute Cloud(Amazon EC2) 인스턴스 또는 관리형 노드 그룹에서 실행 중인 Amazon Elastic Kubernetes Service(Amazon EKS) 포드가 멈췄습니다. 내 포드를 "Running" 또는 "Terminated" 상태로 바꾸려고 합니다.
해결 방법
중요: 다음 단계는 Amazon EC2 인스턴스 또는 관리형 노드 그룹에서 시작된 포드에만 적용됩니다. 이러한 단계는 AWS Fargate에서 시작된 포드에는 적용되지 않습니다.
포드 상태 찾기
Amazon EKS에서 포드 상태 문제를 해결하려면, 다음 단계를 완료하세요.
-
포드의 상태를 확인하려면 다음 명령어를 실행합니다.
$ kubectl get pod
-
포드의 이벤트 기록에서 정보를 가져오려면, 다음 명령어를 실행합니다.
$ kubectl describe pod YOUR_POD_NAME
-
포드 상태에 따라 다음 섹션의 단계를 완료하세요.
포드가 Pending 상태입니다.
참고: 다음 단계의 예제 명령은 기본 네임스페이스에 있습니다. 다른 네임스페이스의 경우, 명령에 -n YOURNAMESPACE를 추가합니다.
리소스가 부족하거나 hostPort를 정의했기 때문에 포드가 Pending 상태로 멈출 수 있습니다. 자세한 내용을 보려면 Kubernetes 웹사이트의 포드 단계를 참조하세요.
워커 노드의 리소스가 충분하지 않은 경우 불필요한 포드를 삭제하세요. 워커 노드에 리소스를 더 추가할 수도 있습니다. 클러스터에 리소스가 충분하지 않은 경우, Kubernetes 클러스터 오토스케일러를 사용하여 워커 노드 그룹을 자동으로 확장합니다.
CPU 부족 예제:
$ kubectl describe pod frontend-cpu Name: frontend-cpu ... Status: Pending ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 22s (x14 over 13m) default-scheduler 0/3 nodes are available: 3 Insufficient cpu.
메모리 부족 예:
$ kubectl describe pod frontend-memory Name: frontend-memory ... Status: Pending ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 80s (x14 over 15m) default-scheduler 0/3 nodes are available: 3 Insufficient memory.
포드에 hostPort를 정의한 경우, 다음 모범 사례를 따르세요.
- hostIP, hostPort 및 protocol 조합은 고유해야 하므로 필요한 경우에만 hostPort를 지정하세요.
- hostPort를 지정하는 경우, 워커 노드와 동일한 수의 포드를 스케줄링합니다.
참고: 포드를 hostPort에 바인딩할 때, 포드를 예약할 수 있는 위치의 수가 제한되어 있습니다.
다음 예시는 frontend-port-77f67cff67-2bv7w라는 Pending 상태인 포드에 대한 describe 명령의 출력을 보여줍니다. 요청된 호스트 포트를 클러스터의 워커 노드에 사용할 수 없기 때문에 포드가 스케줄링되지 않았습니다.
$ kubectl describe pod frontend-port-77f67cff67-2bv7w Name: frontend-port-77f67cff67-2bv7w ... Status: Pending IP: IPs: <none> Controlled By: ReplicaSet/frontend-port-77f67cff67 Containers: app: Image: nginx Port: 80/TCP Host Port: 80/TCP ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 11s (x7 over 6m22s) default-scheduler 0/3 nodes are available: 3 node(s) didn't have free ports for the requested pod ports.
노드에 포드가 허용하지 않는 테인트가 있어서 포드를 스케줄링할 수 없는 경우, 예제 출력은 다음과 비슷합니다.
$ kubectl describe pod nginx Name: nginx ... Status: Pending ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 8s (x10 over 9m22s) default-scheduler 0/3 nodes are available: 3 node(s) had taint {key1: value1}, that the pod didn't tolerate.
노드 테인트를 확인하려면, 다음 명령을 실행합니다.
$ kubectl get nodes -o custom-columns=NAME:.metadata.name,TAINTS:.spec.taints
노드 테인트를 유지하려면, PodSpec에서 포드에 대한 톨러레이션을 지정해야 합니다. 자세한 내용을 보려면 Kubernetes 웹사이트의 개념을 참조하세요. 또는 테인트 값 끝에 **-**를 추가하여 노드 테인트를 제거합니다.
$ kubectl taint nodes NODE_Name key1=value1:NoSchedule-
포드가 아직 Pending 상태인 경우, 추가 문제 해결 섹션의 단계를 완료하세요.
컨테이너가 Waiting 상태입니다.
Docker 이미지가 잘못되었거나 저장소 이름이 잘못되어 컨테이너가 Waiting 상태일 수 있습니다. 또는 이미지가 존재하지 않거나 권한이 없기 때문에 포드가 Waiting 상태일 수 있습니다.
이미지와 리포지토리 이름이 올바른지 확인하려면 Docker Hub, Amazon Elastic Container Registry (Amazon ECR) 또는 다른 컨테이너 이미지 리포지토리에 로그인하세요. 리포지토리 또는 리포지토리의 이미지를 포드 사양에 지정된 리포지토리 또는 이미지 이름과 비교합니다. 이미지가 존재하지 않거나 권한이 없는 경우, 다음 단계를 완료하세요.
-
지정한 이미지를 저장소에서 사용할 수 있고 이미지를 가져올 수 있도록 올바른 권한이 구성되어 있는지 확인합니다.
-
이미지를 가져올 수 있고 일반적인 네트워킹 및 리포지토리 권한 문제가 없는지 확인하려면 이미지를 수동으로 가져오세요. Amazon EKS 워커 노드에서 이미지를 가져오려면 Docker를 사용해야 합니다.
$ docker pull yourImageURI:yourImageTag
-
이미지가 존재하는지 확인하려면 이미지와 태그가 모두 Docker Hub 또는 Amazon ECR에 있는지 확인하세요.
참고: Amazon ECR을 사용하는 경우 리포지토리 정책이 NodeInstanceRole에 대한 이미지 풀을 허용하는지 확인하세요. 또는 AmazonEC2ContainerRegistryReadOnly 읽기 전용 역할이 정책에 연결되어 있는지 확인하세요.
다음 예제는 이미지 풀 오류로 인해 컨테이너가 Waiting 상태에 있는 Pending 상태의 포드를 보여줍니다.
$ kubectl describe po web-test Name: web-test ... Status: Pending IP: 192.168.1.143 Containers: web-test: Container ID: Image: somerandomnonexistentimage Image ID: Port: 80/TCP Host Port: 0/TCP State: Waiting Reason: ErrImagePull ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 66s default-scheduler Successfully assigned default/web-test to ip-192-168-6-51.us-east-2.compute.internal Normal Pulling 14s (x3 over 65s) kubelet, ip-192-168-6-51.us-east-2.compute.internal Pulling image "somerandomnonexistentimage" Warning Failed 14s (x3 over 55s) kubelet, ip-192-168-6-51.us-east-2.compute.internal Failed to pull image "somerandomnonexistentimage": rpc error: code = Unknown desc = Error response from daemon: pull access denied for somerandomnonexistentimage, repository does not exist or may require 'docker login' Warning Failed 14s (x3 over 55s) kubelet, ip-192-168-6-51.us-east-2.compute.internal Error: ErrImagePull
컨테이너가 여전히 Waiting 상태인 경우, 추가 문제 해결 섹션의 단계를 완료하세요.
포드가 CrashLoopBackOff 상태입니다.
“Back-Off restarting failed container” 출력 메시지가 표시되면 Kubernetes가 컨테이너를 시작한 직후 컨테이너가 종료되었을 수 있습니다.
현재 포드의 로그에서 오류를 찾으려면, 다음 명령어를 실행합니다.
$ kubectl logs YOUR_POD_NAME
충돌한 이전 포드의 로그에서 오류를 찾으려면 다음 명령어를 실행합니다.
$ kubectl logs --previous YOUR-POD_NAME
다중 컨테이너 포드의 경우, 끝에 컨테이너 이름을 추가합니다. 예를 들면, 다음과 같습니다.
$ kubectl logs [-f] [-p] (POD | TYPE/NAME) [-c CONTAINER]
활성 프로브가 Succesful 상태를 반환하지 않는 경우, 라이브니스 프로브가 애플리케이션에 맞게 올바르게 구성되었는지 확인하세요. 자세한 내용을 보려면 Kubernetes 웹사이트의 프로브 구성을 참조하세요.
다음 예제는 포드가 시작된 후 애플리케이션이 종료되기 때문에 CrashLoopBackOff 상태에 있는 포드를 보여줍니다.
$ kubectl describe pod crash-app-b9cf4587-66ftw Name: crash-app-b9cf4587-66ftw ... Containers: alpine: Container ID: containerd://a36709d9520db92d7f6d9ee02ab80125a384fee178f003ee0b0fcfec303c2e58 Image: alpine Image ID: docker.io/library/alpine@sha256:e1c082e3d3c45cccac829840a25941e679c25d438cc8412c2fa221cf1a824e6a Port: <none> Host Port: <none> State: Waiting Reason: CrashLoopBackOff Last State: Terminated Reason: Completed Exit Code: 0 Started: Tue, 12 Oct 2021 12:26:21 +1100 Finished: Tue, 12 Oct 2021 12:26:21 +1100 Ready: False Restart Count: 4 ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Started 97s (x4 over 2m25s) kubelet Started container alpine Normal Pulled 97s kubelet Successfully pulled image "alpine" in 1.872870869s Warning BackOff 69s (x7 over 2m21s) kubelet Back-off restarting failed container Normal Pulling 55s (x5 over 2m30s) kubelet Pulling image "alpine" Normal Pulled 53s kubelet Successfully pulled image "alpine" in 1.858871422s
다음은 포드에서 실패한 활성 프로브의 예입니다.
$ kubectl describe pod nginx Name: nginx ... Containers: nginx: Container ID: containerd://950740197c425fa281c205a527a11867301b8ec7a0f2a12f5f49d8687a0ee911 Image: nginx Image ID: docker.io/library/nginx@sha256:06e4235e95299b1d6d595c5ef4c41a9b12641f6683136c18394b858967cd1506 Port: 80/TCP Host Port: 0/TCP State: Waiting Reason: CrashLoopBackOff Last State: Terminated Reason: Completed Exit Code: 0 Started: Tue, 12 Oct 2021 13:10:06 +1100 Finished: Tue, 12 Oct 2021 13:10:13 +1100 Ready: False Restart Count: 5 Liveness: http-get http://:8080/ delay=3s timeout=1s period=2s #success=1 #failure=3 ... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Pulled 2m25s kubelet Successfully pulled image "nginx" in 1.876232575s Warning Unhealthy 2m17s (x9 over 2m41s) kubelet Liveness probe failed: Get "http://192.168.79.220:8080/": dial tcp 192.168.79.220:8080: connect: connection refused Normal Killing 2m17s (x3 over 2m37s) kubelet Container nginx failed liveness probe, will be restarted Normal Pulling 2m17s (x4 over 2m46s) kubelet Pulling image "nginx"
포드가 여전히 CrashLoopBackOff 상태인 경우, 추가 문제 해결 섹션의 단계를 완료하세요.
포드가 Terminating 상태입니다.
포드가 Terminating 상태로 멈춘 경우, 해당 포드가 실행 중인 노드와 파이널라이저의 상태를 확인하세요. 파이널라이저는 포드가 Terminated로 전환되기 전에 종료 처리를 수행하는 함수입니다. 자세한 내용을 보려면 Kubernetes 웹사이트의 파이널라이저를 참조하십시오. 종료하는 포드의 파이널라이저를 확인하려면, 다음 명령을 실행합니다.
$ kubectl get po nginx -o yaml apiVersion: v1 kind: Pod metadata: ... finalizers: - sample/do-something ...
위 예제에서는 파이널라이저 sample/do-something이 제거된 후에만 포드가 Terminated로 전환됩니다. 일반적으로 커스텀 컨트롤러는 파이널라이저를 처리한 다음 제거합니다. 그러면 포드가 Terminated 상태로 전환됩니다.
이 문제를 해결하려면, 커스텀 컨트롤러의 포드가 제대로 실행되는지 확인하세요. 컨트롤러 포드 관련 문제를 해결하고 사용자 지정 컨트롤러가 파이널라이저 프로세스를 완료하도록 합니다. 그러면 포드가 자동으로 Terminated 상태로 전환됩니다. 또는 다음 명령을 실행하여 파이널라이저를 직접 삭제합니다.
$ kubectl edit po nginx
추가 문제 해결
포드가 여전히 멈춘 경우, 다음 단계를 완료하세요.
-
워커 노드가 클러스터에 있고 Ready 상태인지 확인하려면 다음 명령을 실행합니다.
$ kubectl get nodes
노드 상태가 NotReady인 경우 노드 상태를 NotReady 또는 Unknown 상태에서 Ready 상태로 변경하려면 어떻게 해야 하나요?를 참조하세요. 노드가 클러스터에 가입할 수 없는 경우, 워커 노드를 Amazon EKS 클러스터에 참여시키려면 어떻게 해야 하나요?를 참조하세요.
-
Kubernetes 클러스터의 버전을 확인하려면, 다음 명령을 실행합니다.
$ kubectl version --short
-
Kubernetes 워커 노드의 버전을 확인하려면, 다음 명령을 실행합니다.
$ kubectl get node -o custom-columns=NAME:.metadata.name,VERSION:.status.nodeInfo.kubeletVersion
-
클러스터의 Kubernetes 서버 버전이 허용 가능한 버전 차이 내에서 워커 노드의 버전과 일치하는지 확인합니다. 자세한 내용을 보려면 Kubernetes 웹사이트의 버전 스큐 정책을 참조하세요.
중요: 패치 버전은 클러스터와 워커 노드 간에 다를 수 있습니다 (예: 클러스터의 경우 v1.21.x, 워커 노드의 경우 v1.21.y). 클러스터와 워커 노드 버전이 호환되지 않는 경우 eksctl 또는 AWS CloudFormation을 사용하여 새 노드 그룹을 생성하세요. 또는 호환되는 Kubernetes 버전을 사용하여 새로운 관리형 노드 그룹(예: Kubernetes: v1.21, 플랫폼: eks.1 이상)을 생성합니다. 그런 다음, 호환되지 않는 Kubernetes 버전이 포함된 노드 그룹을 삭제합니다. -
Kubernetes 컨트롤 플레인이 워커 노드와 통신할 수 있는지 확인합니다. Amazon EKS 보안 그룹 요구 사항 및 고려 사항의 필수 규칙과 비교하여 방화벽 규칙을 확인하세요. 그런 다음, 노드가 Ready 상태인지 확인합니다.
관련 콘텐츠
- 질문됨 2달 전lg...
- 질문됨 일 년 전lg...
- 질문됨 일 년 전lg...
- 질문됨 2년 전lg...
- AWS 공식업데이트됨 2년 전
- AWS 공식업데이트됨 10달 전
- AWS 공식업데이트됨 일 년 전
- AWS 공식업데이트됨 일 년 전