Kubernetes-värd
Kubernetes är ett populärt val för värdprogram Orleans . Orleans kommer att köras i Kubernetes utan specifik konfiguration, men det kan också dra nytta av extra kunskap som värdplattformen kan ge.
Paketet Microsoft.Orleans.Hosting.Kubernetes
lägger till integrering för att vara värd för ett Orleans program i ett Kubernetes-kluster. Paketet tillhandahåller en tilläggsmetod, UseKubernetesHosting, som utför följande åtgärder:
- SiloOptions.SiloName är inställt på poddnamnet.
- EndpointOptions.AdvertisedIPAddress är inställt på poddens IP-adress.
- EndpointOptions.SiloListeningEndpoint & EndpointOptions.GatewayListeningEndpoint är konfigurerade för att lyssna på valfri adress, med konfigurerade SiloPort och GatewayPort. Standardportvärden
11111
för och30000
används om inga värden anges explicit). - ClusterOptions.ServiceId anges till värdet för poddetiketten med namnet
orleans/serviceId
. - ClusterOptions.ClusterId anges till värdet för poddetiketten med namnet
orleans/clusterId
. - Tidigt i startprocessen kommer silon att avsöka Kubernetes för att hitta vilka silor som inte har motsvarande poddar och markera dessa silor som döda.
- Samma process sker vid körning för en delmängd av alla silor för att ta bort belastningen på Kubernetes API-server. Som standard tittar 2 silor i klustret på Kubernetes.
Observera att Kubernetes-värdpaketet inte använder Kubernetes för klustring. För klustring behövs fortfarande en separat klusterprovider. Mer information om hur du konfigurerar kluster finns i dokumentationen för serverkonfiguration .
Den här funktionen ställer vissa krav på hur tjänsten distribueras:
- Silonamn måste matcha poddnamn.
- Poddar måste ha en
orleans/serviceId
och-etikettorleans/clusterId
som motsvarar silo ochServiceId
ClusterId
. Metoden ovan sprider dessa etiketter till motsvarande alternativ i Orleans från miljövariabler. - Poddar måste ha följande miljövariabler inställda:
POD_NAME
,POD_NAMESPACE
,POD_IP
, ,ORLEANS_SERVICE_ID
,ORLEANS_CLUSTER_ID
.
I följande exempel visas hur du konfigurerar dessa etiketter och miljövariabler korrekt:
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
För RBAC-aktiverade kluster kan Kubernetes-tjänstkontot för poddarna också behöva beviljas den åtkomst som krävs:
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, readiness och startup probes
Kubernetes kan avsöka poddar för att fastställa hälsotillståndet för en tjänst. Mer information finns i Konfigurera liveness, beredskap och startavsökningar i Kubernetes dokumentation.
Orleans använder ett protokoll för klustermedlemskap för att snabbt identifiera och återställa från en process eller ett nätverksfel. Varje nod övervakar en delmängd av andra noder och skickar periodiska avsökningar. Om en nod inte svarar på flera på varandra följande avsökningar från flera andra noder tas den med två skäl bort från klustret. När en misslyckad nod får reda på att den har tagits bort avslutas den omedelbart. Kubernetes startar om den avslutade processen och försöker ansluta till klustret igen.
Kubernetes avsökningar kan hjälpa till att avgöra om en process i en podd körs och inte har fastnat i ett zombietillstånd. avsökningar verifierar inte anslutning mellan poddar eller svarstider eller utför några funktionskontroller på programnivå. Om en podd inte svarar på en liveness-avsökning kan Kubernetes så småningom avsluta podden och schemalägga om den. Kubernetes avsökningar och Orleansavsökningar kompletterar därför varandra.
Den rekommenderade metoden är att konfigurera Liveness-avsökningar i Kubernetes som utför en enkel lokal kontroll av att programmet fungerar som avsett. Dessa avsökningar kan avsluta processen om det finns en total frysning, till exempel på grund av ett körningsfel eller en annan osannolik händelse.
Resurskvoter
Kubernetes fungerar tillsammans med operativsystemet för att implementera resurskvoter. Detta gör att processor- och minnesreservationer och/eller gränser kan tillämpas. För ett primärt program som hanterar interaktiv belastning rekommenderar vi att du inte implementerar restriktiva gränser om det inte behövs. Det är viktigt att notera att begäranden och gränser skiljer sig avsevärt åt i deras betydelse och var de implementeras. Innan du anger begäranden eller begränsningar tar du dig tid att få en detaljerad förståelse för hur de implementeras och tillämpas. Minnet kanske till exempel inte mäts jämnt mellan Kubernetes, Linux-kerneln och ditt övervakningssystem. CPU-kvoter kanske inte tillämpas på det sätt som du förväntar dig.
Felsökning
Poddar kraschar och klagar på att KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT must be defined
Fullständigt undantagsmeddelande:
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()
- Kontrollera att
KUBERNETES_SERVICE_HOST
variablerna ochKUBERNETES_SERVICE_PORT
miljövariablerna har angetts i podden. Du kan kontrollera genom att köra följande kommandokubectl exec -it <pod_name> /bin/bash -c env
. - Se till att värdet
automountServiceAccountToken
är sant på kubernetesdeployment.yaml
. Mer information finns i Konfigurera tjänstkonton för poddar