1. 什么是Service Mesh?
Service Mesh是一种专门处理服务间通信的基础设施层。它通常位于应用代码之前,与服务部署在一起,但对应用程序透明。Service Mesh主要负责服务间的流量管理、安全、监控和可观察性等功能。
2. 关键组件
Service Mesh通常包含以下几个关键组件:
a. Sidecar代理
每个服务旁边都有一个Sidecar代理(如Envoy、Linkerd等),这个代理处理服务间的所有网络通信。它可以拦截进出服务的所有流量,并执行诸如负载均衡、服务发现、断路器、重试、超时、限流等操作。
b. 控制平面
控制平面是管理Sidecar代理的组件,负责配置代理的路由规则、安全策略、监控策略等。例如,Istio的控制平面包括Pilot(服务发现和流量管理)、Citadel(安全)、Galley(配置管理)和Mixer(策略和遥测)。
c. 数据平面
数据平面由部署在每个服务旁边的Sidecar代理组成,负责实际的数据包转发和流量管理。
Isito 架构
数据平面(Envoy)
Envoy是Istio默认的Sidecar代理,负责调解微服务间的所有网络通信,与应用程序部署在同一Pod中。它根据控制平面的指令对流量进行路由和策略控制,同时将请求属性上报给控制平面以供决策。 12
控制平面组件
- Pilot :负责管理和配置Envoy代理,下发路由规则(如动态路由、负载均衡策略)实现流量调度。
- Mixer :收集流量监控数据(如请求时长、流量体积等),并基于策略引擎执行安全检查或监控配置。
- Citadel :提供证书管理功能,支持服务间加密(mTLS)和身份认证。
- Galley :管理Istio中的配置文件,支持动态更新路由规则等配置。
Pilot 将服务发现机制提炼为供数据面使用的 API ,即任何 Sidecar 都可以使用的标准格式。这种松耦合的设计模式使 Istio 能在多种环境( Kubernetes、Consul 和 Nomad )下运行,同时保持用于流量管理操作的相同。
除了服务发现, Pilot 更重要的一个功能是向数据面下发规则,包括VirtualService 、DestinationRule 、Gateway 、ServiceEntry 等流量治理规则,也包括认证授权等安全规则。Pilot 负责将各种规则转换成Envoy 可识别的格式,通过标准的XDS 协议发送给Envoy,指导Envoy 完成功作。在通信上, Envoy 通过gRPC 流式订阅Pilot 的配置资源。如下图所示, Pilot 将VirtualService 表达的路由规则分发到Evnoy 上, Envoy 根据该路由规则进行流量转发。
Citadel 通过内置身份和凭证管理提供“服务间”和“最终用户”身份验证。Citadel 可用于升级服务网格中未加密的流量,并能够为运维人员提供基于服务标识( 如 Kubernetes 中 Pod 的标签或版本号 )而不是网络层的强制执行策略。
Citadel 一直监听Kube-apiserver ,以Secret 的形式为每个服务都生成证书密钥,并在Pod 创建时挂载到Pod 上,代理容器使用这些文件来做服务身份认证,进而代理两端服务实现双向TLS认证、通道加密、访问授权等安全功能,这样用户就不用在代码里面维护证书密钥了。如下图所示,frontend 服务对forecast 服务的访问用到了HTTP 方式,通过配置即可对服务增加认证功能, 双方的Envoy 会建立双向认证的TLS 通道,从而在服务间启用双向认证的HTTPS 。
Istio-galley 并不直接向数据面提供业务能力,而是在控制面上向其他组件提供支持。Galley 作为负责配置管理的组件,验证配置信息的格式和内容的正确性,并将这些配置信息提供给管理面的Pilot和Mixer服务使用,这样其他管理面组件只用和Galley 打交道,从而与底层平台解耦。在新的版本中Galley的作用越来越核心。
确认 Istio 已就绪
kubectl -n istio-system get pod -l app=istiod # 必须 1/1 Running
打开自动注入(如果还没做)
kubectl create ns bookinfo
kubectl label ns bookinfo istio-injection=enabled
一键部署官方示例
kubectl apply -n bookinfo -f https://raw.githubusercontent.com/istio/istio/release-1.20/samples/bookinfo/platform/kube/bookinfo.yaml
等所有 Pod 都 Running
kubectl -n bookinfo wait --for=condition=ready pod --all --timeout=300s
部署 Gateway + VirtualService(暴露 80 端口)
kubectl apply -n bookinfo -f https://raw.githubusercontent.com/istio/istio/release-1.20/samples/bookinfo/networking/bookinfo-gateway.yaml
设置端口转发(本地访问)
kubectl -n istio-system port-forward svc/istio-ingressgateway 8080:80 &
selector:
istio: ingressgateway # use istio default controller
servers:
- port:
number: 8080
name: http
protocol: HTTP
hosts:
- "*"
---
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
先杀掉刚才的 127.0.0.1 转发
pkill -f "port-forward.*istio-ingressgateway"
重新监听 0.0.0.0
kubectl -n istio-system port-forward --address=0.0.0.0 svc/istio-ingressgateway 8080:80 &
k8s 删除容器命令