练习 - 使用 Kubernetes 实现基础结构复原
在上一单元中,通过使用 .NET 本机复原扩展添加故障处理代码来实现复原能力。 但是,此更改仅适用于已更改的服务。 更新一个有许多服务的大型应用将是不简单的。
本单元不使用 基于代码 的复原能力,而是使用一种称为 基于基础结构 的复原方法,用于跨整个应用。 你的职责将是:
- 将没有任何复原能力的应用重新部署到 Kubernetes。
- 在 Kubernetes 群集中部署 Linkerd。
- 配置应用以使用 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
将 eShop 服务部署到 Docker 中心
生成的服务的本地映像需要托管在容器注册表中才能部署到 Kubernetes 中。 在本单元中,你将使用 Docker Hub 作为容器注册表。
运行以下命令,将映像推送到 Docker 中心:
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 的映像。
在 codespace 中,打开文件 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 清单。- 生成的清单通过管道传输到
kubectl apply
,用于在 Kubernetes 群集中安装这些控制平面资源。
输出的第一行显示控制平面已安装在其自己的 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。 若要为这两个服务实现 Linkerd,需要:
- 修改 eShop 部署,以便 Linkerd 在 Pod 中创建其代理容器。
- 要在优惠券服务的路由上配置重试操作,请将服务配置文件对象添加到群集。
修改 eShop 部署
必须将服务配置为使用 Linkerd 代理容器。
将
linkerd.io/inject: enabled
批注添加到模板元数据下的 backend-deploy.yml 文件中。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 具有扩展,可提供额外的功能。 安装 viz 扩展并在 Linkerd 的仪表板中查看应用的状态。
在终端中,运行以下命令以安装扩展:
linkerd viz install | kubectl apply -f -
使用以下命令查看仪表板:
linkerd viz dashboard
转到“端口”选项卡,可看到一个新端口,该端口已通过正在运行的“linkerd viz 仪表板”进程进行转发。 选择 “在浏览器中打开 ”以打开仪表板。
在 Linkerd 仪表板中,选择 “命名空间”。
在“HTTP 指标”下,选择 默认值。
测试 Linkerd 复原能力
重新部署的容器正常运行后,使用以下步骤通过 Linkerd 测试应用的行为:
使用以下命令检查正在运行的 Pod 的状态:
kubectl get pods --all-namespaces
停止所有产品和服务 Pod:
kubectl scale deployment productsbackend --replicas=0
转到 eShop Web 应用并尝试查看产品。 出现延迟,直到出现错误消息, “加载产品时出现问题。请稍后重试。
重启产品服务 Pod:
kubectl scale deployment productsbackend --replicas=1
应用现在应显示产品。
Linkerd 采用的复原方法与基于代码的复原所采用的方法不同。 Linkerd 透明地连续多次快速重试该操作。 无需更改应用以支持此行为。
其他信息
有关 Linkerd 配置的详细信息,请参阅以下资源: