42、Istio:提升服务网格安全性、弹性与实现零停机更新

Istio:提升服务网格安全性、弹性与实现零停机更新

1. 验证访问令牌与恢复请求
  • 再次发起请求,使用以下命令:
curl -k https://minikube.me/product-composite/1 -H "Authorization: Bearer $ACCESS_TOKEN" -i

该请求应失败,并返回 HTTP 响应状态码 401(未授权)和错误消息 “Jwt issuer is not configured”。由于 Istio 传播更改(发行者的新名称)需要几秒钟时间,可能需要重复执行该命令几次,直到请求失败,这证明 Istio 正在验证访问令牌。
- 将发行者的名称恢复为 http://auth-server ,使用命令:

kubectl edit RequestAuthentication product-composite-request-authentication
  • 验证请求是否再次正常工作。先等待几秒钟让更改传播,然后运行命令:
curl -k https://minikube.me/product-composite/1 -H "Authorization: Bearer $ACCESS_TOKEN"
2. 使用相互认证(mTLS)保护内部通信
2.1 mTLS 简介

使用相互认证时,服务通过出示证书证明其身份,客户端也通过出示客户端证书向服务证明其身份,相比仅证明服务身份的普通 TLS/HTTPS,提供了更高的安全性。但设置和维护相互认证(如为客户端提供新证书和轮换过期证书)很复杂,因此很少使用。而 Istio 能完全自动化服务网格内部通信的相互认证证书的供应和轮换。

2.2 为何使用 mTLS

如果 Kubernetes 集群内的 Pod 被攻破,攻击者可以监听其他 Pod 之间的流量。若内部通信以明文发送,攻击者很容易获取敏感信息。使用相互认证可以防止攻击者窃听内部网络流量,减少此类入侵造成的损害。

2.3 配置 mTLS

要启用 Istio 管理的相互认证,需要在服务器端使用 PeerAuthentication 策略,在客户端使用 DestinationRule 进行配置。
- PeerAuthentication 策略配置在通用 Helm 图表模板 _istio_base.yaml 中,示例如下:

apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
spec:
  mtls:
    mode: PERMISSIVE

该策略配置为允许 mTLS 和普通 HTTP 请求(使用 PERMISSIVE 模式),使 Kubernetes 能够使用普通 HTTP 调用存活和就绪探针。
- DestinationRule 清单的核心部分(要求 mTLS)如下:

trafficPolicy:
  tls:
    mode: ISTIO_MUTUAL
2.4 验证 mTLS 保护

验证内部通信是否受 mTLS 保护的步骤如下:
1. 确保在之前观察服务网格部分启动的负载测试仍在运行,并报告 200(OK)。
2. 在 Web 浏览器中访问 Kiali 图表( https://kiali.minikube.me )。
3. 点击 “Display” 按钮,启用 “Security” 标签。图表将在所有受 Istio 自动相互认证保护的通信链路上显示锁图标。

3. 确保服务网格的弹性
3.1 Istio 弹性机制概述

Istio 提供了类似于 Spring 框架的机制,如超时、重试和一种称为异常检测的断路器,用于处理服务网格中的临时故障。但对 RabbitMQ、MySQL 和 MongoDB 的调用不由 Istio 代理处理,若需要使用 TLS 保护,需手动配置。

在处理临时故障时,使用语言原生机制还是委托给 Istio 这样的服务网格,存在不同情况。在很多情况下,将处理错误的逻辑(如断路器的回退替代方案)与微服务的其他业务逻辑放在一起很重要,将处理临时故障的逻辑放在源代码中也更便于使用 JUnit 和测试容器进行测试。但如果微服务部署后发现无法处理生产中偶尔出现的临时故障,使用 Istio 添加超时或重试机制会很方便,而无需等待微服务的新版本发布。

3.2 通过注入故障测试弹性
  • 故障注入配置 :可以使用虚拟服务 kubernetes/resilience-tests/product-virtual-service-with-faults.yml 注入故障,示例如下:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: product
spec:
  hosts:
    - product
  http:
  - route:
    - destination:
        host: product
    fault:
      abort:
        httpStatus: 500
        percentage:
          value: 20

该定义表示发送到产品服务的请求中有 20% 将以 HTTP 状态码 500(内部服务器错误)中止。
- 测试步骤
1. 确保在观察服务网格部分启动的使用 siege 的负载测试正在运行。
2. 使用以下命令应用故障注入:

kubectl apply -f kubernetes/resilience-tests/product-virtual-service-with-faults.yml
  1. 监控 siege 负载测试工具的输出。所有请求仍应成功(返回状态 200(OK)),但部分请求(20%)会多花一秒完成,这表明产品组合微服务中的重试机制已启动。
  2. 使用以下命令移除故障注入,结束测试:
kubectl delete -f kubernetes/resilience-tests/product-virtual-service-with-faults.yml
3.3 通过注入延迟测试弹性
  • 延迟注入配置 :可以使用虚拟服务 kubernetes/resilience-tests/product-virtual-service-with-delay.yml 注入延迟,示例如下:
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: product
spec:
  hosts:
    - product
  http:
  - route:
    - destination:
        host: product
    fault:
      delay:
        fixedDelay: 3s
        percent: 100

该定义表示发送到产品服务的所有请求将延迟 3 秒。产品组合服务发送到产品服务的请求配置为 2 秒后超时,断路器配置为连续 3 次请求失败时打开,打开后将快速失败(立即抛出异常,不尝试调用底层服务),产品组合微服务的业务逻辑将捕获此异常并应用回退逻辑。
- 测试步骤
1. 在运行 siege 的终端窗口中按 Ctrl + C 停止负载测试。
2. 使用以下命令在产品服务中创建临时延迟:

kubectl apply -f kubernetes/resilience-tests/product-virtual-service-with-delay.yml
  1. 获取访问令牌:
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
  1. 连续发送六个请求:
for i in {1..6}; do time curl -k https://minikube.me/product-composite/1 -H "Authorization: Bearer $ACCESS_TOKEN"; done

预期结果如下:
- 前三次失败调用后,断路器打开。
- 后三次调用,断路器应用快速失败逻辑。
- 后三次调用返回回退响应。
5. 使用以下命令移除临时延迟,模拟延迟问题已解决:

kubectl delete -f kubernetes/resilience-tests/product-virtual-service-with-delay.yml
  1. 使用步骤 4 中的 for 循环命令发送新请求,验证是否再次返回正确答案且无延迟。
4. 实现零停机更新
4.1 零停机更新背景

随着越来越多的自治微服务相互独立更新,能够无停机部署更新变得至关重要。Kubernetes 可以执行滚动升级实现无停机,但无法在将所有用户路由到新版本之前测试新版本。而 Istio 可以部署新版本,但最初将所有用户路由到现有版本,之后使用细粒度路由机制控制用户如何路由到新旧版本。

4.2 升级策略
  • 金丝雀部署 :除一组选定的测试用户被路由到新版本外,所有用户都被路由到旧版本。当测试用户批准新版本后,可以使用蓝绿部署将普通用户路由到新版本。
  • 蓝绿部署 :传统的蓝绿部署是将所有用户切换到蓝色或绿色版本(一个是新版本,另一个是旧版本)。如果切换到新版本时出现问题,很容易切换回旧版本。使用 Istio 可以逐步将用户转移到新版本,例如从 20% 的用户开始,然后慢慢增加百分比。如果新版本中发现致命错误,随时可以将所有用户快速路由回旧版本。
4.3 部署场景
  1. 部署微服务的 v1 和 v2 版本,配置路由将所有请求发送到微服务的 v1 版本。
  2. 允许测试组进行金丝雀测试,验证微服务的新 v2 版本。为简化测试,仅部署核心微服务(产品、推荐和评论微服务)的新版本。
  3. 使用蓝绿部署开始将普通用户转移到新版本,最初是一小部分用户,随着时间推移,越来越多的用户被路由到新版本,直到最终所有用户都被路由到新版本。如果在新 v2 版本中检测到致命错误,可以快速切换回 v1 版本。
4.4 源代码更改

要同时运行微服务的多个版本,Deployment 对象及其对应的 Pod 必须有不同的名称,例如 product-v1 product-v2 ,但每个微服务只能有一个 Kubernetes Service 对象,所有到特定微服务的流量始终通过同一个 Service 对象,无论请求最终将路由到哪个版本的 Pod。使用 Istio 的 VirtualService DestinationRule 对象配置金丝雀测试和蓝绿部署的实际路由规则, prod-env Helm 图表中的 values.yaml 文件用于指定生产环境中每个微服务将使用的版本。

4.5 虚拟服务和目标规则

要在微服务的两个版本之间拆分流量,需要在发送方的虚拟服务中指定两个版本之间的权重分布,虚拟服务将流量分散到两个子集( old new )。接收方的 DestinationRule 定义了 new old 子集的具体含义,它使用标签来确定哪些 Pod 运行微服务的旧版本和新版本。为支持金丝雀测试,虚拟服务中需要一个路由规则,始终将金丝雀测试人员路由到新子集,假设金丝雀测试人员的请求包含名为 X-group 且值为 test 的 HTTP 头。

通用 Helm 图表中添加了一个模板 _istio_vs_green_blue_deploy.yaml 用于创建一组可以在微服务的两个版本之间拆分流量的虚拟服务,示例如下:

{{- define "common.istio_vs_green_blue_deploy" -}}
{{- range $name := .Values.virtualServices }}
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: {{ $name }}
spec:
  hosts:
  - {{ $name }}
  http:
  - match:
    - headers:
        X-group:
          exact: test
    route:
    - destination:
        host: {{ $name }}
        subset: new
  - route:
    - destination:
        host: {{ $name }}
        subset: old
      weight: 100

总结

本文介绍了 Istio 在服务网格中的多个重要功能,包括验证访问令牌、使用 mTLS 保护内部通信、确保服务网格的弹性以及实现零停机更新。通过这些功能,Istio 可以提高服务网格的安全性、可靠性和可管理性,帮助开发者更好地应对微服务架构中的各种挑战。

流程图

graph LR
    A[开始] --> B[验证访问令牌]
    B --> C[使用 mTLS 保护内部通信]
    C --> D[确保服务网格弹性]
    D --> E[实现零停机更新]
    E --> F[结束]

表格

功能 描述
验证访问令牌 通过再次发起请求并验证失败信息,证明 Istio 验证访问令牌
mTLS 保护内部通信 服务和客户端通过证书相互认证,Istio 自动化证书管理
服务网格弹性 通过注入故障和延迟测试重试和断路器机制
零停机更新 使用金丝雀部署和蓝绿部署策略,控制用户路由到新旧版本

5. 详细解析虚拟服务和目标规则

5.1 虚拟服务路由配置详解

在前面提到的虚拟服务模板 _istio_vs_green_blue_deploy.yaml 中,其核心作用是在微服务的不同版本间分配流量。下面详细解析其配置:

{{- define "common.istio_vs_green_blue_deploy" -}}
{{- range $name := .Values.virtualServices }}
apiVersion: networking.istio.io/v1beta1
kind: VirtualService
metadata:
  name: {{ $name }}
spec:
  hosts:
  - {{ $name }}
  http:
  - match:
    - headers:
        X-group:
          exact: test
    route:
    - destination:
        host: {{ $name }}
        subset: new
  - route:
    - destination:
        host: {{ $name }}
        subset: old
      weight: 100
  • hosts 字段 :指定了该虚拟服务所适用的主机名,这里使用 {{ $name }} 动态获取服务名称,意味着该虚拟服务会对指定名称的服务生效。
  • http 部分 :包含了路由规则。
    • 第一个 match 规则 :通过匹配 HTTP 头 X-group 的值为 test ,将符合条件的请求(即来自金丝雀测试人员的请求)路由到 new 子集,也就是新版本的微服务。
    • 第二个 route 规则 :将其他请求(即非金丝雀测试人员的请求)路由到 old 子集,权重为 100,表示目前所有这类请求都会被发送到旧版本的微服务。
5.2 目标规则的作用与配置

目标规则 DestinationRule 用于定义如何处理路由到不同子集的流量。它通过标签来区分不同版本的 Pod。示例如下:

apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
  name: product
spec:
  host: product
  subsets:
  - name: old
    labels:
      version: v1
  - name: new
    labels:
      version: v2
  • host 字段 :指定了目标服务的名称。
  • subsets 部分 :定义了不同的子集。
    • old 子集:通过 labels 中的 version: v1 标签,将带有该标签的 Pod 识别为旧版本的微服务实例。
    • new 子集:同理,通过 labels 中的 version: v2 标签,将带有该标签的 Pod 识别为新版本的微服务实例。

6. 部署与服务配置

6.1 Deployment 对象配置

为了同时运行微服务的不同版本,Deployment 对象需要有不同的名称。以产品微服务为例, product-v1 product-v2 的 Deployment 配置示例如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: product-v1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: product
      version: v1
  template:
    metadata:
      labels:
        app: product
        version: v1
    spec:
      containers:
      - name: product
        image: product-image:v1
        ports:
        - containerPort: 8080
apiVersion: apps/v1
kind: Deployment
metadata:
  name: product-v2
spec:
  replicas: 3
  selector:
    matchLabels:
      app: product
      version: v2
  template:
    metadata:
      labels:
        app: product
        version: v2
    spec:
      containers:
      - name: product
        image: product-image:v2
        ports:
        - containerPort: 8080

这里通过 labels 中的 version 字段区分不同版本的 Pod,同时 replicas 字段指定了每个版本的副本数量。

6.2 Service 对象配置

每个微服务只能有一个 Kubernetes Service 对象,它是流量进入微服务的统一入口。示例如下:

apiVersion: v1
kind: Service
metadata:
  name: product
spec:
  selector:
    app: product
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080

selector 字段通过 app: product 标签选择所有属于产品微服务的 Pod,无论其版本是 v1 还是 v2。

7. 在 prod - env Helm 图表中整合配置

7.1 values.yaml 文件配置

prod-env Helm 图表中的 values.yaml 文件用于指定生产环境中每个微服务将使用的版本。示例如下:

virtualServices:
  - product
  - recommendation
  - review
product:
  version: v2
recommendation:
  version: v2
review:
  version: v2

这里指定了产品、推荐和评论微服务在生产环境中使用的版本为 v2。

7.2 配置整合流程

以下是配置整合的流程图:

graph LR
    A[values.yaml 配置版本] --> B[生成 VirtualService]
    B --> C[生成 DestinationRule]
    C --> D[创建 Deployment]
    D --> E[创建 Service]
    E --> F[流量根据规则路由]

通过 values.yaml 文件的配置,驱动生成相应的虚拟服务、目标规则,然后创建不同版本的 Deployment 和统一的 Service,最终实现流量根据规则在不同版本的微服务之间进行路由。

8. 总结与最佳实践

8.1 关键功能总结
  • 安全性 :通过验证访问令牌和使用 mTLS 保护内部通信,提高了服务网格的安全性,防止攻击者窃听和非法访问。
  • 弹性 :利用注入故障和延迟的方式,测试服务网格的重试和断路器机制,确保在面对临时故障时服务的稳定性。
  • 零停机更新 :借助金丝雀部署和蓝绿部署策略,实现微服务的无停机更新,降低了升级风险。
8.2 最佳实践建议
  • 安全性方面 :定期更新证书,确保 mTLS 配置的有效性;合理配置 JWT 发行者,防止访问令牌验证出现问题。
  • 弹性方面 :在开发阶段就对重试和断路器机制进行充分测试,确保在生产环境中能够有效应对故障;根据服务的实际情况调整故障注入的比例和延迟时间,以更准确地模拟真实场景。
  • 零停机更新方面 :在进行金丝雀测试时,选择合适的测试用户群体,确保能够全面发现新版本的问题;在蓝绿部署过程中,逐步增加新版本的流量比例,同时密切监控服务的运行状态。

表格总结

配置类型 关键配置项 作用
VirtualService hosts http 路由规则 在微服务不同版本间分配流量,支持金丝雀测试
DestinationRule host subsets 识别不同版本的微服务实例
Deployment name labels 创建不同版本的微服务 Pod
Service selector 作为流量进入微服务的统一入口
values.yaml virtualServices 、各微服务版本 指定生产环境中微服务的版本
内容概要:本文介绍了一套针对智能穿戴设备的跑步/骑行轨迹记录系统实战方案,旨在解决传统运动APP存在的定位漂移、数据断层和路径分析单一等问题。系统基于北斗+GPS双模定位、惯性测量单元(IMU)和海拔传感器,实现高精度轨迹采集,并通过卡尔曼滤波算法修正定位误差,在信号弱环境下利用惯性导航补位,确保轨迹连续性。系统支持跑步骑行两种场景的差异化功能,包括实时轨迹记录、多维度路径分析(如配速、坡度、能耗)、数据可视化(地图标注、曲线图、3D回放)、异常提醒及智能优化建议,并可通过蓝牙/Wi-Fi同步数据至手机APP,支持社交分享专业软件导出。技术架构涵盖硬件层、设备端手机端软件层以及云端数据存储,强调低功耗设计用户体验优化。经过实测验证,系统在定位精度、续航能力和场景识别准确率方面均达到预期指标,具备良好的实用性和扩展性。; 适合人群:具备一定嵌入式开发或移动应用开发经验,熟悉物联网、传感器融合数据可视化的技术人员,尤其是从事智能穿戴设备、运动健康类产品研发的工程师和产品经理;也适合高校相关专业学生作为项目实践参考。; 使用场景及目标:① 开发高精度运动轨迹记录功能,解决GPS漂移断点问题;② 实现跑步骑行场景下的差异化数据分析个性化反馈;③ 构建完整的“终端采集-手机展示-云端存储”系统闭环,支持社交互动商业拓展;④ 掌握低功耗优化、多源数据融合、动态功耗调节等关键技术在穿戴设备中的落地应用。; 阅读建议:此资源以真实项目为导向,不仅提供详细的技术实现路径,还包含硬件选型、测试验证商业扩展思路,建议读者结合自身开发环境,逐步实现各模块功能,重点关注定位优化算法、功耗控制策略跨平台数据同步机制的设计调优。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值