En este documento se describe un procedimiento manual para Google Distributed Cloud si tienes problemas con los montajes de NFS con un volumen o un pod bloqueado y has creado tu clúster con DataPlane v2 habilitado.
Este problema se ha solucionado en las siguientes versiones:
- En la versión secundaria 1.16, la versión 1.16.4-gke.37 y las posteriores.
- En la versión secundaria 1.28, la versión 1.28.200-gke.111 y las posteriores.
Te recomendamos que actualices a una versión en la que se haya solucionado este problema. Si no puedes actualizar, sigue los procedimientos que se indican en las secciones siguientes.
Si usas una versión en la que no se ha corregido este problema, es posible que tengas problemas si tienes cargas de trabajo que usan volúmenes de ReadWriteMany basados en controladores de almacenamiento que son susceptibles a este problema, como los siguientes (entre otros):
- Robin.io
- Portworx (volúmenes de servicio de sharedv4)
- csi-nfs
Es posible que los montajes de NFS en algunas arquitecturas de almacenamiento se bloqueen cuando se conecten a un endpoint mediante un servicio de Kubernetes (ClusterIP) y DataPlane v2. Este comportamiento se debe a las limitaciones de la forma en que el código de socket del kernel de Linux interactúa con el programa eBPF de Cillium. Es posible que los contenedores se bloqueen en las operaciones de E/S o que no se puedan eliminar, ya que el montaje de NFS obsoleto no se puede desmontar.
Puede que tengas este problema si usas RWX almacenamiento alojado en servidores NFS
que se ejecutan en un nodo de Kubernetes, incluidas soluciones de almacenamiento
definidas por software o hiperconvergentes, como Ondat, Robin.io o Portworx.
Revisar la configuración de un clúster
Obtén algunos valores de configuración de tu clúster. En la siguiente sección, utilizarás los valores de estos pasos para crear un manifiesto kube-proxy.
- Obtén - ClusterCIDRde- cm/cilium-config:- kubectl get cm -n kube-system cilium-config -o yaml | grep native-routing-cidr- El siguiente ejemplo de salida muestra que usarías - 192.168.0.0/16como- ClusterCIDR:- ipv4-native-routing-cidr: 192.168.0.0/16 native-routing-cidr: 192.168.0.0/16
- Obtén el - APIServerAdvertiseAddressy el- APIServerPortdel DaemonSet- anetd:- kubectl get ds -n kube-system anetd -o yaml | grep KUBERNETES -A 1- El siguiente ejemplo de salida muestra que usarías - 21.1.4.119como- APIServerAdvertiseAddressy- 443como- APIServerPort:- - name: KUBERNETES_SERVICE_HOST value: 21.1.4.119 - name: KUBERNETES_SERVICE_PORT value: "443"
- Obtén el - RegistryCredentialsSecretNamedel- anetdDaemonSet:- kubectl get ds -n kube-system anetd -o yaml | grep imagePullSecrets -A 1- El siguiente ejemplo de salida muestra que usarías - private-registry-credscomo- RegistryCredentialsSecretName:- imagePullSecrets: - name: private-registry-creds
- Obtén el - Registrydel- anetdDameonSet:- kubectl get ds -n kube-system anetd -o yaml | grep image- El siguiente ejemplo de salida muestra que usarías - gcr.io/gke-on-prem-releasecomo- Registry:- image: gcr.io/gke-on-prem-release/cilium/cilium:v1.12.6-anthos1.15-gke4.2.7
- Obtén el - KubernetesVersionde la etiqueta de imagen de- kube-apiserveren el espacio de nombres del clúster del clúster de administrador:- KUBECONFIG=ADMIN_KUBECONFIG kubectl get sts -n CLUSTER_NAME kube-apiserver -o yaml | grep image- Sustituye - ADMIN_KUBECONFIGpor el archivo kubeconfig de tu clúster de administrador y- CLUSTER_NAMEpor el nombre de tu clúster de usuario.- En el siguiente ejemplo de salida se muestra que usarías - v1.26.2-gke.1001como- KubernetesVersion:- image: gcr.io/gke-on-prem-release/kube-apiserver-amd64:v1.26.2-gke.1001 imagePullPolicy: IfNotPresent
Preparar archivos de manifiesto kube-proxy
Usa los valores obtenidos en la sección anterior para crear y aplicar un manifiesto YAML que implemente kube-proxy en tu clúster.
- Crea un archivo de manifiesto llamado - kube-proxy.yamlen el editor que prefieras:- nano kube-proxy.yaml
- Copia y pega la siguiente definición de 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- En este archivo de manifiesto YAML, define los siguientes valores: - APIServerAdvertiseAddress: el valor de- KUBERNETES_SERVICE_HOST, como- 21.1.4.119.
- APIServerPort: el valor de- KUBERNETES_SERVICE_PORT, como- 443.
- Registry: el prefijo de la imagen de Cilium, como- gcr.io/gke-on-prem-release.
- RegistryCredentialsSecretName: el nombre del secreto de extracción de imágenes, como- private-registry-creds.
 
- Guarda y cierra el archivo de manifiesto en el editor. 
Preparar parche de anetd
Crea y prepara una actualización para anetd:
- Crea un archivo de manifiesto llamado - cilium-config-patch.yamlen el editor que prefieras:- nano cilium-config-patch.yaml
- Copia y pega la siguiente definición de YAML: - data: kube-proxy-replacement: "disabled" kube-proxy-replacement-healthz-bind-address: "" retry-kube-proxy-healthz-binding: "false" enable-host-reachable-services: "false"
- Guarda y cierra el archivo de manifiesto en el editor. 
Desplegar kube-proxy y reconfigurar anetd
Aplica los cambios de configuración al clúster. Crea copias de seguridad de tu configuración actual antes de aplicar los cambios.
- Crea una copia de seguridad de la configuración actual de - anetdy- cilium-config:- kubectl get ds -n kube-system anetd > anetd-original.yaml kubectl get cm -n kube-system cilium-config > cilium-config-original.yaml
- Aplica - kube-proxy.yamlcon- kubectl:- kubectl apply -f kube-proxy.yaml
- Comprueba que los pods estén - Running:- kubectl get pods -n kube-system -o wide | grep kube-proxy- En el siguiente ejemplo de salida condensada se muestra que los pods se están ejecutando correctamente: - 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) [...]
- Aplica un parche al ConfigMap - cilium-configcon- kubectl:- kubectl patch cm -n kube-system cilium-config --patch-file cilium-config-patch.yaml
- Editar - anetdcon- kubectl:- kubectl edit ds -n kube-system anetd- En el editor que se abre, edita la especificación de - anetd. Inserta lo siguiente como primer elemento de- 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- Sustituye - Imagepor la misma imagen que se usa en los demás contenedores de Cilium del- anetdDaemonSet, como- gcr.io/gke-on-prem-release/cilium/cilium:v1.12.6-anthos1.15-gke4.2.7.
- Guarda y cierra el archivo de manifiesto en el editor. 
- Para aplicar estos cambios, reinicia todos los nodos de tu clúster. Para minimizar las interrupciones, puedes intentar agotar cada nodo antes de reiniciar. Sin embargo, es posible que los pods que usan volúmenes RWX se queden en el estado - Terminatingdebido a que los montajes NFS no funcionan y bloquean el proceso de drenaje.- Puedes forzar la eliminación de los pods bloqueados y permitir que el nodo se vacíe correctamente: - kubectl delete pods -–force -–grace-period=0 --namespace POD_NAMESPACE POD_NAME- Sustituye - POD_NAMEpor el pod que quieras eliminar y- POD_NAMESPACEpor su espacio de nombres.
Siguientes pasos
Si necesitas más ayuda, ponte en contacto con el servicio de atención al cliente de Cloud.
También puedes consultar la sección Obtener asistencia para obtener más información sobre los recursos de asistencia, incluidos los siguientes:
- Requisitos para abrir un caso de asistencia.
- Herramientas para ayudarte a solucionar problemas, como registros y métricas.
- Componentes, versiones y funciones compatibles de Google Distributed Cloud para VMware (solo software).