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

インストール

マルチ NIC、containerd、プロキシを使用しているときに、クラスタの作成に失敗する

次の条件の組み合わせがある場合、クラスタの作成が失敗します。

  • クラスタが、コンテナ ランタイムとして containerd を使用するように構成されている(クラスタ構成ファイルで nodeConfig.containerRuntimecontainerd に設定されている。これはベアメタル版 Anthos クラスタ バージョン 1.8 のデフォルトです)。

  • クラスタが、Pod 用に複数のネットワーク インターフェース(マルチ NIC)を提供するように構成されている(クラスタ構成ファイルで spec.clusterNetwork.multipleNetworkInterfacestrue に設定されている)。

  • クラスタが、プロシキを使用するように構成されている(spec.proxy.url はクラスタ構成ファイルで指定されます)。クラスタの作成に失敗しても、この設定はクラスタを作成しようとするときに伝搬されます。このプロキシ設定は、HTTPS_PROXY 環境変数として、または containerd 構成(/etc/systemd/system/containerd.service.d/09-proxy.conf)で確認できます。

この問題の回避方法として、すべてのノードマシンで NO_PROXY 環境変数にサービス CIDR(clusterNetwork.services.cidrBlocks)を追加します。

コントロール グループ 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 が使用されていることを意味します。

プリフライト チェックにより、クラスタマシンで cgroup v2 が使用されていないことが確認されます。

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

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

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

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

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

インストール中に、/bin/sh: /tmp/disks_check.sh: Permission denied に関するエラーが表示されることがあります。これらのエラー メッセージは、/tmpnoexec オプションでマウントした場合に発生します。bmctl を機能させるには、/tmp マウント ポイントから noexec オプションを削除する必要があります。

アプリケーションのデフォルト認証情報と 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 以降で修正されています。

Docker サービス

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

レジストリ ミラーと Cloud Audit Logging

1.8.2 より前のバージョンのベアメタル版 Anthos クラスタでは、bmctl レジストリ ミラー パッケージに gcr.io/anthos-baremetal-release/auditproxy:gke_master_auditproxy_20201115_RC00 イメージがありません。レジストリ ミラーの使用時に Cloud Audit Logging 機能を有効にするには、次のコマンドを使用して、欠落しているイメージを手動でダウンロードし、レジストリ サーバーに push する必要があります。

docker pull gcr.io/anthos-baremetal-release/auditproxy:gke_master_auditproxy_20201115_RC00
docker tag gcr.io/anthos-baremetal-release/auditproxy:gke_master_auditproxy_20201115_RC00 REGISTRY_SERVER/anthos-baremetal-release/auditproxy:gke_master_auditproxy_20201115_RC00
docker push REGISTRY_SERVER/anthos-baremetal-release/auditproxy:gke_master_auditproxy_20201115_RC00

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 が含まれます(上記の回避策で修正できます)。

vSphere へのインストール

vSphere VM にベアメタル版 Anthos クラスタをインストールする場合は、tx-udp_tnl-segmentation フラグと tx-udp_tnl-csum-segmentation フラグをオフに設定する必要があります。これらのフラグは、vSphere ドライバ VMXNET3 によるハードウェア セグメンテーション オフロードに関連しており、ベアメタル版 Anthos クラスタの GENEVE トンネルでは機能しません。

各ノードで次のコマンドを実行して、これらのフラグの現在の値を確認します。ethtool -k NET_INTFC |grep segm ... tx-udp_tnl-segmentation: on tx-udp_tnl-csum-segmentation: on ... NET_INTFC を、ノードの IP アドレスに関連付けられたネットワーク インターフェースに置き換えます。

RHEL 8.4 では、ethtool でこれらのフラグがオフではない場合でもオフと表示されることがあります。これらのフラグを明示的にオフに設定するには、次のコマンドを使用して、フラグをオンにしてからオフにします。

ethtool -K ens192 tx-udp_tnl-segmentation on
ethtool -K ens192 tx-udp_tnl-csum-segmentation on

ethtool -K ens192 tx-udp_tnl-segmentation off
ethtool -K ens192 tx-udp_tnl-csum-segmentation off

このフラグの変更はリブート時に保持されません。起動スクリプトを構成することで、システムの起動時にこれらのフラグを明示的に設定します。

ノード 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. クラスタのランタイムを決定します。

    runc バージョンを更新する前に、クラスタで使用するコンテナ ランタイムを決定する必要があります。クラスタ構成ファイルの containerRuntime フィールドは、クラスタで使用するコンテナ ランタイムを示します。containerRuntimecontainerd に設定されている場合、クラスタは containerd ランタイムを使用します。このフィールドが docker に設定されているか、設定されていない場合、クラスタは Docker ランタイムを使用します。

    この値を取得するには、任意のエディタでクラスタ構成ファイルを開きます。または、管理クラスタ kubeconfig にアクセスできる場合は次のコマンドを実行します。

    kubctl describe cluster CLUSTER_NAME -n CLUSTER_NAMESPACE | grep -i runtime

    次のように置き換えます。

    • CLUSTER_NAME: バックアップするクラスタの名前。
    • CLUSTER_NAMESPACE: クラスタの名前空間。デフォルトでは、ベアメタル版 Anthos クラスタのクラスタ名前空間は、先頭に cluster- が付いたクラスタの名前です。
  2. containerd.io と docker-ce のいずれかをインストールし、最新の runc コマンドライン ツールを抽出するには、各ノードでのオペレーティング システムとコンテナ ランタイムに対応するコマンドを実行します。

    Ubuntu Containerd

    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
    

    Ubuntu Docker

    sudo apt update
    sudo apt install docker-ce
    # 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 containerd

    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
    

    CentOS / RHEL Docker

    sudo dnf install docker-ce
    # 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
  3. 停止した 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. クラスタのアップグレードをもう一度行ってください。

メンテナンス モードでバージョン 1.8 クラスタのアップグレードが失敗する

以前いずれかのノードマシンがメンテナンス モードになったことがある場合、バージョン 1.8.x クラスタをバージョン 1.9.x にアップグレードしようとすると失敗します。これは、これらのノードに残っているアノテーションによるものです。

この問題の影響を受けているかどうかを判断するには、次の手順を行います。

  1. 次のコマンドを実行して、アップグレードするクラスタのバージョンを取得します。

    kubectl --kubeconfig ADMIN_KUBECONFIG get cluster CLUSTER_NAME  \
        -n CLUSTER_NAMESPACE --output=jsonpath="{.spec.anthosBareMetalVersion}"
    

    1.8 マイナー リリース(1.8.3 など)のバージョン値が返される場合は、続行します。それ以外の場合、この問題は該当しません。

  2. 次のコマンドを実行して、以前にメンテナンス モードにしたノードがクラスタにあるかどうかを確認します。

    kubectl --kubeconfig ADMIN_KUBECONFIG get BareMetalMachines -n CLUSTER_NAMESPACE  \
        --output=jsonpath="{.items[*].metadata.annotations}"
    

    返されたアノテーションに baremetal.cluster.gke.io/maintenance-mode-duration が含まれている場合、この既知の問題の影響を受けています。

クラスタのアップグレードのブロックを解除するには、影響を受ける各ノードマシンで次のコマンドを実行して、baremetal.cluster.gke.io/maintenance-mode-duration アノテーションを削除します。

kubectl --kubeconfig ADMIN_KUBECONFIG  annotate BareMetalMachine -n CLUSTER_NAMESPACE \
    NODE_MACHINE_NAME baremetal.cluster.gke.io/maintenance-mode-duration-

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

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

特定のロードバランサ構成のため 1.7.x からクラスタをアップグレードできない

次のロードバランサ構成では、クラスタをバージョン 1.7.x から 1.8.y にアップグレードするとエラーが発生する可能性があります。

  • 手動で構成した外部ロードバランサ(loadBalancer.modemanual に設定)

  • 別のノードプール(loadBalancer.nodePoolSpec.nodes を指定)を使用したバンドル型ロード バランシング(loadBalancer.modebundled に設定)

このエラーの兆候は、コントロール プレーン ノードの cal-update ジョブがタスク Check apiserver health で失敗し、接続拒否のエラー メッセージが表示されることです。

以下は、cal-update ジョブのログの例です。

TASK [cal-update : Check apiserver health] *************************************
Thursday 20 January 2022  13:50:46 +0000 (0:00:00.033)       0:00:09.316 ******
FAILED - RETRYING: Check apiserver health (30 retries left).
FAILED - RETRYING: Check apiserver health (29 retries left).
FAILED - RETRYING: Check apiserver health (28 retries left).
FAILED - RETRYING: Check apiserver health (27 retries left).
FAILED - RETRYING: Check apiserver health (26 retries left).
...
FAILED - RETRYING: Check apiserver health (3 retries left).
FAILED - RETRYING: Check apiserver health (2 retries left).
FAILED - RETRYING: Check apiserver health (1 retries left).
[WARNING]: Consider using the get_url or uri module rather than running 'curl'.
If you need to use command because get_url or uri is insufficient you can add
'warn: false' to this command task or set 'command_warnings=False' in
ansible.cfg to get rid of this message.
fatal: [10.50.116.79]: FAILED! => {"attempts": 30, "changed": true, "cmd": "curl
-k https://127.0.0.1/healthz", "delta": "0:00:00.008949", "end": "2022-01-20
19:22:30.381875", "msg": "non-zero return code", "rc": 7, "start": "2022-01-20
19:22:30.372926", "stderr": "  % Total    % Received % Xferd  Average Speed
Time    Time     Time  Current\n                                 Dload  Upload
Total   Spent    Left  Speed\n\r  0     0    0     0    0     0      0      0 --
:--:-- --:--:-- --:--:--     0curl: (7) Failed to connect to 127.0.0.1 port 443:
Connection refused", "stderr_lines": ["  % Total    % Received % Xferd  Average
Speed   Time    Time     Time  Current", "                                 Dload
Upload   Total   Spent    Left  Speed", "", "  0     0    0     0    0     0
0      0 --:--:-- --:--:-- --:--:--     0curl: (7) Failed to connect to
127.0.0.1 port 443: Connection refused"], "stdout": "", "stdout_lines": []}

手動の回避策として、アップグレードの前に、ポート 443(チェックが行われる場所)からポート 6444apiserver がリッスンする場所)へのポート転送を作成します。ポート転送を作成するには、各コントロール プレーン ノードで次のコマンドを実行します。

sudo iptables -t nat -I OUTPUT -p tcp -o lo --dport 443 -j REDIRECT --to-ports 6444

cal-update ジョブは、調整がある場合に実行され、ポート 443 を調べます。そのため、1.8.x のアップグレードされたクラスタのために、このポート転送を保持する必要があります。

バージョン 1.9.0 以降にアップグレードしてから、各コントロール プレーン ノードで次のコマンドを実行して、ポート転送を削除します。

sudo iptables -t nat -D OUTPUT -p tcp -o lo --dport 443 -j REDIRECT --to-ports 6444

1.8.0 と 1.8.1 の管理クラスタ、ハイブリッド クラスタ、スタンドアロン クラスタへのアップグレードが完了しない

管理クラスタ、ハイブリッド クラスタ、スタンドアロン クラスタについて、バージョン 1.7.x からバージョン 1.8.0 または 1.8.1 へのアップグレードが失敗することがあります。このアップグレード障害は、クラスタの作成後に更新したクラスタに発生します。

このアップグレードの問題は、アップグレード対象のノードが記載されていないコンソール出力 Waiting for upgrade to complete ... を示しています。この現象は、管理クラスタが Kubernetes バージョン v1.20.8-gke.1500(ベアメタル版 Anthos クラスタのリリース 1.8.0 と 1.8.1 用の Kubernetes バージョン)に正常にアップグレードされたことも示しています。

このアップグレードに関する問題は、ベアメタル版 Anthos クラスタ リリース 1.8.2 で修正されます。

この問題がクラスタの 1.8.0 または 1.8.1 へのアップグレードに影響するかどうかを確認するには以下のようにうします。

  1. 次のシェル スクリプトを作成します。

    if [ $(kubectl get cluster <var>CLUSTER\_NAME -n <var>CLUSTER\_NAMESPACE
        --kubeconfig bmctl-workspace/.kindkubeconfig -o=jsonpath='{.metadata.generation}')
        -le $(kubectl get cluster CLUSTER_NAME -n CLUSTER_NAMESPACE
        --kubeconfig bmctl-workspace/.kindkubeconfig
        -o=jsonpath='{{.status.systemServiceConditions[?(@.type=="Reconciling")].observedGeneration}}') ];
        then echo "Bug Detected"; else echo "OK"; fi

    以下を置き換えます。

    • CLUSTER_NAME: チェック対象のクラスタの名前。
    • CLUSTER_NAMESPACE: クラスタの名前空間。
  2. アップグレードの処理中、プリフライト チェックが完了した後にスクリプトを実行します。

    observedGeneration 値が generation 値以上の場合、Bug Detected がコンソール出力に書き込まれます。この出力は、クラスタのアップグレードが影響を受けることを示しています。

  3. アップグレードのブロックを解除するには、次のコマンドを実行します。

    kubectl get --raw=/apis/baremetal.cluster.gke.io/v1/namespaces/CLUSTER_NAMESPACE/clusters/CLUSTER_NAME/status \
        --kubeconfig bmctl-workspace/.kindkubeconfig | \
        sed -e 's/\("systemServiceConditions":\[{[^{]*"type":"DashboardReady"}\),{[^{}]*}/\1/g' | \
        kubectl replace --raw=/apis/baremetal.cluster.gke.io/v1/namespaces/CLUSTER_NAMESPACE/clusters/CLUSTER_NAME/status \
        --kubeconfig bmctl-workspace/.kindkubeconfig -f-
    

    以下を置き換えます。

    • CLUSTER_NAME: チェック対象のクラスタの名前。
    • CLUSTER_NAMESPACE: クラスタの名前空間。

1.8.3 または 1.8.4 へのアップグレード

ベアメタル版 Anthos クラスタをバージョン 1.8.3 または 1.8.4 にアップグレードすると、nil コンテキスト エラーで失敗する場合があります。nil コンテキスト エラーが発生してクラスタのアップグレードが失敗した場合にアップグレードを完了する手順は次のとおりです。

  1. サービス アカウントのキーファイルを指すように GOOGLE_APPLICATION_CREDENTIALS 環境変数を設定します。

    export GOOGLE_APPLICATION_CREDENTIALS=KEY_PATH
    

    KEY_PATH をサービス アカウント キーが含まれる JSON ファイルのパスに置き換えます。

  2. bmctl upgrade cluster コマンドをもう一度実行します。

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

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

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

Ubuntu 18.04 と 18.04.1 に互換性がない

1.8.1 または 1.8.2 にアップグレードするには、クラスタノード マシンと bmctl を実行するワークステーションに Linux カーネル バージョン 4.17.0 以降が必要です。そうでない場合、anetd ネットワーク コントローラが機能しません。この場合、kube-system 名前空間の anet 接頭辞を持つ Pod がクラッシュし、次のエラー メッセージが表示されます: BPF NodePort services needs kernel 4.17.0 or newer.

この問題は、Ubuntu 18.04 と 18.04.1 で発生します。これらはカーネル バージョンは 4.15 であるためです。

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

containerd を使用する 1.7.x クラスタのアップグレード

1.8.x へのクラスタのアップグレードは、プレビューの containerd 機能を使用するように構成されている 1.7.x クラスタに対してはブロックされます。containerd プレビューでは、推奨される systemd ドライバではなく、誤ったコントロール グループ(cgroup)ドライバ cgroupfs が使用されます。cgroupfs ドライバを使用するクラスタがリソース不足に陥ると、クラスタの不安定性が報告されます。リリース 1.8.0 の GA containerd 機能では、正しい systemd ドライバが使用されます。

プレビュー版の containerd コンテナ ランタイム機能を使用する既存の 1.7.x クラスタがある場合は、containerd 用に構成された新しい 1.8.0 クラスタを作成し、既存のアプリとワークロードをすべて移行することをおすすめします。これにより、containerd コンテナ ランタイムを使用する際のクラスタの安定性が確保されます。

SELinux のアップグレードの失敗

containerd コンテナ ランタイムが構成された 1.7.1 クラスタをアップグレードして、RHEL または CentOS 上で SELinux を実行すると、失敗します。containerd を使用してワークロードを移行するように構成された 1.8.0 クラスタを新しく作成することをおすすめします。

ノードが到達不能になると、ノードのドレインを開始できません

ベアメタル版 Anthos クラスタから Node にアクセスできない場合、Node のドレイン プロセスは開始されません。たとえば、クラスタのアップグレード プロセス中に 1 つの Node がオフラインになると、アップグレードが停止する可能性があります。めったに発生することではありません。この問題が発生する可能性を最小限に抑えるには、アップグレードを開始する前に Node が正常に動作していることを確認してください。

オペレーション

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

リセット / 削除

Namespace の削除

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

containerd サービス

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

セキュリティ

クラスタ CA / 証明書はアップグレード中にローテーションされます。オンデマンド ローテーション サポートはプレビュー機能です。

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

クラスタ CA のローテーション(プレビュー機能)

クラスタでユーザー クラスタの認証局(CA)のローテーションを実行すると、すべてのユーザー認証フローが失敗します。これは、認証フローで使用される ClientConfig カスタム リソースが CA のローテーション中に新しい CA データで更新されないために発生します。クラスタでクラスタ CA のローテーションを実行した場合は、kube-public Namespace の default ClientConfig の certificateAuthorityData フィールドに古いクラスタ CA が含まれているかどうかを確認します。

この問題を手動で解決するには、現在のクラスタ CA で certificateAuthorityData フィールドを更新します。

ネットワーキング

レイヤ 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 の名前で置き換えます。

egressSourceIP アドレスの重複

下り(外向き)NAT ゲートウェイ機能のプレビューを使用する場合、別の EgressNATPolicy オブジェクトに対してすでに使用されている egressSourceIP アドレスを指定するトラフィック選択ルールを設定できます。これにより、下り(外向き)トラフィック ルーティングの競合が発生する可能性があります。開発チームと連携し、EgressNATPolicy カスタム リソースで egressSourceIP アドレスを指定する前に、使用可能なフローティング IP アドレスを決定します。

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 アドレスの検証は行われません。その検証は、クラスタ / ノードプールの作成時にのみ行われます。

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-*

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

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

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

構成

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

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

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

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

Anthos VM ランタイム

  • Pod を再起動すると、Pod 上の VM は IP アドレスを変更するか、IP アドレスが完全に失われます。VM の IP アドレスが変更されても、Kubernetes サービスとして公開されている VM アプリケーションのネットワーク到達性に影響はありません。IP アドレスが失われた場合、VM から dhclient を実行して VM の IP アドレスを取得する必要があります。

SELinux

Pod の作成中の SELinux エラー

SELinux により、コンテナ ランタイムが tmpfs マウントでラベルを設定できない場合、Pod の作成に失敗することがあります。この失敗はまれですが、SELinux が Enforcing モードで、一部のカーネルにある場合に発生することがあります。

SELinux が Pod 作成の失敗の原因であることを確認するには、次のコマンドを使用して kubelet ログにエラーがあるかどうかを確認します。

journalctl -u kubelet

SELinux によって Pod の作成が失敗すると、コマンドのレスポンスに次のようなエラーが含まれます。

error setting label on mount source '/var/lib/kubelet/pods/
6d9466f7-d818-4658-b27c-3474bfd48c79/volumes/kubernetes.io~secret/localpv-token-bpw5x':
failed to set file label on /var/lib/kubelet/pods/
6d9466f7-d818-4658-b27c-3474bfd48c79/volumes/kubernetes.io~secret/localpv-token-bpw5x:
permission denied

この問題が SELinux の強制適用に関連していることを確認するには、次のコマンドを実行します。

ausearch -m avc

このコマンドは、監査ログでアクセス ベクトル キャッシュ(AVC)権限エラーを検索します。次のサンプル レスポンスの avc: denied は、Pod の作成エラーが SELinux の適用に関連していることを確認します。

type=AVC msg=audit(1627410995.808:9534): avc:  denied  { associate } for
pid=20660 comm="dockerd" name="/" dev="tmpfs" ino=186492
scontext=system_u:object_r:container_file_t:s0:c61,c201
tcontext=system_u:object_r:locale_t:s0 tclass=filesystem permissive=0

SELinux でのこの Pod 作成の問題の根本的な原因は、次の Linux イメージにあるカーネル バグです。

  • 8.3 より前の Red Hat Enterprise Linux(RHEL)リリース
  • 8.3 より前の CentOS リリース

マシンを再起動すると、問題からの回復に役立ちます。

Pod 作成エラーの発生を防止するには、カーネルのバグを修正した RHEL 8.3 以降または CentOS 8.3 以降を使用してください。

スナップショット

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 以降で修正されています。

ロギングとモニタリング

stackdriver-log-forwarder Pod の再起動が停止する

バージョン 1.9 より前のベアメタル版 Anthos クラスタでは、ノードが強制的にシャットダウンされると、stackdriver-log-forwarder Pod が再起動状態で停止する場合があります。この場合に、次のようなログエントリが表示される可能性があります。

[error] [input:storage_backlog:storage_backlog.7] chunk validation failed, data might
be corrupted. Found 0 valid records, failed content starts right after byte 0.

stackdriver-log-forwarder Pod が停止すると、ほとんどのログが Cloud Logging に送信できなくなり、フラッシュされていないデータは失われます。この問題を解決するには、ロギング パイプラインをリセットします。

ロギング パイプラインをリセットするには:

  1. stackdriver-operator をスケールダウンします。

    kubectl --kubeconfig=KUBECONFIG -n kube-system scale deploy \
        stackdriver-operator --replicas=0
    
  2. stackdriver-log-forwarder DaemonSet を削除します。

    kubectl --kubeconfig KUBECONFIG -n kube-system delete daemonset \
        stackdriver-log-forwarder
    

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

  3. 次の DaemonSet をデプロイして、fluent-bit バッファ内の壊れたデータをクリーンアップします。

    kubectl --kubeconfig 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
    
  4. DaemonSet がすべてのノードをクリーンアップしたことを確認します。

    次のコマンドの出力は、クラスタ内のノードの数と同じになります。

    kubectl --kubeconfig KUBECONFIG logs -n kube-system -l app=fluent-bit-cleanup | \
        grep "cleaned up" | wc -l
    kubectl --kubeconfig KUBECONFIG -n kube-system get pods -l app=fluent-bit-cleanup \
        --no-headers | wc -l
    
  5. クリーンアップの DaemonSet を削除します。

    kubectl --kubeconfig KUBECONFIG -n kube-system delete ds fluent-bit-cleanup
    
  6. 演算子をスケールアップして、ロギング パイプラインが再デプロイされるのを待ちます。

    kubectl --kubeconfig=KUBECONFIG -n kube-system scale deploy \
        stackdriver-operator --replicas=1
    

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