Teilen über


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 und 30000 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 und orleans/clusterId aufweisen, die ServiceId und ClusterId 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 und KUBERNETES_SERVICE_PORT in Ihrem Pod festgelegt sind. Sie können überprüfen, indem Sie den folgenden Befehl kubectl exec -it <pod_name> /bin/bash -c envausführen.
  • Stellen Sie sicher, dass automountServiceAccountToken für Ihre Kubernetes-Datei deployment.yaml auf true festgelegt ist. Weitere Informationen finden Sie unter Dienstkonten für Pods konfigurieren.