Hébergement Kubernetes
Kubernetes est un choix populaire pour l’hébergement d’applications Orleans. Orleans s’exécute dans Kubernetes sans configuration spécifique. Toutefois, il peut également tirer parti des informations supplémentaires fournies par la plateforme d’hébergement.
Le package Microsoft.Orleans.Hosting.Kubernetes
ajoute l’intégration nécessaire pour l’hébergement d’une application Orleans dans un cluster Kubernetes. Le package fournit une méthode d’extension, UseKubernetesHosting, qui effectue les actions suivantes :
- SiloOptions.SiloName a la valeur du nom du pod.
- EndpointOptions.AdvertisedIPAddress a la valeur de l’IP du pod.
- EndpointOptions.SiloListeningEndpoint et EndpointOptions.GatewayListeningEndpoint sont configurés pour écouter sur n’importe quelle adresse, avec SiloPort et GatewayPort également configurés. Les valeurs de port par défaut
11111
et30000
sont utilisées si aucune valeur n’est définie explicitement). - ClusterOptions.ServiceId a la valeur de l’étiquette de pod nommée
orleans/serviceId
. - ClusterOptions.ClusterId a la valeur de l’étiquette de pod nommée
orleans/clusterId
. - Au début du processus de démarrage, le silo sonde Kubernetes à l’aide d’une probe pour détecter les silos qui n’ont pas de pods correspondants, et marquer ces silos comme étant morts.
- Le même processus se produit au moment de l’exécution pour un sous-ensemble de tous les silos, afin de supprimer la charge sur le serveur d’API de Kubernetes. Par défaut, 2 silos du cluster surveillent Kubernetes.
Notez que le package d’hébergement Kubernetes n’utilise pas Kubernetes pour le clustering. Pour le clustering, un fournisseur de clustering distinct est toujours nécessaire. Pour plus d’informations sur la configuration du clustering, consultez la documentation relative à la configuration du serveur.
Cette fonctionnalité impose certaines obligations relatives au déploiement du service :
- Les noms de silos doivent correspondre aux noms de pods.
- Les pods doivent avoir une étiquette
orleans/serviceId
etorleans/clusterId
qui correspond auServiceId
et auClusterId
du silo. La méthode mentionnée ci-dessus propage ces étiquettes au sein des options correspondantes dans Orleans à partir des variables d’environnement. - Les variables d’environnement suivantes doivent être définies pour les pods :
POD_NAME
,POD_NAMESPACE
,POD_IP
,ORLEANS_SERVICE_ID
,ORLEANS_CLUSTER_ID
.
L’exemple suivant montre comment configurer correctement ces étiquettes et ces variables d’environnement :
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
Pour les clusters avec contrôle RBAC, vous devrez peut-être également octroyer l’accès nécessaire au compte de service Kubernetes des pods :
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: ''
Probes liveness, readiness et startup
Kubernetes peut sonder les pods à l’aide d’une probe pour déterminer l’intégrité d’un service. Pour plus d’informations, consultez Configurer les probes liveness, readiness et startup dans la documentation de Kubernetes.
Orleans utilise un protocole d’appartenance à un cluster pour détecter rapidement les défaillances de processus ou réseau, et effectuer une reprise d’activité après sinistre. Chaque nœud effectue le monitoring d’un sous-ensemble d’autres nœuds en envoyant des probes périodiques. Si un nœud ne répond pas à plusieurs probes successives de plusieurs autres nœuds, il est supprimé de force du cluster. Une fois qu’un nœud défaillant apprend qu’il a été supprimé, il s’arrête immédiatement. Kubernetes redémarre le processus arrêté, puis tente de rejoindre le cluster.
Les probes Kubernetes permettent de déterminer si un processus de pod est en cours d’exécution, et s’il n’est pas bloqué à l’état de zombie. Les probes ne vérifient pas la connectivité ou la réactivité entre les pods, et n’effectuent aucune vérification des fonctionnalités au niveau de l’application. Si un pod ne répond pas à une probe liveness, Kubernetes peut finir par l’arrêter et le replanifier. Les probes de Kubernetes et les probes d’Orleans sont donc complémentaires.
L’approche recommandée consiste à configurer les probes Liveness dans Kubernetes pour qu’elles vérifient simplement localement que l’application fonctionne comme prévu. Ces probes servent à arrêter le processus en cas de gel total, par exemple à la suite d’une erreur d’exécution ou de tout autre événement inattendu.
Quotas de ressources
Kubernetes fonctionne conjointement avec le système d’exploitation pour implémenter des quotas de ressources. Cela permet d’appliquer des réservations et/ou des limites de processeur et de mémoire. Pour une application principale qui traite une charge interactive, nous vous recommandons de ne pas implémenter de limites restrictives, sauf si cela est nécessaire. Il est important de noter que les demandes et les limites sont très différentes, que ce soit dans le cadre de leur signification ou de leur implémentation. Avant de définir des demandes ou des limites, prenez le temps de comprendre en détail la façon dont elles sont implémentées et appliquées. Par exemple, il est possible que la mémoire ne soit pas mesurée de manière uniforme entre Kubernetes, le noyau Linux et votre système de monitoring. Les quotas de processeur ne sont peut-être pas appliqués tel que vous le souhaitez.
Dépannage
Les pods plantent, en indiquant KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT must be defined
Message d’exception complet :
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()
- Vérifiez que les variables d’environnement
KUBERNETES_SERVICE_HOST
etKUBERNETES_SERVICE_PORT
sont définies dans votre pod. Pour ce faire, vous pouvez exécuter la commande suivantekubectl exec -it <pod_name> /bin/bash -c env
. - Vérifiez que
automountServiceAccountToken
a la valeur true dans votre fichierdeployment.yaml
Kubernetes. Pour plus d’informations, consultez Configurer des comptes de service pour les pods