Delen via


Kubernetes-hosting

Kubernetes is een populaire keuze voor het hosten van Orleans toepassingen. Orleans wordt uitgevoerd in Kubernetes zonder specifieke configuratie; het kan echter ook profiteren van extra kennis die het hostingplatform biedt.

Het Microsoft.Orleans.Hosting.Kubernetes-pakket voegt integratie toe voor het hosten van een Orleans toepassing in een Kubernetes-cluster. Het pakket biedt een extensiemethode, UseKubernetesHostingwaarmee de volgende acties worden uitgevoerd:

Houd er rekening mee dat het Kubernetes-hostingpakket geen Kubernetes gebruikt voor clustering. Er is nog steeds een afzonderlijke clusterprovider nodig. Zie de documentatie Server-configuratie voor meer informatie over het configureren van clustering.

Deze functionaliteit legt enkele vereisten op voor de implementatie van de service:

  • Silonamen moeten overeenkomen met podnamen.
  • Pods moeten de orleans/serviceId en orleans/clusterId labels hebben die overeenkomen met de ServiceId en ClusterId van de silo. De UseKubernetesHosting methode geeft deze labels door aan de bijbehorende Orleans opties van omgevingsvariabelen.
  • Pods moeten de volgende omgevingsvariabelen hebben ingesteld: POD_NAME, POD_NAMESPACE, POD_IP, ORLEANS_SERVICE_ID, ORLEANS_CLUSTER_ID.

In het volgende voorbeeld ziet u hoe u deze labels en omgevingsvariabelen correct configureert:

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

Voor clusters met RBAC-functionaliteit kan het verlenen van de vereiste toegang tot het Kubernetes-serviceaccount voor de pods ook nodig zijn:

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: ''

Liveness, gereedheid en opstarttests

Kubernetes kan pods testen om de servicestatus te bepalen. Zie Liveness, Readiness and Startup Probes configureren in de Kubernetes-documentatie voor meer informatie.

Orleans gebruikt een clusterlidmaatschapsprotocol om onmiddellijk proces- of netwerkfouten te detecteren en te herstellen. Elk knooppunt bewaakt een subset van andere knooppunten en verzendt periodieke tests. Als een knooppunt niet reageert op meerdere opeenvolgende tests van meerdere andere knooppunten, wordt het knooppunt door het cluster geforceerd verwijderd. Zodra een mislukt knooppunt weet dat het wordt verwijderd, wordt het onmiddellijk beëindigd. Kubernetes start het beëindigde proces opnieuw op, waarna het probeert zich weer bij het cluster aan te sluiten.

Kubernetes-tests helpen bepalen of een proces in een pod wordt uitgevoerd en niet vastzit in een zombiestatus. Deze tests controleren de connectiviteit of reactiesnelheid tussen pods niet en voeren ook geen functionaliteitscontroles op toepassingsniveau uit. Als een pod niet reageert op een livenessprobe, kan Kubernetes die pod uiteindelijk beëindigen en opnieuw inplannen. Kubernetes-tests en Orleans -tests zijn daarom complementair.

De aanbevolen aanpak is het configureren van Liveness Probes in Kubernetes die een eenvoudige, lokale controle uitvoeren dat de toepassing naar behoren wordt uitgevoerd. Deze sondes dienen om het proces te beëindigen als er bijvoorbeeld een volledige bevriezing optreedt vanwege een runtimefout of een andere onwaarschijnlijke gebeurtenis.

Resourcequota

Kubernetes werkt met het besturingssysteem om resourcequota te implementeren. Hierdoor kunnen CPU- en geheugenreserveringen en/of limieten worden afgedwongen. Voor een primaire toepassing die interactieve belasting biedt, wordt het implementeren van beperkende limieten niet aanbevolen, tenzij dat nodig is. Het is belangrijk om te weten dat aanvragen en limieten aanzienlijk verschillen in betekenis en implementatielocatie. Voordat u aanvragen of limieten instelt, moet u een gedetailleerd inzicht krijgen in hoe ze worden geïmplementeerd en afgedwongen. Het is bijvoorbeeld mogelijk dat het geheugen niet uniform wordt gemeten tussen Kubernetes, de Linux-kernel en het bewakingssysteem. CPU-quota worden mogelijk niet afgedwongen zoals verwacht.

Probleemoplossing

Pods storten neer en klagen over KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT must be defined.

Volledige uitzonderingsbericht:

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()
  • Controleer of de omgevingsvariabelen KUBERNETES_SERVICE_HOST en KUBERNETES_SERVICE_PORT zijn ingesteld in de Pod. Controleer door de opdracht kubectl exec -it <pod_name> /bin/bash -c envuit te voeren.
  • Zorg ervoor dat automountServiceAccountToken is ingesteld op true in de Kubernetes deployment.yaml. Zie Serviceaccounts configureren voor podsvoor meer informatie.