このドキュメントでは、NFS マウントの問題でボリュームまたは Pod が停止し、DataPlane v2 を有効にしてクラスタを作成した場合に、Google Distributed Cloud で行う操作について詳しく説明します。
この問題は、次のバージョンで修正されています。
- マイナー バージョン 1.16 の場合は、バージョン 1.16.4-gke.37 以降。
- マイナー バージョン 1.28 の場合は、バージョン 1.28.200-gke.111 以降。
この問題が修正されているバージョンにアップグレードすることをおすすめします。アップグレードできない場合は、次のセクションで説明する手順で操作してください。
この問題が修正されていないバージョンを使用していて、この問題の影響を受けやすいストレージ ドライバを搭載した ReadWriteMany
ボリュームを使用するワークロードがあると、問題が発生する可能性があります。このようなドライバとしては、次のようなものがあります。
- Robin.io
- Portworx(
sharedv4
サービス ボリューム) csi-nfs
一部のストレージ アーキテクチャの NFS マウントは、Kubernetes Service(ClusterIP)と DataPlane v2 を使用してエンドポイントに接続すると、停止することがあります。この問題は、Linux カーネル ソケット コードが Cillium の eBPF プログラムとやり取りする方法に制限があるために発生します。機能しない NFS マウントはマウント解除できないため、コンテナが I/O でブロックされたり、強制終了できなくなる可能性があります。
この問題は、Kubernetes ノードで実行される NFS サーバーでホストされている RWX
ストレージを使用している場合に発生することがあります。これには、Ondat、Robin.io、Portworx などのソフトウェア定義ストレージ ソリューションやハイパーコンバージド ストレージ ソリューションが含まれます。
既存のクラスタ構成を確認する
クラスタから既存の構成値を取得します。ここで取得した値は、次のセクションで kube-proxy
マニフェストを作成する際に使用します。
cm/cilium-config
からClusterCIDR
を取得します。kubectl get cm -n kube-system cilium-config -o yaml | grep native-routing-cidr
次の出力例は、
ClusterCIDR
として192.168.0.0/16
を使用することを示しています。ipv4-native-routing-cidr: 192.168.0.0/16 native-routing-cidr: 192.168.0.0/16
anetd
DaemonSet からAPIServerAdvertiseAddress
とAPIServerPort
を取得します。kubectl get ds -n kube-system anetd -o yaml | grep KUBERNETES -A 1
次の出力例は、
APIServerAdvertiseAddress
として21.1.4.119
を使用し、APIServerPort
として443
を使用することを示しています。- name: KUBERNETES_SERVICE_HOST value: 21.1.4.119 - name: KUBERNETES_SERVICE_PORT value: "443"
anetd
DaemonSet からRegistryCredentialsSecretName
を取得します。kubectl get ds -n kube-system anetd -o yaml | grep imagePullSecrets -A 1
次の出力例は、
RegistryCredentialsSecretName
としてprivate-registry-creds
を使用することを示しています。imagePullSecrets: - name: private-registry-creds
anetd
DameonSet からRegistry
を取得します。kubectl get ds -n kube-system anetd -o yaml | grep image
次の出力例は、
Registry
としてgcr.io/gke-on-prem-release
を使用することを示しています。image: gcr.io/gke-on-prem-release/cilium/cilium:v1.12.6-anthos1.15-gke4.2.7
管理クラスタのクラスタ Namespace で
kube-apiserver
のイメージタグからKubernetesVersion
を取得します。KUBECONFIG=ADMIN_KUBECONFIG kubectl get sts -n CLUSTER_NAME kube-apiserver -o yaml | grep image
ADMIN_KUBECONFIG
は、管理クラスタの kubeconfig ファイルに置き換え、CLUSTER_NAME
はユーザー クラスタの名前に置き換えます。次の出力例は、
KubernetesVersion
としてv1.26.2-gke.1001
を使用することを示しています。image: gcr.io/gke-on-prem-release/kube-apiserver-amd64:v1.26.2-gke.1001 imagePullPolicy: IfNotPresent
kube-proxy
マニフェストを準備する
前のセクションで取得した値を使用して、kube-proxy
をクラスタにデプロイする YAML マニフェストを作成して適用します。
任意のエディタで、
kube-proxy.yaml
という名前のマニフェストを作成します。nano kube-proxy.yaml
次の YAML 定義をコピーして貼り付けます。
apiVersion: apps/v1 kind: DaemonSet metadata: labels: k8s-app: kube-proxy name: kube-proxy namespace: kube-system spec: selector: matchLabels: k8s-app: kube-proxy template: metadata: annotations: scheduler.alpha.kubernetes.io/critical-pod: "" labels: k8s-app: kube-proxy spec: containers: - command: - kube-proxy - --v=2 - --profiling=false - --iptables-min-sync-period=10s - --iptables-sync-period=1m - --oom-score-adj=-998 - --ipvs-sync-period=1m - --ipvs-min-sync-period=10s - --cluster-cidr=ClusterCIDR env: - name: KUBERNETES_SERVICE_HOST value:APIServerAdvertiseAddress - name: KUBERNETES_SERVICE_PORT value: "APIServerPort" image: Registry/kube-proxy-amd64:KubernetesVersion imagePullPolicy: IfNotPresent name: kube-proxy resources: requests: cpu: 100m memory: 15Mi securityContext: privileged: true volumeMounts: - mountPath: /run/xtables.lock name: xtables-lock - mountPath: /lib/modules name: lib-modules imagePullSecrets: - name: RegistryCredentialsSecretName nodeSelector: kubernetes.io/os: linux hostNetwork: true priorityClassName: system-node-critical serviceAccount: kube-proxy serviceAccountName: kube-proxy tolerations: - effect: NoExecute operator: Exists - effect: NoSchedule operator: Exists volumes: - hostPath: path: /run/xtables.lock type: FileOrCreate name: xtables-lock - hostPath: path: /lib/modules type: DirectoryOrCreate name: lib-modules --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: system:kube-proxy roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: system:node-proxier subjects: - kind: ServiceAccount name: kube-proxy namespace: kube-system --- apiVersion: v1 kind: ServiceAccount metadata: name: kube-proxy namespace: kube-system
この YAML マニフェストで、次の値を設定します。
APIServerAdvertiseAddress
:KUBERNETES_SERVICE_HOST
の値(21.1.4.119
など)。APIServerPort
:KUBERNETES_SERVICE_PORT
の値(443
など)。Registry
: Cilium イメージの接頭辞(gcr.io/gke-on-prem-release
など)。RegistryCredentialsSecretName
: イメージ pull シークレット名(private-registry-creds
など)。
エディタでマニフェスト ファイルを保存して閉じます。
anetd
パッチを準備する
anetd
の更新を作成して準備します。
任意のエディタで、
cilium-config-patch.yaml
という名前のマニフェストを作成します。nano cilium-config-patch.yaml
次の YAML 定義をコピーして貼り付けます。
data: kube-proxy-replacement: "disabled" kube-proxy-replacement-healthz-bind-address: "" retry-kube-proxy-healthz-binding: "false" enable-host-reachable-services: "false"
エディタでマニフェスト ファイルを保存して閉じます。
kube-proxy
をデプロイして anetd
を再構成する
構成の変更をクラスタに適用します。変更を適用する前に、既存の構成のバックアップを作成します。
現在の
anetd
とcilium-config
の構成をバックアップします。kubectl get ds -n kube-system anetd > anetd-original.yaml kubectl get cm -n kube-system cilium-config > cilium-config-original.yaml
kubectl
を使用してkube-proxy.yaml
を適用します。kubectl apply -f kube-proxy.yaml
Pod が
Running
であることを確認します。kubectl get pods -n kube-system -o wide | grep kube-proxy
次の要約された出力の例は、Pod が正しく実行されていることを示しています。
kube-proxy-f8mp9 1/1 Running 1 (4m ago) [...] kube-proxy-kndhv 1/1 Running 1 (5m ago) [...] kube-proxy-sjnwl 1/1 Running 1 (4m ago) [...]
kubectl
を使用してcilium-config
ConfigMap にパッチを適用します。kubectl patch cm -n kube-system cilium-config --patch-file cilium-config-patch.yaml
kubectl
を使用してanetd
を編集します。kubectl edit ds -n kube-system anetd
開いたエディタで
anetd
の仕様を編集します。initContainers
の最初の項目として、次のように挿入します。- name: check-kube-proxy-rules image: Image imagePullPolicy: IfNotPresent command: - sh - -ec - | if [ "$KUBE_PROXY_REPLACEMENT" != "strict" ]; then kube_proxy_forward() { iptables -L KUBE-FORWARD; } until kube_proxy_forward; do sleep 2; done fi; env: - name: KUBE_PROXY_REPLACEMENT valueFrom: configMapKeyRef: key: kube-proxy-replacement name: cilium-config optional: true securityContext: privileged: true
Image
は、anetd
DaemonSet の他の Cilium コンテナで使用されているイメージ(gcr.io/gke-on-prem-release/cilium/cilium:v1.12.6-anthos1.15-gke4.2.7
など)に置き換えます。エディタでマニフェスト ファイルを保存して閉じます。
これらの変更を適用するには、クラスタ内のすべてのノードを再起動します。中断を最小限に抑えるために、再起動の前に各ノードのドレインを試すことができます。ただし、NFS マウントの破損が原因でドレイン プロセスがブロックされると、RWX ボリュームを使用する Pod が
Terminating
状態のままになる場合があります。ブロックされた Pod を強制的に削除すると、ノードを正しくドレインできます。
kubectl delete pods -–force -–grace-period=0 --namespace POD_NAMESPACE POD_NAME
POD_NAME
は、削除する Pod に置き換え、POD_NAMESPACE
はその Namespace に置き換えます。