Detaillierte Erklärung des Pod of K8s (1)
Pod ist die Grundeinheit für die Erstellung, Planung und Verwaltung von k8s. Der übergeordnete Controller sendet Anweisungen an das auf dem Knoten installierte Kubelet, um den Pod zu verwalten. Daher müssen wir mehr über den Pod wissen.
Die grundlegendsten Vorgänge sind das Erstellen, Löschen, Planen und Anzeigen von Pods!
Für die Pod-Erstellung gibt es entsprechende Ressourcenzuweisungen und Ressourcenbeschränkungen für Pods; für die Pod-Erstellungsplanung, basierend auf der hohen Verfügbarkeit von Pods, für die Planung von Pods für Knotenknoten in verschiedenen Rechenzentren; und für die Datenspeicherung für Pod-Anwendungen
Kommunikation zwischen Pod und API-Server
Die Knoten kommunizieren mit der Kontrollebene:
Alle API-Aufrufe, die von einem Knoten (oder darauf laufenden Pods) erfolgen, enden am API-Server. Kubernetes verwendet das Hub-and-Spoke-API-Modell.
Pods , die eine Verbindung zum API-Server herstellen möchten, können dies sicher über ein Dienstkonto tun. Kubernetes fügt automatisch das öffentliche Stammzertifikat und ein gültiges Bearer-Token in den Pod ein, wenn der Pod instanziiert wird. kubernetes
Der Dienst (im default
Namespace) ist mit einer virtuellen IP-Adresse konfiguriert, die kube-proxy
Anfragen an (über) den HTTPS-Endpunkt des API-Servers weiterleitet.
Es gibt zwei Hauptkommunikationspfade von der Steuerungsebene (API-Server) zu den Knoten
1. Vom API-Server zum Kubelet-Prozess, der auf jedem Knoten im Cluster ausgeführt wird
2. Stellen Sie über die Proxy- Funktion eine Verbindung zu einem beliebigen Knoten, Pod oder Dienst vom API-Server her.
API-Server für Kubelet
Verbindungen vom API-Server zum Kubelet werden verwendet, um:
- Pod-Protokolle abrufen.
- Anhängen (über kubectl) an einen laufenden Pod.
- Stellt die Portweiterleitungsfunktion von Kubelet bereit.
API-Server für Knoten, Pods und Dienste
Verbindungen vom API-Server zu Knoten, Pods oder Diensten erfolgen standardmäßig über einfaches HTTP , sodass weder Authentifizierung noch Verschlüsselung erfolgt.
https:
Diese Verbindungen können über sichere HTTPS-Verbindungen ausgeführt werden , indem der Knoten-, Pod- oder Dienstname in der API-URL vorangestellt wird . Diese Verbindungen überprüfen jedoch weder das vom HTTPS-Endpunkt vorgelegte Zertifikat noch das Client-Zertifikat .
Obwohl die Verbindung verschlüsselt ist, bietet sie daher keine Integritätsgarantien. Der Betrieb dieser Verbindungen über nicht vertrauenswürdige oder öffentliche Netzwerke ist derzeit nicht sicher .
SSH-Tunnel
Kubernetes unterstützt die Verwendung von SSH-Tunneln , um den Kommunikationspfad von der Steuerungsebene zu den Knoten zu sichern. In dieser Konfiguration richtet der API-Server einen SSH-Tunnel zu jedem Knoten im Cluster ein (der mit dem SSH-Server verbunden ist, der Port 22 überwacht) und überträgt alle Anforderungen über diesen Tunnel an das Kubelet, den Knoten, den Pod oder den Dienst. Dieser Tunnel stellt sicher, dass die Kommunikation nicht außerhalb des Netzwerks, in dem die Clusterknoten ausgeführt werden, offengelegt wird.
Beschleunigen Sie den Pod-Start
In k8s Version 1.27 hinzugefügte Funktionen
Der Image-Pull ist standardmäßig ein serieller Job. Kubelet sendet jeweils nur eine Image-Pull-Anfrage, und andere Images müssen warten, bis die Pull-Anfrage verarbeitet wird.
Parallele Jobeinstellungen, die Mirror Pull ermöglichen können
serializeImagePulls 默认为true,设置为false # kubelet 中配置
Um eine Serverüberlastung durch das Abrufen von Bildern zu verhindern, können Sie die Anzahl der parallelen Pulls festlegen
maxParallelImagePulls n # kubelet 中配置
Erhöhtes Kubelet-Standard-API-Abfragelimit pro Sekunde
Wenn mehrere Pods erstellt werden, ist eine große Bandbreite erforderlich, um auf den Kube-Apiserver zuzugreifen. Im Falle einer plötzlichen Skalierung muss Kubelet den Pod-Status synchronisieren und ConfigMap, Secret oder Volume vorbereiten.
Vor Version 1.27 kubeAPIQPS
war der Standardwert 5 kubeAPIBurst
und der Standardwert 10; zuvor war dies bei Knoten mit mehr als 50 Pods häufig beim Pod-Start auf dem Kubelet der Fall volume mount timeout
.
In der Version v1.27 kubeAPIQPS
wurde der Standardwert von kubeAPIBurst auf 50 und der Standardwert von kubeAPIBurst auf 100 erhöht
Ereignisgesteuerte Aktualisierungen des Containerstatus
Kubernetes bietet Kubelet zwei Methoden zur Erkennung von Pod-Lebenszyklusereignissen
Der ereignisbasierte Mechanismus wurde auf die Betaversion erweitert, ist jedoch standardmäßig deaktiviert
Erhöhen Sie bei Bedarf die Pod-Ressourcenlimits
Einige Pods verbrauchen beim Start möglicherweise viel CPU oder Speicher. Wenn das CPU-Limit niedrig ist, kann es den Pod-Startvorgang erheblich verlangsamen.
Kubernetes v1.22 führt ein Feature-Gate namens MemoryQoS ein
memoryThrottlingFactor # 默认值最初为 0.8,Kubernetes v1.27 中更改为 0.9
Durch Verringern dieses Faktors (der eine niedrigere Obergrenze für Containergruppen festlegt) erhöht sich der Rückgewinnungsdruck. Durch die Erhöhung dieses Faktors wird der Erholungsdruck verringert.
Pod-Ressourcen ändern
Wenn für einen Pod eine CPU- oder Speicherressource festgelegt ist, führt eine Änderung des Ressourcenwerts zu einem Neustart des Pods. Dies ist ein destruktiver Vorgang für die laufende Last.
In Version 1.27 können Benutzer mit der Alpha-Funktion die Größe der den Pods zugewiesenen CPU- und Speicherressourcen anpassen, ohne den Container neu starten zu müssen.
Dies bedeutet auch, dass Felder in Pod-Definitionen resource
nicht mehr als Indikatoren für die tatsächlichen Ressourcen des Pods betrachtet werden können. Vorgesetzte müssen sich ein neues Feld im Pod-Status ansehen, um den tatsächlichen Ressourcenstatus zu erhalten.
Der Benutzer kann das Verhalten des Containers steuern, wenn Ressourcen angepasst werden:
restartPolicy
Neues Feld zum Pod-Status hinzugefügt resize
: Zeigt den Status der letzten ausstehenden angeforderten Anpassung an
Der Wert der Größenänderung:
- Vorgeschlagen: Dieser Wert gibt an, dass die angeforderte Anpassung bestätigt wurde und die Anfrage überprüft und protokolliert wurde.
- InProgress: Dieser Wert zeigt an, dass der Knoten die Anpassungsanforderung angenommen hat und sie auf die Container des Pods anwendet.
- Zurückgestellt: Dieser Wert bedeutet, dass die angeforderte Anpassung zu diesem Zeitpunkt nicht genehmigt werden kann und der Knoten es erneut versucht. Anpassungen können tatsächlich implementiert werden, wenn andere Pods beenden und Knotenressourcen freigeben.
- Undurchführbar: Dieser Wert ist ein Signal dafür, dass der Knoten den angeforderten Anpassungswert nicht durchführen kann. Dies kann passieren, wenn die angeforderte Anpassung die maximalen Ressourcen überschreitet, die ein Knoten einem Pod zuweisen kann.
Anwendungsszenario
- Laufende Pods sind ressourcenbeschränkt oder erfordern zu viele oder zu wenige Anforderungen.
- Einige Pods mit überdimensionierten Ressourcen werden für einen Knoten geplant, was dazu führt, dass Pods aufgrund unzureichender CPU oder Arbeitsspeicher nicht auf Clustern mit geringer Ressourcenauslastung geplant werden können.
- Das Entfernen bestimmter zustandsbehafteter Pods, die mehr Ressourcen erfordern, ist ein teurer oder störender Vorgang. In diesem Szenario ist es günstiger, die Ressourcen anderer Pods mit niedrigerer Priorität im Knoten herunterzuskalieren oder diese Pods zu entfernen.
Um Feature-Funktionen nutzen zu können, müssen Sie „Feature Gating“ -InPlacePodVerticalScaling aktivieren
root@vbuild:~/go/src/k8s.io/kubernetes# FEATURE_GATES=InPlacePodVerticalScaling=true ./hack/local-up-cluster.sh
Individueller Zugriffsmodus für das persistente Volume eines Pods
Ein neuer Zugriffsmodus, der in k8s v1.22 für PersistentVolume (PVs) und PersistentVolumeClaim (PVCs) eingeführt wurde.
Was ist der Einzelzugriffsmodus (ReadWriteOncePod) für persistente Volumes?
Mit diesem Zugriffsmodus können Sie den Speicher-Volume-Zugriff auf einen einzelnen Pod im Cluster beschränken und so sicherstellen, dass jeweils nur ein Pod auf das Speicher-Volume schreiben kann.
Anwendungsszenario: Für zustandsbehaftete Workloads, die einen einzelnen Autor für den Zugriff auf den Speicher erfordern.
Diese Funktion ist in Clustern der Version 1.27 und höher standardmäßig aktiviert
Wie fange ich mit ReadWriteOncePod an?
ReadWriteOncePod unterstützt nur CSI-Volumes . Bevor Sie diese Funktion nutzen können, müssen Sie die folgenden CSI-Sidecars auf die folgenden Versionen oder höher aktualisieren:
Um ReadWriteOncePod zu verwenden, erstellen Sie einen PVC mit dem ReadWriteOncePod-Zugriffsmodus:
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: single-writer-only
spec:
accessModes:
- ReadWriteOncePod #仅允许一个容器访问且独占写入权限。
resources:
requests:
storage: 1Gi
Einschränkungen bei der Verteilung der Pod-Topologie
Um eine hohe Verfügbarkeit zu erreichen und die Ressourcennutzung zu verbessern, können Topology Spread Constraints verwendet werden, um die Verteilung von Pods auf Fehlerdomänen im Cluster zu steuern, wie z. B. Regionen (Regions), Verfügbarkeitszonen (Zones), Knoten und andere benutzerdefinierte Topologien Domänen
Angenommen, Sie haben einen Cluster mit bis zu zwanzig Knoten und möchten eine automatisch skalierende Arbeitslast ausführen (Anwendung läuft auf k8s). Wie viele Replikate sollten Sie verwenden?
Die Antwort könnte mindestens 2 Pods und maximal 15 Pods sein.
Stellen Sie sich ein Problem vor: Wenn nur zwei Pods vorhanden sind und die beiden Pods zufällig auf einem Knotenknoten generiert werden und der Knotenknoten ausfällt, tritt ein einzelner Fehlerpunkt auf!
Betrachten Sie ein weiteres Problem: Angenommen, Sie haben 3 Knoten, auf denen jeweils 5 Pods ausgeführt werden. Diese Knoten verfügen über genügend Kapazität, um viele Replikate auszuführen. Allerdings sind die Clients, die mit dieser Arbeitslast interagieren, auf drei verschiedene Rechenzentren (oder Infrastrukturverfügbarkeitszonen) verteilt, und die Netzwerklatenz kann aufgrund des Sendens von Netzwerkverkehr zwischen Verfügbarkeit höher als erwartet sein Für Zonen fallen einige Netzwerkkosten an
Konfigurieren Sie über das Feld topologySpreadConstraints
---
apiVersion: v1
kind: Pod
metadata:
name: example-pod
spec:
# 配置一个拓扑分布约束
topologySpreadConstraints:
- maxSkew: <integer>
minDomains: <integer> # 可选;自从 v1.25 开始成为 Beta
topologyKey: <string>
whenUnsatisfiable: <string>
labelSelector: <object>
matchLabelKeys: <list> # 可选;自从 v1.27 开始成为 Beta
nodeAffinityPolicy: [Honor|Ignore] # 可选;自从 v1.26 开始成为 Beta
nodeTaintsPolicy: [Honor|Ignore] # 可选;自从 v1.26 开始成为 Beta
### 其他 Pod 字段置于此处
Weitere Informationen erhalten Sie über den Befehl kubectl EXPLAIN Pod.spec.topologySpreadConstraints oder unter Pod-API-Planung
Bedeutung einiger Felder
- maxSkew beschreibt, wie gleichmäßig diese Pods wahrscheinlich verteilt werden. Sie müssen dieses Feld angeben und der Wert muss größer als Null sein. Seine Semantik
whenUnsatisfiable
ändert sich mit dem Wert von:
- Wenn Sie wählen
whenUnsatisfiable: DoNotSchedule
,maxSkew
wird die maximal zulässige Differenz zwischen der Anzahl übereinstimmender Pods in der Zieltopologie und dem globalen Minimum definiert (die Mindestanzahl übereinstimmender Pods in berechtigten Domänen oder Null, wenn die Anzahl berechtigter Domänen kleiner als MinDomains ist). Wenn Sie beispielsweise über 3 Availability Zones mit 2, 2 und 1 passenden Pods verfügen,MaxSkew
legen Sie den Wert auf 1 fest und haben ein globales Minimum von 1.- Wenn Sie wählen
whenUnsatisfiable: ScheduleAnyway
, bevorzugt der Scheduler topologische Domänen, die die Versatzwerte reduzieren.
minDomains stellt die Mindestanzahl berechtigter Domänen dar. Dieses Feld ist optional. Eine Domäne ist eine bestimmte Instanz einer Topologie. Berechtigte Domänen sind Domänen, deren Knoten mit dem Knotenselektor übereinstimmen.
veranschaulichen:
minDomains
Feld ist ein Beta-Feld, das in 1.25 standardmäßig deaktiviert ist. Sie können dieses Feld aktivieren, indem SieMinDomainsInPodTopologySpread
Feature Gating aktivieren .
- Der angegebene
minDomains
Wert muss größer als 0 sein. Sie könnenwhenUnsatisfiable: DoNotSchedule
nur angegebene kombinierenminDomains
.- Wenn die Anzahl qualifizierter topologischer Schlüsselübereinstimmungsdomänen kleiner als ist
minDomains
, setzt die topologische Verteilung das „globale Minimum“ vor derskew
Berechnung auf 0. Das „globale Minimum“ ist die Mindestanzahl übereinstimmender Pods in einer berechtigten Domäne oder Null, wenn die Anzahl berechtigter Domänen geringer istminDomains
.- Wenn die Anzahl der geeigneten topologischen Schlüsselübereinstimmungsdomänen gleich oder größer ist
minDomains
, hat dieser Wert keine Auswirkung auf die Planung.- Wenn Sie nicht angeben
minDomains
, verhält sich die Einschränkung wieminDomains
gleich 1.
- topologyKey ist der Schlüssel für die Knotenbezeichnung . Knoten gelten als in derselben topologischen Domäne befindlich, wenn sie mit diesem Schlüssel markiert sind und denselben Tag-Wert haben. Wir bezeichnen jede Instanz in einer topologischen Domäne (dh einem Schlüssel-Wert-Paar) als Domäne. Der Planer versucht, in jeder Topologiedomäne eine ausgewogene Anzahl von Pods zu platzieren. Darüber hinaus definieren wir berechtigte Domänen als Domänen, deren Knoten die Anforderungen von nodeAffinityPolicy und nodeTaintsPolicy erfüllen.
- whenUnsatisfiable gibt an, was zu tun ist, wenn der Pod die Verteilungsbeschränkungen nicht erfüllt:
DoNotSchedule
(Standard) Weist den Planer an, keine Planung vorzunehmen.ScheduleAnyway
Weisen Sie den Planer an, weiterhin mit der Planung fortzufahren. Ordnen Sie die Knoten einfach danach an, wie sie die Abweichung minimieren können.
- labelSelector wird verwendet, um passende Pods zu finden. Pods, die dieser Bezeichnung entsprechen, werden gezählt, um die Anzahl der Pods in der entsprechenden Topologiedomäne zu ermitteln. Einzelheiten finden Sie unter Etikettenauswahl .
- matchLabelKeys ist eine Liste von Pod-Label-Schlüsseln, die zur Auswahl der Pod-Sammlung verwendet wird, die zur Berechnung der Verteilungsmethode benötigt wird. Diese Schlüssel werden verwendet, um Werte von Pod-Labels nachzuschlagen, und diese Schlüssel-Wert-Labels werden
labelSelector
logisch mit UND verknüpft, um einen Satz bestehender Pods auszuwählen, anhand dessen die Verteilung neuer Pods berechnet werden soll. Identische Schlüssel sind inmatchLabelKeys
und verboten. Kann nicht festgelegt werden, wennlabelSelector
nicht festgelegt ist . Schlüssel, die nicht in Pod-Labels vorhanden sind, werden ignoriert. Null oder eine leere Liste bedeutet, dass nur eine Übereinstimmung erfolgt .labelSelector
matchLabelKeys
labelSelector
Mit matchLabelKeys
müssen Sie nicht aktualisieren, wenn Sie Pod-Revisionen ändern pod.spec
. Ein Controller oder Bediener muss lediglich den Tag-Schlüssel für verschiedene Revisionen auf einen anderen Wert setzen. Der Planer matchLabelKeys
ermittelt den Wert automatisch basierend auf . Wenn Sie beispielsweise ein Deployment konfigurieren, können Sie durch Pod-Template-Hash verschlüsselte Beschriftungen verwenden , die vom Deployment-Controller automatisch hinzugefügt werden, um zwischen verschiedenen Revisionen desselben Deployments zu unterscheiden.
topologySpreadConstraints:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: foo
matchLabelKeys:
- pod-template-hash
veranschaulichen:
matchLabelKeys
„Felder“ ist ein Feld auf Beta-Ebene, das in 1.27 standardmäßig aktiviert ist. Sie können dieses Feld deaktivieren, indem SieMatchLabelKeysInPodTopologySpread
das Feature-Gating deaktivieren .
nodeAffinityPolicy gibt an, wie wir mit der nodeAffinity/nodeSelector des Pods umgehen, wenn wir die Abweichung der Pod-Topologieverteilung berechnen. Die Optionen sind:
- Ehre: Nur Knoten, die mit nodeAffinity/nodeSelector übereinstimmen, werden in die Berechnung einbezogen.
- Ignorieren: nodeAffinity/nodeSelector wird ignoriert. Alle Knoten werden in die Berechnung einbezogen.
Wenn dieser Wert Null ist, entspricht dieses Verhalten der Honor-Richtlinie.
veranschaulichen:
nodeAffinityPolicy
ist ein Beta-Level-Feld, das in 1.26 standardmäßig aktiviert ist. Sie können dieses Feld deaktivieren, indem SieNodeInclusionPolicyInPodTopologySpread
das Feature-Gating deaktivieren .
nodeTaintsPolicy gibt an, wie wir Knoten-Taints bei der Berechnung der Pod-Topologie-Verteilungsverzerrung behandeln. Die Optionen sind:
- Ehre: Beinhaltet Knoten ohne Taints und Knoten, deren Taints von neuen Pods toleriert werden.
- Ignorieren: Knotenmarkierungen werden ignoriert. Beziehen Sie alle Knoten ein.
Wenn dieser Wert null ist, entspricht dieses Verhalten der Ignore-Richtlinie.
veranschaulichen:
nodeTaintsPolicy
ist ein Beta-Level-Feld, das in Version 1.26 standardmäßig aktiviert ist. Sie können dieses Feld deaktivieren, indem SieNodeInclusionPolicyInPodTopologySpread
das Feature-Gating deaktivieren .
Mindestanzahl von Domänen in der Pod-Topologieverteilung
k8s v1.25 topologySpreadConstraints
führt zwei neue Felder ein nodeAffinityPolicy
und nodeTaintPolicy
definiert Knoten
Diese Funktion wurde in Version 1.25 als Alpha eingeführt. Standardmäßig deaktiviert, daher muss Feature-Gating explizit aktiviert werden, wenn diese Funktion in v1.25 verwendet werden soll NodeInclusionPolicyInPodTopologySpread
. In der nächsten Version v1.26 werden die relevanten Funktionen auf die Betaversion erweitert und standardmäßig aktiviert.
apiVersion: v1
kind: Pod
metadata:
name: example-pod
spec:
# 配置拓扑分布约束
topologySpreadConstraints:
- maxSkew: <integer>
# ...
nodeAffinityPolicy: [Honor|Ignore]
nodeTaintsPolicy: [Honor|Ignore]
# 在此处添加其他 Pod 字段
nodeAffinityPolicy
Das Feld gibt an, wie Kubernetes mit den Pods umgeht nodeAffinity
oder nodeSelector
die Verteilung der Pod-Topologie berechnet.
Wenn ja , filtert kube-scheduler
Honor
bei der Berechnung des Verteilungsversatzes Knoten heraus , die nichtnodeAffinity
übereinstimmen .nodeSelector
Wenn ja
Ignore
, werden alle Knoten einbezogen, unabhängig davon, ob sie mit dem Pod übereinstimmennodeAffinity
/ oder nichtnodeSelector
.Aus Gründen der Abwärtskompatibilität
nodeAffinityPolicy
ist der StandardwertHonor
.
nodeTaintsPolicy
Das Feld definiert, wie Kubernetes Node-Taints bei der Berechnung der topologischen Verteilung von Pods behandelt.
Wenn ja
Honor
, werden nur eingehende Pods auf einem infizierten Knoten mit der tolerierenden Bezeichnung in die Berechnung der Verteilungsverzerrung einbezogen.Wenn dies der Fall ist
Ignore
, berücksichtigt Kube-Scheduler Knoten-Taints bei der Berechnung der Verteilungsabweichung überhaupt nicht, sodass auch Knoten mit Pods berücksichtigt werden, die keine Taints tolerieren.Aus Gründen der Abwärtskompatibilität
nodeTaintsPolicy
ist der StandardwertIgnore
.
Kubernetes v1.25 führte ein matchLabelKeys
neues Feld namens to ein topologySpreadConstraints
. matchLabelKeys
ist eine Liste von Pod-Label-Schlüsseln, die zur Auswahl von Pods für die Berechnung der Verteilung verwendet werden. Diese Schlüssel werden verwendet, um den Labelwert nachzuschlagen, wenn der Pod geplant wird. Diese Schlüsselwertlabels werden labelSelector
logisch mit AND verknüpft, um die vorhandene Pod-Gruppe für die neue Pod-Berechnungsverteilungsmethode auszuwählen.
Mit matchLabelKeys
können Sie nicht aktualisieren, wenn sich die Revision ändert pod.spec
. Ein Controller oder Operator verwaltet fortlaufende Upgrades, indem er einfach unterschiedliche Werte für denselben Tag-Schlüssel für verschiedene Revisionen festlegt. Der Planer matchLabelKeys
schließt die Aufgabe automatisch basierend auf ab. Wenn Sie beispielsweise ein Deployment konfigurieren, können Sie den Tag-Schlüssel des vom Deployment-Controller automatisch hinzugefügten Pod-Template-Hash verwenden , um zwischen verschiedenen Revisionen innerhalb eines einzelnen Deployments zu unterscheiden.
topologySpreadConstraints:
- maxSkew: 1
topologyKey: kubernetes.io/hostname
whenUnsatisfiable: DoNotSchedule
labelSelector:
matchLabels:
app: foo
matchLabelKeys:
- pod-template-hash
Referenz: Kubernetes 1.27: Fortschritte beim schnelleren Pod-Start
Kubernetes 1.27: Pod-Ressourcen direkt anpassen (Alpha)
Kubernetes 1.27: Single-Pod-Zugriffsmodus für persistente Volumes auf Beta aktualisiert