39、使用Kubernetes和服务网格简化系统架构与提升管理能力

本文还有配套的精品资源,点击获取 menu-r.4af5f7ec.gif

使用Kubernetes和服务网格简化系统架构与提升管理能力

1. 启动Minikube并设置命名空间

首先,我们需要启动Minikube实例,并将默认命名空间设置为“hands - on”,可以使用以下命令:

minikube start
kubectl config set-context $(kubectl config current-context) --namespace=hands-on

通过成功执行这些测试,我们验证了微服务在没有Kubernetes的情况下也能正常工作。

2. Kubernetes简化微服务架构

Kubernetes的一些功能可以简化微服务架构,减少与微服务一起开发和部署的支持服务数量。具体如下:
- 替代Spring Cloud Config Server :可以使用Kubernetes的ConfigMaps和Secrets来替代Spring Cloud Config Server。
- 替代Spring Cloud Gateway :Kubernetes的Ingress对象可以替代Spring Cloud Gateway。
- 自动证书配置 :使用cert - manager可以为Ingress控制器暴露的HTTPS端点自动配置证书,避免了手动配置的繁琐工作。
- 跨平台验证 :为了验证微服务的源代码可以在其他平台上运行,而不局限于Kubernetes,我们使用Docker Compose部署微服务并运行测试脚本。

3. 服务网格简介

服务网格是一个基础设施层,用于控制和观察服务(如微服务)之间的通信。它具有以下能力:
- 可观测性 :可视化微服务之间的流量流动。
- 安全性 :保护服务之间的通信。
- 策略执行 :实施各种策略。
- 弹性 :确保系统在故障时的稳定性。
- 流量管理 :控制流量的路由。

服务网格的核心组件之一是轻量级代理组件,它会被注入到每个要加入服务网格的微服务中。所有进出微服务的流量都会通过其代理组件。代理组件由服务网格中的控制平面在运行时使用代理暴露的API进行配置,控制平面还会通过这些API从代理收集遥测数据,以可视化服务网格中的流量情况。

服务网格还包含数据平面,由代理组件以及处理服务网格内外流量的入口网关和出口网关组成。网关组件也通过代理组件与控制平面通信,其结构如下:

graph LR
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
    A(控制平面):::process --> B(代理组件):::process
    A --> C(入口网关):::process
    A --> D(出口网关):::process
    B <--> E(微服务1):::process
    B <--> F(微服务2):::process
    C <--> G(外部流量进入):::process
    D <--> H(外部流量出去):::process
4. Istio简介

Istio是一个流行的开源服务网格实现,可以使用各种安装工具部署在多个Kubernetes发行版和平台上。我们将使用Istio的CLI工具istioctl在基于Minikube的单节点Kubernetes集群中安装Istio。

Istio分为控制平面和数据平面。作为操作者,我们可以通过在Kubernetes API服务器中创建Istio对象(如声明路由规则)来定义所需状态。控制平面会读取这些对象并向数据平面中的代理发送命令,以根据所需状态采取行动,例如配置路由规则。代理处理微服务之间的实际通信,并将遥测数据报告回控制平面,用于可视化服务网格中的情况。

当在Kubernetes上部署Istio时,其大多数运行时组件部署在单独的Kubernetes命名空间istio - system中,具体部署组件如下表所示:
| 组件名称 | 说明 |
| ---- | ---- |
| istiod | 运行整个控制平面的守护进程 |
| istio - ingressgateway和istio - egressgateway | 入口和出口网关组件,属于数据平面 |
| Kiali | 为服务网格提供可观测性,可视化网格中的情况 |
| Tracing(使用Jaeger) | 处理和可视化分布式跟踪信息 |
| Prometheus | 进行基于时间序列的数据摄取和存储,如性能指标 |
| Grafana | 可视化Prometheus收集的性能指标和其他时间序列相关数据 |

5. 向微服务注入Istio代理

在之前章节中,我们在Kubernetes中部署的微服务作为单个容器运行在Kubernetes Pod中。为了让微服务加入基于Istio的服务网格,需要向每个微服务注入Istio代理,这通过在运行微服务的Pod中添加一个额外的容器来实现。

Istio代理可以在创建Pod对象时自动注入,也可以使用istioctl工具手动注入:
- 自动注入 :要让Istio自动将代理注入到命名空间中的新Pod,可以为命名空间添加标签 istio - injection: enabled 。如果要排除某些Pod的自动注入,可以为其添加注解 sidecar.istio.io/inject: "false"
- 手动注入 :对于现有Deployment对象的Pod,可以使用以下命令手动注入Istio代理:

kubectl get deployment sample-deployment -o yaml | istioctl kube-inject -f - | kubectl apply -f -

该命令实际上由三个单独的命令组成:
1. kubectl get deployment :从Kubernetes API服务器获取名为sample - deployment的Deployment的当前定义,并以YAML格式返回。
2. istioctl kube - inject :读取 kubectl get deployment 命令的定义,并在Deployment处理的Pod中添加一个用于Istio代理的额外容器,更新Deployment对象中现有容器的配置,使进出流量通过Istio代理。
3. kubectl apply :读取 istioctl kube - inject 命令更新后的配置并应用该配置,启动Deployment所属Pod的升级。

在实际操作中,我们将通过应用以下hands - on命名空间的定义来自动注入Istio代理:

apiVersion: v1
kind: Namespace
metadata:
  name: hands-on
  labels:
    istio-injection: enabled

由于在编写本文时,Istio不能完全作为MySQL、MongoDB和RabbitMQ的代理,因此我们会在它们的Helm图表的values.yaml文件中添加以下注解,将它们排除在服务网格之外:

annotations:
  sidecar.istio.io/inject: "false"
6. Istio API对象

Istio带有一组Kubernetes自定义资源定义(CRDs),用于扩展Kubernetes的API。我们将使用以下Istio对象:
| 对象名称 | 说明 |
| ---- | ---- |
| Gateway | 配置如何处理进出服务网格的流量,依赖于虚拟服务将传入流量路由到Kubernetes服务。我们将使用它接受以minikube.me结尾的DNS名称的HTTPS传入流量,替代之前使用的Ingress对象。 |
| VirtualService | 定义服务网格中的路由规则,描述如何将来自Istio网关的传入流量路由到Kubernetes服务以及服务之间的路由。还可用于注入故障和延迟,测试服务网格的可靠性和弹性。 |
| DestinationRule | 定义路由到特定服务的流量的策略和规则,如设置内部HTTP流量的加密策略,定义服务子集以进行零停机(蓝绿)部署。 |
| PeerAuthentication | 控制服务网格内的服务到服务认证,Istio可以通过自动配置相互TLS(mTLS)来保护服务之间的通信。为了允许Kubernetes使用纯HTTP调用存活和就绪探针,我们将配置Istio允许mTLS和纯HTTP的混合模式(PERMISSIVE模式)。 |
| RequestAuthentication | 根据请求中提供的凭证对最终用户进行认证,支持使用JSON Web Tokens(JWTs),特别是根据OpenID Connect(OIDC)规范使用时。我们将通过指定其JWKS发现端点来配置Istio使用认证服务器对外部请求进行认证。 |
| AuthorizationPolicy | 提供Istio中的访问控制,在本文中我们不使用Istio的访问控制,而是重用产品组合微服务中现有的访问控制。因此,我们将配置一个AuthorizationPolicy对象,允许任何经过身份验证的用户(即包含有效JWT作为OIDC访问令牌的请求)访问产品组合微服务。 |

7. 简化微服务架构

Istio的一些组件在功能上与当前微服务架构中使用的组件有重叠:
- 替代Kubernetes Ingress控制器 :Istio的入口网关可以作为边缘服务器,替代Kubernetes Ingress控制器。它具有以下优点:
- 可以将流经它的流量的遥测数据报告给控制平面。
- 可用于更细粒度的路由。
- 可以在将请求路由到服务网格之前进行认证和授权。
为了利用这些优点,我们将用Istio入口网关替换Kubernetes Ingress控制器。之前使用的Ingress对象的定义已从 kubernetes/helm/environments 中的 dev - env prod - env Helm图表中移除。Istio入口网关使用不同的IP地址,因此我们还需要更新运行测试时使用的主机名 minikube.me 映射的IP地址。
- 替代Zipkin服务器 :Istio附带的Jaeger组件可以用于分布式跟踪,替代与微服务一起部署的Zipkin服务器。

综上所述,Kubernetes和服务网格(如Istio)为微服务架构的简化和管理提供了强大的功能。通过合理使用这些技术,我们可以提高微服务系统的可观测性、安全性、弹性和可管理性。

使用Kubernetes和服务网格简化系统架构与提升管理能力

8. 替换Kubernetes Ingress控制器为Istio入口网关的详细步骤

在前面提到,我们要将Kubernetes Ingress控制器替换为Istio入口网关,下面详细介绍具体步骤:
1. 移除旧的Ingress对象定义 :将之前使用的Ingress对象的定义从 kubernetes/helm/environments 中的 dev - env prod - env Helm图表中移除。
2. 创建Istio Gateway和VirtualService对象 :按照之前介绍的Istio API对象的功能,创建相应的Gateway和VirtualService对象来配置流量路由。
3. 更新IP地址映射 :由于Istio入口网关使用不同的IP地址,我们需要更新运行测试时使用的主机名 minikube.me 映射的IP地址。具体操作流程如下:

graph LR
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
    A(移除旧Ingress定义):::process --> B(创建Istio对象):::process
    B --> C(获取Istio入口网关IP):::process
    C --> D(更新minikube.me IP映射):::process
9. 服务网格的安全性和认证配置

服务网格的安全性至关重要,Istio提供了多种认证和授权机制来保障服务间通信的安全。
- PeerAuthentication配置 :为了保护服务之间的通信,Istio可以自动配置相互TLS(mTLS)。但为了允许Kubernetes使用纯HTTP调用存活和就绪探针,我们将配置Istio为PERMISSIVE模式,允许mTLS和纯HTTP的混合。示例配置如下:

apiVersion: security.istio.io/v1beta1
kind: PeerAuthentication
metadata:
  name: default
spec:
  mtls:
    mode: PERMISSIVE
  • RequestAuthentication配置 :根据请求中提供的凭证对最终用户进行认证,支持使用JSON Web Tokens(JWTs)。我们通过指定其JWKS发现端点来配置Istio使用认证服务器对外部请求进行认证。示例配置如下:
apiVersion: security.istio.io/v1beta1
kind: RequestAuthentication
metadata:
  name: jwt-example
spec:
  selector:
    matchLabels:
      app: product-composite
  jwtRules:
  - issuer: "https://example.com"
    jwksUri: "https://example.com/.well-known/jwks.json"
  • AuthorizationPolicy配置 :我们不使用Istio的访问控制,而是重用产品组合微服务中现有的访问控制。配置一个AuthorizationPolicy对象,允许任何经过身份验证的用户(即包含有效JWT作为OIDC访问令牌的请求)访问产品组合微服务。示例配置如下:
apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: allow-authenticated
spec:
  selector:
    matchLabels:
      app: product-composite
  action: ALLOW
  rules:
  - from:
    - source:
        requestPrincipals: ["*"]
10. 服务网格的弹性测试

为了确保服务网格的可靠性和弹性,我们可以使用VirtualService对象注入故障和延迟进行测试。
- 注入故障 :可以通过配置VirtualService对象,在请求路由时返回错误响应,模拟服务故障。示例配置如下:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: product-composite
spec:
  hosts:
  - product-composite
  http:
  - fault:
      abort:
        percent: 10
        httpStatus: 500
    route:
    - destination:
        host: product-composite
  • 注入延迟 :通过配置VirtualService对象,在请求路由时添加延迟,模拟网络延迟或服务响应缓慢。示例配置如下:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: product-composite
spec:
  hosts:
  - product-composite
  http:
  - fault:
      delay:
        percent: 10
        fixedDelay: 5s
    route:
    - destination:
        host: product-composite
11. 零停机部署(蓝绿部署)

在微服务架构中,零停机部署是非常重要的,Istio的DestinationRule对象可以帮助我们实现零停机部署。
1. 定义服务子集 :在DestinationRule中定义服务的不同版本,例如旧版本(蓝色)和新版本(绿色)。示例配置如下:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: product-composite
spec:
  host: product-composite
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
  1. 配置路由规则 :通过VirtualService对象配置流量路由,开始时将所有流量导向旧版本,然后逐步将流量导向新版本。示例配置如下:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: product-composite
spec:
  hosts:
  - product-composite
  http:
  - route:
    - destination:
        host: product-composite
        subset: v1
      weight: 100
    - destination:
        host: product-composite
        subset: v2
      weight: 0

随着测试和验证的进行,可以逐步调整权重,将流量从旧版本转移到新版本,实现零停机部署。

12. 总结与最佳实践

通过使用Kubernetes和服务网格(如Istio),我们可以显著简化微服务架构,提高系统的可观测性、安全性、弹性和可管理性。以下是一些最佳实践总结:
- 合理使用API对象 :根据不同的需求,合理使用Istio的各种API对象,如Gateway、VirtualService、DestinationRule等,来配置流量路由、安全策略和服务治理。
- 自动化注入代理 :使用自动注入机制将Istio代理注入到微服务中,减少手动配置的工作量。
- 定期进行弹性测试 :通过注入故障和延迟,定期对服务网格进行弹性测试,确保系统在故障情况下的稳定性。
- 遵循安全配置原则 :按照最佳实践配置PeerAuthentication、RequestAuthentication和AuthorizationPolicy,保障服务间通信的安全。

通过遵循这些最佳实践,我们可以更好地利用Kubernetes和服务网格的功能,构建更加健壮和高效的微服务系统。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值