概念

简单的说,Istio注入其实就是将一些额外的容器、配置添加到我们的Pod模板中。注入的方式有两种,一种是手工注入,还有一个自动注入。下面这张图我们明显可以看出来相对于注入前的Pod,注入后的Pod多了2个容器,其实还有写入了一些iptables规则。

手工注入

我们先创建一个namespace

kubectl create ns injection

我们编写一个pod的yaml

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

kubectl apply -f nginx-demo.yaml

执行注入,注入本身并不是在原来的pod资源上注入的,而是先生成一个新的注入过的deployment,然后再杀死原来的deployment

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

可以从下面图片看出,注入的deployment pod已经再生成了

我们对比之前的pod,注入后的pod现在是2个容器,在之前我们说会多2个容器,其实有一个容器定义在initC里面,也就是他在执行写初始化操作后就会死亡,所以总共就是2个容器

我们导出注入后的pod的yaml看一下发生了哪些变化

kubectl get pods -n injection -o yaml > test-injection.yaml

首先我们看到的是第一个我们定义的nginx容器

第二个容器istio-proxy

第三个就是我们说的初始化后就死亡的容器istio-init

下面,我们来看看istio-init初始化到底做了什么

kubectl log test-injection-568487774c-jwgxk -c istio-init -n injection

一开始,istio-init设置了定义了一些环境和变量

然后主要就是写入一些iptables策略

我们进入istio-proxy容器看看

kubectl exec -it test-injection-568487774c-jwgxk -c istio-proxy -n injection -- /bin/sh

可以看到容器里面有2个进程,pilot-agent和envoy,还开放了一些端口

pilot-agent其实是polot-discovery的代理,它负责生成envoy启动配置、启动envoy、监控并管理envoy的运行情况。
从下面这张图我们看下下注入的原理

首先API Server接收到客户端传来关于istio流控的资源文件请求,然后将集群状态写入到Etcd中去,API Server会解析istio流控资源文件,生成一些istio流控的规则,Istiod Pod中的discovery容器有个Pilot-discovery进程会一直监听API Server,一旦有新的规则写入,它会将规则解析成envoy的配置,然后下发给pilot-agent,pilot-agent会重新应用envoy配置文件,envoy会根据配置文件做一些流量的限制

自动注入

自动注入其实就是给namespace打上一个标签istio-injection=enabled

kubectl label ns injection istio-injection=enabled