次の方法で共有


Kubernetes ホスティング

Kubernetes は、Orleans アプリケーションをホストするための一般的な選択肢です。 Orleans は、特定の構成なしで Kubernetes で実行されますが、ホスティング プラットフォームによる提供が可能な追加の知識を利用することもできます。

Microsoft.Orleans.Hosting.Kubernetes パッケージは、Kubernetes クラスターで Orleans アプリケーションをホストするための統合を追加します。 このパッケージには、次のアクションを実行する拡張メソッドである、UseKubernetesHosting が用意されています。

  • SiloOptions.SiloName がポッド名に設定されます。
  • EndpointOptions.AdvertisedIPAddress がポッド IP に設定されます。
  • EndpointOptions.SiloListeningEndpointEndpointOptions.GatewayListeningEndpoint は、構成された SiloPortGatewayPort を使用して任意のアドレスでリッスンするように構成されます。 値が明示的に設定されていない場合は、既定のポート値 1111130000 が使用されます。
  • ClusterOptions.ServiceId は、orleans/serviceId という名前のポッド ラベルの値に設定されます。
  • ClusterOptions.ClusterId は、orleans/clusterId という名前のポッド ラベルの値に設定されます。
  • スタートアップ プロセスの早い段階で、サイロは Kubernetes をプローブして、対応するポッドがないサイロを見つけ、それらのサイロを非稼働としてマークします。
  • Kubernetes の API サーバーの負荷を取り除くために、すべてのサイロのサブセットに対して実行時に同じプロセスが発生します。 既定では、クラスター内の 2 つのサイロが Kubernetes を監視します。

Kubernetes ホスティング パッケージでは、クラスタリングに Kubernetes が使用されないことに注意してください。 クラスタリングには、別のクラスタリング プロバイダーが引き続き必要です。 クラスタリングの構成の詳細については、「サーバー構成」のドキュメントを参照してください。

この機能により、サービスのデプロイ方法にいくつかの要件が課されます。

  • サイロ名はポッド名と一致する必要があります。
  • ポッドには、サイロの ServiceIdClusterId に対応する orleans/serviceIdorleans/clusterId のラベルが必要です。 上記のメソッドは、これらのラベルを環境変数から Orleans の対応するオプションに伝達します。
  • ポッドには以下の環境変数が設定されている必要があります: POD_NAMEPOD_NAMESPACEPOD_IP, ORLEANS_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 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

RBAC が有効なクラスターの場合、ポッドの 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: ''

liveness、readiness、startup の probe

Kubernetes はポッドをプローブして、サービスの正常性を判断できます。 詳細については、liveness probe、readiness probe、startup probe の構成に関する Kubernetes のドキュメントを参照してください。

Orleans では、クラスター メンバーシップ プロトコルを使用して、プロセスまたはネットワークの障害を迅速に検出して復旧します。 各ノードは、他のノードのサブセットを監視し、定期的な probe を送信します。 ノードは、他の複数のノードからの連続する複数の probe に応答できなかった場合、クラスターから強制的に削除されます。 障害が発生したノードは、削除されたことを認識すると、直ちに終了します。 Kubernetes は終了したプロセスを再起動し、クラスターへの再参加を試みます。

Kubernetes での probe は、ポッド内のプロセスが実行されているか、ゾンビ状態でスタックしていないかを判断するのに役立ちます。 probe は、ポッド間の接続や応答性を検証したり、アプリケーション レベルの機能チェックを実行したりしません。 ポッドが liveness probe に応答しない場合、Kubernetes は最終的にそのポッドを終了し、再スケジュールする可能性があります。 したがって、Kubernetes の probe と Orleans の probe は補完的です。

推奨されるアプローチは、Kubernetes で Liveness Probe を構成し、アプリケーションが意図したとおりに実行されているかどうかの単純なローカルのみのチェックを実行することです。 これらの probe は、たとえばランタイム エラーやその他の予期しないイベントによって完全なフリーズが発生した場合に、プロセスを終了するために機能します。

リソース クォータ

Kubernetes は、オペレーティング システムと連携してリソース クォータを実装します。 これにより、CPU とメモリの予約や制限を適用できます。 対話型の負荷を処理するプライマリ アプリケーションの場合は、必要な場合を除き、制約の大きい制限を実装しないことをお勧めします。 要求と制限は、その意味と実装される場所が大幅に異なるという点に注意することが重要です。 要求または制限を設定する前に、時間をかけて、それらがどのように実装および適用されるかを詳細に理解してください。 たとえば、Kubernetes、Linux カーネル、監視システムの間でメモリを一様に測定できない場合があります。 CPU クォータは、想定した方法では適用されない場合があります。

トラブルシューティング

ポッドがクラッシュし、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()
  • KUBERNETES_SERVICE_HOST および KUBERNETES_SERVICE_PORT 環境変数がポッド内に設定されていることを確認します。 確認するには、次のコマンドを実行します: kubectl exec -it <pod_name> /bin/bash -c env
  • Kubernetes の deployment.yamlautomountServiceAccountTokentrue に設定されていることを確認します。 詳細については、「ポッドのサービス アカウントを構成する」を参照してください。