Хостинг Kubernetes
Kubernetes — это популярный выбор для размещения Orleans приложений. Orleans будет выполняться в Kubernetes без определенной конфигурации, однако он также может воспользоваться дополнительными знаниями, которые может предоставить платформа размещения.
Пакет Microsoft.Orleans.Hosting.Kubernetes
добавляет интеграцию для размещения приложения Orleans в кластере Kubernetes. Пакет предоставляет метод расширения UseKubernetesHosting, который выполняет следующие действия:
- SiloOptions.SiloName устанавливается как имя pod.
- EndpointOptions.AdvertisedIPAddress присвоен IP-адрес узла.
-
EndpointOptions.SiloListeningEndpoint & EndpointOptions.GatewayListeningEndpoint настроены на прослушивание всех адресов при помощи настроенных SiloPort и GatewayPort. Значения портов по умолчанию
11111
и30000
используются, если значения не заданы явным образом). -
ClusterOptions.ServiceId задано значение метки pod с именем
orleans/serviceId
. -
ClusterOptions.ClusterId задано значение метки pod с именем
orleans/clusterId
. - В начале работы силос проверит Kubernetes на наличие силосов, не имеющих соответствующих подов, и пометит эти силосы как неактивные.
- Тот же процесс будет выполняться во время выполнения для подмножества всех силосов, чтобы удалить нагрузку на сервер API Kubernetes. По умолчанию 2 силоса в кластере будут отслеживать Kubernetes.
Обратите внимание, что пакет размещения Kubernetes не использует Kubernetes для кластеризации. Для кластеризации требуется отдельный поставщик кластеризации. Дополнительные сведения о настройке кластеризации см. в документации по конфигурации сервера .
Эта функция накладывает некоторые требования к развертыванию службы:
- Имена Silo должны совпадать с именами pod.
- Модули Pod должны иметь метки
orleans/serviceId
иorleans/clusterId
, соответствующиеServiceId
иClusterId
силосной башни. Упомянутый выше метод будет распространять упомянутые метки в соответствующие параметры в 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 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
Для кластеров с поддержкой 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, чтобы определить работоспособность службы. Дополнительные сведения см. в разделе Настройка активности, готовности и запуска проб в документации Kubernetes.
Orleans использует протокол членства в кластере для оперативного обнаружения и восстановления от сбоев процесса или сети. Каждый узел отслеживает подмножество других узлов, отправляя периодические пробы. Если узел не может реагировать на несколько последовательных проб из нескольких других узлов, он будет принудительно удален из кластера. Как только недействующий узел узнает, что он был удалён, он немедленно завершает работу. Kubernetes перезапустит завершенный процесс и попытается повторно присоединиться к кластеру.
Пробы Kubernetes могут помочь определить, выполняется ли процесс в модуле pod и не застрял в состоянии зомби. Пробы не проверяют подключение между модулями pod или скорость реагирования или выполняют проверки функциональности на уровне приложения. Если модуль pod не может реагировать на пробу активности, kubernetes может в конечном итоге завершить этот модуль и перепланировать его. Поэтому пробы Kubernetes и пробы 'Orleans' дополняют друг друга.
Рекомендуемый подход — настроить пробы Liveness в 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, вdeployment.yaml
Kubernetes. Дополнительные сведения см. в разделе Настройка учетных записей служб для модулей pod.