演習 - Kubernetes を使用してインフラストラクチャの回復性を実装する
前のユニットでは、.NET ネイティブの回復性拡張機能を使用してエラー処理コードを追加することで、回復性を実装しました。 ただし、この変更は、変更したサービスにのみ適用されます。 多くのサービスを使用して大規模なアプリを更新することは、問題のないものになります。
このユニットでは、 コードベースの 回復性を使用する代わりに、アプリ全体にまたがる インフラストラクチャ ベースの 回復性と呼ばれるアプローチを使用します。 あなたは次のことをする予定です。
- 回復性なしでアプリを Kubernetes に再デプロイします。
- Linkerd を Kubernetes クラスターにデプロイします。
- 回復性のために Linkerd を使用するようにアプリを構成します。
- Linkerd を使用してアプリの動作を調べる。
アプリを再デプロイする
Linkerd を適用する前に、コード ベースの回復性が追加される前の状態にアプリを戻します。 元に戻すには、次の手順に従います。
下部のパネルで、[ ターミナル ] タブを選択し、次の git コマンドを実行して変更を元に戻します。
cd Store git checkout Program.cs git checkout Store.csproj cd .. dotnet publish /p:PublishProfile=DefaultContainer
Kubernetes のインストール
コードスペースに Kubernetes と k3d をインストールします。 k3d は、ローカル コンピューター上の仮想マシン (VM) 内で単一ノード Kubernetes クラスターを実行するツールです。 Kubernetes デプロイをローカルでテストし、コードスペース内で適切に実行する場合に便利です。
次のコマンドを実行して、Kubernetes と MiniKube をインストールします。
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | sudo gpg --dearmor -o /etc/apt/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.28/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubectl
curl -s https://raw.githubusercontent.com/k3d-io/k3d/main/install.sh | bash
k3d cluster create devcluster --config k3d.yml
Docker Hub に eShop サービスをデプロイする
Kubernetes にデプロイするには、ビルドするサービスのローカル イメージをコンテナー レジストリでホストする必要があります。 このユニットでは、コンテナー レジストリとして Docker Hub を使用します。
次のコマンドを実行して、イメージを Docker Hub にプッシュします。
sudo docker login
sudo docker tag products [your username]/productservice
sudo docker tag store [your username]/storeimage
sudo docker push [your username]/productservice
sudo docker push [your username]/storeimage
docker-compose ファイルを Kubernetes マニフェストに変換する
現時点では、Docker でアプリを実行する方法を定義します。 Kubernetes では、アプリの実行方法を定義するために別の形式が使用されます。 Kompose というツールを使用して、docker-compose ファイルを Kubernetes マニフェストに変換できます。
Docker Hub にプッシュしたイメージを使用するには、これらのファイルを編集する必要があります。
コードスペースで、ファイル backend-deploy.ymlを開きます。
次の行を変更します。
containers: - image: [YOUR DOCKER USER NAME]/productservice:latestプレースホルダー [DOCKER ユーザー名] を実際の Docker ユーザー名に置き換えます。
frontend-deploy.yml ファイルに対して次の手順を繰り返します。
次の行を変更します。
containers: - name: storefrontend image: [YOUR DOCKER USER NAME]/storeimage:latestプレースホルダー [DOCKER ユーザー名] を実際の Docker ユーザー名に置き換えます。
eShop アプリを Kubernetes にデプロイします。
kubectl apply -f backend-deploy.yml,frontend-deploy.yml次のメッセージのような出力が表示されます。
deployment.apps/productsbackend created service/productsbackend created deployment.apps/storefrontend created service/storefrontend createdすべてのサービスが実行されていることを確認します。
kubectl get pods次のメッセージのような出力が表示されます。
NAME READY STATUS RESTARTS AGE backend-66f5657758-5gnkw 1/1 Running 0 20s frontend-5c9d8dbf5f-tp456 1/1 Running 0 20s[ ポート ] タブに切り替えて、Kubernetes で実行されている eShop を表示するには、 フロントエンド (32000) ポートの横にある地球アイコンを選択します。
linkerd をインストールする
開発コンテナーには Linkerd CLI をインストールする必要があります。 次のコマンドを実行して、Linkerd の前提条件が満たされていることを確認します。
curl -sL run.linkerd.io/install | sh
export PATH=$PATH:/home/vscode/.linkerd2/bin
linkerd check --pre
次に示す出力の一例が表示されます。
kubernetes-api
--------------
√ can initialize the client
√ can query the Kubernetes API
kubernetes-version
------------------
√ is running the minimum Kubernetes API version
√ is running the minimum kubectl version
pre-kubernetes-setup
--------------------
√ control plane namespace does not already exist
√ can create non-namespaced resources
√ can create ServiceAccounts
√ can create Services
√ can create Deployments
√ can create CronJobs
√ can create ConfigMaps
√ can create Secrets
√ can read Secrets
√ can read extension-apiserver-authentication configmap
√ no clock skew detected
pre-kubernetes-capability
-------------------------
√ has NET_ADMIN capability
√ has NET_RAW capability
linkerd-version
---------------
√ can determine the latest version
√ cli is up-to-date
Status check results are √
Linkerd を Kubernetes にデプロイする
まず、次のコマンドを実行して、カスタム リソース定義 (CRD) をインストールします。
linkerd install --crds | kubectl apply -f -
次に、次のコマンドを実行します。
linkerd install --set proxyInit.runAsRoot=true | kubectl apply -f -
上記のコマンドでは次のことが行われます。
linkerd installは、必要なコントロール プレーン リソースを含む Kubernetes マニフェストを生成します。- 生成されたマニフェストは、kubernetes クラスターにコントロール プレーン リソースをインストールする
kubectl applyにパイプされます。
出力の最初の行は、コントロール プレーンが独自の linkerd 名前空間にインストールされたことを示しています。 残りの出力は、作成されるオブジェクトを表します。
namespace/linkerd created
clusterrole.rbac.authorization.k8s.io/linkerd-linkerd-identity created
clusterrolebinding.rbac.authorization.k8s.io/linkerd-linkerd-identity created
serviceaccount/linkerd-identity created
clusterrole.rbac.authorization.k8s.io/linkerd-linkerd-controller created
Linkerd デプロイを検証する
次のコマンドを実行します。
linkerd check
上記のコマンドは、Linkerd CLI とコントロール プレーンの構成を分析します。 Linkerd が正しく構成されている場合は、次の出力が表示されます。
kubernetes-api
--------------
√ can initialize the client
√ can query the Kubernetes API
kubernetes-version
------------------
√ is running the minimum Kubernetes API version
√ is running the minimum kubectl version
linkerd-existence
-----------------
√ 'linkerd-config' config map exists
√ heartbeat ServiceAccount exist
√ control plane replica sets are ready
√ no unschedulable pods
√ controller pod is running
√ can initialize the client
√ can query the control plane API
linkerd-config
--------------
√ control plane Namespace exists
√ control plane ClusterRoles exist
√ control plane ClusterRoleBindings exist
√ control plane ServiceAccounts exist
√ control plane CustomResourceDefinitions exist
√ control plane MutatingWebhookConfigurations exist
√ control plane ValidatingWebhookConfigurations exist
√ control plane PodSecurityPolicies exist
linkerd-identity
----------------
√ certificate config is valid
√ trust anchors are using supported crypto algorithm
√ trust anchors are within their validity period
√ trust anchors are valid for at least 60 days
√ issuer cert is using supported crypto algorithm
√ issuer cert is within its validity period
√ issuer cert is valid for at least 60 days
√ issuer cert is issued by the trust anchor
linkerd-api
-----------
√ control plane pods are ready
√ control plane self-check
√ [kubernetes] control plane can talk to Kubernetes
√ [prometheus] control plane can talk to Prometheus
√ tap api service is running
linkerd-version
---------------
√ can determine the latest version
√ CLI is up to date
control-plane-version
---------------------
√ control plane is up to date
√ control plane and CLI versions match
linkerd-addons
--------------
√ 'linkerd-config-addons' config map exists
linkerd-grafana
---------------
√ grafana add-on service account exists
√ grafana add-on config map exists
√ grafana pod is running
Status check results are √
ヒント
インストールされた Linkerd コンポーネントの一覧を表示するには、次のコマンドを実行します。 kubectl -n linkerd get deploy
Linkerd を使用するようにアプリを構成する
Linkerd はデプロイされますが、構成されていません。 アプリの動作は変更されません。
Linkerd はサービス内部を認識しないため、失敗した要求を再試行するのが適切かどうかを判断できません。 たとえば、支払いに失敗した HTTP POST を再試行するのは不適切な考えです。 この理由から 、サービス プロファイル が必要です。 サービス プロファイルは、サービスのルートを定義するカスタム Kubernetes リソースです。 また、再試行やタイムアウトなどのルートごとの機能も有効になります。 Linkerd は、サービス プロファイル マニフェストで構成されたルートのみを再試行します。
簡潔にするために、アグリゲーターとクーポン サービスにのみ Linkerd を実装します。 これら 2 つのサービスに Linkerd を実装するには、次の操作を行います。
- Linkerd がポッドにプロキシ コンテナーを作成するように eShop デプロイを変更します。
- クーポン サービスのルートで再試行を構成するには、サービス プロファイル オブジェクトをクラスターに追加します。
eShop の展開を変更する
Linkerd プロキシ コンテナーを使用するようにサービスを構成する必要があります。
テンプレート メタデータの下のbackend-deploy.yml ファイルに
linkerd.io/inject: enabled注釈を追加します。template: metadata: annotations: linkerd.io/inject: enabled labels:linkerd.io/inject: enabled注釈を同じ場所のfrontend-deploy.yml ファイルに追加します。Kubernetes クラスター内のデプロイを更新します。
kubectl apply -f backend-deploy.yml,frontend-deploy.yml
製品サービスの Linkerd サービス プロファイルを適用する
製品サービスのサービス プロファイル マニフェストは次のとおりです。
apiVersion: linkerd.io/v1alpha2
kind: ServiceProfile
metadata:
name: backend
namespace: default
spec:
routes:
- condition:
method: GET
pathRegex: /api/Product
name: GET /v1/products
isRetryable: true
retryBudget:
retryRatio: 0.2
minRetriesPerSecond: 10
ttl: 120s
上記のマニフェストは、次の構成が行われます。
- パターン
/api/Productに一致するべき等の HTTP GET ルートを再試行できます。 - 再試行は、要求の負荷に最大で20%を追加し、さらに毎秒10回の「無料」再試行を上限とします。
Kubernetes クラスターでサービス プロファイルを使用するには、次のコマンドを実行します。
kubectl apply -f - <<EOF
apiVersion: linkerd.io/v1alpha2
kind: ServiceProfile
metadata:
name: backend
namespace: default
spec:
routes:
- condition:
method: GET
pathRegex: /api/Product
name: GET /v1/products
isRetryable: true
retryBudget:
retryRatio: 0.2
minRetriesPerSecond: 10
ttl: 120s
EOF
次のような出力が表示されます。
serviceprofile.linkerd.io/backend created
サービス メッシュに監視をインストールする
Linkerd には、追加の機能を提供する拡張機能があります。 拡張機能をインストールし、Linkerd のダッシュボードでアプリの状態を表示します。
ターミナルで、次のコマンドを実行して拡張機能をインストールします。
linkerd viz install | kubectl apply -f -次のコマンドを使用してダッシュボードを表示します。
linkerd viz dashboard[PORTS] タブに移動して、linkerd viz dashboardプロセスで転送された新しいポートを確認します。 [ ブラウザーで開く ] を選択してダッシュボードを開きます。
Linkerd ダッシュボードで、[ 名前空間] を選択します。
[HTTP メトリック] で、[既定値] を選択 します。

Linkerd の回復性をテストする
再デプロイされたコンテナーが正常な状態になった後、次の手順を使用して、Linkerd でアプリの動作をテストします。
次のコマンドを使用して、実行中のポッドの状態を確認します。
kubectl get pods --all-namespacesすべての製品サービス ポッドを停止します。
kubectl scale deployment productsbackend --replicas=0eShop Web アプリに移動し、製品の表示を試みます。 エラーメッセージ「製品の読み込みに問題があります。後でもう一度やり直してください。」が表示されるまで遅れがあります。
製品サービス ポッドを再起動します。
kubectl scale deployment productsbackend --replicas=1これで、アプリに製品が表示されます。
Linkerd は、コード ベースの回復性で見たものとは異なる回復性のアプローチに従います。 Linkerd は、操作を何度も連続して透過的に再試行しました。 この動作をサポートするために、アプリを変更する必要はありませんでした。
追加情報
Linkerd 構成の詳細については、次のリソースを参照してください。