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
ClusterCIDR
decm/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/16
comoClusterCIDR
:ipv4-native-routing-cidr: 192.168.0.0/16 native-routing-cidr: 192.168.0.0/16
Obtén
APIServerAdvertiseAddress
yAPIServerPort
del DaemonSetanetd
: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.119
comoAPIServerAdvertiseAddress
y443
comoAPIServerPort
:- name: KUBERNETES_SERVICE_HOST value: 21.1.4.119 - name: KUBERNETES_SERVICE_PORT value: "443"
Obtén el
RegistryCredentialsSecretName
del DaemonSetanetd
: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-creds
comoRegistryCredentialsSecretName
:imagePullSecrets: - name: private-registry-creds
Obtén el
Registry
del DaemonSetanetd
: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-release
comoRegistry
:image: gcr.io/gke-on-prem-release/cilium/cilium:v1.12.6-anthos1.15-gke4.2.7
Obtén el valor de
KubernetesVersion
de la etiqueta de la imagen parakube-apiserver
en 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_KUBECONFIG
por el archivo kubeconfig de tu clúster de administrador yCLUSTER_NAME
por el nombre de tu clúster de usuario.En el siguiente ejemplo de resultado, se muestra que usarías
v1.26.2-gke.1001
comoKubernetesVersion
: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.yaml
en 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 deKUBERNETES_SERVICE_HOST
, como21.1.4.119
.APIServerPort
: Es el valor deKUBERNETES_SERVICE_PORT
, como443
.Registry
: Es el prefijo de la imagen de Cilium, comogcr.io/gke-on-prem-release
.RegistryCredentialsSecretName
: Es el nombre del secreto de extracción de la imagen, comoprivate-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.yaml
en 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
anetd
ycilium-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.yaml
conkubectl
: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-config
conkubectl
:kubectl patch cm -n kube-system cilium-config --patch-file cilium-config-patch.yaml
Edita
anetd
conkubectl
: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 eninitContainers
:- 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
Image
por la misma imagen que se usa en los otros contenedores de Cilium en el DaemonSetanetd
, comogcr.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
Terminating
debido 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_NAME
por el Pod que intentas borrar yPOD_NAMESPACE
por 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).