ベアメタル版 Anthos クラスタの既知の問題

インストール

コントロール グループ v2 の非互換性

コントロール グループ v2(cgroup v2)は、ベアメタル版 Anthos クラスタ 1.6 と互換性がありません。Kubernetes 1.18 では cgroup v2 はサポートされていません。また、Docker は、20.10 以降は試験運用版のサポートのみを提供しています。systemd はバージョン 247.2-2 では、デフォルトで cgroup v2 に切り替えられました。/sys/fs/cgroup/cgroup.controllers の存在は、システムで cgroup v2 が使用されていることを意味します。

ベアメタル版 Anthos クラスタ 1.6.2 を起動すると、プリフライト チェックにより、クラスタマシンで cgroup v2 が使用されていないことが確認されます。

インストール中の無害なエラー メッセージ

高可用性(HA)クラスタのインストール中に、etcdserver leader change に関するエラーが表示されることがあります。このエラー メッセージは無害なもので、無視してかまいません。

クラスタのインストールに bmctl を使用すると、create-cluster.log の一番最後に Log streamer failed to get BareMetalMachine のログメッセージが表示されます。このエラー メッセージは無害なもので、無視して構いません。

クラスタ作成ログを調査すると、クラスタの登録または Webhook の呼び出しに関する一時的なエラーが見つかる場合があります。インストールではこうした操作を成功するまで再試行するため、これらのエラーは無視しても問題ありません。

プリフライト チェックとサービス アカウント認証情報

管理クラスタまたはハイブリッド クラスタによってトリガーされるインストール(つまり、ユーザー クラスタなど、bmctl で作成されていないクラスタ)では、プリフライト チェックは、Google Cloud Platform サービス アカウントの認証情報や、関連付けられている権限を検証しません。

プリフライト チェックと権限が拒否されました

インストール中に、/bin/sh: /tmp/disks_check.sh: Permission denied に関するエラーが表示されることがあります。このエラー メッセージは、noexec オプションを付けて /tmp がマウントされていることが原因で出力されます。bmctl が機能するためには、/tmp のマウント ポイントから noexec オプションを削除する必要があります。

ダッシュボードを表示する前に Cloud Monitoring ワークスペースを作成する

ベアメタル版 Anthos クラスタ のモニタリング ダッシュボードを表示するには、事前に Google Cloud Console からクラウド モニタリング ワークスペースを作成する必要があります。

アプリケーションのデフォルト認証情報と bmctl

bmctl は、クラスタ オペレーションのロケーションの値が global に設定されていないときに、アプリケーションのデフォルト認証情報(ADC)を使用して cluster spec でその値を検証します。

ADC を機能させるには、GOOGLE_APPLICATION_CREDENTIALS 環境変数をサービス アカウント認証情報ファイルに向けるか、gcloud auth application-default login を実行する必要があります。

Ubuntu 20.04 LTS と bmctl

バージョン 1.8.2 より前のベアメタル版 Anthos クラスタにおいて、最新の Linux カーネル(Ubuntu 5.8 カーネル上の GCP Ubuntu 20.04 LTS イメージを含む)を使用する一部の Ubuntu 20.04 LTS ディストリビューションでは、非 init ネットワーク名前空間で /proc/sys/net/netfilter/nf_conntrack_max が読み取り専用になっています。これにより、bmctl は最大接続トラッキング テーブル サイズを設定できなくなり、ブートストラップ クラスタが起動しなくなります。誤ったテーブルサイズの症状として、次のサンプル エラーログに示すように、ブートストラップ クラスタ内の kube-proxy Pod がクラッシュ ループします。

kubectl logs -l k8s-app=kube-proxy -n kube-system --kubeconfig ./bmctl-workspace/.kindkubeconfig
I0624 19:05:08.009565       1 conntrack.go:100] Set sysctl 'net/netfilter/nf_conntrack_max' to 393216
F0624 19:05:08.009646       1 server.go:495] open /proc/sys/net/netfilter/nf_conntrack_max: permission denied

これを回避するには、ホストで net/netfilter/nf_conntrack_max を必要な値に手動で設定します。sudo sysctl net.netfilter.nf_conntrack_max=393216なお、必要な値はノードのコア数によって異なります。上述の kubectl logs コマンドを使用して、kube-proxy ログから目的の値を確認します。

この問題は、ベアメタル版 Anthos クラスタ リリース 1.8.2 以降で修正されています。

Ubuntu 20.04.3+ LTS と HWE

Ubuntu 20.04.3 では、ハードウェア イネーブルメント(HWE)パッケージでカーネル 5.11 が有効になりました。ベアメタル版 Anthos クラスタ 1.7.x では、このカーネルがサポートされません。カーネル 5.11 を使用する場合は、ベアメタル リリース 1.8.0 以降の Anthos クラスタをダウンロードしてアップグレードしてください。

Docker サービス

クラスタ ノードマシンで、Docker 実行可能ファイルが PATH 環境変数に存在し、Docker サービスが有効になっていない場合は、プリフライト チェックで不合格になり、Docker service is not active が報告されます。このエラーを修正するには、Docker を削除するか、Docker サービスを有効にします。

containerd には PATH に /usr/local/bin が必要です

containerd ランタイムがあるクラスタでは、kubeadm init コマンドが crictl バイナリを見つけるために、/usr/local/bin が SSH ユーザーの PATH に含まれている必要があります。crictl が見つからない場合は、クラスタの作成が失敗します。

root ユーザーとしてログインしていない場合は、sudo を使用して kubeadm init コマンドを実行します。sudo PATH はルート プロファイルと異なる場合があり、/usr/local/bin を含めることはできません。

このエラーは、/etc/sudoerssecure_path/usr/local/bin を追加して修正します。あるいは、別の /bin ディレクトリに crictl のシンボリック リンクを作成します。

ベアメタル版 Anthos クラスタ 1.8.2 以降では、コマンドを実行するとき、PATH に /usr/local/bin が追加されます。ただし、root 以外のユーザーとしてスナップショットを実行すると、引き続き crictl: command not found が含まれます(上記の回避策で修正できます)。

ノード readiness のフラッピング

クラスタでノード readiness のフラッピング(ノードのステータスが ReadyNotReady 間で急速に変化する)が発生することがあります。この動作は、Pod Lifecycle Event Generator(PLEG)の異常により発生します。PLEG は kubelet のモジュールです。

PLEG 異常 がこの動作の原因であることを確認するには、次の journalctl コマンドを使用して PLEG のログエントリを確認します。

journalctl -f | grep -i pleg

次のようなログエントリは、PLEG が異常であることを示します。

...
skipping pod synchronization - PLEG is not healthy: pleg was last seen active
3m0.793469
...

既知の runc 競合状態は、異常な PLEG の考えられる原因です。停止した runc プロセスは、競合状態の症状です。runc init プロセスのステータスを確認するには、次のコマンドを使用します。

ps aux | grep 'runc init'

問題を解決するには:

  1. 各ノードで次のコマンドを実行して、最新の containerd.io をインストールし、最新の runc コマンドライン ツールを抽出します。

    Ubuntu

    sudo apt update
    sudo apt install containerd.io
    # Back up current runc
    cp /usr/local/sbin/runc ~/
    sudo cp /usr/bin/runc /usr/local/sbin/runc
    
    # runc version should be > 1.0.0-rc93
    /usr/local/sbin/runc --version
    

    CentOS/RHEL

    sudo dnf install containerd.io
    # Back up current runc
    cp /usr/local/sbin/runc ~/
    sudo cp /usr/bin/runc /usr/local/sbin/runc
    
    # runc version should be > 1.0.0-rc93
    /usr/local/sbin/runc --version
    
  2. 停止した runc init プロセスがある場合は、ノードを再起動します。

    別の方法として、停止したプロセスを手動でクリーンアップすることもできます。

アップグレードと更新

.manifests ディレクトリがない場合に bmctl update cluster が失敗する

bmctl update cluster を実行する前に .manifests ディレクトリが削除されると、コマンドは次のようなエラーで失敗します。

Error updating cluster resources.: failed to get CRD file .manifests/1.9.0/cluster-operator/base/crd/bases/baremetal.cluster.gke.io_clusters.yaml: open .manifests/1.9.0/cluster-operator/base/crd/bases/baremetal.cluster.gke.io_clusters.yaml: no such file or directory

この問題は、まず bmctl check cluster を実行することで修正できます。これにより、.manifests ディレクトリが再作成されます。

この問題は、Anthos clusters on bare metal 1.10 以前で発生し、バージョン 1.11 以降では修正されています。

error during manifests operations でアップグレード進まない

場合によっては、クラスタのアップグレードが完了せず、bmctl CLI が応答しなくなる可能性があります。この問題は、リソースが正しく更新されていないことが原因の可能性があります。この問題の影響を受けるかどうかを判断するには、次の手順を行います。

  1. anthos-cluster-operator ログを調べて、次のエントリのようなエラーを探します。

    controllers/Cluster "msg"="error during manifests operations" "error"="1 error occurred:
    ...
    {RESOURCE_NAME} is invalid: metadata.resourceVersion: Invalid value: 0x0: must be specified for an update
    

    こうしたエントリは、リソースが誤って更新された場合の症状です。ここで、{RESOURCE_NAME} は問題リソースの名前です。

  2. ログにこれらのエラーがある場合は、kubectl edit を使用して、ログ メッセージに含まれているリソースから kubectl.kubernetes.io/last-applied-configuration アノテーションを削除します。

  3. 変更を保存してリソースに適用します。

  4. クラスタのアップグレードをもう一度行ってください。

bmctl update でメンテナンス ブロックが削除されない

bmctl update コマンドでは、クラスタ リソース構成の maintenanceBlocks セクションを削除や変更をすることはできません。メンテナンス モードでノードを削除する手順などの詳細については、ノードをメンテナンス モードにするをご覧ください。

クラスタの 1.7.5 から 1.7.6 へのアップグレードはブロックされる

ベアメタル版 Anthos バージョン 1.7.5 のクラスタは、バージョン 1.7.6 にアップグレードできません。この障害は、ベアメタル版 Anthos クラスタの他のバージョンには影響しません。たとえば、クラスタをバージョン 1.7.4 からバージョン 1.7.6 へはアップグレードできます。バージョン 1.7.5 を使用している場合、リリース 1.7.6 で対処されたセキュリティ脆弱性の修正を取得するには、それより新しいリリースが利用可能になったときにアップグレードする必要があります。

1.6.0 からのアップグレード。

1.6.0 リリースはアップグレードできません。

1.7.0 から 1.7.x へのアップグレード

1.7.0 から 1.7.x にアップグレードすると、クラスタがコントロール プレーン ノードのアップグレードで進まなくなる場合があります。MACHINE-IP-machine-upgrade ジョブが実行と失敗を繰り返すことが確認できます。この問題は、次のものが含まれる 1.7.0 クラスタに影響を与えます。

  • コントロール プレーン ノードにプリインストールされた Docker。
  • ランタイムとして選択された containerd

この問題は、ベアメタル版 Anthos クラスタが、containerd ではなく Docker に cri-socket を誤って構成したことが原因で発生します。この問題を解決するには、Docker 用のイメージの pull 認証情報を設定する必要があります。

  1. Docker にログインします。

    docker login gcr.io
    

    これにより、$HOME/.docker/config.json ファイルが作成されます。

  2. すべてのコントロール プレーン ノードの IP アドレスをスペースで区切って列挙します。

    IPs=(NODE_IP1 NODE_IP2 ...)
    
  3. Docker 構成を各ノードにコピーします。

    for ip in "${IPs[@]}"; do
      scp $HOME/.docker/config.json USER_NAME@{ip}:docker-config.json
    

    USER_NAME は、管理クラスタの構成ファイルに構成されたユーザー名に置き換えます。

  4. Docker のイメージ pull 認証情報を設定します。

    ssh USER_NAME@${ip} "sudo mkdir -p /root/.docker && sudo cp docker-config.json /root/.docker/config.json"
    

ユーザー クラスタのパッチ アップグレードの制限

管理クラスタによって管理されるユーザー クラスタは、ベアメタル版 Anthos クラスタのバージョン以下で、かつマイナー リリースの違いが 1 以内でなければなりません。たとえば、バージョン 1.7.2 のユーザー クラスタを管理するバージョン 1.8.1(anthosBareMetalVersion: 1.8.1)の管理クラスタは使用できますが、バージョン 1.6.3 のユーザー クラスタは 1 つのマイナー リリースに入りません。

管理クラスタが使用しているリリース バージョンの後に新しいセキュリティ パッチがリリースされた場合は、アップグレードの制限により、ユーザー クラスタをそのパッチにアップグレードできません。たとえば、管理クラスタが 2021 年 7 月 29 日リリースのバージョン 1.8.2 の場合、ユーザー クラスタをバージョン 1.7.3 にアップグレードすることはできません。これは 2021 年 8 月 16 日にリリースされているためです。

コントロール グループ ドライバが間違って cgroupfs に構成されている

コントロール グループ(cgroup)ドライバに関する問題が発生した場合は、それがベアメタル版 Anthos クラスタで systemd ではなく cgroupfs に構成されている可能性があります。

問題を解決するには:

  1. マシンにログインして /etc/containerd/config.toml を開きます。

  2. [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] の下に、SystemdCgroup = true を追加します。

    ...
       [plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
         [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
           runtime_type = "io.containerd.runc.v2"
           runtime_engine = ""
           runtime_root = ""
           privileged_without_host_devices = false
           base_runtime_spec = ""
           [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
             SystemdCgroup = true
     [plugins."io.containerd.grpc.v1.cri".cni]
       bin_dir = "/opt/cni/bin"
       conf_dir = "/etc/cni/net.d"
       max_conf_num = 1
       conf_template = ""
    ...
    
  3. 変更を保存し、ファイルを閉じます。

  4. /etc/systemd/system/kubelet.service.d/10-kubeadm.conf を開きます。

  5. ファイルの末尾に、--cgroup-driver=systemd --runtime-cgroups=/system.slice/containerd.service を追加します。

    [Service]
    Environment="HOME=/root"
    Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf"
    Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml"
    # This is a file that "kubeadm init" and "kubeadm join" generates at runtime, populating the KUBELET_KUBEADM_ARGS variable dynamically
    EnvironmentFile=-/var/lib/kubelet/kubeadm-flags.env
    # This is a file that the user can use for overrides of the kubelet args as a last resort. Preferably, the user should use
    # the .NodeRegistration.KubeletExtraArgs object in the configuration files instead. KUBELET_EXTRA_ARGS should be sourced from this file.
    EnvironmentFile=-/etc/default/kubelet
    ExecStart=
    ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS --cgroup-driver=systemd --runtime-cgroups=/system.slice/containerd.service
    
  6. 変更を保存して、サーバーを再起動します。

  7. 次のコマンドを実行して、systemd がコントロール グループ ドライバであることを確認します。

    systemd-cgls
    

    kubepods.slice セクションがあり、すべての Pod がこのセクションにあることを確認します。

オペレーション

kubeconfig シークレットが上書きされる

bmctl check cluster コマンドをユーザー クラスタで実行すると、ユーザー クラスタ kubeconfig シークレットが管理クラスタ kubeconfig で上書きされます。このファイルを上書きすると、更新やアップグレードなどの標準のクラスタ オペレーションが、影響を受けるユーザー クラスタで失敗します。この問題は、バージョン 1.11.1 以前のベアメタル版 Anthos クラスタに適用されます。

ユーザー クラスタがこの問題の影響を受けているかどうかを判断するには、次のコマンドを実行します。

kubectl --kubeconfig ADMIN_KUBECONFIG get secret -n cluster-USER_CLUSTER_NAME \
    USER_CLUSTER_NAME -kubeconfig  -o json  | jq -r '.data.value'  | base64 -d

以下を置き換えます。

  • ADMIN_KUBECONFIG: 管理クラスタの kubeconfig ファイルのパス。
  • USER_CLUSTER_NAME: 確認するユーザー クラスタの名前。

出力内のクラスタ名(次のサンプル出力の contexts.context.cluster を参照)が管理クラスタ名である場合は、指定したユーザー クラスタが影響を受けます。

user-cluster-kubeconfig  -o json  | jq -r '.data.value'  | base64 -d
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data:LS0tLS1CRU...UtLS0tLQo=
    server: https://10.200.0.6:443
  name: ci-aed78cdeca81874
contexts:
- context:
    cluster: ci-aed78cdeca81874
    user: ci-aed78cdeca81874-admin
  name: ci-aed78cdeca81874-admin@ci-aed78cdeca81874
current-context: ci-aed78cdeca81874-admin@ci-aed78cdeca81874
kind: Config
preferences: {}
users:
- name: ci-aed78cdeca81874-admin
  user:
    client-certificate-data: LS0tLS1CRU...UtLS0tLQo=
    client-key-data: LS0tLS1CRU...0tLS0tCg==

次の手順で、影響を受けるユーザー クラスタ(USER_CLUSTER_NAME)に機能を復元します。

  1. ユーザー クラスタ kubeconfig ファイルを見つけます。

    Anthos clusters on bare metal は、クラスタの作成時に管理ワークステーションに kubeconfig ファイルを生成します。デフォルトでは、このファイルは bmctl-workspace/USER_CLUSTER_NAME ディレクトリにあります。

  2. この kubeconfig が正しいユーザー クラスタ kubeconfig であることを確認します。

    kubectl get nodes --kubeconfig PATH_TO_GENERATED_FILE
    

    PATH_TO_GENERATED_FILE は、ユーザー クラスタ kubeconfig ファイルのパスに置き換えます。 レスポンスで、ユーザー クラスタのノードの詳細が返されます。クラスタのマシン名が正しいことを確認します。

  3. 次のコマンドを実行して、管理クラスタ内の壊れた kubeconfig ファイルを削除します。

    kubectl delete secret -n USER_CLUSTER_NAMESPACE USER_CLUSTER_NAME-kubeconfig
    
  4. 次のコマンドを実行して、正しい kubeconfig シークレットを管理クラスタに保存し直します。

    kubectl create secret generic -n USER_CLUSTER_NAMESPACE USER_CLUSTER_NAME-kubeconfig \
        --from-file=value=PATH_TO_GENERATED_FILE
    

リセット / 削除

ユーザー クラスタのサポート

ユーザー クラスタは、bmctl reset コマンドでリセットできません。

マウント ポイントと fstab

リセットしても、/mnt/localpv-share/ の下のマウント ポイントがマウント解除されることはありません。また、/etc/fstab 内の対応するエントリがクリーンアップされることもありません。

Namespace の削除

Namespace を削除すると、新しいリソースをその Namespace に作成されることが妨げれられ、そうしたリソースにはマシンをリセットするジョブも含まれます。ユーザー クラスタを削除する場合は、まず、クラスタ オブジェクトを削除した後、Namespace を削除する必要があります。そうしないと、マシンをリセットするジョブが作成できず、削除プロセスではマシンのクリーンアップ手順が省略されます。

containerd サービス

bmctl reset コマンドで、containerd 構成ファイルやバイナリが削除されません。containerd systemd サービスは、起動されたまま実行し続けます。このコマンドでは、ノードにスケジュールされた Pod を実行するコンテナを削除します。

セキュリティ

クラスタ CA / 証明書はアップグレード中にローテーションされます。現在、オンデマンド ローテーション サポートは利用できません。

ベアメタル版 Anthos クラスタは、kubelet 提供の証明書を自動的にローテーションします。各 kubelet ノード エージェントは、証明書の有効期限が近くなると、証明書署名リクエスト(CSR)を送信できます。この CSR は、管理クラスタ内のコントローラで検証し、承認されます。

ロギングとモニタリング

ノードログが Cloud Logging にエクスポートされない

ノード名にドット(.)を含むノードのログは、Cloud Logging にエクスポートされません。この問題を回避するには、次の手順で stackdriver-log-forwarder-config リソースにフィルタを追加して、Stackdriver Operator がこうしたログを認識してエクスポートできるようにします。

  1. Stackdriver Operator(stackdriver-operator)のサイズをスケールダウンします。

    kubectl --kubeconfig ADMIN_KUBECONFIG -n kube-system scale \
        deploy stackdriver-operator --replicas=0
    
  2. Log Forwarder の configmap stackdriver-log-forwarder-config を編集します。

    kubectl --kubeconfig ADMIN_KUBECONFIG -n kube-system edit configmap \
        stackdriver-log-forwarder-config
    
  3. configmap の input-systemd.conf セクションの末尾に、次のフィルタを追加します。

       [FILTER]
           Name    lua
           Match_Regex   container-runtime|kubelet|node-problem-detector|node-journal
           script  replace_dot.lua
           call    replace
    
     replace_dot.lua: |
       function replace(tag, timestamp, record)
           new_record = record
    
           local local_resource_id_key = "logging.googleapis.com/local_resource_id"
    
           -- Locate the local_resource_id
           local local_resource_id = record[local_resource_id_key]
    
           local first = 1
           local new_local_resource_id = ""
           for s in string.gmatch(local_resource_id, "[^.]+") do
               new_local_resource_id = new_local_resource_id .. s
               if first == 1 then
                   new_local_resource_id = new_local_resource_id .. "."
                   first = 0
               else
                   new_local_resource_id = new_local_resource_id .. "_"
               end
           end
    
           -- Remove the trailing underscore
           new_local_resource_id = new_local_resource_id:sub(1, -2)
           new_record[local_resource_id_key] = new_local_resource_id
           return 1, timestamp, new_record
       end
    
  4. すべての Log Forwarder Pod を削除します。

    kubectl --kubeconfig ADMIN_KUBECONFIG -n kube-system patch daemonset \
        stackdriver-log-forwarder -p \
        '{"spec": {"template": {"spec": {"nodeSelector": {"non-existing": "true"}}}}}'
    

    stackdriver-log-forwarder Pod が削除されたことを確認して、次のステップに進みます。

  5. DaemonSet をデプロイして、fluent-bit のバッファにある破損して、処理されていないすべてのデータをクリーンアップします。

    kubectl --kubeconfig ADMIN_KUBECONFIG -n kube-system apply -f - << EOF
        apiVersion: apps/v1
        kind: DaemonSet
        metadata:
          name: fluent-bit-cleanup
          namespace: kube-system
        spec:
          selector:
            matchLabels:
              app: fluent-bit-cleanup
          template:
            metadata:
              labels:
                app: fluent-bit-cleanup
            spec:
              containers:
              - name: fluent-bit-cleanup
                image: debian:10-slim
                command: ["bash", "-c"]
                args:
                - |
                  rm -rf /var/log/fluent-bit-buffers/
                  echo "Fluent Bit local buffer is cleaned up."
                  sleep 3600
                volumeMounts:
                - name: varlog
                  mountPath: /var/log
                securityContext:
                  privileged: true
              tolerations:
              - key: "CriticalAddonsOnly"
                operator: "Exists"
              - key: node-role.kubernetes.io/master
                effect: NoSchedule
              - key: node-role.gke.io/observability
                effect: NoSchedule
              volumes:
              - name: varlog
                hostPath:
                  path: /var/log
    EOF
    
  6. 次のコマンドを使用して、DaemonSet によってすべてのノードがクリーンアップされたことを確認します。

    kubectl --kubeconfig ADMIN_KUBECONFIG logs -n kube-system \
        -l app=fluent-bit-cleanup | grep "cleaned up" | wc -l
    
    kubectl --kubeconfig ADMIN_KUBECONFIG -n kube-system get pods \
        -l app=fluent-bit-cleanup --no-headers | wc -l
    

    2 つのコマンドの出力では、クラスタ内のノード数が同じになるはずです。

  7. クリーンアップの DaemonSet を削除します。

    kubectl --kubeconfig ADMIN_KUBECONFIG -n kube-system delete ds fluent-bit-cleanup
    
  8. Pod を再起動します。

    kubectl --kubeconfig ADMIN_KUBECONFIG -n kube-system patch \
        daemonset stackdriver-log-forwarder --type json \
        -p='[{"op": "remove", "path": "/spec/template/spec/nodeSelector/non-existing"}]'
    

ネットワーキング

レイヤ 2 負荷分散がバンドルされたクライアント ソース IP

外部トラフィック ポリシーLocal に設定すると、バンドルされたレイヤ 2 負荷分散に No route to host などのルーティング エラーが発生する可能性があります。外部トラフィック ポリシーは、デフォルトで ClusterexternalTrafficPolicy: Cluster)に設定されています。この設定では、Kubernetes がクラスタ全体のトラフィックを処理します。LoadBalancer または NodePort のタイプの Service は、externalTrafficPolicy: Local を使用してクライアントの送信元 IP アドレスを保持できます。ただし、この設定では、Kubernetes はノードローカルのトラフィックのみを処理します。

クライアントの送信元 IP アドレスを保持する場合は、サービス IP に到達できるようにするために、追加の構成が必要になることがあります。構成の詳細については、バンドルされた負荷分散の構成に記載されているクライアントの送信元 IP アドレスの保持をご覧ください。

firewalld の変更で Cilium iptable ポリシー チェーンが消去される

CentOS または Red Had Enterprise Linux(RHEL)で firewalld を有効にしてベアメタル版 Anthos クラスタを実行している場合は、firewalld を変更すると、ホスト ネットワーク上の Cilium iptables チェーンが削除される場合があります。この iptables チェーンは、起動時に anetd Pod によって追加されます。Cilium の iptables チェーンが失なわれると、Node 上の Pod は、Node 外部のネットワーク接続を失います。

iptables チェーンが削除される firewalld の変更には、次に挙げるものがありますが、これに限定されません。

  • systemctl を使用した firewalld の再起動
  • コマンドライン クライアント(firewall-cmd --reload)を使用した firewalld の再読み込み

この接続の問題は、Node で anetd を再起動することにより解決できます。anetd は、次のコマンドを使用して anetd Pod を見つけて削除することで再起動します。

kubectl get pods -n kube-system
kubectl delete pods -n kube-system ANETD_XYZ

ANETD_XYZ は、anetd Pod の名前で置き換えます。

I/O タイムアウトとリバースパス フィルタリングによる Pod 接続の失敗

ベアメタル版 Anthos クラスタは、ソース検証(net.ipv4.conf.all.rp_filter=0)を無効にするために、ノード上でリバースパス フィルタリングを構成します。rp_filter 設定が 1 または 2 に変更されると、ノード外の通信タイムアウトにより Pod は失敗します。

この問題は、Kubernetes Service の IP アドレスとの通信で接続エラーが発生していることを示しています。表示されるエラーの種類の例を次に示します。

  • 特定のノードのすべての Pod が Service の IP アドレスと通信できない場合、istiod Pod によって次のようなエラーが報告されることがあります。

     {"severity":"Error","timestamp":"2021-11-12T17:19:28.907001378Z",
        "message":"watch error in cluster Kubernetes: failed to list *v1.Node:
        Get \"https://172.26.0.1:443/api/v1/nodes?resourceVersion=5  34239\":
        dial tcp 172.26.0.1:443: i/o timeout"}
    
  • すべてのノードで実行される localpv デーモンセットの場合、ログに次のようなタイムアウトが示される場合があります。

     I1112 17:24:33.191654       1 main.go:128] Could not get node information
    (remaining retries: 2): Get
    https://172.26.0.1:443/api/v1/nodes/NODE_NAME:
    dial tcp 172.26.0.1:443: i/o timeout
    

リバースパス フィルタリングは、IPv4 構成フォルダ(net/ipv4/conf/all)内の rp_filter ファイルで設定されています。sysctl コマンドは、ネットワーク セキュリティ構成ファイル(/etc/sysctl.d/60-gce-network-security.conf など)にリバースパス フィルタリング設定を格納します。sysctl コマンドは、リバースパス フィルタリング設定をオーバーライドできます。

Pod の接続を復元するには、net.ipv4.conf.all.rp_filter を手動で 0 に戻すか、anetd Pod を再起動して net.ipv4.conf.all.rp_filter0 に戻します。anetd Pod を再起動するには、次のコマンドを使用して anetd Pod を見つけて削除します。新しい anetd Pod が代わりに開始されます。

kubectl get pods -n kube-system
kubectl delete pods -n kube-system ANETD_XYZ

ANETD_XYZ は、anetd Pod の名前で置き換えます。

net.ipv4.conf.all.rp_filter を手動で設定するには、次のコマンドを実行します。

sysctl -w net.ipv4.conf.all.rp_filter = 0

ブートストラップ(kind)クラスタ IP アドレスとクラスタノードの IP アドレスの重複

192.168.122.0/2410.96.0.0/27 は、ブートストラップ(kind)クラスタで使用されるデフォルトの Pod と Service の CIDR です。それがクラスタ ノード マシンの IP アドレスと重複すると、プリフライト チェックが不合格になります。この競合を回避するには、--bootstrap-cluster-pod-cidr フラグと --bootstrap-cluster-service-cidr フラグを bmctl に渡して別の値を指定します。

異なるクラスタ間での IP アドレスの重複

異なるクラスタ間で重複する IP アドレスを検証するプリフライト チェックはありません。

ベアメタル版 Anthos クラスタの hostport 機能

現在、ContainerPorthostport 機能は、サポートされていません。

OS

CentOS でクラスタの作成またはアップグレードの失敗

2020 年 12 月、CentOS コミュニティと Red Hat は CentOS の開発およびサポートの終了を発表しました。2022 年 1 月 31 日に CentOS 8 はサポート終了(EOL)となりました。EOL の結果として、yum リポジトリが CentOS で機能しなくなり、クラスタの作成とクラスタのアップグレードのオペレーションが失敗するようになりました。これは、CentOS のすべてのサポートされているバージョンに適用され、Anthos clusters on bare metal のすべてのバージョンに影響します。

回避策として、次のコマンドを実行し、CentOS でアーカイブ フィードを使用します。

sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-Linux-*
sed -i 's|#baseurl=http://mirror.centos.org|baseurl=http://vault.centos.org|g' \
    /etc/yum.repos.d/CentOS-Linux-*

長期的な解決策としては、UbuntuRHEL など、サポートされている別のオペレーティング システムへの移行を検討してください。

オペレーティング システムのエンドポイントの上限

RHEL と CentOS では、クラスタレベルの上限が 100,000 エンドポイントに制限されています。この数は、Kubernetes サービスによって参照されるすべての Pod の合計です。2 つのサービスが同一の Pod セットを参照する場合、2 つの別のエンドポイント セットとしてカウントされます。RHEL と CentOS 上の基礎的な nftable 実装には、この制約が存在します。これはベアメタル版 Anthos クラスタの固有の制限ではありません。

構成

コントロール プレーンとロードバランサの仕様

コントロール プレーンとロードバランサのノードプールの仕様は、特別なものです。これらの仕様で、重要なクラスタ リソースが宣言され管理されます。そのリソースの原本が、クラスタ構成ファイルのそれぞれのセクションです。

  • spec.controlPlane.nodePoolSpec
  • spec.LoadBalancer.nodePoolSpec

したがって、トップレベルのコントロール プレーンとロードバランサのノードプール リソースは、直接変更しないでください。代わりに、クラスタ構成ファイル内の関連するセクションを変更してください。

クラスタとノードプール仕様の変更可能なフィールド

現在、クラスタを作成すると、クラスタ構成ファイルの次のクラスタ仕様フィールドとノードプール仕様フィールドのみを更新できます(これが変更可能なフィールドです)。

  • Cluster オブジェクト(kind: Cluster)の場合は、次のフィールドが変更可能です。

    • spec.anthosBareMetalVersion
    • spec.bypassPreflightCheck
    • spec.controlPlane.nodePoolSpec.nodes
    • spec.loadBalancer.nodePoolSpec.nodes
    • spec.maintenanceBlocks
    • spec.nodeAccess.loginUser
  • NodePool オブジェクト(kind: NodePool)の場合は、次のフィールドが変更可能です。

    • spec.nodes

スナップショット

root 以外のログイン ユーザーとしてスナップショットを取得する

ベアメタル版 Anthos クラスタのバージョン 1.8.1 以前を使用している場合、root としてログインしていないと、bmctl コマンドではクラスタのスナップショットを取得できません。リリース 1.8.2 以降では、ベアメタル版 Anthos クラスタはクラスタ仕様の nodeAccess.loginUser を優先します。管理クラスタにアクセスできない場合は、--login-user フラグを使用してログイン ユーザーを指定できます。

なお、コンテナ ランタイムとして containerd を使用している場合、スナップショットでは引き続き crictl コマンドを実行できません。この問題を回避するには、Containerd で PATH に /usr/local/bin が必要になります。この問題は、SUDO に使用される PATH 設定によって発生します。

GKE 接続

gke-connect-agent Pod のクラッシュ ループ

GKE Connect ゲートウェイの使用量が多いと、gke-connect-agentPod のメモリ不足の問題が発生する場合があります。メモリ不足の問題の症状には次のようなものがあります。

  • gke-connect-agent Pod の再起動回数が多い、または最終的にクラッシュ ループ状態になる。
  • 接続ゲートウェイが機能しなくなる。

このメモリ不足の問題に対処するには、gke-connect Namespace の接頭辞 gke-connect-agent を含むデプロイを編集し、メモリ上限を 256 MiB 以上に引き上げます。

kubectl patch deploy $(kubectl get deploy -l app=gke-connect-agent -n gke-connect -o jsonpath='{.items[0].metadata.name}') -n gke-connect --patch '{"spec":{"containers":[{"resources":{"limits":{"memory":"256Mi"}}}]}}'

この問題は、ベアメタル版 Anthos クラスタ リリース 1.8.2 以降で修正されています。