7.3. CRI-O 컨테이너 런타임 문제 해결

7.3.1. CRI-O 컨테이너 런타임 엔진 정보

CRI-O는 Kubernetes 네이티브 컨테이너 런타임 구현으로 운영 체제와 긴밀하게 통합되는 효율적이고 최적화된 Kubernetes 환경을 제공합니다. CRI-O는 컨테이너 실행, 중지 및 다시 시작 기능을 제공합니다.

CRI-O 컨테이너 런타임 엔진은 각 OpenShift Container Platform 클러스터 노드에서 systemd 서비스를 사용하여 관리됩니다. 컨테이너 런타임 문제가 발생하면 각 노드에서 crio systemd 서비스의 상태를 확인합니다. 컨테이너 런타임 문제가 발생하면 노드에서 CRI-O journald 장치 로그를 수집합니다.

7.3.2. CRI-O 런타임 엔진 상태 확인

각 클러스터 노드에서 CRI-O 컨테이너 런타임 엔진 상태를 확인할 수 있습니다.

사전 요구 사항

  • cluster-admin 역할의 사용자로 클러스터에 액세스할 수 있어야 합니다.
  • OpenShift CLI(oc)가 설치되어 있습니다.

절차

  1. 디버그 Pod 내에서 노드의 crio systemd 서비스를 쿼리하여 CRI-O 상태를 검토합니다.

    1. 노드의 디버그 Pod를 시작합니다.

      $ oc debug node/my-node
    2. 디버그 쉘 내에서 /host를 root 디렉터리로 설정합니다. 디버그 Pod는 Pod 내의 /host에 호스트의 루트 파일 시스템을 마운트합니다. root 디렉토리를 /host로 변경하면 호스트의 실행 경로에 포함된 바이너리를 실행할 수 있습니다.

      # chroot /host
      참고

      Red Hat Enterprise Linux CoreOS (RHCOS)를 실행하는 OpenShift Container Platform 4.10 클러스터 노드는 변경할 수 없으며 Operator를 통해 클러스터 변경 사항을 적용합니다. SSH를 사용하여 클러스터 노드에 액세스하는 것은 권장되지 않습니다. 그러나 OpenShift Container Platform API를 사용할 수 없거나 kubelet이 대상 노드에서 제대로 작동하지 않는 경우 oc 작업이 영향을 받습니다. 이러한 상황에서 대신 ssh core @ <node>.<cluster_name>.<base_domain>을 사용하여 노드에 액세스할 수 있습니다.

    3. crio systemd 서비스가 노드에서 활성 상태인지 확인합니다.

      # systemctl is-active crio
    4. 더 자세한 crio.service 상태 요약을 출력합니다.

      # systemctl status crio.service

7.3.3. CRI-O journald 장치 로그 수집

CRI-O 문제가 발생하는 경우 노드에서 CRI-O journald 장치 로그를 얻을 수 있습니다.

사전 요구 사항

  • cluster-admin 역할의 사용자로 클러스터에 액세스할 수 있어야 합니다.
  • API 서비스가 작동하고 있어야 합니다.
  • OpenShift CLI(oc)가 설치되어 있습니다.
  • 컨트롤 플레인 또는 컨트롤 플레인 시스템의 정규화된 도메인 이름이 있어야 합니다.

절차

  1. CRI-O journald 장치 로그를 수집합니다. 다음 예제는 클러스터 내의 모든 컨트롤 플레인 노드에서 로그를 수집합니다.

    $ oc adm node-logs --role=master -u crio
  2. 특정 노드에서 CRI-O journald 장치 로그를 수집합니다.

    $ oc adm node-logs <node_name> -u crio
  3. API가 작동하지 않으면 대신 SSH를 사용하여 로그를 확인합니다. <node>.<cluster_name>.<base_domain>을 적절한 값으로 바꿉니다.

    $ ssh core@<node>.<cluster_name>.<base_domain> journalctl -b -f -u crio.service
    참고

    Red Hat Enterprise Linux CoreOS (RHCOS)를 실행하는 OpenShift Container Platform 4.10 클러스터 노드는 변경할 수 없으며 Operator를 통해 클러스터 변경 사항을 적용합니다. SSH를 사용하여 클러스터 노드에 액세스하는 것은 권장되지 않습니다. SSH를 통해 진단 데이터를 수집하기 전에 oc adm must gather 및 기타 oc 명령을 실행하여 충분한 데이터를 수집할 수 있는지 확인하십시오. 그러나 OpenShift Container Platform API를 사용할 수 없거나 kubelet이 대상 노드에서 제대로 작동하지 않는 경우 oc 작업이 영향을 받습니다. 이러한 상황에서 ssh core@<node>.<cluster_name>.<base_domain>을 사용하여 노드에 액세스할 수 있습니다.

7.3.4. CRI-O 스토리지 정리

다음 문제가 발생하는 경우 CRI-O 임시 스토리지를 수동으로 삭제할 수 있습니다.

  • 노드는 모든 Pod에서 실행할 수 없으며 다음과 같은 오류가 나타납니다.

    Failed to create pod sandbox: rpc error: code = Unknown desc = failed to mount container XXX: error recreating the missing symlinks: error reading name of symlink for XXX: open /var/lib/containers/storage/overlay/XXX/link: no such file or directory
  • 작업 노드에 새 컨테이너를 생성할 수 없으며 "can't stat lower layer" 오류가 나타납니다.

    can't stat lower layer ...  because it does not exist.  Going through storage to recreate the missing symlinks.
  • 클러스터 업그레이드 후 또는 재부팅을 시도하는 경우 노드는 NotReady 상태입니다.
  • crio(컨테이너 런타임 구현)가 제대로 작동하지 않습니다.
  • 컨테이너 런타임 인스턴스(crio)가 작동하지 않기 때문에 oc debug node/<nodename>을 사용하여 노드에서 디버그 쉘을 시작할 수 없습니다.

CRI-O 스토리지를 완전히 지우고 오류를 해결하려면 다음 프로세스를 따르십시오.

사전 요구 사항

  • cluster-admin 역할의 사용자로 클러스터에 액세스할 수 있어야 합니다.
  • OpenShift CLI(oc)가 설치되어 있습니다.

절차

  1. 노드에서 cordon을 사용합니다. 이는 노드가 Ready 상태가 되면 워크로드가 예약되지 않도록 하기 위한 것입니다. SchedulingDisabled가 상태 섹션에 있으면 예약이 비활성화되어 있음을 알 수 있습니다.

    $ oc adm cordon <nodename>
  2. 노드를 cluster-admin으로 드레이닝합니다.

    $ oc adm drain <nodename> --ignore-daemonsets --delete-emptydir-data
    참고

    Pod 또는 Pod 템플릿의 terminationGracePeriodSeconds 속성은 정상 종료 기간을 제어합니다. 이 속성은 기본적으로 30초이지만 필요에 따라 애플리케이션별로 사용자 지정할 수 있습니다. 90초 이상 설정하면 Pod가 SIGKILLed 로 표시되고 성공적으로 종료되지 않을 수 있습니다.

  3. 노드가 반환되면 SSH 또는 콘솔을 통해 노드에 다시 연결합니다. 그런 다음 root 사용자에 연결합니다.

    $ ssh core@node1.example.com
    $ sudo -i
  4. kubelet을 수동으로 중지합니다.

    # systemctl stop kubelet
  5. 컨테이너 및 pod를 중지합니다.

    1. 다음 명령을 사용하여 HostNetwork 에 없는 Pod를 중지합니다. 제거를 통해 HostNetwork 에 있는 네트워킹 플러그인 pod를 사용하므로 먼저 제거해야 합니다.

      .. for pod in $(crictl pods -q); do if [[ "$(crictl inspectp $pod | jq -r .status.linux.namespaces.options.network)" != "NODE" ]]; then crictl rmp -f $pod; fi; done
    2. 다른 모든 Pod를 중지합니다.

      # crictl rmp -fa
  6. crio 서비스를 수동으로 중지합니다.

    # systemctl stop crio
  7. 이러한 명령을 실행한 후 임시 스토리지를 완전히 초기화할 수 있습니다.

    # crio wipe -f
  8. crio 및 kubelet 서비스를 시작합니다.

    # systemctl start crio
    # systemctl start kubelet
  9. crio 및 kubelet 서비스가 시작되고 노드가 Ready 상태에 있으면 정리가 작동했는지 알 수 있습니다.

    $ oc get nodes

    출력 예

    NAME				    STATUS	                ROLES    AGE    VERSION
    ci-ln-tkbxyft-f76d1-nvwhr-master-1  Ready, SchedulingDisabled   master	 133m   v1.23.0

  10. 노드를 예약 가능으로 표시합니다. SchedulingDisabled 상태가 더 이상 아닐 때 예약이 활성화되어 있음을 알 수 있습니다.

    $ oc adm uncordon <nodename>

    출력 예

    NAME				     STATUS	      ROLES    AGE    VERSION
    ci-ln-tkbxyft-f76d1-nvwhr-master-1   Ready            master   133m   v1.23.0