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:
- SiloOptions.SiloName is ingesteld op de podnaam.
- EndpointOptions.AdvertisedIPAddress is ingesteld op het IP-adres van de pod.
-
EndpointOptions.SiloListeningEndpoint & EndpointOptions.GatewayListeningEndpoint zijn geconfigureerd om te luisteren naar een willekeurig adres, met de geconfigureerde SiloPort en GatewayPort. Standaardpoortwaarden van
11111
en30000
worden gebruikt als er geen waarden expliciet zijn ingesteld). -
ClusterOptions.ServiceId is ingesteld op de waarde van het podlabel met de naam
orleans/serviceId
. -
ClusterOptions.ClusterId is ingesteld op de waarde van het podlabel met de naam
orleans/clusterId
. - Vroeg in het opstartproces zal de silo Kubernetes testen om te vinden welke silo's geen bijbehorende pods hebben en die silo's als dood markeren.
- Hetzelfde proces vindt tijdens runtime plaats voor een subset van alle silo's om de belasting op de API-server van Kubernetes te verwijderen. Standaard kijken 2 silo's in het cluster naar Kubernetes.
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
enorleans/clusterId
label hebben dat overeenkomt met deServiceId
enClusterId
van 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
enKUBERNETES_SERVICE_PORT
omgevingsvariabelen zijn ingesteld in uw pod. U kunt dit controleren door de volgende opdracht uit te voerenkubectl 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.