Istio初探

Posted by hujin on September 26, 2021

背景

网络上很多理论性的说明,包括istio的前世今生,这里就不赘述了,本文将通过安装和实际操作的方式来简单了解下istio的特性.

准备

下载最新版本istio

1
2
3
yum install -y socat
curl -L https://istio.io/downloadIstio | sh -
cd istio-1.11.2

安装istioctl

1
cp bin/istioctl /usr/bin

自动补全

1
2
3
yum install -y bash-completion
echo "source /usr/share/bash-completion/bash_completion">>/root/.bashrc
source /root/.bashrc

安装

安装istio,这里使用的profile是demo

profile实际对应一些参数的开关,可以通过istioctl profile list和istioctl profile dump demo查看具体的参数设置,通过也可以自己修改和创建profile;默认情况下dashboard工具(kiali)是没有安装的,需要手动安装

1
istioctl manifest apply --set profile=demo

卸载istio

1
istioctl manifest generate --set profile=demo | kubectl delete -f -

安装kiali

安装kiali时发现必须安装prometheus,否则界面会报错,应该是有依赖的

1
2
kubectl apply -f samples/addons/kiali.yaml
kubectl apply -f samples/addons/prometheus.yaml

登录kiali

当有实际访问流量时,在kiali的Graph界面中会实时展示访问的设备,以及报文流向、流速,百分比等等,可以在界面选择

1
2
3
4
5
[root@controller01 istio-1.11.2]# kubectl get svc  -n istio-system  kiali
NAME    TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)                          AGE
kiali   NodePort   10.96.140.29   <none>        20001:31919/TCP,9090:32281/TCP   13h

浏览器访问:http://178.104.163.66:31919/

更新istio

升级istioctl

1
2
3
istioctl profile dump demo > demo.yaml
sed 's/jwtPolicy: third-party-jwt/jwtPolicy: first-party-jwt/g' demo.yaml
istioctl upgrade -f demo.yaml

已经inject过的资源升级(再inject一次)

这里分两种情况,如果是通过设置namespace的方式自动inject,则可以rollupdate;如果之前是手动inject的,则再执行一次inject后apply下,触发更新

1
istioctl kube-inject -f xx.yaml | kubectl apply -f -

功能验证DEMO

我们会通过创建两个pod,三个svc,一个virtualservice是完成demo,其中:

  • svc1:绑定pod1,暴露80端口
  • svc2:绑定pod2,暴露80端口
  • svc-vs: 绑定pod1和pod2,会发现访问每个后端的概率都是50%,无法调整
  • virtual-service: 通过注入svc-vs,设置访问svc1和svc2的概率分别是10%和90%
  • client pod: 用来作为客户端访问virtual-service的

架构如下:

1
2
3
                                        svc1 --> pod1
client  --> virtual-service(svc-vs)
                                        svc2 -- pod2

创建资源

创建三个deployment

deployment1.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nginx
spec:
  selector:
    matchLabels:
      app: my-nginx
      run: vs
  replicas: 1
  template:
    metadata:
      labels:
        app: my-nginx
        run: vs
    spec:
      containers:
      - name: my-nginx
        image: httpd:alpine
        ports:
        - containerPort: 80

deployment2.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nginx-2
spec:
  selector:
    matchLabels:
      app: my-nginx-2
      run: vs
  replicas: 1
  template:
    metadata:
      labels:
        app: my-nginx-2
        run: vs
    spec:
      containers:
      - name: my-nginx-2
        image: httpd:alpine
        ports:
        - containerPort: 80

deployment-client.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nginx-client
spec:
  selector:
    matchLabels:
      client: my-nginx
  replicas: 1
  template:
    metadata:
      labels:
        client: my-nginx
    spec:
      containers:
      - name: my-nginx
        image: httpd:alpine
        ports:
        - containerPort: 80

创建两个svc,后端对应deployment中的pod

svc1.yaml

1
2
3
4
5
6
7
8
9
10
11
12
apiVersion: v1
kind: Service
metadata:
  name: my-apache
  labels:
    run: my-apache
spec:
  ports:
  - port: 80
    protocol: TCP
  selector:
    app: my-nginx

svc2.yaml

1
2
3
4
5
6
7
8
9
10
11
12
apiVersion: v1
kind: Service
metadata:
  name: my-apache-2
  labels:
    run: my-apache-2
spec:
  ports:
  - port: 80
    protocol: TCP
  selector:
    app: my-nginx-2

创建一个svc,后端对应所有deployment中的pod

1
2
3
4
5
6
7
8
9
10
11
12
apiVersion: v1
kind: Service
metadata:
  name: my-apache-vs
  labels:
    run: my-apache-vs
spec:
  ports:
  - port: 80
    protocol: TCP
  selector:
    run: vs

创建virtualservice

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: hujin-virtual-svc
spec:
  hosts:
  - my-apache-vs
  http:
  - route:
    - destination:
        host: my-apache
        port:
          number: 80
      weight: 10
    - destination:
        host: my-apache-2
        port:
          number: 80
      weight: 90

部署

1
2
3
4
5
6
7
8
istioctl kube-inject -f deployment1.yaml  | kubectl apply -f -
istioctl kube-inject -f deployment2.yaml  | kubectl apply -f -
istioctl kube-inject -f svc1.yaml  | kubectl apply -f -
istioctl kube-inject -f svc2.yaml  | kubectl apply -f -
istioctl kube-inject -f svc-vs.yaml  | kubectl apply -f -

kubectl apply -f virtualservice.yaml
kubectl apply -f deployment-client.yaml

通过k8s原生方式访问资源

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
获取所有service资源
[root@controller01 istio]# kubectl get svc
NAME           TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes     ClusterIP   10.96.0.1       <none>        443/TCP   107d
my-apache      ClusterIP   10.96.40.245    <none>        80/TCP    41m
my-apache-2    ClusterIP   10.96.155.136   <none>        80/TCP    35m
my-apache-vs   ClusterIP   10.96.57.227    <none>        80/TCP    27m

访问每个svc,可以发现此时svc-vs中访问每个后端的概率是50%,且无法调整
[root@controller01 istio]# curl 10.96.40.245
<html><body><h1>test1</h1></body></html>
[root@controller01 istio]# curl 10.96.155.136
<html><body><h1>test2</h1></body></html>
[root@controller01 istio]# curl 10.96.57.227
<html><body><h1>test1</h1></body></html>
[root@controller01 istio]# curl 10.96.57.227
<html><body><h1>test2</h1></body></html>

通过istio注入方式访问资源,可以发现访问比例是按照设置的百分比来的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[root@controller01 istio]# kubectl exec -it my-nginx-client-7f844864c7-cq7tq -- sh
/usr/local/apache2 # wget -q -O - http://my-apache-vs
<html><body><h1>test2</h1></body></html>
/usr/local/apache2 # wget -q -O - http://my-apache-vs
<html><body><h1>test1</h1></body></html>
/usr/local/apache2 # wget -q -O - http://my-apache-vs
<html><body><h1>test2</h1></body></html>
/usr/local/apache2 # wget -q -O - http://my-apache-vs
<html><body><h1>test2</h1></body></html>
/usr/local/apache2 # wget -q -O - http://my-apache-vs
<html><body><h1>test2</h1></body></html>
/usr/local/apache2 # wget -q -O - http://my-apache-vs
<html><body><h1>test2</h1></body></html>
/usr/local/apache2 # wget -q -O - http://my-apache-vs
<html><body><h1>test2</h1></body></html>
/usr/local/apache2 # wget -q -O - http://my-apache-vs
<html><body><h1>test2</h1></body></html>