• Русский
  • Устранение неполадок с рабочим кластером, зависшим в состоянии Provisioned

    Используйте это руководство, если рабочий кластер в Immutable Infrastructure достиг Cluster.status.phase = Provisioned, а control plane Kubernetes сообщает о готовности, но кластер так и не становится полностью пригодным к использованию.

    Диагностический процесс предполагает, что рабочий кластер был создан путем применения манифестов Cluster API провайдера в кластере global.

    Область применения

    Диагностический процесс в этом руководстве ориентирован на контроллер импорта кластера global, который общий для всех провайдеров Immutable Infrastructure. Четыре инварианта из раздела Инварианты исправно импортированного кластера — наличие clusters.platform.tkestack.io, метка capi.cpaas.io/imported, число ClusterCredential и ServiceAccount sentry в рабочем кластере — применимы ко всем провайдерам.

    Строки журналов в этом руководстве используют заполнители для имен объектов reconciler, поскольку каждый провайдер инфраструктуры использует собственные типы объектов (например, собственные инфраструктурные CRD Cluster и Machine у провайдера). При чтении журналов вашего провайдера подставляйте вместо заполнителей реальные имена объектов, которые отображаются в выводе reconciler вашего провайдера. Сам диагностический шаблон не зависит от провайдера — от него зависят только имена объектов в строках журнала.

    Если ваша среда использует Huawei Cloud Stack и симптомы ниже также включают зависание kubeadm init на узле, у которого конфигурация пула содержит hostname с точками, см. Устранение неполадок с рабочими кластерами HCS для ознакомления со специфичным для провайдера шаблоном после завершения общего диагностического процесса на этой странице.

    Симптомы

    Кластер достигает состояния частичного успеха и остается в нем. Одновременно наблюдаются следующие признаки:

    Где смотретьЧто вы видите
    Cluster.status.phase (в кластере global)Provisioned
    KubeadmControlPlane.status.readytrue
    Machine.status.phaseRunning
    Machine.status.conditions[?(@.type=="NodeHealthy")]status: False, reason: NodeConditionsFailed, message: Node condition Ready is False
    MachineDeployment.status.conditions[?(@.type=="Available")]status: False, reason: NotAvailable, message: WorkersAvailable: 0 available replicas
    Внутри рабочего кластера: kubectl get nodesОдин или несколько узлов имеют STATUS=NotReady, потому что CNI не запущен

    Типичная вторичная сигнатура появляется в журналах reconciler провайдера инфраструктуры в кластере global:

    ERROR  failed to reconcile <CNI-AppRelease-object>: ServiceAccount "sentry" not found
    ERROR  failed to reconcile <Infra-Cluster-object>: ServiceAccount "sentry" not found

    <CNI-AppRelease-object> и <Infra-Cluster-object> — это заполнители для фактических типов объектов, которые использует ваш провайдер. Например, объект CNI AppRelease обычно именуется по развертываемому CNI, а имя объекта инфраструктурного кластера соответствует CRD вашего провайдера (собственный CRD *Cluster).

    Reconciler пытается применить CNI через ресурс AppRelease, который выполняется под ServiceAccount sentry самого рабочего кластера. Если этот ServiceAccount отсутствует, CNI никогда не разворачивается, и рабочие узлы остаются в состоянии NotReady.

    Инварианты исправно импортированного кластера

    После того как рабочий кластер достигает исправного устойчивого состояния, должны выполняться все следующие условия. Проверяйте каждый инвариант из контекста кластера global, если не указано иное.

    1. Существует объект clusters.platform.tkestack.io/<cluster-name>.

      kubectl get clusters.platform.tkestack.io <cluster-name>
    2. Ресурс Cluster API Cluster содержит метку capi.cpaas.io/imported: "".

      В исправно импортированном кластере значение метки равно пустой строке "", поэтому один только запрос jsonpath не позволяет отличить «метка отсутствует» от «значение метки пустое». Используйте jq, чтобы явно проверить наличие метки:

      kubectl get cluster <cluster-name> -n <namespace> -o json | \
        jq -r 'if (.metadata.labels | has("capi.cpaas.io/imported"))
               then "present (value=\"\(.metadata.labels["capi.cpaas.io/imported"])\")"
               else "missing"
               end'

      Ожидаемый вывод: present (value=""). missing означает, что импорт не завершен.

    3. Для кластера помечен ровно один объект clustercredentials.platform.tkestack.io.

      kubectl get clustercredentials.platform.tkestack.io -o json | \
        jq -r --arg c <cluster-name> \
          '.items[] | select(.metadata.labels["cluster.x-k8s.io/cluster-name"]==$c) | .metadata.name'

      Должно быть выведено ровно одно имя.

    4. Внутри рабочего кластера ServiceAccount sentry существует в cpaas-system.

      kubectl --kubeconfig <workload-kubeconfig> -n cpaas-system get serviceaccount sentry

    Если какой-либо инвариант нарушен, значит рабочий кластер не был импортирован контроллером импорта кластера global, и описанная выше схема симптомов ожидаема.

    Диагностические шаги

    Шаг 1 — Убедитесь, что поверхность Cluster API исправна

    kubectl get cluster <cluster-name> -n <namespace> -o wide
    kubectl get kubeadmcontrolplane -n <namespace>
    kubectl get machinedeployment -n <namespace>

    Сбой на этом этапе не связан с шаблоном импорта; исследуйте сам провайдер инфраструктуры.

    Шаг 2 — Проверьте условия Machine и Node

    kubectl get machine -n <namespace> \
      -l cluster.x-k8s.io/cluster-name=<cluster-name> \
      -o jsonpath='{range .items[*]}{.metadata.name}{" phase="}{.status.phase}{" "}{range .status.conditions[*]}{.type}={.status} {end}{"\n"}{end}'

    Если phase=Running, но условие NodeHealthy имеет значение False, базовый узел рабочего кластера находится в состоянии NotReady. Перейдите к шагу 3.

    Шаг 3 — Изучите журналы reconciler провайдера инфраструктуры

    kubectl logs -n cpaas-system <infra-provider-manager-pod> --tail=200 | \
      grep -E 'ServiceAccount|sentry|<cluster-name>'

    Если вы видите повторяющиеся ошибки ServiceAccount "sentry" not found в сочетании со сбоем reconcile объекта CNI AppRelease, значит CNI рабочего кластера не разворачивается, потому что процесс импорта не завершен. Перейдите к шагу 4.

    Шаг 4 — Проверьте, что кластер global импортировал рабочий кластер

    Выполните проверки инвариантов из предыдущего раздела. Совокупная диагностическая сигнатура неудачного импорта выглядит так:

    • clusters.platform.tkestack.io/<cluster-name> возвращает NotFound.
    • Cluster.metadata.labels не содержит capi.cpaas.io/imported.

    Шаг 5 — Проверьте инвариант количества ClusterCredential

    kubectl get clustercredentials.platform.tkestack.io -o json | \
      jq -r --arg c <cluster-name> \
        '[.items[] | select(.metadata.labels["cluster.x-k8s.io/cluster-name"]==$c)] | length'

    В исправном кластере выводится 1. Значение больше 1 (например, 8) означает, что процесс импорта неоднократно пытался завершиться неудачно, оставляя за собой осиротевшие учетные данные.

    Шаблон, указывающий на неудачный импорт

    Диагностика указывает на неудачный импорт, если все следующие условия выполняются одновременно:

    • Поверхность Cluster API исправна (Cluster.status.phase=Provisioned, KubeadmControlPlane.status.ready=true).
    • Machine.condition.NodeHealthy=False, и по крайней мере один рабочий узел находится в состоянии NotReady.
    • В журналах провайдера инфраструктуры повторяется сообщение ServiceAccount "sentry" not found.
    • clusters.platform.tkestack.io/<cluster-name> не существует.
    • Ресурс Cluster не содержит метку capi.cpaas.io/imported.
    • Для кластера помечено более одного объекта clustercredentials.platform.tkestack.io.

    Когда этот шаблон имеет место, начальный импорт рабочего кластера в кластере global не удался, и контроллер импорта в настоящее время не выполняет повторную попытку с нуля.

    Что не устраняет этот шаблон

    WARNING

    Перезапуск pod cluster-transformer в кластере global не выполняет повторный импорт рабочего кластера, если его первоначальный импорт уже завершился неудачей по этому шаблону. После ручного перезапуска pod в журналах не будет записей, относящихся к затронутому кластеру, и отсутствующая запись clusters.platform.tkestack.io не создается.

    Не рассчитывайте на то, что контроллер со временем восстановится сам, если для одного и того же кластера присутствует более одного осиротевшего ClusterCredential.

    Следующий шаг

    Обратитесь в службу поддержки платформы со следующей информацией:

    • Имя и namespace кластера.
    • Вывод диагностических команд из шагов 1–5.
    • Имена и метки времени создания всех объектов clustercredentials.platform.tkestack.io, у которых совпадает метка cluster.x-k8s.io/cluster-name с затронутым кластером.

    Восстановление в настоящее время требует удаления и повторного создания рабочего кластера после очистки осиротевших записей ClusterCredential. Не выполняйте это в production-кластере без указаний службы поддержки платформы: путь повторного создания инициирует удаление базовых виртуальных машин на платформе IaaS, и перед применением повторного создания необходимо проверить детали, специфичные для провайдера (например, планирование IP-pool и hostname в DCS или перераспределение HCSMachineConfigPool в HCS).

    См. также