ボリュームマウントの競合により、ワークロード クラスターのアップグレードが builtin-generic-v3.3.0 (またはそれ以上) クラスタークラスで停止しました
search cancel

ボリュームマウントの競合により、ワークロード クラスターのアップグレードが builtin-generic-v3.3.0 (またはそれ以上) クラスタークラスで停止しました

book

Article ID: 428149

calendar_today

Updated On:

Products

Tanzu Kubernetes Runtime VMware vSphere Kubernetes Service

Issue/Introduction

免責事項:これは英文の記事「Workload Cluster Upgrade Stuck builtin-generic-v3.3.0 (or higher) clusterclass due to Volume Mount Conflicts」の日本語訳です。記事はベストエフォートで翻訳を進めているため、ローカライズ化コンテンツは最新情報ではない可能性があります。最新情報は英語版の記事で参照してください。

ワークロードクラスタのアップグレードにおいて、目的の KR バージョン上で新しく作成されたコントロールプレーンマシンが Provisioning または Provisioned 状態のまま停止しています。

アップグレードは、すべてのコントロールプレーンマシンを目的の KR バージョンへアップグレードすることから開始されます。

Note: すべてのコントロールプレーンマシンが目的の KR バージョン上で正常(Healthy)になるまで、ワーカーマシンのアップグレードは開始されません。

 

Provisioned / Provisioning 状態で停止している新しいコントロールプレーンマシンに直接 SSH 接続すると、以下のようなエラーメッセージが確認されます。

cat /var/log/cloud-init-output.log

error applying: error applying task .mount: unit with key .mount could not be enabled 
Unit /run/systemd/generator/.mount is transient or generated. 
Failed to run module scripts_user (scripts in /var/lib/cloud/instance/scripts)

以下のドキュメントをご参照ください: SSH to TKG Service Cluster Nodes as the System User Using a Password

 

Supervisor クラスタのコンテキストに接続した状態では、以下の症状が確認されます。

  • クラスタは目的の KR バージョン上にあります:
    kubectl get cluster -n <affected workload cluster namespace>
  • 目的の KR バージョン上にある 1 台以上の Machine が Provisioned または Provisioning 状態で停止しています:
    kubectl get machines -n <affected workload cluster namespace>
  • 目的の KR バージョン上に存在する Machine は、すべて Provisioning または Provisioned 状態で停止しています。
    • これらの Machine は Provisioning または Provisioned 状態のまま、再作成を繰り返します(デフォルト 120 分)。
  • Provisioning 状態で停止している Machine を describe すると、以下のメッセージが表示されます:
    kubectl describe machine -n <workload cluster namespace> <stuck Provisioning node name>
    
    * VirtualMachineProvisioned: Provisioning
    * NodeHealthy: Waiting for VSphereMachine to report spec.providerID
    
    machinehealthcheck-controller  Machine <workload cluster namespace>/<stuck Provisioning node name> has unhealthy Node
    
  • 該当ワークロードクラスタの kubeadmControlPlane (KCP) を describe すると、以下のようなメッセージが表示されます: Note: この症状は、Provisioning 状態の Machine がコントロールプレーンマシンである場合に発生します。
    kubectl get kcp -n <affected workload cluster namespace>
    
    kubectl describe kcp -n <affected workload cluster namespace> <workload cluster kcp name>
    
    Message:               Rolling 3 replicas with outdated spec (1 replicas up to date)
    
     Message:               * Machine <stuck Provisioning control plane node>
      * EtcdMemberHealthy: Waiting for a Node with spec.providerID vsphere://<provider ID> to exist
    * Etcd member <stuck Provisioning control plane node> does not have a corresponding Machine
    
    Message:               Scaling down control plane to 3 replicas (actual 4)

Environment

vSphere Supervisor

Originally deployed on vSphere 7 or 8.0 GA then later directly upgraded to vSphere 8.0u2 (or higher), skipping vSphere 8.0u1

Workload Cluster using or upgrading to builtin-generic-v3.3.0 (or higher) clusterClass

Cause

本事象は、Server-Side Apply に起因するレガシーなフィールド所有権の競合に関連しています。 詳細については、以下の KB をご参照ください: Workload Cluster Upgrade Stuck on New Node Stuck Provisioning due to Legacy Fields

このシナリオでは、ワークロードクラスタの KubeadmControlPlane リソースに以下が含まれています:

  • spec.kubeadmConfigSpec.mounts (ボリュームマウントを定義しており、cloud-init によって処理されます)
  • spec.kubeadmConfigSpec.preKubeadmCommands 内の machineadm への参照 (同一のボリュームマウントを設定しようとしており、machineadm によって処理されます)


このような二重の設定が発生する要因は以下のとおりです:

  • 非推奨となった API バージョン(v1beta1)に由来するレガシーな managed fields がリソース上に存在している
  • 上記 KB で説明されているフィールド所有権の境界により、トポロジーリコンシーラが競合している mounts フィールドをクリーンアップできない
  • cloud-init(mounts を処理)と machineadm(preKubeadmCommands を処理)の両方が、 同一のボリュームマウントを設定しようとすることで、ノード上で systemd ユニットの競合が発生する


systemd のエラーは、マウントユニットが 2 つの異なる方法で定義されているために発生します:

  • cloud-init によって 1 回定義されている
  • machineadm によって 1 回定義されている

Resolution

Note: 本事象は、vSphere 8.0u1 へのアップグレードをスキップした vSphere 8.0u2 以降の環境で特有に発生します。

 

Resolution

本問題は、vSphere Kubernetes Service v3.5.0 にて修正されています。

環境が VKS v3.5.0 へアップグレードされた後は、まだアップグレードされていないワークロードクラスタに対して、以下の回避策を適用する必要はありません。

 

For Future Workload Cluster Upgrades

以下の KB 記事内の Additional Information セクションをご参照ください:

Workload Cluster Upgrade Stuck on New Node Stuck Provisioning due to Legacy Fields

 

For Workload Clusters Stuck Upgrading Affected By This Issue - Workaround

  1. Supervisor クラスタのコンテキストへ接続します。

  2. 影響を受けているワークロードクラスタの machinehealthcheck(mhc)を一時的に無効化します:
    • システムは mhc を使用して、10~15 分ごとに障害が発生したワークロードクラスタノードを再作成します。
      kubectl patch cluster.v1beta1.cluster.x-k8s.io <workload cluster name> -n <workload cluster namespace> --type=merge -p='{"spec":{"topology":{"controlPlane":{"machineHealthCheck":{"enable":false}}}}}'

       

  3. 影響を受けているワークロードクラスタで、machineHealthCheck の無効化フラグが false に正常に設定されたことを確認します:
    kubectl get cluster.v1beta1.cluster.x-k8s.io <workload cluster name> -n <workload cluster namespace> -o yaml | grep -A2 machineHealthCheck

     

  4. 影響を受けているワークロードクラスタの KubeadmControlPlane(kcp)内に存在する競合フィールドを確認します:
    kubectl get kcp -n <workload cluster namespace>
    
    kubectl get kcp <kcp name> -n <workload cluster namespace> -o jsonpath='{.spec.kubeadmConfigSpec.mounts}'

     

  5. 競合するフィールドが存在する場合は、KubeadmControlPlane(kcp)のバックアップを取得します:
    kubectl get kcp <kcp name> -n <workload cluster namespace> -o yaml > kcp_backup.yaml

     

  6. 影響を受けているワークロードクラスタの KubeadmControlPlane(kcp)から競合フィールドをクリーンアップします:
    kubectl patch kcp <kcp name> -n <workload cluster namespace> --type=json -p='[{"op": "remove", "path": "/spec/kubeadmConfigSpec/mounts"}]'

     

  7. 以下の KB 記事に記載されている Additional Information の手順に従ってください:
  8. IMPORTANT: 影響を受けているワークロードクラスタで machineHealthCheck を再度有効化します:
    kubectl patch cluster <workload cluster name> -n <workload cluster namespace> --type=merge -p='{"spec":{"topology":{"controlPlane":{"machineHealthCheck":{"enable":true}}}}}' 

     

  9. Provisioned 状態で停止しているコントロールプレーンマシンを再作成するようシステムに指示します:
    kubectl annotate machine -n <workload cluster namespace> <stuck provisioned machine name> 'cluster.x-k8s.io/remediate-machine=""'

    Note: 注釈を付与する前に、マシンが自動的に更新される場合があります。

  10. 新しく作成されたノードが Running 状態になることを確認するため、監視します:
    watch kubectl get machine,vm -o wide -n <workload cluster namespace>