老婆都能懂的云原生之istio的概念
作者:肥嘟嘟左卫门熊
网上已经有很多很好的istio相关的文章,写这篇文章是因为他们都太长了,讲了很多概念,虽然很细但是难以先形成一个完整的认识。
故写一篇小白文解释一下istio是什么,怎么用?
不过至少需要具备一点k8s的知识,知道k8s是什么
1.首先说一下,istio是什么
按照isito文档中给出的定义:
Istio提供一种简单的方式来建立已部署的服务的网络,具备负载均衡,服务到服务认证,监控等等功能,而不需要改动任何服务代码。
Istio服务网格逻辑上分为数据面板
和控制面板
。
-
数据面板
由一组智能代理(Envoy)组成,代理部署为边车,调解和控制微服务之间所有的网络通信。 -
控制面板
负责管理和配置代理来路由流量,以及在运行时执行策略。
那么问题来了
- 这里已部署的服务指的是什么?
- 简单的方式指的是什么?
- 怎么实现的具备负载均衡,服务到服务认证,监控等等功能?
我们一一解答~
1.已部署的服务指的是什么?
已部署的服务即任意k8s服务,比如
这里涉及到一些k8s的概念
-
Service是k8s中的一种资源,通常用来为pod提供稳定公开的网络服务,将流量导入对应的pod。
-
Pod是一组运行的容器,容器里面是用户提供的服务。
当用户访问 x.x.x.x:32010
时,流量进入32010
端口的Service1
,通过Service1
转入Pod1
;
如果用户访问的是x.x.x.x:32010/backend
,则后端流量会继续通过Pod1
内的nginx配置,转入后端的Service2
;
比如
proxy_pass http://Service2.namespace.svc.cluster.local.:80;
其中http://Service2.namespace.svc.cluster.local.:80
是k8s资源Service的域名访问方式
(在 Kubernetes 中,Service 和 Pod 都会被分配对应的 DNS A 记录(从域名解析 IP 的记录),因此可以通过上述域名访问service资源。)
2.简单的方式指的是什么?
即通过对所有pod注入sidecar,从而调解和控制服务之间所有的网络通信。
这里再稍微说一下sidecar是什么?
- Sidecar即边车模式
所谓的边车模式,对应于我们生活中熟知的边三轮摩托车。也就是说,我们可以通过给一个摩托车加上一个边车的方式来扩展现有的服务和功能。这样可以很容易地做到 " 控制 " 和 " 逻辑 " 的分离。
具体来说,你可以理解为,边车就有点像一个服务的 Agent,这个服务所有对外的进出通讯都通过这个 Agent 来完成
。
由“边车”来实现监控,日志等与业务逻辑没有关系的控制功能。
具体到本服务中,即给pod里都加上了一个sidecar容器
实现方式很简单,这里举其中一个方式为例,命名空间添加标签,给命名空间添加标签,指示 Istio 在部署应用的时候,自动注入 Envoy 边车代理
kubectl label namespace default istio-injection=enabled
之后,当我们在default命名空间下创建pod,则会自动添加一个sidecar代理,pod内容器数量会从x个变为x+1个
# Before
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
pod-558b8b4b76-2llld 1/1 Running 0 2m41s
# After
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
pod-558b8b4b76-v3das 2/2 Running 0 2m41s
这便是istio的数据面板
(下图中的Proxy即为sidecar)
proxy由Envoy(一种网络代理sidecar)实现,Envoy相当于打工人,目前只是把打工人安插在了每个工作单位(pod)里。
3.怎么实现的具备负载均衡,服务到服务认证,监控等等功能?
打工人sidecar通常根据VirtualService和DestinationRule这两个crd,描述istio的控制面板,实现对流量的控制
- VirtualService 用于对流量进行路由
下面的例子是将带有【header】【id:exampleid】的http请求转到版本v2,其他http请求找发到版本v1的VirtualService。
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: service1
namespace: testns
spec:
hosts: #接收流量的目标主机
- service1
http:
- match:
- headers:
id:
exact: exampleid
route:
- destination:
host: service1
subset: v2
- route:
- destination:
host: service1
subset: v1
- DestinationRule 用于定义流量路由后的策略,比如负载均衡的方式等
下面的例子将service1
按labels
拆分为两个版本,从而将VirtualService
的流量路由转发到对应版本的pod
中。
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: service1 #DestinationRule的名称
namespace: testns #DestinationRule的命名空间
spec:
host: service1 #注册中心的服务名,如k8s中的Service2.namespace.svc.cluster.local,如果使用短名称Service2,则会自动根据命名空间补全
subsets: #一组Service Endpoint的子集
- name: v1 #子集名,可以用于VirtualService的路由规则
labels: #用于筛选子集的标签集
version: v1
- name: v2
labels: #用于筛选子集的标签集
version: v2
通过上述配置,即完成了一个将带指定头部的请求导入v2版本服务,其他请求导入v1版本服务的灰度发布istio配置!
总结
下图是宏观视图,可以更形象的展示Istio两个面板的功能和合作:
通过数据面板sidecar负责对数据进行控制,控制面板来配置路由策略,完成服务网格的搭建。
本文只介绍了最基础的istio使用方式和大概的istio架构~ 如果对istio有兴趣可以直接从官方文档入手进行深入了解~
注释
-
endpoints的概念: 即每个pod的ip和port,比如10.222.76.153:8081,交给service管理,访问service实际访问的就是背后endpoint集合之一
https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.22/#endpoints-v1-core
https://stackoverflow.com/questions/52857825/what-is-an-endpoint-in-kubernetes -
crd的概念:CustomResourceDefinition ,对k8s资源的一种自定义,达到对 Kubernetes API 进行扩展满足需求的目的。本文中的VirtualService和DestinationRule都属于crd
# 通过下面的命令可以看到默认命名空间下的crd资源有哪些
kubectl get crd