Freigeben über


Kubernetes-Hosting

Kubernetes ist eine beliebte Wahl für das Hosten Orleans Anwendungen. Orleans wird in Kubernetes ohne spezifische Konfiguration ausgeführt; Es kann jedoch auch von zusätzlichem Wissen profitieren, das die Hostingplattform bietet.

Das Microsoft.Orleans.Hosting.Kubernetes-Paket fügt Integration zum Hosten einer Orleans Anwendung in einem Kubernetes-Cluster hinzu. Das Paket stellt eine Erweiterungsmethode bereit, UseKubernetesHostingdie die folgenden Aktionen ausführt:

Beachten Sie, dass das Kubernetes-Hostingpaket Kubernetes nicht für clustering verwendet. Es ist noch ein separater Clusteringanbieter erforderlich. Weitere Informationen zum Konfigurieren von Clustering finden Sie in der Serverkonfiguration Dokumentation.

Diese Funktionalität setzt einige Anforderungen für die Dienstbereitstellung auf:

  • Silonamen müssen mit Podnamen übereinstimmen.
  • Pods müssen orleans/serviceId und orleans/clusterId Labels aufweisen, die den Silos ServiceId und ClusterId entsprechen. Die UseKubernetesHosting Methode verteilt diese Bezeichnungen in die entsprechenden Orleans Optionen 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 identifies the service to Orleans
        orleans/serviceId: dictionary-app

        # This label identifies an instance of a cluster to Orleans.
        # Typically, this is the same value as the previous label, or any
        # fixed value.
        # In cases where you don't use rolling deployments (for example,
        # blue/green deployments),
        # this value can allow for distinct clusters that don't communicate
        # directly with each other,
        # but 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 Orleans uses
          - containerPort: 11111
          - containerPort: 30000
          env:
          # The Azure Storage connection string for clustering is injected as an
          # environment variable.
          # You must create it 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's 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 kann es außerdem notwendig sein, dem Kubernetes-Dienstkonto für die Pods die erforderlichen Zugriffsrechte zu gewähren:

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 können Pods testen, um den Dienststatus zu ermitteln. Weitere Informationen finden Sie in der Kubernetes-Dokumentation unter Configure Liveness, Readiness and Startup Probes .

Orleans verwendet ein Clustermitgliedschaftsprotokoll, um 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 aufeinanderfolgende Prüfungen von mehreren anderen Knoten reagiert, entfernt der Cluster ihn zwangsweise. Sobald ein fehlgeschlagener Knoten von seiner Entfernung erfährt, beendet er sich sofort selbst. Kubernetes startet den beendeten Prozess neu, der dann versucht, erneut am Cluster teilnehmen zu können.

Kubernetes-Sonden überprüfen, ob ein Prozess in einem Pod ausgeführt wird und sich nicht in einem Zombie-Zustand befindet. Diese Prüfpunkte überprüfen weder die Inter-Pod-Konnektivität noch die Reaktionsfähigkeit, noch führen sie Funktionsprüfungen auf Anwendungsebene durch. Wenn ein Pod nicht auf eine Liveness-Probe reagiert, beendet Kubernetes diesen Pod möglicherweise und plant ihn neu. Kubernetes Sonden und Orleans Sonden ergänzen sich daher.

Der empfohlene Ansatz ist das Konfigurieren von Liveness-Prüfungen in Kubernetes, die eine einfache, nur lokal durchgeführte Überprüfung der Anwendung vornehmen, um sicherzustellen, dass sie wie beabsichtigt funktioniert. Diese Sonden dienen dazu, den Prozess zu beenden, falls es zu einem totalen Einfrieren kommt, beispielsweise wegen eines Laufzeitfehlers oder eines anderen unwahrscheinlichen Ereignisses.

Ressourcenkontingente

Kubernetes arbeitet mit dem Betriebssystem zusammen, um Ressourcenkontingente zu implementieren. Dies ermöglicht das Erzwingen von CPU- und Arbeitsspeicherreservierungen und/oder Grenzwerten. Für eine primäre Anwendung, die interaktive Last bedient, sollten restriktive Grenzwerte nur implementiert werden, wenn es notwendig ist. Es ist wichtig zu beachten, dass Anforderungen und Grenzwerte erheblich in Bedeutung und Implementierungsstandort unterschiedlich sind. Bevor Sie Anforderungen oder Grenzwerte festlegen, nehmen Sie sich 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 dem Überwachungssystem gemessen werden. CPU-Kontingente werden möglicherweise nicht wie erwartet 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 KUBERNETES_SERVICE_HOST Variablen und KUBERNETES_SERVICE_PORT Umgebungsvariablen innerhalb des Pods festgelegt sind. Überprüfen Sie, indem Sie den Befehl kubectl exec -it <pod_name> /bin/bash -c envausführen.
  • Stellen Sie sicher, dass automountServiceAccountToken in Kubernetes true auf deployment.yaml festgelegt ist. Weitere Informationen finden Sie unter Dienstkonten für Pods konfigurieren.