Delen via


Kubernetes-hosting

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

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

Het Kubernetes-hostingpakket maakt geen gebruik van Kubernetes voor clustering. Voor clustering is nog steeds een afzonderlijke clusteringprovider 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 een orleans/serviceId en orleans/clusterId label hebben dat overeenkomt met de ServiceId en ClusterIdvan de silo. Met de hierboven genoemde methode worden deze labels doorgegeven aan de bijbehorende opties in Orleans 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 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

Voor clusters met RBAC-functionaliteit moet het Kubernetes-serviceaccount voor de pods mogelijk ook de vereiste toegang krijgen:

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 status van een service te bepalen. Zie voor meer informatie liveness, gereedheid en opstarttests configureren in de documentatie van Kubernetes.

Orleans een clusterlidmaatschapsprotocol gebruikt om onmiddellijk een proces- of netwerkfout 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 geforceerd verwijderd uit het cluster. Zodra een mislukt knooppunt weet dat het is verwijderd, wordt het onmiddellijk beëindigd. Kubernetes start het beëindigde proces opnieuw op en probeert opnieuw aan het cluster te worden gekoppeld.

Kubernetes-probes kunnen helpen om te bepalen of een proces in een pod wordt uitgevoerd en niet vastzit in een zombie-status. Probes verifiëren de connectiviteit of reactiesnelheid tussen pods niet en voeren ook geen functionaliteitscontroles op toepassingsniveau uit. Als een pod niet reageert op een livenesstest, kan Kubernetes die pod uiteindelijk beëindigen en opnieuw plannen. De probes van Kubernetes en de probes van Orleanszijn daarom complementair.

De aanbevolen methode is om Liveness Probes te configureren in Kubernetes, waarbij een eenvoudige lokale controle wordt uitgevoerd of de toepassing naar behoren wordt uitgevoerd. Deze sondes dienen om het proces te beëindigen indien er een totale bevriezing optreedt, bijvoorbeeld door een runtimefout of een andere onwaarschijnlijke gebeurtenis.

Resourcequota

Kubernetes werkt samen 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, raden we u aan geen beperkende limieten te implementeren, tenzij dat nodig is. Het is belangrijk te weten dat aanvragen en limieten aanzienlijk verschillen in hun betekenis en waar ze worden geïmplementeerd. Voordat u aanvragen of limieten instelt, moet u de tijd nemen om een gedetailleerd inzicht te 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 uw bewakingssysteem. CPU-quota worden mogelijk niet afgedwongen op de manier die u 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 KUBERNETES_SERVICE_HOST en KUBERNETES_SERVICE_PORT omgevingsvariabelen zijn ingesteld in uw pod. U kunt dit controleren door de volgende opdracht uit te voeren kubectl exec -it <pod_name> /bin/bash -c env.
  • Zorg ervoor dat automountServiceAccountToken is ingesteld op _true_ op uw Kubernetes-deployment.yaml. Zie Serviceaccounts configureren voor podsvoor meer informatie.