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 probe、readiness probe、startup probe
Kubernetes はポッドをプローブして、サービスの正常性を判断できます。 詳細については、liveness probe、readiness probe、startup probe の構成に関する Kubernetes のドキュメントを参照してください。
Orleans では、クラスター メンバーシップ プロトコルを使用して、プロセスまたはネットワークの障害を迅速に検出して復旧します。 各ノードは、定期的なプローブを送信して、他のノードのサブセットを監視します。 ノードが他の複数のノードから連続する複数のプローブに応答できない場合、そのノードはクラスターから強制的に削除されます。 障害が発生したノードが削除されたことを確認すると、直ちに終了します。 Kubernetes は終了したプロセスを再起動し、クラスターへの再参加を試みます。
Kubernetes のプローブは、ポッド内のプロセスが実行されていて、ゾンビ状態でスタックしていないかどうかを判断するのに役立ちます。 プローブは、ポッド間接続や応答性を検証したり、アプリケーション レベルの機能チェックを実行したりしません。 ポッドがライブネス プローブに応答できない場合、Kubernetes は最終的にそのポッドを終了し、スケジュールを変更する可能性があります。 したがって、Kubernetes のプローブと Orleans' プローブは補完的です。
推奨される方法は、アプリケーションが意図したとおりに実行されている単純なローカルのみのチェックを実行する Kubernetes で Liveness 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
を実行して確認できます。automountServiceAccountToken
が で true に設定されていることを Kubernetesdeployment.yaml
で確認します。 詳細については、「ポッド のサービス アカウントの構成」を参照してください。
.NET