Compartilhar via


Hospedagem do Kubernetes

O Kubernetes é uma opção popular para hospedar aplicativos Orleans. Orleans será executado no Kubernetes sem uma configuração específica, no entanto, ele também pode aproveitar o conhecimento extra que a plataforma de hospedagem pode fornecer.

O pacote Microsoft.Orleans.Hosting.Kubernetes adiciona integração para hospedar um aplicativo Orleans em um cluster do Kubernetes. O pacote fornece um método de extensão, UseKubernetesHosting, que executa as seguintes ações:

Observe que o pacote de hospedagem do Kubernetes não usa o Kubernetes para clustering. Para agrupamento, ainda é necessário um provedor separado. Para obter mais informações sobre como configurar o clustering, consulte a documentação de configuração do servidor.

Essa funcionalidade impõe alguns requisitos sobre como o serviço é implantado:

  • Os nomes de silo devem corresponder aos nomes de pod.
  • Os pods devem ter um rótulo orleans/serviceId e orleans/clusterId que correspondam ao ServiceId e ClusterId do silo. O método mencionado acima propagará esses rótulos para as opções correspondentes em Orleans a partir das variáveis de ambiente.
  • Os pods devem ter as seguintes variáveis de ambiente definidas: POD_NAME, POD_NAMESPACE, POD_IP, ORLEANS_SERVICE_ID, ORLEANS_CLUSTER_ID.

O exemplo a seguir mostra como configurar esses rótulos e variáveis de ambiente corretamente:

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

Para clusters habilitados para RBAC, a conta de serviço do Kubernetes utilizada pelos pods também pode precisar receber o acesso necessário.

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

Investigações de atividade, preparação e inicialização

O Kubernetes pode investigar os pods para determinar a integridade de um serviço. Para obter mais informações, confira Configurar as investigações de atividade, preparação e inicialização na documentação do Kubernetes.

Orleans usa um protocolo de associação de cluster para detectar e recuperar rapidamente de um processo ou falhas de rede. Cada nó monitora um subconjunto de outros nós, enviando investigações periódicas. Se um nó não responder a várias investigações sucessivas de vários outros nós, será removido à força do cluster. Quando um nó com falha descobre que foi removido, ele termina imediatamente. O Kubernetes reiniciará o processo encerrado e tentará reencontrar o cluster.

As investigações do Kubernetes podem ajudar a determinar se um processo em um pod está em execução e não está paralisado em um estado de zumbi. as sondas não verificam a conectividade ou a capacidade de resposta entre pods, nem executam verificações de funcionalidade no nível do aplicativo. Se um pod não responder a uma investigação de atividade, o Kubernetes poderá terminar eventualmente esse pod e reagendá-lo. As investigações do Kubernetes e as investigações de Orleans' são, portanto, complementares.

A abordagem recomendada é configurar probes de liveness no Kubernetes, que executam uma verificação local simples de que o aplicativo está funcionando conforme o esperado. Essas sondas servem para encerrar o processo se houver um congelamento total, por exemplo, devido a uma falha durante o tempo de execução ou outro evento pouco provável.

Cotas de recursos

O Kubernetes funciona em conjunto com o sistema operacional, para implementar cotas de recursos. Isso permite que as reservas de CPU e memória e/ou limites sejam impostas. Para um aplicativo primário que esteja servindo carga interativa, recomendamos não implementar limites restritivos, a menos que seja necessário. É importante observar que as solicitações e os limites são substancialmente diferentes em seu significado e onde são implementados. Antes de definir solicitações ou limites, reserve um tempo para obter uma compreensão detalhada de como elas são implementadas e impostas. Por exemplo, a memória pode não ser medida uniformemente entre o Kubernetes, o kernel do Linux e o sistema de monitoramento. As cotas de CPU podem não ser impostas da maneira esperada.

Solução de problemas

Falha nos pods com reclamação de KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT must be defined

Mensagem de exceção completa:

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()
  • Verifique se as variáveis de ambiente KUBERNETES_SERVICE_HOST e KUBERNETES_SERVICE_PORT estão definidas dentro do pod. Você pode verificar executando o seguinte comando kubectl exec -it <pod_name> /bin/bash -c env.
  • Verifique se automountServiceAccountToken está definido como verdadeiro no seu Kubernetes deployment.yaml. Para obter mais informações, confira Configurar contas de serviço para pods.