MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

Kubernetes 中的服务网格 Istio 集成与应用

2021-10-285.2k 阅读

一、Kubernetes 与服务网格简介

Kubernetes 已经成为容器编排领域的事实标准,它提供了容器化应用的自动化部署、扩展和管理能力。在 Kubernetes 集群中,多个容器化的微服务协同工作,构成复杂的分布式系统。然而,随着微服务架构的广泛应用,管理这些微服务之间的通信变得愈发复杂。例如,服务发现、负载均衡、故障容错、安全通信等问题,都需要额外的机制来处理。

服务网格应运而生,它为微服务架构提供了一个基础设施层,用于处理服务间通信的关键功能。服务网格通过在每个服务旁边注入一个称为 Sidecar 的代理,拦截和管理服务之间的所有网络流量,实现了对服务通信的细粒度控制。

二、Istio 服务网格概述

Istio 是目前最流行的服务网格实现之一,它由 Google、IBM 和 Lyft 共同开发。Istio 提供了一种统一的方式来管理、保护和监控微服务之间的通信。Istio 架构主要由控制平面和数据平面组成。

1. 控制平面

控制平面主要由以下组件构成:

  • Pilot:负责服务发现、流量管理和路由规则的分发。它从 Kubernetes 中获取服务和端点信息,并将配置推送给数据平面的 Envoy 代理。例如,Pilot 可以根据定义的路由规则,将特定版本的请求路由到相应版本的服务实例。
  • Mixer:用于策略执行和遥测数据收集。它可以对服务间的流量进行配额控制、访问控制等策略检查,并收集流量指标、日志等遥测数据。比如,通过 Mixer 可以限制某个服务对另一个服务的调用频率。
  • Citadel:提供服务间通信的身份验证和授权功能,确保微服务之间的通信是安全的。它管理证书的颁发、更新和撤销,实现双向 TLS 认证。

2. 数据平面

数据平面由一系列部署在每个服务旁边的 Envoy 代理组成。Envoy 是一个高性能的代理,它负责实际的流量处理,如接收、转发、负载均衡服务间的请求,并将遥测数据发送给 Mixer。

三、Istio 在 Kubernetes 中的集成步骤

1. 安装 Istio 控制平面

首先,确保已经安装了 Kubernetes 集群。然后,可以通过 Istio 提供的安装工具 istioctl 来安装 Istio 控制平面。例如,使用以下命令下载并安装 istioctl:

curl -L https://istio.io/downloadIstio | sh -
cd istio-<version>
export PATH=$PWD/bin:$PATH

接下来,使用 istioctl 安装默认配置的 Istio 控制平面:

istioctl install --set profile=default

安装完成后,可以通过 kubectl 查看 Istio 相关的 Pod 和服务是否正常运行:

kubectl get pods -n istio-system

2. 注入 Sidecar 代理

为了让 Istio 管理微服务的通信,需要在每个微服务的 Pod 中注入 Envoy 代理。Istio 提供了两种方式来注入 Sidecar:自动注入和手动注入。

自动注入: 在 Kubernetes 命名空间上启用自动注入功能:

kubectl label namespace <namespace> istio-injection=enabled

当在该命名空间中创建新的 Pod 时,Kubernetes 会自动调用 Istio 的注入 webhook,为 Pod 注入 Envoy 代理。例如,创建一个简单的 Nginx 服务:

apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

将上述 YAML 文件保存为 nginx.yaml,然后在已启用自动注入的命名空间中创建资源:

kubectl apply -f nginx.yaml -n <namespace>

手动注入: 使用 istioctl 手动注入 Envoy 代理。例如,对于上述的 Nginx 服务,可以先不创建 Deployment,而是使用以下命令手动注入 Sidecar:

istioctl kube-inject -f nginx.yaml | kubectl apply -f -

四、Istio 流量管理应用

1. 基本路由规则

在 Istio 中,可以使用 VirtualService 资源来定义流量路由规则。例如,将所有发往 nginx 服务的请求路由到默认版本:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: nginx
spec:
  hosts:
  - nginx
  http:
  - route:
    - destination:
        host: nginx
        subset: v1

上述配置中,定义了一个名为 nginx 的 VirtualService,将所有发往 nginx 服务的 HTTP 请求路由到 v1 子集。要创建子集,可以使用 DestinationRule:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: nginx
spec:
  host: nginx
  subsets:
  - name: v1
    labels:
      version: v1

2. 基于权重的流量路由

可以通过设置路由规则中的权重,实现流量的按比例分配。例如,将 80% 的流量发送到 v1 版本,20% 的流量发送到 v2 版本:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: nginx
spec:
  hosts:
  - nginx
  http:
  - route:
    - destination:
        host: nginx
        subset: v1
      weight: 80
    - destination:
        host: nginx
        subset: v2
      weight: 20

假设 v2 版本的 Nginx 服务 Deployment 如下:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-v2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
      version: v2
  template:
    metadata:
      labels:
        app: nginx
        version: v2
    spec:
      containers:
      - name: nginx
        image: nginx:1.16.1
        ports:
        - containerPort: 80

3. 基于请求头的流量路由

还可以根据请求头中的信息进行流量路由。例如,将带有特定用户标识的请求路由到特定版本:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: nginx
spec:
  hosts:
  - nginx
  http:
  - match:
    - headers:
        user-agent:
          exact: special-user-agent
    route:
    - destination:
        host: nginx
        subset: v2
  - route:
    - destination:
        host: nginx
        subset: v1

五、Istio 安全通信应用

1. 双向 TLS 认证

Istio 的 Citadel 组件可以自动为服务生成和管理证书,实现服务间的双向 TLS 认证。默认情况下,Istio 控制平面安装后,双向 TLS 是启用的。为了验证双向 TLS 是否生效,可以查看 Envoy 代理的日志,确认是否使用了 TLS 加密进行通信。

在 DestinationRule 中,可以进一步配置 TLS 模式。例如,强制使用双向 TLS:

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: nginx
spec:
  host: nginx
  trafficPolicy:
    tls:
      mode: ISTIO_MUTUAL

2. 基于身份的访问控制

Istio 可以基于服务的身份进行访问控制。通过在 Mixer 中定义授权策略,只有经过授权的服务才能访问特定的服务。例如,只允许名为 app1 的服务访问 nginx 服务:

apiVersion: "config.istio.io/v1alpha2"
kind: denier
metadata:
  name: denyrequest
  namespace: istio-system
spec:
  status:
    code: 7
    message: "Not allowed to access"
---
apiVersion: "config.istio.io/v1alpha2"
kind: rule
metadata:
  name: denyrequestifnotapp1
  namespace: istio-system
spec:
  match: "destination.labels['app'] == 'nginx' && source.labels['app'] != 'app1'"
  actions:
  - handler: denyrequest.denier
    instances:
    - requestheaders.istio-system

六、Istio 遥测数据收集与分析

1. 指标收集

Istio 的 Mixer 可以收集各种指标数据,如请求流量、响应时间、错误率等。这些指标数据可以发送到 Prometheus 等监控系统。默认情况下,Istio 已经配置了与 Prometheus 的集成。

可以通过 Prometheus 的查询语句来分析这些指标。例如,查询 nginx 服务的每秒请求数:

rate(istio_requests_total{destination_service="nginx"}[1m])

2. 日志收集

Istio 可以将服务间通信的日志发送到集中式日志管理系统,如 Elasticsearch 和 Kibana。通过配置 Mixer,可以定义日志的格式和发送目标。例如,将日志发送到 Fluentd,再由 Fluentd 转发到 Elasticsearch:

apiVersion: "config.istio.io/v1alpha2"
kind: fluentd
metadata:
  name: fluentdlog
  namespace: istio-system
spec:
  address: fluentd.istio-system:24224
  format: json
  tag: istio.nginx
---
apiVersion: "config.istio.io/v1alpha2"
kind: rule
metadata:
  name: lognginxrequests
  namespace: istio-system
spec:
  match: "destination.labels['app'] == 'nginx'"
  actions:
  - handler: fluentdlog.fluentd
    instances:
    - requestlog.istio-system

七、Istio 故障注入与容错

1. 故障注入

在 Istio 中,可以通过 VirtualService 进行故障注入,模拟服务故障场景,以便测试系统的容错能力。例如,向 nginx 服务的请求中注入延迟:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: nginx
spec:
  hosts:
  - nginx
  http:
  - fault:
      delay:
        fixedDelay: 5s
        percent: 100
    route:
    - destination:
        host: nginx
        subset: v1

上述配置会对所有发往 nginx 服务 v1 子集的请求引入 5 秒的延迟。

2. 容错机制

Istio 支持多种容错机制,如重试、超时等。例如,为 nginx 服务配置重试机制:

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: nginx
spec:
  hosts:
  - nginx
  http:
  - route:
    - destination:
        host: nginx
        subset: v1
    retries:
      attempts: 3
      perTryTimeout: 2s

这里配置了对 nginx 服务 v1 子集的请求最多重试 3 次,每次重试的超时时间为 2 秒。

八、Istio 多集群集成

在实际生产环境中,可能会有多 Kubernetes 集群,Istio 提供了多集群集成的能力。

1. 多集群控制平面

可以部署一个共享的 Istio 控制平面来管理多个 Kubernetes 集群。通过在每个集群中配置与控制平面的连接,实现统一的服务网格管理。例如,在每个集群中安装 Istio 时,指定控制平面的地址:

istioctl install --set profile=default --set meshConfig.controlPlaneAuthPolicy=SHARED_INTERNET --set values.global.controlPlaneAddress=<control - plane - address>

2. 跨集群服务发现与通信

Istio 通过跨集群服务发现机制,使得不同集群中的服务可以相互发现和通信。例如,一个集群中的服务可以像访问本地服务一样访问另一个集群中的服务,通过统一的服务入口和出口网关进行流量转发。

九、Istio 性能优化与注意事项

1. 性能优化

  • 资源优化:合理配置 Envoy 代理的资源请求和限制,避免因资源不足或过度分配导致的性能问题。例如,根据服务的流量大小,调整 Envoy 的 CPU 和内存请求。
  • 配置优化:精简 Istio 的配置,避免过多复杂的路由规则和策略,减少配置处理的开销。例如,合并相似的路由规则,减少不必要的 DestinationRule 定义。

2. 注意事项

  • 版本兼容性:Istio 与 Kubernetes 以及其他相关组件之间存在版本兼容性要求,在升级或安装时要确保版本匹配。例如,某些 Istio 版本可能只支持特定范围的 Kubernetes 版本。
  • 安全配置:正确配置 Istio 的安全机制,如双向 TLS 和访问控制,防止潜在的安全漏洞。例如,定期更新证书,确保通信安全。
  • 监控与调优:密切关注 Istio 产生的遥测数据,及时发现性能瓶颈和异常情况,并进行调优。例如,通过监控指标发现某个服务的响应时间过长,及时调整相关配置或优化服务代码。