服务网格 Istio 全系列之六 —— Istio 注入


1 Istio 注入与平台生态影响

        虽然 Istio 是平台间独立的,不仅支持 K8s、Consul,也同样支持虚拟机,但是本文部署平台环境还是聚焦在 K8S。

1.1 环境准备

        在本系列文章的第二篇中提到过资源的 Istio 注入,这里再做一个回顾。

        新建 jiuxi 命名空间:

# kubectl create ns jiuxi

        编写 nginx deployment 资源文件 nginx-deploy.yaml:

apiVersion: apps/v1 kind: Deployment metadata:   name: nginx     namespace: jiuxi     labels:     app: nginx spec:     replicas: 1     selector:         matchLabels:             app: nginx     template:         metadata:             labels:                 app: nginx         spec:             containers:             -   name: nginx                 image: nginx:1.14-alpine                 ports:                 - containerPort: 80

        新建 nginx deployment 资源:

# kubectl apply -f nginx-deploy.yaml

        创建成功后的截图如下:

image.png

1.2 Istio 注入操作

        执行 Istio 注入操作之前,须确保 Istio 和 istioctl 都正确安装。

        手动执行 Istio 注入操作:

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

        执行成功之后截图如下:

image.png

        此时 nginx pod 内部容器从原来的 1 个变成了 2 个(严格意义上应该是 3 个,因为有个启动容器执行完就结束了,因此这里看不到,后面会细说)。

1.3 Istio 注入本质

        我们再审视一下 Istio 注入过程:

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

        该命令通过管道符 “|” 将两步操作合为一步,"|" 前在 nginx-deploy.yaml 资源文件注入 istio 内容,"|" 后部署经过 Istio 注入的新的 nginx-deploy.yaml 文件。

        那么 Istio 到底注入了哪些内容呢?执行如下命令查看:

# kubectl edit deployment -n jiuxi nginx

        发现在原来基础上增加了一个初始化容器(initContainers):

image.png

        又增加了一个 istio-proxy 容器:

image.png

        还有一些环境变量信息,如下图所示:

image.png

        由此可知,Istio 注入本质就是在宿主资源中添加 Istio 特性,从而起到提高整个平台的能力。类似克拉克加了披风变成超人,布洛克吸附外星物质变成毒液一样的道理。

image.png

image.png

        下图展示了 Istio 在 nginx pod 中注入新容器 istio-init、istio-proxy:

image.png

1.4 Istio 注入 pod 后各容器作用以及关系

        上图演示了 pod 在 Istio 注入后产生了 2 个新的容器,这样原来单容器的 pod 现在变成了 3 个容器共存同一个 pod 中,而且宿主容器(nginx)跟 istio-proxy 容器还处于同一网络空间。

istio-init: 初始化容器。作用是初始化 pod 网络空间,创建 iptables 规则。

istio-proxy: sidecar 容器。作用是启动 pilot-agent 和 envoy 进程。

        可以通过 kubectl exec -it 命令进入 nginx pod 的 nginx 和 istio-proxy 容器,发现两个容器共享同一网络空间。如下图所示:

image.png

1.5 istio-proxy 和 envoy 关系

        envoy 其实本质与 nginx 和 haproxy 一样,都属于网络代理服务器,运行时则是一个进程。envoy 在架构设计上也采用了类似 nginx 的设计模式(多线程、非阻塞、异步IO),后面的课程我会详细讲解。

        istio-proxy 是运行在 pod 中的一个容器。该容器运行时会启动两个关键的进程 pilot-agent 和 envoy。pilot-agent 进程会定时跟 Istio 的 pilot 组件进行通信,envoy 进程会接收入口和出口网络流量。istio-proxy 容器内的进程如下截图所示:

image.png

1.6 istio-proxy 和 kube-proxy 关系

        从表现形式上说,istio-proxy 是容器(运行在 pod 内),kube-proxy 是 pod (资源类型是 daemonset)。

        从处理网络流量角度来说,istio-proxy 和 kube-proxy 本质上都是通过 iptables/netfilter 来处理网络流量。只不过 istio-proxy 和 kube-proxy 活动在不同的网络空间。istio-proxy 位于 pod 网络空间,处理的是 pod 内的网络流量,而 kube-proxy 位于宿主机网络空间,处理的是宿主机内网络流量(因为 kube-proxy 是 daemonset,因此它位于 k8s 集群的每个 node 节点上)。

1.7 envoy 进程服务端口

        上面我们介绍了 envoy 是运行在 istio-proxy 容器内的一个进程,改进程的作用是管理网络流量(类比 nginx),下图展示 envoy 进程开启的网络端口,网络流量可以通过端口进入到 envoy 进程内部。网络流量、网络端口和 envoy 进程的关系就像风、窗户和房屋的关系一样,风(网络流量)通过窗口(网络端口)进入到房屋(envoy),一个房屋(envoy)可以不止一个窗户(网络端口)。

        下图展示 envoy 进程监听的端口号:

image.png

        服务端口作用截图如下:

image.png


2 总结

        自此,笔者带你轻松完爆了 Istio 的注入以及对平台生态的影响。下章节将继续介绍 Istio 注入后对网络流量的流向的改变。