Ce document décrit une procédure manuelle pour Google Distributed Cloud si vous rencontrez des problèmes avec les montages NFS avec un volume ou un pod bloqué et que vous avez créé votre cluster avec DataPlane v2 activé.
Ce problème a été résolu dans les versions suivantes :
- Pour la version mineure 1.16, utilisez la version 1.16.4-gke.37 ou ultérieure.
- Pour la version mineure 1.28, utilisez la version 1.28.200-gke.111 ou ultérieure.
Nous vous recommandons de mettre à niveau vers une version où ce problème est résolu. Si vous ne parvenez pas à effectuer la mise à niveau, suivez les procédures décrites dans les sections suivantes.
Si vous utilisez une version où ce problème n'est pas résolu, vous pouvez rencontrer des problèmes si vous avez des charges de travail utilisant des volumes ReadWriteMany alimentés par des pilotes de stockage sensibles à ce problème, tels que (mais sans s'y limiter) :
- Robin.io
- Portworx (volumes de service sharedv4)
- csi-nfs
Les montages NFS sur certaines architectures de stockage peuvent se bloquer lorsqu'ils sont connectés à un point de terminaison à l'aide d'un service Kubernetes (ClusterIP) et de DataPlane v2. Ce comportement est dû aux limites de la façon dont le code de socket du noyau Linux interagit avec le programme eBPF de Cillium. Les conteneurs peuvent être bloqués sur les E/S ou même être impossibles à arrêter, car le montage NFS obsolète ne peut pas être démonté.
Ce problème peut se produire si vous utilisez un stockage RWX hébergé sur des serveurs NFS qui s'exécutent sur un nœud Kubernetes, y compris des solutions de stockage hyperconvergées ou définies par logiciel telles qu'Ondat, Robin.io ou Portworx.
Vérifier la configuration du cluster existant
Récupérez certaines valeurs de configuration existantes de votre cluster. Vous utiliserez les valeurs de ces étapes pour créer un fichier manifeste kube-proxy dans la section suivante.
- Obtenez la - ClusterCIDRà partir de- cm/cilium-config:- kubectl get cm -n kube-system cilium-config -o yaml | grep native-routing-cidr- L'exemple de résultat suivant montre que vous devez utiliser - 192.168.0.0/16comme- ClusterCIDR:- ipv4-native-routing-cidr: 192.168.0.0/16 native-routing-cidr: 192.168.0.0/16
- Obtenez - APIServerAdvertiseAddresset- APIServerPortà partir du DaemonSet- anetd:- kubectl get ds -n kube-system anetd -o yaml | grep KUBERNETES -A 1- L'exemple de résultat suivant montre que vous devez utiliser - 21.1.4.119comme- APIServerAdvertiseAddresset- 443comme- APIServerPort:- - name: KUBERNETES_SERVICE_HOST value: 21.1.4.119 - name: KUBERNETES_SERVICE_PORT value: "443"
- Obtenez le - RegistryCredentialsSecretNameà partir du DaemonSet- anetd:- kubectl get ds -n kube-system anetd -o yaml | grep imagePullSecrets -A 1- L'exemple de résultat suivant montre que vous devez utiliser - private-registry-credscomme- RegistryCredentialsSecretName:- imagePullSecrets: - name: private-registry-creds
- Obtenez le - Registryà partir du DaemonSet- anetd:- kubectl get ds -n kube-system anetd -o yaml | grep image- L'exemple de résultat suivant montre que vous devez utiliser - gcr.io/gke-on-prem-releasecomme- Registry:- image: gcr.io/gke-on-prem-release/cilium/cilium:v1.12.6-anthos1.15-gke4.2.7
- Récupérez - KubernetesVersionà partir du tag d'image pour- kube-apiserverdans l'espace de noms du cluster d'administrateur :- KUBECONFIG=ADMIN_KUBECONFIG kubectl get sts -n CLUSTER_NAME kube-apiserver -o yaml | grep image- Remplacez - ADMIN_KUBECONFIGpar le fichier kubeconfig de votre cluster d'administrateur et- CLUSTER_NAMEpar le nom de votre cluster d'utilisateur.- L'exemple de résultat suivant montre que vous devez utiliser - v1.26.2-gke.1001comme- KubernetesVersion:- image: gcr.io/gke-on-prem-release/kube-apiserver-amd64:v1.26.2-gke.1001 imagePullPolicy: IfNotPresent
Préparer les fichiers manifestes kube-proxy
Utilisez les valeurs obtenues dans la section précédente pour créer et appliquer un fichier manifeste YAML qui déploiera kube-proxy sur votre cluster.
- Créez un fichier manifeste nommé - kube-proxy.yamldans l'éditeur de votre choix :- nano kube-proxy.yaml
- Copiez et collez la définition YAML suivante : - 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- Dans ce fichier manifeste YAML, définissez les valeurs suivantes : - APIServerAdvertiseAddress: valeur de- KUBERNETES_SERVICE_HOST, par exemple- 21.1.4.119.
- APIServerPort: valeur de- KUBERNETES_SERVICE_PORT, par exemple- 443.
- Registry: préfixe de l'image Cilium, tel que- gcr.io/gke-on-prem-release.
- RegistryCredentialsSecretName: nom du secret d'extraction d'image, tel que- private-registry-creds.
 
- Enregistrez et fermez le fichier manifeste dans l'éditeur. 
Préparer le correctif anetd
Créez et préparez une mise à jour pour anetd :
- Créez un fichier manifeste nommé - cilium-config-patch.yamldans l'éditeur de votre choix :- nano cilium-config-patch.yaml
- Copiez et collez la définition YAML suivante : - data: kube-proxy-replacement: "disabled" kube-proxy-replacement-healthz-bind-address: "" retry-kube-proxy-healthz-binding: "false" enable-host-reachable-services: "false"
- Enregistrez et fermez le fichier manifeste dans l'éditeur. 
Déployer kube-proxy et reconfigurer anetd
Appliquez les modifications de configuration à votre cluster. Créez des sauvegardes de votre configuration existante avant d'appliquer les modifications.
- Sauvegardez votre configuration actuelle de - anetdet- cilium-config:- kubectl get ds -n kube-system anetd > anetd-original.yaml kubectl get cm -n kube-system cilium-config > cilium-config-original.yaml
- Appliquez - kube-proxy.yamlà l'aide de- kubectl:- kubectl apply -f kube-proxy.yaml
- Vérifiez que les pods sont - Running:- kubectl get pods -n kube-system -o wide | grep kube-proxy- L'exemple de résultat condensé suivant montre que les pods s'exécutent correctement : - 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) [...]
- Appliquez le correctif au ConfigMap - cilium-configà l'aide de- kubectl:- kubectl patch cm -n kube-system cilium-config --patch-file cilium-config-patch.yaml
- Modifiez - anetdà l'aide de- kubectl:- kubectl edit ds -n kube-system anetd- Dans l'éditeur qui s'ouvre, modifiez la spécification de - anetd. Insérez les éléments suivants en tant que premier élément sous- 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- Remplacez - Imagepar la même image que celle utilisée dans les autres conteneurs Cilium du DaemonSet- anetd, comme- gcr.io/gke-on-prem-release/cilium/cilium:v1.12.6-anthos1.15-gke4.2.7.
- Enregistrez et fermez le fichier manifeste dans l'éditeur. 
- Pour appliquer ces modifications, redémarrez tous les nœuds de votre cluster. Pour minimiser les perturbations, vous pouvez essayer de vider chaque nœud avant le redémarrage. Toutefois, les pods utilisant des volumes RWX peuvent être bloqués dans un état - Terminatingen raison de montages NFS défectueux qui bloquent le processus de vidange.- Vous pouvez forcer la suppression des pods bloqués et permettre au nœud de se vider correctement : - kubectl delete pods -–force -–grace-period=0 --namespace POD_NAMESPACE POD_NAME- Remplacez - POD_NAMEpar le pod que vous essayez de supprimer et- POD_NAMESPACEpar son espace de noms.
Étapes suivantes
Si vous avez besoin d'une aide supplémentaire, contactez Cloud Customer Care.
Vous pouvez également consulter Obtenir de l'aide pour en savoir plus sur les ressources d'assistance, y compris les suivantes :
- Conditions requises pour ouvrir une demande d'assistance.
- Des outils pour vous aider à résoudre les problèmes, tels que les journaux et les métriques.
- Composants, versions et fonctionnalités compatibles de Google Distributed Cloud pour VMware (logiciel uniquement).