Istio入门

Istio 在逻辑上分为数据平面和控制平面。

数据平面,由一组高性能的智能代理(基于 Envoy 改进的 istio-proxy)组成,它们控制和协调了被代理服务的所有网络通信,同时也负责收集和上报相关的监控数据。

控制平面,负责制定应用策略来控制网络流量的路由。

Istio 由多个组件组成,核心组件及其作用为如下:

Ingressgateway,控制外部流量访问 Istio 内部的服务。

Egressgateway,控制 Istio 内部访问外部服务的流量。

Pilot,负责管理服务网格内部的服务和流量策略。它将服务信息和流量控制的高级路由规则在运行时传播给 Proxy,并将特定平台的服务发现机制抽象为 Proxy 可使用的标准格式。

Citadel,提供身份认证和凭证管理。

Galley,负责验证、提取、处理和分发配置。

Proxy,作为服务代理,调节所有 Service Mesh 单元的入口和出口流量。

这其中 Proxy 属于数据平面,以 Sidecar 的方式与应用程序一同部署到 Pod 中,而 PilotCitadel Galley 属于控制平面。

除此之外,Istio 中还提供一些额外的插件,如 grafanaistio-tracingkiali prometheus,用于进行可视化的数据查看、流量监控和链路追踪等。

Pilot:Istio 控制面中最核心的模块,负责运行时配置下发,具体来说,就是和 Envoy 之间基于 xDS 协议进行的各种 Envoy 配置信息的推送,包括服务发现、路由发现、集群发现、监听器发现等。

Citadel:负责证书的分发和轮换,使 Sidecar 代理两端实现双向 TLS 认证、访问授权等。

Galley:配置信息的格式和正确性校验,将配置信息提供给 Pilot 使用。

Istio 通过 Galley 模块管理配置,Pilot 模块解析配置为 xDS 协议格式,通过 gRPC 和 Envoy 进行通信,以便完成配置和节点信息更新,pilot-agent 作为 Envoy 守护模块,保证 Envoy 的正常运行和平滑重启。

本地业务服务 productpage 通过 iptables 劫持的方式和本地 Envoy 进行通信,Envoy 完成服务发现后将请求转发到 ProductDetail 服务的所在 Pod,同样通过 iptables 劫持的方式将请求转发到本地的业务服务 ProductDetail。

实例服务原理解析

apiVersion: v1
kind: Service
metadata:
  name: productpage
  labels:
    app: productpage
    service: productpage
spec:
  ports:
  - port: 9080
    name: http
  selector:
    app: productpage

首先定义了一个 Service 类型的资源,而 Service 是 Kubernetes 抽象出来的服务概念,一组 Pod 的集合便是 Kubernetes 的 Service。Pod 是有生命周期的,Pod 的 IP 在不同的生命周期内发生变化,但抽象出来的 Service 名称是不会变化的。

这样就可以通过服务名访问这些后端 IP,而不用感知后端 Pod IP 的变化。

然后在 Metadata 中定义了这一组 Service 的 label ,通过 selector 指定响应的标签,就可以访问带有这组标签定义的 Pod 集合。另外这组配置还指定了服务端口为 9080,服务的协议为 HTTP ,这些信息将用于 Sidecar 的代理转发。

接下来,通过 Deployment 控制 Pod 的生命周期,定义了 Pod 的副本数量。下面的示例中,定义一个 replicas 为 1,也就是 Pod 的副本数量为 1,因为是测试环境,所以没有设置更多的副本数量保障服务的 SLA 。

当然一些常规的镜像拉取地址和拉取方式也做了定义:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: productpage-v1
  labels:
    app: productpage
    version: v1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: productpage
      version: v1
  template:
    metadata:
      labels:
        app: productpage
        version: v1
    spec:
      serviceAccountName: bookinfo-productpage
      containers:
      - name: productpage
        image: docker.io/istio/examples-bookinfo-productpage-v1:1.16.2
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 9080
        volumeMounts:
        - name: tmp
          mountPath: /tmp
      volumes:
      - name: tmp
        emptyDir: {}

另外在 Kubernetes 的 Service 里面并没有版本的概念,如果想进行染色或者金丝雀发布,就需要借助 Istio 的能力。通过上述命令可以看到,在 Deployment 类型中定义了 Version V1 的 lable,这个 lable 最终会转化成不同的服务名,比如 productpage-v1 的方式,下发到 Sidecar 中, Sidecar 根据这个服务名称进行服务发现,以实现不同版本号访问的方法。

下一步,用到了 Ingress 模式。定义一组网关类型的资源, Istio 通过 Gateway 将服务发布成外部可访问的服务,通过 80 端口将服务通过 Ingress 网关转发到特定的服务上。

apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: bookinfo-gateway
spec:
  selector:
    istio: ingressgateway # use istio default controller
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"

在这里,Gateway 资源类型,需要配合 VirtualService 类型的资源一起使用。那么,定义匹配到的 URI 具体路由到哪个服务呢?

在这个程序中可以看到匹配到 /productpage 路径的服务,而 route 中定义了 destination 的 host 将会是路由的服务名

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: bookinfo
spec:
  hosts:
  - "*"
  gateways:
  - bookinfo-gateway
  http:
  - match:
    - uri:
        exact: /productpage
    - uri:
        prefix: /static
    - uri:
        exact: /login
    - uri:
        exact: /logout
    - uri:
        prefix: /api/v1/products
    route:
    - destination:
        host: productpage
        port:
          number: 9080
posted @ 2023-01-18 17:32  muzinan110  阅读(102)  评论(0编辑  收藏  举报