En este documento, se detalla un procedimiento manual para Google Distributed Cloud si tienes problemas con las activaciones de NFS con un volumen o Pod atascado, y creaste tu clúster con DataPlane v2 habilitado.
Este problema se corrigió en las siguientes versiones:
- Para la versión secundaria 1.16, la versión 1.16.4-gke.37 y versiones posteriores.
- Para la versión secundaria 1.28, la versión 1.28.200-gke.111 y versiones posteriores.
Te recomendamos que actualices a una versión en la que se haya corregido este problema. Si no puedes actualizar, usa los procedimientos que se describen en las siguientes secciones.
Si usas una versión en la que no se corrigió este problema, es posible que tengas problemas si tienes cargas de trabajo que usan volúmenes de ReadWriteMany con controladores de almacenamiento que son susceptibles a este problema, como los siguientes (sin limitarse a ellos):
- Robin.io
- Portworx (volúmenes de servicio de sharedv4)
- csi-nfs
Los segmentos de NFS en algunas arquitecturas de almacenamiento pueden quedar atascados cuando se conectan a un extremo con un servicio de Kubernetes (ClusterIP) y DataPlane v2. Este comportamiento se debe a las limitaciones en la forma en que el código de socket del kernel de Linux interactúa con el programa eBPF de Cilium. Es posible que los contenedores se bloqueen en E/S o incluso que no se puedan detener, ya que no se puede desmontar el montaje de NFS obsoleto.
Es posible que experimentes este problema si usas almacenamiento RWX alojado en servidores NFS que se ejecutan en un nodo de Kubernetes, incluidas las soluciones de almacenamiento definidas por software o hiperconvergentes, como Ondat, Robin.io o Portworx.
Revisa la configuración del clúster existente
Obtén algunos valores de configuración existentes de tu clúster. Usarás los valores de estos pasos para crear un manifiesto kube-proxy en la siguiente sección.
- Obtén el - ClusterCIDRde- cm/cilium-config:- kubectl get cm -n kube-system cilium-config -o yaml | grep native-routing-cidr- En el siguiente ejemplo de resultado, se 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 - APIServerAdvertiseAddressy- APIServerPortdel DaemonSet- anetd:- kubectl get ds -n kube-system anetd -o yaml | grep KUBERNETES -A 1- En el siguiente ejemplo de resultado, se 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 DaemonSet- anetd:- kubectl get ds -n kube-system anetd -o yaml | grep imagePullSecrets -A 1- En el siguiente ejemplo de resultado, se muestra que usarías - private-registry-credscomo- RegistryCredentialsSecretName:- imagePullSecrets: - name: private-registry-creds
- Obtén el - Registrydel DaemonSet- anetd:- kubectl get ds -n kube-system anetd -o yaml | grep image- En el siguiente ejemplo de resultado, se 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 valor de - KubernetesVersionde la etiqueta de la imagen para- kube-apiserveren el espacio de nombres del clúster de administrador:- KUBECONFIG=ADMIN_KUBECONFIG kubectl get sts -n CLUSTER_NAME kube-apiserver -o yaml | grep image- Reemplaza - 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 resultado, 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
Prepara manifiestos de kube-proxy
Usa los valores obtenidos en la sección anterior para crear y aplicar un manifiesto YAML que implementará kube-proxy en tu clúster.
- Crea un manifiesto llamado - kube-proxy.yamlen el editor que elijas:- 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 manifiesto YAML, establece los siguientes valores: - APIServerAdvertiseAddress: Es el valor de- KUBERNETES_SERVICE_HOST, como- 21.1.4.119.
- APIServerPort: Es el valor de- KUBERNETES_SERVICE_PORT, como- 443.
- Registry: Es el prefijo de la imagen de Cilium, como- gcr.io/gke-on-prem-release.
- RegistryCredentialsSecretName: Es el nombre del secreto de extracción de la imagen, como- private-registry-creds.
 
- Guarda y cierra el archivo de manifiesto en tu editor. 
Prepara el parche de anetd
Crea y prepara una actualización para anetd:
- Crea un manifiesto llamado - cilium-config-patch.yamlen el editor que elijas:- 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 tu editor. 
Implementa kube-proxy y vuelve a configurar anetd
Aplica los cambios de configuración al clúster. Crea copias de seguridad de tu configuración existente 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
- Verifica que los Pods sean - Running:- kubectl get pods -n kube-system -o wide | grep kube-proxy- En el siguiente ejemplo de resultado condensado, se muestra que los Pods se ejecutan 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
- Edita - anetdcon- kubectl:- kubectl edit ds -n kube-system anetd- En el editor que se abre, edita las especificaciones de - anetd. Inserta lo siguiente como el primer elemento en- 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- Reemplaza - Imagepor la misma imagen que se usa en los otros contenedores de Cilium en el DaemonSet- anetd, 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 tu editor. 
- Para aplicar estos cambios, reinicia todos los nodos de tu clúster. Para minimizar las interrupciones, puedes intentar desviar el tráfico de cada nodo antes de reiniciarlo. Sin embargo, es posible que los Pods que usan volúmenes RWX queden atascados en un estado - Terminatingdebido a que las activaciones de NFS interrumpidas bloquean el proceso de vaciado.- Puedes forzar la eliminación de los Pods bloqueados y permitir que el nodo se drene correctamente: - kubectl delete pods -–force -–grace-period=0 --namespace POD_NAMESPACE POD_NAME- Reemplaza - POD_NAMEpor el Pod que intentas borrar y- POD_NAMESPACEpor su espacio de nombres.
¿Qué sigue?
Si necesitas asistencia adicional, comunícate con Atención al cliente de Cloud.
También puedes consultar Cómo 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).