使用服务网格助力微服务部署与流量管理
1. 虚拟服务与目标规则
虚拟服务的模板中, range 指令会遍历 virtualServices 变量中定义的元素。在清单的 spec 部分, hosts 字段用于指定该虚拟服务将应用到的 Kubernetes 服务名称。在 http 部分,声明了三个路由目标:
- 一条路由匹配金丝雀测试用户的 HTTP 头 X-group ,设置为 test ,此路由始终将请求发送到新子集。
- 一条路由目标指向旧子集,另一条指向新子集。
- 权重以百分比形式指定,且权重总和始终为 100。初始时,所有流量都路由到旧子集。
为了基于 HTTP 头路由将金丝雀测试用户路由到新版本, product-composite 微服务已更新以转发 X-group HTTP 头。
目标规则复用了之前引入的模板,用于指定微服务的版本。例如,产品微服务的目标规则声明如下:
destinationRules:
- ...
- name: product
subsets:
- labels:
version: v1
name: old
- labels:
version: v2
name: new
这表明发送到旧子集的流量将定向到产品微服务的 v1 Pod,而发送到新子集的流量将定向到 v2 Pod。
2. 部署与服务调整
为了让目标规则能够根据 Pod 的标签识别其版本,在通用 Helm 图表的部署模板 _deployment.yaml 中添加了版本标签:
version: {{ .Values.image.tag }}
在 prod-env 图表中,为了让 Pod 及其部署对象的名称包含版本信息,在 values.yaml 文件中使用 fullnameOverride 字段指定包含版本信息的名称,例如:
product:
fullnameOverride: product-v1
recommendation:
fullnameOverride: recommendation-v1
review:
fullnameOverride: review-v1
不过,这会导致对应的服务对象名称也包含版本信息。为避免此问题,通用 Helm 图表中的服务模板 _service.yaml 进行了更新,使用 common.name 模板替代之前的 common.fullname 模板。
为了能够部署三个核心微服务的多个版本,在 kubernetes/helm/components 文件夹中复制了它们的 Helm 图表,并在新图表名称后添加 -green 后缀。新图表与现有图表的唯一区别是不包含通用图表中的服务模板,避免为每个核心微服务创建两个服务对象。新图表名称分别为 product-green 、 recommendation-green 和 review-green 。
3. prod-env Helm 图表整合
prod-env Helm 图表包含通用 Helm 图表中的 _istio_vs_green_blue_deploy.yaml 模板以及 dev-env 图表包含的模板。三个新的 *-green Helm 图表作为依赖添加到 Chart.yaml 文件中。
在 values.yaml 文件中,将所有内容整合在一起。v1 版本的核心微服务定义包含版本信息,v2 版本使用新的 *-green Helm 图表,除名称和 Docker 镜像标签外,其他值与 v1 版本相同。例如,产品微服务 v2 版本的配置如下:
product-green:
fullnameOverride: product-v2
image:
tag: v2
为三个核心微服务声明虚拟服务的方式如下:
virtualServices:
- product
- recommendation
- review
4. 部署 v1 和 v2 版本的微服务
为了测试微服务的 v1 和 v2 版本,需要移除之前的开发环境并创建生产环境。具体步骤如下:
1. 卸载开发环境:
helm uninstall hands-on-dev-env
- 监控开发环境中 Pod 的终止情况,直到
kubectl get pods报告No resources found in hands-on namespace。 - 在 Kubernetes 外部启动 MySQL、MongoDB 和 RabbitMQ:
eval $(minikube docker-env)
docker-compose up -d mongodb mysql rabbitmq
- 为 Docker 镜像添加 v1 和 v2 版本标签:
docker tag hands-on/auth-server hands-on/auth-server:v1
docker tag hands-on/product-composite-service hands-on/product-composite-service:v1
docker tag hands-on/product-service hands-on/product-service:v1
docker tag hands-on/recommendation-service hands-on/recommendation-service:v1
docker tag hands-on/review-service hands-on/review-service:v1
docker tag hands-on/product-service hands-on/product-service:v2
docker tag hands-on/recommendation-service hands-on/recommendation-service:v2
docker tag hands-on/review-service hands-on/review-service:v2
- 使用 Helm 部署系统并等待所有部署完成:
helm install hands-on-prod-env \
kubernetes/helm/environments/prod-env \
-n hands-on --wait
- 部署完成后,使用
kubectl get pods验证三个核心微服务的 v1 和 v2 Pod 是否正常运行。 - 运行常规测试验证一切是否正常:
./test-em-all.bash
初始时,测试可能会失败,错误信息如 Response Body: Jwks doesn't have key to match kid or alg from Jwt ,这是由于 Istio 守护进程 istiod 缓存了开发环境中认证服务器的 JWKS 公钥。等待一段时间(最多一分钟),刷新后的密钥传播完成后,再次运行测试应该可以成功。如果测试仍然失败,简单重新运行命令通常可以解决问题。
5. 验证初始流量路由
为了验证所有请求是否都路由到微服务的 v1 版本,需要启动负载测试工具 siege ,并使用 Kiali 观察服务网格中的流量。具体步骤如下:
1. 获取新的访问令牌并启动 siege 负载测试工具:
ACCESS_TOKEN=$(curl https://writer:secret-writer@minikube.me/oauth2/token \
-d grant_type=client_credentials -d scope="product:read product:write" \
-ks | jq .access_token -r)
echo ACCESS_TOKEN=$ACCESS_TOKEN
siege https://minikube.me/product-composite/1 -H "Authorization: Bearer $ACCESS_TOKEN" -c1 -d1 -v
- 访问 Kiali 的 Web UI(https://kiali.minikube.me):
- 点击
Display菜单按钮,选择Namespace Boxes。 - 点击
App graph菜单按钮,选择Versioned app graph。 - 预期只会看到流量流向微服务的 v1 版本。
- 点击
6. 运行金丝雀测试
为了进行金丝雀测试,让部分用户路由到新版本,而其他用户仍路由到旧版本,需要在发送到外部 API 的请求中添加 X-group HTTP 头并设置为 test 。
可以通过检查响应中的 serviceAddresses 字段来查看是哪个版本的微服务处理了请求。具体步骤如下:
1. 发送正常请求,验证是否是 v1 版本的微服务响应:
ACCESS_TOKEN=$(curl https://writer:secret-writer@minikube.me/oauth2/token \
-d grant_type=client_credentials -d scope="product:read product:write" \
-ks | jq .access_token -r)
echo ACCESS_TOKEN=$ACCESS_TOKEN
curl -ks https://minikube.me/product-composite/1 -H "Authorization: Bearer $ACCESS_TOKEN" | jq .serviceAddresses
预期响应显示所有三个核心服务都是 v1 版本。
- 发送带有
X-group: test头的请求,验证是否是 v2 版本的微服务响应:
curl -ks https://minikube.me/product-composite/1 -H "Authorization: Bearer $ACCESS_TOKEN" -H "X-group: test" | jq .serviceAddresses
预期响应显示所有三个核心微服务都是 v2 版本。
7. 蓝绿部署
为了将部分普通用户路由到微服务的新 v2 版本,需要修改虚拟服务中的权重分布。可以通过编辑虚拟服务的清单文件并执行 kubectl apply 命令,或者使用 kubectl patch 命令直接在 Kubernetes API 服务器上更改虚拟服务对象的权重分布。
7.1 kubectl patch 命令简介
kubectl patch 命令可用于更新 Kubernetes API 服务器中现有对象的特定字段。以 review 微服务的虚拟服务为例,其相关部分定义如下:
spec:
http:
- match:
...
- route:
- destination:
host: review
subset: old
weight: 100
- destination:
host: review
subset: new
weight: 0
一个更改 review 微服务路由到 v1 和 v2 Pod 权重分布的示例 patch 命令如下:
kubectl patch virtualservice review --type=json -p='[
{"op": "add", "path": "/spec/http/1/route/0/weight", "value": 80},
{"op": "add", "path": "/spec/http/1/route/1/weight", "value": 20}
]'
此命令将配置 review 微服务的路由规则,使 80% 的请求路由到旧版本,20% 的请求路由到新版本。
7.2 执行蓝绿部署
执行蓝绿部署的步骤如下:
1. 确保负载测试工具 siege 仍在运行。
2. 使用 kubectl patch 命令将 20% 的用户路由到 review 微服务的新 v2 版本:
kubectl patch virtualservice review --type=json -p='[
{"op": "add", "path": "/spec/http/1/route/0/weight", "value": 80},
{"op": "add", "path": "/spec/http/1/route/1/weight", "value": 20}
]'
- 访问 Kiali 的 Web UI(https://kiali.minikube.me),选择
Graph视图。 - 点击
Display菜单,将边标签更改为Traffic Distribution。 - 等待一分钟,让 Kiali 更新指标,观察路由规则的变化。预期 Kiali 图表显示 80% 的流量流向 v1 服务,20% 的流量流向 v2 服务。
也可以使用 ./kubernetes/routing-tests/split-traffic-between-old-and-new-services.bash 脚本简化更改所有三个核心微服务的权重分布。例如,将所有流量路由到所有微服务的 v2 版本:
./kubernetes/routing-tests/split-traffic-between-old-and-new-services.bash 0 100
Kiali 需要一到两分钟收集指标才能可视化路由变化,但实际路由变化是即时的。
通过以上步骤,可以实现微服务的零停机部署、金丝雀测试和蓝绿部署,有效管理微服务的流量和版本。
使用服务网格助力微服务部署与流量管理
8. 蓝绿部署的深入分析与拓展
在进行蓝绿部署时,除了使用 kubectl patch 命令和脚本调整权重分布外,还需要深入理解其背后的原理和可能遇到的问题。
8.1 权重分布的影响
权重分布的调整直接影响着流量在不同版本微服务之间的分配。例如,当将 review 微服务的权重调整为 80% 到 v1 版本,20% 到 v2 版本时,实际的流量分配可能会因为网络延迟、服务响应时间等因素而略有偏差。以下是一个简单的表格展示不同权重分布下的预期流量分配:
| 旧版本权重 | 新版本权重 | 预期旧版本流量比例 | 预期新版本流量比例 |
| — | — | — | — |
| 100 | 0 | 100% | 0% |
| 80 | 20 | 80% | 20% |
| 50 | 50 | 50% | 50% |
| 20 | 80 | 20% | 80% |
| 0 | 100 | 0% | 100% |
8.2 可能遇到的问题及解决方法
在蓝绿部署过程中,可能会遇到一些问题,如服务响应时间变长、部分请求失败等。这些问题可能是由于新版本微服务的性能问题、配置错误或网络问题引起的。以下是一些常见问题及解决方法:
| 问题描述 | 可能原因 | 解决方法 |
| — | — | — |
| 服务响应时间变长 | 新版本微服务性能不佳 | 检查新版本代码,进行性能优化;增加资源分配 |
| 部分请求失败 | 配置错误或网络问题 | 检查虚拟服务和目标规则的配置;检查网络连接 |
| 流量分配与预期不符 | 网络延迟、服务响应时间差异 | 等待一段时间,让流量分配趋于稳定;调整权重分布 |
9. 金丝雀测试的优化
金丝雀测试是一种在生产环境中对新版本进行小规模测试的方法,可以有效降低新版本上线的风险。为了提高金丝雀测试的效果,可以从以下几个方面进行优化:
9.1 测试用户的选择
选择合适的测试用户是金丝雀测试的关键。可以根据用户的特征、行为习惯等因素进行分组,选择一部分具有代表性的用户作为测试用户。例如,可以选择新用户、活跃用户或特定地区的用户进行测试。
9.2 测试指标的定义
明确测试指标可以帮助我们更好地评估新版本的性能和稳定性。常见的测试指标包括响应时间、吞吐量、错误率等。在测试过程中,需要实时监控这些指标,并与旧版本进行对比。
9.3 自动化测试
自动化测试可以提高测试效率和准确性。可以使用自动化测试工具,如 JMeter、Gatling 等,对新版本进行压力测试、功能测试等。以下是一个使用 JMeter 进行压力测试的简单流程图:
graph LR
A[启动 JMeter] --> B[配置测试计划]
B --> C[添加线程组]
C --> D[设置线程数、循环次数等参数]
D --> E[添加 HTTP 请求]
E --> F[设置请求 URL、请求方法等参数]
F --> G[添加监听器]
G --> H[运行测试]
H --> I[查看测试结果]
10. 服务网格的监控与可视化
服务网格提供了强大的监控和可视化功能,可以帮助我们实时了解微服务的运行状态和流量情况。
10.1 Kiali 的使用
Kiali 是一个用于可视化和监控 Istio 服务网格的工具。通过 Kiali 的 Web UI,我们可以直观地看到微服务之间的调用关系、流量分布等信息。在进行蓝绿部署和金丝雀测试时,可以使用 Kiali 来验证流量是否按照预期进行分配。
10.2 其他监控工具
除了 Kiali 外,还可以使用其他监控工具,如 Prometheus、Grafana 等,对微服务进行更详细的监控。Prometheus 可以收集微服务的各种指标,如 CPU 使用率、内存使用率、请求响应时间等;Grafana 可以将这些指标以图表的形式进行展示,方便我们进行分析和决策。
11. 总结与最佳实践
通过以上的介绍,我们了解了如何使用服务网格进行微服务的部署、金丝雀测试和蓝绿部署,以及如何进行监控和可视化。以下是一些最佳实践总结:
1. 版本管理 :在部署微服务时,使用版本标签来区分不同版本的微服务,方便进行管理和切换。
2. 流量管理 :使用虚拟服务和目标规则来控制流量在不同版本微服务之间的分配,实现零停机部署和金丝雀测试。
3. 监控与可视化 :使用 Kiali、Prometheus、Grafana 等工具对微服务进行实时监控和可视化,及时发现和解决问题。
4. 自动化测试 :使用自动化测试工具对新版本进行全面测试,提高测试效率和准确性。
5. 故障处理 :在部署和测试过程中,可能会遇到各种问题,需要建立完善的故障处理机制,及时响应和解决问题。
通过遵循这些最佳实践,可以有效提高微服务的部署效率、稳定性和可维护性,为企业的数字化转型提供有力支持。
超级会员免费看
63

被折叠的 条评论
为什么被折叠?



