Auf dieser Seite wird beschrieben, wie Sie Probleme mit dem Kubernetes-Planer (kube-scheduler
) für Google Distributed Cloud Virtual for Bare Metal beheben.
Kubernetes plant Pods immer für denselben Satz von Knoten.
Dieser Fehler kann auf verschiedene Arten beobachtet werden:
Unausgeglichene Clusterauslastung. Mit dem Befehl
kubectl top nodes
können Sie die Clusterauslastung für jeden Knoten prüfen. Die folgende übertriebene Beispielausgabe zeigt eine ausgeprägte Auslastung auf bestimmten Knoten: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%
Zu viele Anfragen. Wenn Sie viele Pods gleichzeitig auf demselben Knoten planen und diese Pods HTTP-Anfragen senden, kann es sein, dass die Raten des Knotens begrenzt sind. Der häufig vom Server zurückgegebene Fehler ist
429 Too Many Requests
.Dienst nicht verfügbar. Ein Webserver, der beispielsweise auf einem Knoten unter hoher Last gehostet wird, antwortet möglicherweise auf alle Anfragen mit
503 Service Unavailable
-Fehlern, bis eine geringere Last zunimmt.
Mit den folgenden Schritten können Sie prüfen, ob Pods immer für dieselben Knoten geplant sind:
Führen Sie den folgenden
kubectl
-Befehl aus, um den Status der Pods anzusehen:kubectl get pods -o wide -n default
Prüfen Sie in der Ausgabe die Spalte
NODE
, um die Verteilung der Pods auf Knoten anzusehen. In der folgenden Beispielausgabe sind alle Pods auf demselben Knoten geplant: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
Pods haben eine Reihe von Features, mit denen Sie ihr Planungsverhalten optimieren können. Zu diesen Funktionen gehören Einschränkungen der Topologiestreuung und Anti-Affinitätsregeln. Sie können diese Funktionen einzeln oder in einer Kombination verwenden. Die von Ihnen definierten Anforderungen werden durch kube-scheduler
durch eine UND-Verbindung verbunden.
Die Planerlogs werden nicht auf der Standardausführlichkeitsstufe für das Logging erfasst. Wenn Sie die Planerlogs zur Fehlerbehebung benötigen, führen Sie zum Erfassen der Planerlogs die folgenden Schritte aus:
Erhöhen Sie den Ausführlichkeitsgrad für das Logging:
Bearbeiten Sie das Deployment
kube-scheduler
:kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG edit deployment kube-scheduler \ -n USER_CLUSTER_NAMESPACE
Fügen Sie im Abschnitt
spec.containers.command
das Flag--v=5
hinzu:containers: - command: - kube-scheduler - --profiling=false - --kubeconfig=/etc/kubernetes/scheduler.conf - --leader-elect=true - --v=5
Wenn Sie mit der Fehlerbehebung fertig sind, setzen Sie den Ausführlichkeitsgrad wieder auf die Standardeinstellung zurück:
Bearbeiten Sie das Deployment
kube-scheduler
:kubectl --kubeconfig ADMIN_CLUSTER_KUBECONFIG edit deployment kube-scheduler \ -n USER_CLUSTER_NAMESPACE
Setzen Sie den Ausführlichkeitsstufe auf den Standardwert zurück:
containers: - command: - kube-scheduler - --profiling=false - --kubeconfig=/etc/kubernetes/scheduler.conf - --leader-elect=true
Einschränkungen der Topologieverteilung
Mit Einschränkungen der Topologieverteilung können Sie Pods gemäß ihrer zones
, regions
, node
oder einer anderen benutzerdefinierten Topologie gleichmäßig auf Knoten verteilen.
Das folgende Beispielmanifest zeigt ein Deployment, das Replikate mithilfe von Einschränkungen der Topologieverteilung gleichmäßig auf alle planbaren Knoten verteilt:
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
Bei der Verwendung von Topologiestreuungseinschränkungen gelten die folgenden Überlegungen:
- Der
labels.app: myapp
eines Pods entspricht demlabelSelector
der Einschränkung. - Der
topologyKey
gibtkubernetes.io/hostname
an. Dieses Label wird automatisch an alle Knoten angehängt und mit dem Hostnamen des Knotens ausgefüllt. - Der
matchLabelKeys
verhindert, dass Roll-outs neuer Deployments Pods alter Versionen bei der Berechnung des Pod-Plans berücksichtigen. Das Labelpod-template-hash
wird von einem Deployment automatisch ausgefüllt.
Pod-Anti-Affinität
Mit Pod-Anti-Affinität können Sie Einschränkungen für Pods definieren, die sich auf demselben Knoten befinden können.
Das folgende Beispielmanifest zeigt ein Deployment, das mithilfe von Anti-Affinität Replikate auf einen Pod pro Knoten beschränkt:
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
In diesem Beispiel-Deployment sind Replikate vom Typ 30
angegeben, diese werden aber nur auf so viele Knoten erweitert, dass in Ihrem Cluster verfügbar sind.
Bei der Verwendung von Pod-Anti-Affinität gelten die folgenden Überlegungen:
- Der
labels.app: myapp
eines Pods entspricht demlabelSelector
der Einschränkung. - Der
topologyKey
gibtkubernetes.io/hostname
an. Dieses Label wird automatisch an alle Knoten angehängt und mit dem Hostnamen des Knotens ausgefüllt. Sie können andere Labels verwenden, wenn Ihr Cluster diese unterstützt, z. B.region
oderzone
.
Container-Images vor Abruf
Sofern keine anderen Einschränkungen gelten, zieht kube-scheduler
es standardmäßig vor, Pods auf Knoten zu planen, auf denen das Container-Image bereits heruntergeladen wurde. Dieses Verhalten kann bei kleineren Clustern ohne andere Planungskonfigurationen von Interesse sein, bei denen es möglich wäre, die Images auf jedem Knoten herunterzuladen. Allerdings sollte die Verlässlichkeit auf dieses Konzept nur als letztes Mittel angesehen werden. Eine bessere Lösung ist die Verwendung von nodeSelector
, Einschränkungen der Topologiestreuung oder Affinität / Anti-Affinität. Weitere Informationen finden Sie unter Pods zu Knoten zuweisen.
Wenn Sie dafür sorgen möchten, dass Container-Images vorab auf alle Knoten übertragen werden, können Sie einen DaemonSet
wie im folgenden Beispiel verwenden:
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
Wenn der Pod auf allen Knoten den Status Running
hat, stellen Sie die Pods noch einmal bereit, um zu prüfen, ob die Container jetzt gleichmäßig auf die Knoten verteilt sind.