Ce document décrit une procédure manuelle pour Google Distributed Cloud si vous rencontrez des problèmes avec les installations 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, la version 1.16.4-gke.37 et les versions ultérieures.
- Pour la version mineure 1.28, la version 1.28.200-gke.111 et les versions ultérieures.
Nous vous recommandons de effectuer une mise à niveau vers une version permettant de résoudre ce problème. 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 vos charges de travail utilisant des volumes ReadWriteMany
alimentés par des pilotes de stockage sont susceptibles d'être confrontées à ce problème, par exemple :
- Robin.io
- Portworx (
sharedv4
volumes de service) csi-nfs
Les installations NFS sur certaines architectures de stockage peuvent être bloquées lorsqu'elles sont connectées à un point de terminaison à l'aide d'un service Kubernetes (ClusterIP) et de DataPlane v2. Ce comportement est dû aux limites d'interaction du code du socket du noyau Linux avec le programme eBPF de Cillium. Les conteneurs peuvent être bloqués sur les E/S ou même être impossibles à tuer, car le montage NFS obsolète ne peut pas être désinstallé.
Vous pouvez rencontrer ce problème si vous utilisez un espace de stockage RWX
hébergé sur des serveurs NFS qui s'exécutent sur un nœud Kubernetes, y compris des solutions de stockage définies par logiciel ou hyperconvergées telles que Ondat, Robin.io ou Portworx.
Examiner la configuration de cluster existante
Récupérez certaines valeurs de configuration existantes de votre cluster. Vous allez utiliser les valeurs de ces étapes pour créer un fichier manifeste kube-proxy
dans la section suivante.
Obtenez le
ClusterCIDR
à partir decm/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 utiliseriez
192.168.0.0/16
commeClusterCIDR
:ipv4-native-routing-cidr: 192.168.0.0/16 native-routing-cidr: 192.168.0.0/16
Obtenez les valeurs
APIServerAdvertiseAddress
etAPIServerPort
à partir du DaemonSetanetd
:kubectl get ds -n kube-system anetd -o yaml | grep KUBERNETES -A 1
L'exemple de résultat suivant montre que vous utiliseriez
21.1.4.119
commeAPIServerAdvertiseAddress
et443
commeAPIServerPort
:- name: KUBERNETES_SERVICE_HOST value: 21.1.4.119 - name: KUBERNETES_SERVICE_PORT value: "443"
Récupérez le
RegistryCredentialsSecretName
à partir du DaemonSetanetd
:kubectl get ds -n kube-system anetd -o yaml | grep imagePullSecrets -A 1
L'exemple de résultat suivant montre que vous utiliseriez
private-registry-creds
commeRegistryCredentialsSecretName
:imagePullSecrets: - name: private-registry-creds
Obtenez le
Registry
à partir du DameonSetanetd
:kubectl get ds -n kube-system anetd -o yaml | grep image
L'exemple de résultat suivant montre que vous utiliseriez
gcr.io/gke-on-prem-release
commeRegistry
:image: gcr.io/gke-on-prem-release/cilium/cilium:v1.12.6-anthos1.15-gke4.2.7
Récupérez la valeur
KubernetesVersion
à partir du tag d'image pourkube-apiserver
dans 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_KUBECONFIG
par le fichier kubeconfig de votre cluster d'administrateur etCLUSTER_NAME
par le nom de votre cluster d'utilisateur.L'exemple de résultat suivant montre que vous utiliseriez
v1.26.2-gke.1001
commeKubernetesVersion
:image: gcr.io/gke-on-prem-release/kube-apiserver-amd64:v1.26.2-gke.1001 imagePullPolicy: IfNotPresent
Préparer kube-proxy
fichier manifeste
Utilisez les valeurs obtenues à 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.yaml
dans 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 deKUBERNETES_SERVICE_HOST
(par exemple21.1.4.119
).APIServerPort
: valeur deKUBERNETES_SERVICE_PORT
, par exemple443
.Registry
: préfixe de l'image Cilium, par exemplegcr.io/gke-on-prem-release
.RegistryCredentialsSecretName
: nom du secret d'extraction d'image, par exempleprivate-registry-creds
.
Enregistrez et fermez le fichier manifeste dans l'éditeur.
Préparer anetd
correctif
Créez et préparez une mise à jour pour anetd
:
Créez un fichier manifeste nommé
cilium-config-patch.yaml
dans 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
anetd
etcilium-config
actuelle: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 dekubectl
:kubectl apply -f kube-proxy.yaml
Vérifiez que les pods sont à l'état
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 un correctif au ConfigMap
cilium-config
à l'aide dekubectl
:kubectl patch cm -n kube-system cilium-config --patch-file cilium-config-patch.yaml
Modifiez
anetd
à l'aide dekubectl
:kubectl edit ds -n kube-system anetd
Dans l'éditeur qui s'ouvre, modifiez la spécification de
anetd
. Insérez le code suivant en tant que premier élément sousinitContainers
:- 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
Image
par la même image que celle utilisée dans les autres conteneurs Cilium du DaemonSetanetd
, par exemplegcr.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 drainer chaque nœud avant le redémarrage. Toutefois, les pods utilisant des volumes RWX peuvent être bloqués à l'état
Terminating
en raison d'installations NFS défectueuses qui bloquent le processus de drainage.Vous pouvez forcer la suppression des pods bloqués et permettre au nœud de drainer correctement:
kubectl delete pods -–force -–grace-period=0 --namespace POD_NAMESPACE POD_NAME
Remplacez
POD_NAME
par le pod que vous essayez de supprimer etPOD_NAMESPACE
par son espace de noms.