Kubernetes 메모리 카트리지를 시작할 수 없는 이유 및 대책

17080 단어 kubernetes
Kubernetes 도입을 고려할 때 잘못된 상황 확인부터 해결해야 할 조작까지 파악해야 한다.만약 아직 가져오지 않았다면 이런 문제가 발생하지 않았을까.
이 항목은 자신이 겪은 실패 사례의 원인과 해결 방법을 열거하였다.또 경험에 기초한 것이기 때문에 같은 오류가 발생하더라도 상황에 따라 다른 원인이나 해결 방법이 있을 수 있다.또한 기록된 로그와 설정된 파일의 자원 이름과 값 등을 적절하게 가리기 때문에 적당히 다시 읽기를 바랍니다.

어떤 타이밍에 팟캐스트를 시작할 수 없나요?


Kubernetes는 Pod이 떨어지면 자동으로 Pod 재부팅 등의 관리를 수행합니다.그러나 처음 박스를 만들 때나 구조를 바꾼 박스와 복제 컨트롤러가 스크롤 업데이트를 할 때 잘못된 설정으로 박스가 작동하지 않는 경우가 종종 있다.

스크롤 업데이트 실패


스크롤 업데이트를 진행할 때, 새 상자가 어떤 이유로 시작되지 않으면, error: timed out waiting for any update progress to be made 와 같은 난잡한 정보를 토해내지 못할 것입니다.이런 사태에 빠져도 너무 당황할 필요는 없다.용기 안의 모든 용기를 정상적으로 작동하게 함으로써 용기가 정상이라고 판단하고 정상적인 용기를 생성하지 않으면 스크롤 업데이트를 시작하거나 용기를 교체할 수 없기 때문이다.이렇게 스크롤 업데이트가 시작되지 않은 상황에서 앞의 구조는 그대로 이동하여 시작에 실패한 새 구조는 이동하지 않고 배치됩니다.따라서 외부는 업데이트를 반영하지 않았을 뿐이다.

스크롤 업데이트를 실행할 때 실패를 감지하는 방법


CI에서 스크롤 업데이트를 자동으로 실행하면 테스트에 실패할 수 있습니다.kubectl rolling-update rc 명령은 --output=json JSON에서 결과를 얻을 수 없기 때문에 exit 코드를 기반으로 오류 여부를 판정합니다.

실패할 때 프로세스를 낮추려고 할 때


간단하게 테스트 자체를 실패하게 하려면 배치용 스크립트 파일 set -e 에 실패할 때 배치 과정을 낮춘다.
deploy.sh
set -e
kubectl rolling-update rc --filename=rc.yml

실패할 때 처리하고 싶을 때


때때로 실패를 감지하고 통지 등의 처리를 할 수 있다.이 경우 $?에서 exit 코드를 얻어 평가하고 0 이외에 끝난 상황에서 처리하고 과정을 끝낸다.
deploy.sh
kubectl rolling-update rc --filename=rc.yml
if [[ $? != 0 ]]; then
  # do something
  exit $?
fi

원인 조사 방법

kubectl get pods 명령에서 시작에 실패한 상자를 찾았고 kubectl describe pod <pod-name> 상자에 자세한 내용을 표시합니다.아래와 같이 상태가 표시됩니다.
terminal
Name:                           my-pod
...
Status:                         Pending
...
Containers:
  client:
    Image:              gcr.io/my-prj/client:v0
    State:              Waiting
      Reason:           PullImageError
    Ready:              False
    Restart Count:      0
  nginx:
    Image:              gcr.io/my-prj/nginx:v0
    State:              Waiting
      Reason:           PullImageError
    Ready:              False
    Restart Count:      0
  app:
    Image:              gcr.io/my-prj/app:v0
    State:              Waiting
      Reason:           PullImageError
    Ready:              False
    Restart Count:      0
Conditions:
  Type          Status
  Ready         False
...
Events:
  FirstSeen   LastSeen   Count   From                         SubobjectPath                Reason    Message
  ─────────   ────────   ─────   ────                         ─────────────                ──────    ───────
  33m         33m        1       {scheduler }                                              Scheduled Successfully assigned my-pod to my-node-a
  33m         33m        1       {kubelet my-node-a}   implicitly required container POD   Created   Created with docker id XXXXXXXXXXXX
  33m         33m        1       {kubelet my-node-a}   implicitly required container POD   Started   Started with docker id XXXXXXXXXXXX
  33m         33m        1       {kubelet my-node-a}   implicitly required container POD   Pulled    Container image "gcr.io/google_containers/pause:0.8.0" already present on machine
  33m         8s         199     {kubelet my-node-a}   spec.containers{client}             Pulling   Pulling image "gcr.io/my-prj/client:v0"
  32m         5s         199     {kubelet my-node-a}   spec.containers{client}             Failed    Failed to pull image "gcr.io/my-prj/client:v0": Tag v0 not found in repository gcr.io/my-prj/client
  33m         5s         199     {kubelet my-node-a}   spec.containers{nginx}              Pulling   Pulling image "gcr.io/my-prj/nginx:v0"
  33m         3s         199     {kubelet my-node-a}   spec.containers{app}                Pulling   Pulling image "gcr.io/my-prj/app:v0"
  33m         3s         199     {kubelet my-node-a}   spec.containers{nginx}              Failed    Failed to pull image "gcr.io/my-prj/nginx:v0": Tag v0 not found in repository gcr.io/my-prj/nginx
  33m         1s         199     {kubelet my-node-a}   spec.containers{app}                Failed    Failed to pull image "gcr.io/my-prj/app:v0": Tag v0 not found in repository gcr.io/my-prj/app
부팅에 실패한 컨테이너.Conteinrs.<ContainerName>.StateRunning 이외에 실패한 이유를 표시합니다.또 .Conteinrs.<ContainerName>.State.Reason 상자에서 진행된 컨테이너 가동 사건이 기록돼 있어 EventsReason 된 사건에도 주목하고 있다.

오류 내용 및 해결 방법


모든 오류에 대해 해결 방법을 표시하다.

PullImageError


원인


이미지 검색에 실패했습니다.

해결됨

  • 용기에 사용된 그림이push인지 확인합니다.
  • 이미지 레지스트리 URL이 잘못되었는지 확인합니다.
  • 이미지 태그가 잘못되었는지 확인합니다.
  • rc.yml
    apiVersion: v1
    kind: ReplicationController
    ...
    spec:
      template:
        spec:
          containers:
            - name: app
              image: gcr.io/my-prj/app:v0  # <- ココ
    

    CrashLoopBackOff


    원인


    용기 내의 프로세스가 끝났음을 감지하고 용기의 재시작을 반복합니다.

    해결됨


    컨테이너에서 물러나는 과정은 움직이지 않았습니까?용기가 정상적으로 작동하는지는 프로세스가 하강하는지에 따라 판단되기 때문에 프로세스가 정상적으로 끝나도'프로세스 하강'이 되어 다시 시작됩니다.이런 용기가 다시 시작되면 과정은 다시 정상적으로 끝날 것이다.무한정 계속 가동한다는 얘기다.
    단일 컨테이너 박스의 경우 컨테이너의 재부팅 정책을 프로세스가 비정상적으로 끝날 때만 재부팅하도록 변경합니다.
    rc.yml
    apiVersion: v1
    kind: ReplicationController
    ...
    spec:
      template:
        spec:
          restartPolicy: OnFailure  # <- ココ
    
    다중 용기 상자에 대해서는 상기 옵션을 설정할 수 없습니다.컨테이너는 Dockerfile의 Failed 에서 숙지하고 영구적입니다.
    Dockerfile
    CMD <your-command> && tail -f /dev/null
    
    종료하지 말아야 할 프로세스를 실행 중인 경우 불법으로 종료되었을 수 있습니다.CMD에서 용기에서 뱉은 로그를 확인합니다.

    PodExceedsFreeCPU


    원인


    노드에 남아 있는 CPU 리소스 이상의 CPU 리소스를 요청합니다.

    해결됨


    우선 노드가 보유한 자원량을 파악한다.tail -f /dev/null에 노드의 일람을 표시하고 kubectl -c <container-name> logs <pod-name>에 노드의 상세한 상황을 표시합니다.
    terminal
    Name:                   my-node-a
    ...
    Capacity:
     pods:          40
     cpu:           2
     memory:        7679608Ki
    ...
    Non-terminated Pods:            (10 in total)
      Namespace   Name       CPU Requests   CPU Limits   Memory Requests Memory Limits
      ─────────   ────       ────────────   ──────────   ─────────────── ─────────────
      default     my-pod-a   400m (20%)     400m (20%)   512Mi (6%)      512Mi (6%)
      default     my-pod-b   400m (20%)     400m (20%)   512Mi (6%)      512Mi (6%)
      default     my-pod-c   400m (20%)     400m (20%)   512Mi (6%)      512Mi (6%)
      default     my-pod-d   400m (20%)     400m (20%)   512Mi (6%)      512Mi (6%)
    Allocated resources:
      (Total limits may be over 100%, i.e., overcommitted. More info: http://releases.k8s.io/HEAD/docs/user-guide/compute-resources.md)
      CPU Requests  CPU Limits      Memory Requests Memory Limits
      ────────────  ──────────      ─────────────── ─────────────
      1600m (80%)   1600m (80%)     2048Mi (24%)    2048Mi (24%)
    No events.
    
    CPU 리소스를 80% 사용한 상태이므로 나머지 20%만 남습니다.
    해결 방법용기에 분배되는 자원량을 적당히 설정하다.
    애플리케이션이 작동할 수 있는 경우 각 컨테이너에 할당되는 CPU 리소스를 줄일 수 있습니다.
    rc.yml
    apiVersion: v1
    kind: ReplicationController
    ...
    spec:
      template:
        spec:
          containers:
            - name: app
              resources:
                requests:
                  cpu: 100m  # <- ココ
    
    솔루션 2복사본 수를 올바르게 설정합니다.
    애플리케이션이 복제 복제본 수를 줄일 수 있는 경우 시작된 저장소 수를 줄일 수 있습니다.
    rc.yml
    apiVersion: v1
    kind: ReplicationController
    ...
    spec:
      replicas: 2  # <- ココ
    
    솔루션 3노드 수를 늘리다.
    자원이 절대적으로 부족한 상황에서 kubectl get nodes 노드를 늘리는 것이지 해결 방안 1, 2처럼 조정하면 완성할 수 있는 상황이 아니다.

    OOMKilled


    원인


    컨테이너에 할당된 메모리를 사용하여 컨테이너 안에서 OOM Killer에 의해 프로세스를 죽입니다.

    해결됨

    kubectl describe nodes <node-name>의 수치를 증가시켜 용기가 사용할 수 있는 메모리의 상한선을 높인다.
    rc.yml
    apiVersion: v1
    kind: ReplicationController
    ...
    spec:
      template:
        spec:
          containers:
            - name: app
              resources:
                limits:
                  memory: 1024Mi  # <- ココ
    

    수정 작업


    원인을 확인하면 시작되지 않은 복제 컨트롤러를 삭제합니다.그리고 스크롤 업데이트를 진행할 때, 현재 실행 중인 복제 컨트롤러가 생성한 상자는 문제가 해결된 복제 컨트롤러가 생성한 상자로 순서대로 바뀝니다.
    terminal
    kubectl delete rc <failed-rc>
    kubectl rolling-update rc --filename=rc.yml
    

    마지막


    구조를 변경하지 않으면 이런 오류가 드물기 때문에 구조를 고정한 후에 안정적으로 스크롤하여 업데이트할 수 있다.Kubernetes 확장 용기 관리라는 특징에서 볼 수 있는 자원 관리의 잡감으로 돈가스 자원으로 배치하면 수평 자동 축소가 필요한 상황에서 자원이 없어서 축소할 수 없는 상황이 발생할 수 있다돈가스의 자원에 돈가스의 자원을 상세하게 설정하고 운용하는 것보다 돈이 허락하는 상황에서 노드를 바삭하게 늘리는 것이 좋다.
    is
    잘 작동하지 않는 구조에서 방법을 강구하기 위해 용기의 구조 절차가 여러 차례 재시도되었다.다시 시도할 때 한순간에 정상적으로 작동하면 나중에 떨어지는 상황에서 외부에서도 그 불안정한 포드를 한순간에 방문할 수 있고 때로는 외부에서 무슨 순조롭지 못한 상황을 관측할 수 있는 상태가 된다. 
    RestartPolicy - The life of a pod - Kubernetes Docs  
    Compute Resources - Kubernetes Docs  
    Resizing a Container Cluster - Container Engine — Google Cloud Platform  

    좋은 웹페이지 즐겨찾기