Kubernetes-Hosting
Kubernetes ist eine beliebte Wahl für das Hosten Orleans Anwendungen. Orleans ohne spezifische Konfiguration in Kubernetes ausgeführt werden, kann aber auch zusätzliche Kenntnisse nutzen, die die Hostingplattform bereitstellen kann.
Das Microsoft.Orleans.Hosting.Kubernetes
-Paket fügt Integration zum Hosten einer Orleans Anwendung in einem Kubernetes-Cluster hinzu. Das Paket stellt eine Erweiterungsmethode UseKubernetesHostingbereit, die die folgenden Aktionen ausführt:
- SiloOptions.SiloName wird auf den Podnamen festgelegt.
- EndpointOptions.AdvertisedIPAddress wird auf die IP-Adresse des Pods festgelegt.
- EndpointOptions.SiloListeningEndpoint und EndpointOptions.GatewayListeningEndpoint sind so konfiguriert, dass alle Adressen mit den konfigurierten SiloPort und GatewayPort überwacht werden. Standardportwerte von
11111
und30000
werden verwendet, wenn keine Werte explizit festgelegt werden). - ClusterOptions.ServiceId wird auf den Wert der Podbezeichnung mit dem Namen
orleans/serviceId
festgelegt. - ClusterOptions.ClusterId wird auf den Wert der Podbezeichnung mit dem Namen
orleans/clusterId
festgelegt. - Zu Beginn des Startvorgangs wird Kubernetes vom Silo untersucht, um zu ermitteln, welche Silos nicht über entsprechende Pods verfügen, und diese Silos als inaktiv zu markieren.
- Derselbe Prozess erfolgt zur Laufzeit für eine Teilmenge aller Silos, um die Last auf dem Kubernetes-API-Server zu entfernen. Standardmäßig beobachten 2 Silos im Cluster Kubernetes.
Beachten Sie, dass das Kubernetes-Hostingpaket Kubernetes nicht für clustering verwendet. Für das Clustering ist weiterhin ein separater Clusteringanbieter erforderlich. Weitere Informationen zum Konfigurieren von Clustering finden Sie in der Serverkonfiguration Dokumentation.
Diese Funktionalität legt einige Anforderungen für die Bereitstellung des Diensts fest:
- Silonamen müssen mit Podnamen übereinstimmen.
- Pods müssen Bezeichnungen für
orleans/serviceId
undorleans/clusterId
aufweisen, dieServiceId
undClusterId
des Silos entsprechen. Die oben genannte Methode verteilt diese Bezeichnungen in die entsprechenden Optionen in Orleans aus Umgebungsvariablen. - Pods müssen die folgenden Umgebungsvariablen gesetzt haben:
POD_NAME
,POD_NAMESPACE
,POD_IP
,ORLEANS_SERVICE_ID
,ORLEANS_CLUSTER_ID
.
Das folgende Beispiel zeigt, wie Sie diese Bezeichnungen und Umgebungsvariablen richtig konfigurieren:
apiVersion: apps/v1
kind: Deployment
metadata:
name: dictionary-app
labels:
orleans/serviceId: dictionary-app
spec:
selector:
matchLabels:
orleans/serviceId: dictionary-app
replicas: 3
template:
metadata:
labels:
# This label is used to identify the service to Orleans
orleans/serviceId: dictionary-app
# This label is used to identify an instance of a cluster to Orleans.
# Typically, this will be the same value as the previous label, or any
# fixed value.
# In cases where you are not using rolling deployments (for example,
# blue/green deployments),
# this value can allow for distinct clusters which do not communicate
# directly with each others,
# but which still share the same storage and other resources.
orleans/clusterId: dictionary-app
spec:
containers:
- name: main
image: my-registry.azurecr.io/my-image
imagePullPolicy: Always
ports:
# Define the ports which Orleans uses
- containerPort: 11111
- containerPort: 30000
env:
# The Azure Storage connection string for clustering is injected as an
# environment variable
# It must be created separately using a command such as:
# > kubectl create secret generic az-storage-acct `
# --from-file=key=./az-storage-acct.txt
- name: STORAGE_CONNECTION_STRING
valueFrom:
secretKeyRef:
name: az-storage-acct
key: key
# Configure settings to let Orleans know which cluster it belongs to
# and which pod it is running in
- name: ORLEANS_SERVICE_ID
valueFrom:
fieldRef:
fieldPath: metadata.labels['orleans/serviceId']
- name: ORLEANS_CLUSTER_ID
valueFrom:
fieldRef:
fieldPath: metadata.labels['orleans/clusterId']
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: DOTNET_SHUTDOWNTIMEOUTSECONDS
value: "120"
request:
# Set resource requests
terminationGracePeriodSeconds: 180
imagePullSecrets:
- name: my-image-pull-secret
minReadySeconds: 60
strategy:
rollingUpdate:
maxUnavailable: 0
maxSurge: 1
Für RBAC-fähige Cluster muss dem Kubernetes-Dienstkonto für die Pods möglicherweise auch der erforderliche Zugriff gewährt werden:
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: orleans-hosting
rules:
- apiGroups: [ "" ]
resources: ["pods"]
verbs: ["get", "watch", "list", "delete", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: orleans-hosting-binding
subjects:
- kind: ServiceAccount
name: default
apiGroup: ''
roleRef:
kind: Role
name: orleans-hosting
apiGroup: ''
Live-, Bereitschafts- und Starttests
Kubernetes kann Pods testen, um die Integrität eines Diensts zu ermitteln. Weitere Informationen finden Sie unter Configure Liveness, Readiness and Startup Probes (Konfigurieren von Live-, Bereitschafts- und Starttests) in der Kubernetes-Dokumentation.
Orleans verwendet ein Clustermitgliedschaftsprotokoll, um einen Prozess oder Netzwerkfehler umgehend zu erkennen und wiederherzustellen. Jeder Knoten überwacht eine Teilmenge anderer Knoten und sendet regelmäßige Abfragen. Wenn ein Knoten nicht auf mehrere aufeinander folgende Proben von mehreren anderen Knoten reagiert, wird er forcibly aus dem Cluster entfernt. Sobald ein fehlgeschlagener Knoten lernt, dass er entfernt wurde, wird er sofort beendet. Kubernetes startet den beendeten Prozess neu, und es versucht, erneut am Cluster teilnehmen zu können.
Kubernetes-Sonden können dabei helfen zu bestimmen, ob ein Prozess in einem Pod ausgeführt wird und nicht in einem Zombie-Zustand feststeckt. Sonden überprüfen weder die Inter-Pod-Konnektivität noch die Ansprechbarkeit und führen keine Funktionsprüfungen auf Anwendungsebene durch. Wenn ein Pod längere Zeit nicht auf einen Livetest reagiert, kann Kubernetes diesen Pod beenden und neu planen. Kubernetes Sonden und Orleans'Sonden sind daher komplementär.
Der empfohlene Ansatz besteht darin, Liveness-Probes in Kubernetes zu konfigurieren, die eine einfache lokale Überprüfung durchführen, ob die Anwendung wie beabsichtigt ausgeführt wird. Diese Prüfpunkte dienen dazu, den Prozess zu beenden, wenn beispielsweise aufgrund eines Laufzeitfehlers oder eines anderen unwahrscheinlichen Ereignisses ein totales Einfrieren vorliegt.
Ressourcenkontingente
Kubernetes implementiert in Verbindung mit dem Betriebssystem Ressourcenkontingente. Dadurch können CPU- und Speicherreservierungen und/oder -beschränkungen erzwungen werden. Für eine primäre Anwendung, die die interaktive Last bedient, empfehlen wir, keine restriktiven Grenzwerte zu implementieren, es sei denn, dies ist erforderlich. Es ist wichtig zu beachten, dass Anforderungen und Grenzwerte in ihrer Bedeutung erheblich unterschiedlich sind und wo sie implementiert werden. Bevor Sie Anforderungen oder Grenzwerte festlegen, nehmen Sie sich die Zeit, um detaillierte Kenntnisse darüber zu erhalten, wie sie implementiert und erzwungen werden. Beispielsweise kann der Arbeitsspeicher nicht einheitlich zwischen Kubernetes, dem Linux-Kernel und Ihrem Überwachungssystem gemessen werden. CPU-Kontingente werden möglicherweise nicht in der erwarteten Weise erzwungen.
Fehlerbehebung
Pods stürzen ab und geben die Beschwerde aus: KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT must be defined
.
Vollständige Ausnahmemeldung:
Unhandled exception. k8s.Exceptions.KubeConfigException: unable to load in-cluster configuration, KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT must be defined
at k8s.KubernetesClientConfiguration.InClusterConfig()
- Überprüfen Sie, ob die Umgebungsvariablen
KUBERNETES_SERVICE_HOST
undKUBERNETES_SERVICE_PORT
in Ihrem Pod festgelegt sind. Sie können überprüfen, indem Sie den folgenden Befehlkubectl exec -it <pod_name> /bin/bash -c env
ausführen. - Stellen Sie sicher, dass
automountServiceAccountToken
für Ihre Kubernetes-Dateideployment.yaml
auf true festgelegt ist. Weitere Informationen finden Sie unter Dienstkonten für Pods konfigurieren.