Kubernetes 托管

Kubernetes 是托管 Orleans 应用程序的常用选择。 Orleans 在没有特定配置的情况下在 Kubernetes 中运行;但是,它还可以利用托管平台提供的额外知识。

Microsoft.Orleans.Hosting.Kubernetes 包添加了集成,用于在 Kubernetes 群集中托管 Orleans 应用程序。 该包提供了一个扩展方法,UseKubernetesHosting执行以下操作:

请注意,Kubernetes 托管包不使用 Kubernetes 进行群集。 仍然需要单独的群集提供程序。 有关配置群集的详细信息,请参阅 服务器配置 文档。

此功能对服务部署施加了一些要求:

  • 接收器名称必须与 Pod 名称匹配。
  • Pod 必须具有与筒仓的ServiceIdClusterId对应的orleans/serviceIdorleans/clusterId标签。 该方法 UseKubernetesHosting 将这些标签从环境变量传播到相应的 Orleans 选项中。
  • Pod 必须设置以下环境变量:POD_NAMEPOD_NAMESPACEPOD_IPORLEANS_SERVICE_IDORLEANS_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 identifies the service to Orleans
        orleans/serviceId: dictionary-app

        # This label identifies an instance of a cluster to Orleans.
        # Typically, this is the same value as the previous label, or any
        # fixed value.
        # In cases where you don't use rolling deployments (for example,
        # blue/green deployments),
        # this value can allow for distinct clusters that don't communicate
        # directly with each other,
        # but 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 Orleans uses
          - containerPort: 11111
          - containerPort: 30000
          env:
          # The Azure Storage connection string for clustering is injected as an
          # environment variable.
          # You must create it 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's 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 的群集,可能还需要授予对 Pod 的 Kubernetes 服务帐户所需的访问权限:

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 文档中的 配置 Liveness、Readiness 和 Startup Probes

Orleans 使用群集成员身份协议来及时检测和恢复进程或网络故障。 每个节点监视其他节点的子集,同时定期发送探测信号。 如果节点无法响应来自多个其他节点的多个连续探测,则群集强行删除它。 失败的节点得知其删除后,会立即终止。 Kubernetes 重启终止的进程,然后尝试重新加入群集。

Kubernetes 探针有助于确定 Pod 中的进程是否正在正常执行,并且未停滞在僵尸状态。 这些探测不会验证 Pod 间连接性或响应能力,也不执行应用程序级功能检查。 如果 Pod 无法响应存活探针,Kubernetes 最终可能会终止该 Pod 并重新调度它。 因此,Kubernetes 探测和 Orleans 探测是互补的。

建议的方法是在 Kubernetes 中配置 Liveness Probe,以执行简单的本地检查,确保应用程序按预期运行。 当进程完全冻结时,例如由于运行时故障或其他不太可能发生的事件,这些探测器可用于终止进程。

资源配额

Kubernetes 与操作系统一起工作来实现 资源配额。 这允许强制实施 CPU 和内存预留和/或限制。 对于提供交互式负载的主应用程序,除非有必要,否则不建议实施限制性限制。 请务必注意,请求和限制在含义和实现位置上有很大的不同。 在设置请求或限制之前,请花些时间来详细了解如何实施和强制执行请求。 例如,在 Kubernetes、Linux 内核和监视系统之间可能无法统一测量内存。 可能无法按预期强制实施 CPU 配额。

故障 排除

Pod 崩溃,报错 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()
  • 请检查是否在 Pod 中设置了 KUBERNETES_SERVICE_HOSTKUBERNETES_SERVICE_PORT 环境变量。 通过执行命令 kubectl exec -it <pod_name> /bin/bash -c env进行检查。
  • 请确保在 Kubernetes deployment.yaml 中将 automountServiceAccountToken 设置为 true。 有关详细信息,请参阅为 Pod 配置服务帐户