Поделиться через


Хостинг Kubernetes

Kubernetes — это популярный выбор для размещения Orleans приложений. Orleans выполняется в Kubernetes без специальной конфигурации; однако он также может воспользоваться дополнительными возможностями, которые предоставляет хостинговая платформа.

Пакет Microsoft.Orleans.Hosting.Kubernetes добавляет интеграцию для размещения приложения Orleans в кластере Kubernetes. Пакет предоставляет метод расширения, UseKubernetesHostingвыполняя следующие действия:

  • Задает SiloOptions.SiloName имя контейнера pod.
  • Задает EndpointOptions.AdvertisedIPAddress IP-адрес pod.
  • Настраивает EndpointOptions.SiloListeningEndpoint и EndpointOptions.GatewayListeningEndpoint для прослушивания любого адреса, используя настроенный SiloPort и GatewayPort. Значения портов 11111 и 30000 по умолчанию используются, если значения не заданы явно.
  • Задает ClusterOptions.ServiceId значение метки pod с именем orleans/serviceId.
  • Задает ClusterOptions.ClusterId значение метки pod с именем orleans/clusterId.
  • В начале процесса запуска silo проверяет Kubernetes, чтобы найти, какие силосы не имеют соответствующих pod и помечает эти силосы как мертвые.
  • Тот же процесс происходит во время выполнения для подмножества всех силосов, чтобы уменьшить нагрузку на сервер API Kubernetes. По умолчанию 2 силоса в кластере отслеживают Kubernetes.

Обратите внимание, что пакет размещения Kubernetes не использует Kubernetes для кластеризации. По-прежнему необходим отдельный поставщик кластеризации. Дополнительные сведения о настройке кластеризации см. в документации по конфигурации сервера .

Эта функция накладывает некоторые требования к развертыванию службы:

  • Имена Silo должны совпадать с именами pod.
  • Модули Pod должны иметь orleans/serviceId и orleans/clusterId метки, соответствующие silo ServiceId и ClusterId. Метод UseKubernetesHosting распространяет эти метки на соответствующие Orleans параметры из переменных среды.
  • Модули должны иметь следующие переменные среды: POD_NAME, POD_NAMESPACE, POD_IP, ORLEANS_SERVICE_ID, ORLEANS_CLUSTER_ID.

В следующем примере показано, как правильно настроить эти метки и переменные среды:

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

Для кластеров с поддержкой RBAC также может потребоваться предоставить необходимый доступ к учетной записи службы Kubernetes для модулей pod:

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

Проверки на работоспособность, готовность и запуск

Kubernetes может проверять модули pod для определения работоспособности служб. Дополнительные сведения см. в разделе "Настройка liveness", "Готовность" и "Пробы запуска " в документации Kubernetes.

Orleans использует протокол членства в кластере для оперативного обнаружения и восстановления от сбоев процесса или сети. Каждый узел отслеживает подмножество других узлов, отправляя периодические пробы. Если узел не может реагировать на несколько последовательных проб из нескольких других узлов, кластер принудительно удаляет его. После того как неисправный узел узнает о том, что он удален, он немедленно завершает работу. Kubernetes перезапускает завершенный процесс, который затем пытается повторно присоединиться к кластеру.

Пробы Kubernetes помогают определить, выполняется ли процесс в модуле pod и не застрял в состоянии зомби. Эти пробы не проверяют подключение между pod'ами или их способность к быстрому реагированию, а также не выполняют проверки функциональности на уровне приложения. Если модуль pod не отвечает на пробу активности, Kubernetes может в конечном итоге завершить этот модуль и перепланировать его. Пробы Kubernetes и Orleans пробы являются взаимодополняющими.

Рекомендуемый подход заключается в настройке проверок готовности в Kubernetes, которые выполняют простую локальную проверку того, что приложение работает как задумано. Эти зонды служат для завершения процесса в случае полного зависания, например, из-за сбоя во времени выполнения или другого маловероятного события.

Квоты ресурсов

Kubernetes работает с операционной системой для реализации квот ресурсов. Это позволяет применять резервирования ЦП и памяти и (или) ограничения. Для основного приложения, обслуживающее интерактивную нагрузку, реализация ограничивающих ограничений не рекомендуется, если это не необходимо. Важно отметить, что запросы и ограничения существенно отличаются в значении и расположении реализации. Прежде чем задавать запросы или ограничения, получите подробное представление о том, как они реализуются и применяются. Например, память может не измеряться равномерно между Kubernetes, ядром Linux и системой мониторинга. Квоты ЦП могут не применяться должным образом.

Устранение неполадок

Pоды дают сбой, жалуясь на то, что KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT must be defined

Полное сообщение об исключении:

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()
  • Убедитесь, что переменные среды KUBERNETES_SERVICE_HOST и KUBERNETES_SERVICE_PORT заданы внутри Pod. Проверьте, выполнив команду kubectl exec -it <pod_name> /bin/bash -c env.
  • Убедитесь, что automountServiceAccountToken установлено как true в Kubernetes deployment.yaml. Дополнительные сведения см. в разделе Настройка учетных записей служб для модулей pod.