Kubernetes ホスティング
Kubernetes は、Orleans アプリケーションをホストするための一般的な選択肢です。 Orleans は、特定の構成なしで Kubernetes で実行されますが、ホスティング プラットフォームによる提供が可能な追加の知識を利用することもできます。
Microsoft.Orleans.Hosting.Kubernetes
パッケージは、Kubernetes クラスターで Orleans アプリケーションをホストするための統合を追加します。 このパッケージには、次のアクションを実行する拡張メソッドである、UseKubernetesHosting が用意されています。
- SiloOptions.SiloName がポッド名に設定されます。
- EndpointOptions.AdvertisedIPAddress がポッド IP に設定されます。
- EndpointOptions.SiloListeningEndpoint と EndpointOptions.GatewayListeningEndpoint は、構成された SiloPort と GatewayPort を使用して任意のアドレスでリッスンするように構成されます。 値が明示的に設定されていない場合は、既定のポート値
11111
と30000
が使用されます。 - ClusterOptions.ServiceId は、
orleans/serviceId
という名前のポッド ラベルの値に設定されます。 - ClusterOptions.ClusterId は、
orleans/clusterId
という名前のポッド ラベルの値に設定されます。 - スタートアップ プロセスの早い段階で、サイロは Kubernetes をプローブして、対応するポッドがないサイロを見つけ、それらのサイロを非稼働としてマークします。
- Kubernetes の API サーバーの負荷を取り除くために、すべてのサイロのサブセットに対して実行時に同じプロセスが発生します。 既定では、クラスター内の 2 つのサイロが Kubernetes を監視します。
Kubernetes ホスティング パッケージでは、クラスタリングに Kubernetes が使用されないことに注意してください。 クラスタリングには、別のクラスタリング プロバイダーが引き続き必要です。 クラスタリングの構成の詳細については、「サーバー構成」のドキュメントを参照してください。
この機能により、サービスのデプロイ方法にいくつかの要件が課されます。
- サイロ名はポッド名と一致する必要があります。
- ポッドには、サイロの
ServiceId
とClusterId
に対応するorleans/serviceId
とorleans/clusterId
のラベルが必要です。 上記のメソッドは、これらのラベルを環境変数から Orleans の対応するオプションに伝達します。 - ポッドには以下の環境変数が設定されている必要があります:
POD_NAME
、POD_NAMESPACE
、POD_IP
,ORLEANS_SERVICE_ID
、ORLEANS_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.yaml
でautomountServiceAccountToken
が true に設定されていることを確認します。 詳細については、「ポッドのサービス アカウントを構成する」を参照してください。
.NET