Kubernetes是托管Orleans应用程序的一个流行选择。 Orleans将在Kubernetes中运行,不需要特定的配置,它也可以利用托管平台可以提供的额外信息。
Microsoft.Orleans.Hosting.Kubernetes包增加了在Kubernetes集群中托管Orleans应用程序的集成。该包提供了一个扩展方法,ISiloBuilder.UseKubernetesHosting,它可以执行以下操作:
SiloOptions.SiloName设置为Pod名称EndpointOptions.AdvertisedIPAddress设置为Pod的IPEndpointOptions.SiloListeningEndpoint与EndpointOptions.GatewayListeningEndpoint配置为监听任意地址,各自的端口号通过SiloPort与GatewayPort配置。如果没有显式指定端口号,则默认为11111和30000ClusterOptions.ServiceId设置为名为orleans/serviceId的pod标签的值。ClusterOptions.ClusterId设置为名为orleans/clusterId的pod标签的值。- 在启动过程的初期,Silo将探测Kubernetes,以发现哪些Silo没有相应的pod,并将这些Silo标记为死亡。
- 同样的过程将在运行时发生在所有Silo的一个子集上,以消除Kubernetes的API服务器的负载。默认情况下,集群中的2个Silo将用于监视Kubernetes。
注意,Kubernetes托管包并不使用Kubernetes进行集群化。对于集群化,仍然需要一个单独的集群提供者。关于配置集群的更多信息,请参阅服务器配置。
这种功能对服务的部署方式提出了一些要求:
- Silo名称必须匹配Pod名称.
- Pod必须有
orleans/serviceId和orleans/clusterId标签,与Silo的ServiceId和ClusterId对应。上述方法将把这些标签传播到Orleans环境变量的相应选项中。 - Pods必须设置以下环境变量:
POD_NAME、POD_NAMESPACE、POD_IP、ORLEANS_SERVICE_ID、ORLEANS_CLUSTER_ID。
下面的例子展示了如何正确配置这些标签和环境变量:
apiVersion: apps/v1kind: Deploymentmetadata:name: dictionary-applabels:orleans/serviceId: dictionary-appspec:selector:matchLabels:orleans/serviceId: dictionary-appreplicas: 3template:metadata:labels:# This label is used to identify the service to Orleansorleans/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-appspec:containers:- name: mainimage: my-registry.azurecr.io/my-imageimagePullPolicy: Alwaysports:# Define the ports which Orleans uses- containerPort: 11111- containerPort: 30000env:# 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_STRINGvalueFrom:secretKeyRef:name: az-storage-acctkey: key# Configure settings to let Orleans know which cluster it belongs to# and which pod it is running in- name: ORLEANS_SERVICE_IDvalueFrom:fieldRef:fieldPath: metadata.labels['orleans/serviceId']- name: ORLEANS_CLUSTER_IDvalueFrom:fieldRef:fieldPath: metadata.labels['orleans/clusterId']- name: POD_NAMESPACEvalueFrom:fieldRef:fieldPath: metadata.namespace- name: POD_NAMEvalueFrom:fieldRef:fieldPath: metadata.name- name: POD_IPvalueFrom:fieldRef:fieldPath: status.podIP- name: DOTNET_SHUTDOWNTIMEOUTSECONDSvalue: "120"request:# Set resource requeststerminationGracePeriodSeconds: 180imagePullSecrets:- name: my-image-pull-secretminReadySeconds: 60strategy:rollingUpdate:maxUnavailable: 0maxSurge: 1
对于支持RBAC的集群,Kubernetes服务账户的pod可能也需要被授予所需的权限:
kind: RoleapiVersion: rbac.authorization.k8s.io/v1metadata:name: pod-readerrules:- apiGroups: [ "" ]resources: ["pods"]verbs: ["get", "watch", "list"]---kind: RoleBindingapiVersion: rbac.authorization.k8s.io/v1metadata:name: pod-reader-bindingsubjects:- kind: ServiceAccountname: defaultapiGroup: ''roleRef:kind: Rolename: pod-readerapiGroup: ''
存活、就绪和启动探测器
Kubernetes能够探测Pod以确定服务的健康情况。更多信息,参见Kubernetes文档的配置存活、就绪和启动探测器。
Orleans使用集群成员协议来及时检测和恢复进程或网络故障。 每个节点监控其他节点的一个子集,定期发送探测器。 如果一个节点未能对来自其他多个节点的连续探测作出反应,那么它将被强行从集群中移除。 一旦一个故障的节点得知自己被移除,它就会立即终止工作。 Kubernetes将重新启动被终止的进程,它将试图重新加入集群。
Kubernetes的探测器可以帮助确定一个pod中的进程是否在执行,而不是停留在僵尸状态。探测器不会验证pod间的连接性或响应性,也不会执行任何应用层面的功能检查。 如果一个pod未能响应一个有效性探测器,那么Kubernetes最终可能会终止该pod并重新调度它。 因此,Kubernetes的探测器和Orleans的探测器是互补的。
推荐的方法是在Kubernetes中配置存活探测器,它只执行简单的本地检查,以确保应用程序按预期执行。 这些探测器的作用是在出现完全冻结的情况下终止进程,例如由于运行时故障或其他小概率事件。
资源配额
Kubernetes与操作系统一起工作,实现资源配额。 这允许CPU和内存保留和/或限制被强制执行。 对于一个为交互式负载服务的主要应用,我们建议除非必要,否则不要实施限制性的上限。 需要注意的是,请求和限制在其含义和实施方式上有很大不同。 在设置请求或限制之前,要花时间详细了解它们是如何实现和执行的。 例如,Kubernetes、Linux内核和你的监控系统之间可能不会统一测量内存。CPU配额可能不会以你期望的方式执行。
故障诊断
Pods崩溃,报错信息为: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 definedat k8s.KubernetesClientConfiguration.InClusterConfig()
- 检查
KUBERNETES_SERVICE_HOST和KUBERNETES_SERVICE_PORT环境变量是否已在你的Pod内设置。你可以通过执行以下命令来检查kubectl exec -it <pod_name> /bin/bash -c env。 - 确保在你的Kubernetes
deployment.yaml上将automountServiceAccountToken设置为true。欲了解更多信息,请参阅为Pod配置服务账户。
