En esta página se muestra cómo resolver problemas con el programador de Kubernetes (kube-scheduler
) de Google Distributed Cloud.
Kubernetes siempre programa los pods en el mismo conjunto de nodos
Este error puede observarse de varias formas:
Utilización desequilibrada de los clústeres. Puedes inspeccionar la utilización del clúster de cada nodo con el comando
kubectl top nodes
. En el siguiente ejemplo exagerado se muestra una utilización pronunciada en determinados nodos:NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% XXX.gke.internal 222m 101% 3237Mi 61% YYY.gke.internal 91m 0% 2217Mi 0% ZZZ.gke.internal 512m 0% 8214Mi 0%
Demasiadas solicitudes. Si programas muchos pods a la vez en el mismo nodo y esos pods hacen solicitudes HTTP, es posible que el nodo esté limitado por la frecuencia. El error habitual que devuelve el servidor en este caso es
429 Too Many Requests
.Servicio no disponible. Por ejemplo, un servidor web alojado en un nodo con una carga elevada podría responder a todas las solicitudes con errores
503 Service Unavailable
hasta que la carga sea menor.
Para comprobar si tienes pods que siempre se programan en los mismos nodos, sigue estos pasos:
Ejecuta el siguiente comando
kubectl
para ver el estado de los pods:kubectl get pods -o wide -n default
Para ver la distribución de los pods en los nodos, consulta la columna
NODE
en la salida. En el siguiente ejemplo de salida, todos los pods están programados en el mismo nodo:NAME READY STATUS RESTARTS AGE IP NODE nginx-deployment-84c6674589-cxp55 1/1 Running 0 55s 10.20.152.138 10.128.224.44 nginx-deployment-84c6674589-hzmnn 1/1 Running 0 55s 10.20.155.70 10.128.226.44 nginx-deployment-84c6674589-vq4l2 1/1 Running 0 55s 10.20.225.7 10.128.226.44
Los pods tienen varias funciones que te permiten ajustar su comportamiento de programación. Entre estas funciones se incluyen las restricciones de distribución de topología y las reglas de antiafinidad. Puedes usar una de estas funciones o una combinación de ellas. Los requisitos que definas se combinarán con el operador AND en kube-scheduler
.
Los registros del programador no se capturan en el nivel de detalle de registro predeterminado. Si necesitas los registros del programador para solucionar problemas, sigue estos pasos para capturarlos:
Aumenta el nivel de detalle de los registros:
Edita el
kube-scheduler
Deployment:kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG edit deployment kube-scheduler \ -n USER_CLUSTER_NAMESPACE
Añade la marca
--v=5
en la secciónspec.containers.command
:containers: - command: - kube-scheduler - --profiling=false - --kubeconfig=/etc/kubernetes/scheduler.conf - --leader-elect=true - --v=5
Cuando hayas terminado de solucionar el problema, vuelve a definir el nivel de detalle predeterminado:
Edita el
kube-scheduler
Deployment:kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG edit deployment kube-scheduler \ -n USER_CLUSTER_NAMESPACE
Vuelve a definir el nivel de detalle con el valor predeterminado:
containers: - command: - kube-scheduler - --profiling=false - --kubeconfig=/etc/kubernetes/scheduler.conf - --leader-elect=true
Restricciones de dispersión de la topología
Las restricciones de distribución de la topología se pueden usar para distribuir los pods de forma uniforme entre los nodos según su zones
,
regions
, node
u otra topología definida de forma personalizada.
El siguiente manifiesto de ejemplo muestra una implementación que distribuye las réplicas de forma uniforme entre todos los nodos programables mediante restricciones de distribución de topología:
apiVersion: apps/v1
kind: Deployment
metadata:
name: topology-spread-deployment
labels:
app: myapp
spec:
replicas: 30
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
topologySpreadConstraints:
- maxSkew: 1 # Default. Spreads evenly. Maximum difference in scheduled Pods per Node.
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule # Default. Alternatively can be ScheduleAnyway
labelSelector:
matchLabels:
app: myapp
matchLabelKeys: # beta in 1.27
- pod-template-hash
containers:
# pause is a lightweight container that simply sleeps
- name: pause
image: registry.k8s.io/pause:3.2
Cuando se usan restricciones de distribución de topología, se aplican las siguientes consideraciones:
- El
labels.app: myapp
de un pod coincide con ellabelSelector
de la restricción. - El elemento
topologyKey
especificakubernetes.io/hostname
. Esta etiqueta se asigna automáticamente a todos los nodos y se rellena con el nombre de host del nodo. matchLabelKeys
impide que las implementaciones de nuevas versiones tengan en cuenta los pods de versiones antiguas al calcular dónde programar un pod. La etiquetapod-template-hash
se rellena automáticamente con un Deployment.
Antiafinidad de pods
Antiafinidad de pods: te permite definir restricciones sobre qué pods se pueden colocar en el mismo nodo.
El siguiente manifiesto de ejemplo muestra un Deployment que usa la antiafinidad para limitar las réplicas a un Pod por nodo:
apiVersion: apps/v1
kind: Deployment
metadata:
name: pod-affinity-deployment
labels:
app: myapp
spec:
replicas: 30
selector:
matchLabels:
app: myapp
template:
metadata:
name: with-pod-affinity
labels:
app: myapp
spec:
affinity:
podAntiAffinity:
# requiredDuringSchedulingIgnoredDuringExecution
# prevents Pod from being scheduled on a Node if it
# does not meet criteria.
# Alternatively can use 'preferred' with a weight
# rather than 'required'.
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- myapp
# Your nodes might be configured with other keys
# to use as `topologyKey`. `kubernetes.io/region`
# and `kubernetes.io/zone` are common.
topologyKey: kubernetes.io/hostname
containers:
# pause is a lightweight container that simply sleeps
- name: pause
image: registry.k8s.io/pause:3.2
En este ejemplo de Deployment se especifican 30
réplicas, pero solo se amplía hasta el número de nodos disponibles en el clúster.
Cuando se usa la antiafinidad de pods, se aplican las siguientes consideraciones:
- El
labels.app: myapp
de un pod coincide con ellabelSelector
de la restricción. - El elemento
topologyKey
especificakubernetes.io/hostname
. Esta etiqueta se asigna automáticamente a todos los nodos y se rellena con el nombre de host del nodo. Puedes usar otras etiquetas si tu clúster las admite, comoregion
ozone
.
Pre-pull de imágenes de contenedor
Si no hay ninguna otra restricción, de forma predeterminada, kube-scheduler
prefiere programar pods en nodos que ya tengan descargada la imagen de contenedor. Este comportamiento puede ser interesante en clústeres más pequeños sin otras configuraciones de programación, donde sería posible descargar las imágenes en todos los nodos. Sin embargo, recurrir a este concepto debe considerarse como último recurso. Una solución mejor es usar nodeSelector
, restricciones de dispersión de la topología o afinidad/antiafinidad. Para obtener más información, consulta Asignar pods a nodos.
Si quieres asegurarte de que las imágenes de contenedor se extraigan previamente en todos los nodos, puedes usar un DaemonSet
como en el siguiente ejemplo:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: prepulled-images
spec:
selector:
matchLabels:
name: prepulled-images
template:
metadata:
labels:
name: prepulled-images
spec:
initContainers:
- name: prepulled-image
image: IMAGE
# Use a command the terminates immediately
command: ["sh", "-c", "'true'"]
containers:
# pause is a lightweight container that simply sleeps
- name: pause
image: registry.k8s.io/pause:3.2
Cuando el pod esté Running
en todos los nodos, vuelve a implementar los pods para comprobar si los contenedores se han distribuido de forma uniforme entre los nodos.
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).