Istio 1.5.1部署及实战

2020-04-25  本文已影响0人  天夭夭

Istio

官方文档 https://istio.io/zh/docs
部分资料参考:https://jicki.me/istio/2020/04/13/Istio-1.5/
https://jimmysong.io/istio-handbook/concepts/traffic-management-basic.html

一、基础概念及原理

Istio 是什么?(衣撕丢)

服务网格 又是什么?

Istio 架构

image.png

Istio 组件

Envoy

Mixer

Pilot

Citadel

Galley

二、安装Istio Install

我这里 Kubernetes 版本为1.18 目前只有这么一个集群

搭建 Kubernetes

这一部分这里就省略了, 如需这一部分 文档, 请参考其他的博文。

下载 Istio 项目包

在 macOS 或 Linux 系统中, 也可以通过以下命令下载最新版本的 Istio

# 新建目录
mkdir -p /opt/istio && cd /opt/istio

# 设置安装版本
export ISTIO_VERSION=1.5.1

# 下载文件
curl -L https://istio.io/downloadIstio | sh -

#输出如下:

Istio 1.5.1 Download Complete!

Istio has been successfully downloaded into the istio-1.5.1 folder on your system.

Next Steps:
See https://istio.io/docs/setup/kubernetes/install/ to add Istio to your Kubernetes cluster.

To configure the istioctl client tool for your workstation,
add the /opt/istio/istio-1.5.1/bin directory to your environment path variable with:
         export PATH="$PATH:/opt/istio/istio-1.5.1/bin"

Begin the Istio pre-installation verification check by running:
         istioctl verify-install 

Need more information? Visit https://istio.io/docs/setup/kubernetes/install/ 

#配置环境变量
vi /etc/profile
# 添加
export PATH="$PATH:/opt/istio/istio-1.5.1/bin"

# 生效配置
source /etc/profile

#验证安装
istioctl verify-install

Checking the cluster to make sure it is ready for Istio installation...

#1. Kubernetes-api
-----------------------
Can initialize the Kubernetes client.
Can query the Kubernetes API Server.

#2. Kubernetes-version
-----------------------
Istio is compatible with Kubernetes: v1.18.0.

#3. Istio-existence
-----------------------
Istio will be installed in the istio-system namespace.

#4. Kubernetes-setup
-----------------------
Can create necessary Kubernetes configurations: Namespace,ClusterRole,ClusterRoleBinding,CustomResourceDefinition,Role,ServiceAccount,Service,Deployments,ConfigMap. 

#5. SideCar-Injector
-----------------------
This Kubernetes cluster supports automatic sidecar injection. To enable automatic sidecar injection see https://istio.io/docs/setup/kubernetes/additional-setup/sidecar-injection/#deploying-an-app

-----------------------
Install Pre-Check passed! The cluster is ready for Istio installation.

#配置 istioctl 命令自动补全
#  创建目录
mkdir -p /usr/share/istio

# 拷贝补全脚本
cp tools/istioctl.bash /usr/share/istio/


# 导入自动补全
source /usr/share/istio/istioctl.bash



# 添加到 bashrc 中
vi ~/.bashrc
# 添加如下:
# istio
source /usr/share/istio/istioctl.bash


# 测试tab补全

[root@k8s-node-1 istio-1.5.1]# istioctl 
analyze          authz            dashboard        experimental     manifest         profile          proxy-status     upgrade          verify-install   
authn            convert-ingress  deregister       kube-inject      operator         proxy-config     register         validate         version  

安装 istio

# 通过如下命令进行安装 (manifest 是资源清单, profile 指定类型的清单)
istioctl manifest apply --set profile=demo 

输出如下:
- Applying manifest for component Base...
✔ Finished applying manifest for component Base.
- Applying manifest for component Pilot...
✔ Finished applying manifest for component Pilot.
- Applying manifest for component EgressGateways...
- Applying manifest for component IngressGateways...
- Applying manifest for component AddonComponents...
✔ Finished applying manifest for component EgressGateways.
✔ Finished applying manifest for component IngressGateways.
✔ Finished applying manifest for component AddonComponents.

✔ Installation complete
#查看部署情况

#如果集群运行在一个不支持外部负载均衡器的环境中(例如:minikube),istio-ingressgateway 的 EXTERNAL-IP 将显示为 <pending> 状态。请使用服务的 NodePort 或 端口转发来访问网关。
kubectl get pods -n istio-system
NAME                                   READY   STATUS    RESTARTS   AGE
grafana-5f6f8cbf75-lqnjg               1/1     Running   0          17m
istio-egressgateway-74896c8487-mjlg8   1/1     Running   0          17m
istio-ingressgateway-54d494869-7npql   1/1     Running   0          17m
istio-tracing-9dd6c4f7c-x5kcp          1/1     Running   0          17m
istiod-756bd84654-n2k6m                1/1     Running   0          18m
kiali-869c6894c5-64vmw                 1/1     Running   0          17m
prometheus-c89875c74-rgzdx             2/2     Running   0          17m


kubectl get svc -n istio-system 
NAME                        TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                                                                                                                                      AGE
grafana                     ClusterIP      10.254.35.48    <none>        3000/TCP                                                                                                                                     158m
istio-egressgateway         ClusterIP      10.254.10.123   <none>        80/TCP,443/TCP,15443/TCP                                                                                                                     158m
istio-ingressgateway        LoadBalancer   10.254.26.46    <pending>     15020:32142/TCP,80:30000/TCP,443:32701/TCP,15029:30413/TCP,15030:30781/TCP,15031:31714/TCP,15032:32419/TCP,31400:30673/TCP,15443:31123/TCP   158m
istio-pilot                 ClusterIP      10.254.54.205   <none>        15010/TCP,15011/TCP,15012/TCP,8080/TCP,15014/TCP,443/TCP                                                                                     158m
istiod                      ClusterIP      10.254.3.7      <none>        15012/TCP,443/TCP                                                                                                                            158m
jaeger-agent                ClusterIP      None            <none>        5775/UDP,6831/UDP,6832/UDP                                                                                                                   158m
jaeger-collector            ClusterIP      10.254.2.80     <none>        14267/TCP,14268/TCP,14250/TCP                                                                                                                158m
jaeger-collector-headless   ClusterIP      None            <none>        14250/TCP                                                                                                                                    158m
jaeger-query                ClusterIP      10.254.61.2     <none>        16686/TCP                                                                                                                                    158m
kiali                       ClusterIP      10.254.7.135    <none>        20001/TCP                                                                                                                                    158m
prometheus                  ClusterIP      10.254.8.200    <none>        9090/TCP                                                                                                                                     158m
tracing                     ClusterIP      10.254.39.104   <none>        80/TCP                                                                                                                                       158m
zipkin                      ClusterIP      10.254.32.230   <none>        9411/TCP                                                                                                                                     158m
kubectl patch service istio-ingressgateway -n istio-system -p '{"spec":{"type":"NodePort"}}'

kubectl get svc -n istio-system istio-ingressgateway 
NAME                   TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)                                                                                                                                      AGE
istio-ingressgateway   NodePort   10.254.26.46   <none>        15020:32142/TCP,80:30000/TCP,443:32701/TCP,15029:30413/TCP,15030:30781/TCP,15031:31714/TCP,15032:32419/TCP,31400:30673/TCP,15443:31123/TCP   176m

#验证 istio版本
[root@k8s-node-1 ~]# istioctl version
client version: 1.5.1
control plane version: 1.5.1
data plane version: 1.5.1 (3 proxies)

#Kiali 组件
#Kiali 以 web ui 的方式可视化服务网格。
#查看 kiali svc
[root@k8s-node-1 kubeadm]# kubectl get svc -n istio-system  kiali
NAME    TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)     AGE
kiali   ClusterIP   10.254.7.135   <none>        20001/TCP   4h24m
#配置访问(我这里的node节点为云主机,所以我配置了一个 ingress)
[root@k8s-node-1 ~]# cat kiali-ingress.yaml 
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: kiali-ingress
  namespace: istio-system
spec:
  rules:
  - host: kiali.aaa.me
    http:
      paths:
      - backend:
          serviceName: kiali
          servicePort: 20001

#创建ingress服务
[root@k8s-node-1 kubeadm]# kubectl apply -f kiali-ingress.yaml 
ingress.extensions/kiali-ingress created

# 查看服务
[root@k8s-node-1 ~]# kubectl get ingress -n istio-system 
NAME            CLASS    HOSTS             ADDRESS       PORTS   AGE
kiali-ingress   <none>   kiali.jicki.me    10.254.8.81   80      2m31s

Istio Profile

Profile 相关的介绍以及具体的区别

[root@k8s-node-1 istio]# istioctl profile list
Istio configuration profiles:
    minimal
    remote
    separate
    default
    demo
    empty
[root@k8s-node-1 istio]# istioctl profile dump default > default.yaml

istio injection

三、实操使用

对某个namespaces实现injection 自动注入

# 注入
[root@k8s-node-1 ~]# kubectl label namespace default istio-injection=enabled
namespace/jicki labeled


# 检测注入情况
[root@k8s-node-1 ~]# istioctl analyze -n default
✔ No validation issues found when analyzing namespace: default.


# 查看 namespace 的 labels
[root@k8s-node-1 ~]# kubectl get ns --show-labels
NAME              STATUS   AGE     LABELS
default           Active   9d     istio-injection=enabled

手动注入

kubectl apply -f <(istioctl kube-inject -f  file_name.yaml)

实战1、实现对流量控制

#创建pod
vim  nginx-test.yaml
apiVersion: apps/v1
kind: Deployment 
metadata: 
  name: nginx-1
  labels:
    web: nginx-1
spec: 
  replicas: 1
  selector:
    matchLabels:
      web: nginx-1
  template: 
    metadata: 
      labels: 
        app: nginx 
        web: nginx-1
        version: v1.0.0
    spec: 
      containers: 
        - name: nginx 
          image: nginx:alpine 
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 80
              name: http
          command: ["/bin/sh", "-c", "echo 'hello nginx-1' > /usr/share/nginx/html/index.html; nginx  -g  'daemon off;'"]
---
apiVersion: apps/v1
kind: Deployment 
metadata: 
  name: nginx-2
  labels:
    web: nginx-2
spec: 
  replicas: 1
  selector:
    matchLabels:
      web: nginx-2
  template: 
    metadata: 
      labels: 
        app: nginx 
        web: nginx-2
        version: v1.0.1
    spec: 
      containers: 
        - name: nginx 
          image: nginx:alpine 
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 80
              name: http
          command: ["/bin/sh", "-c", "echo 'hello nginx-2' > /usr/share/nginx/html/index.html; nginx  -g  'daemon off;'"]
---
apiVersion: apps/v1
kind: Deployment 
metadata: 
  name: nginx-3
  labels:
    web: nginx-3
spec: 
  replicas: 1
  selector:
    matchLabels:
      web: nginx-3
  template: 
    metadata: 
      labels: 
        app: nginx 
        web: nginx-3
        version: v1.0.2
    spec: 
      containers: 
        - name: nginx 
          image: nginx:alpine 
          imagePullPolicy: IfNotPresent
          ports:
            - containerPort: 80
              name: http
          command: ["/bin/sh", "-c", "echo 'hello nginx-3' > /usr/share/nginx/html/index.html; nginx  -g  'daemon off;'"]
---
apiVersion: apps/v1
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc-1
  labels:
    web: nginx-1
spec:
  ports:
    - port: 80
      name: http
      targetPort: 80
      protocol: TCP
  selector:
    web: nginx-1
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc-2
  labels:
    web: nginx-2
spec:
  ports:
    - port: 80
      name: http
      targetPort: 80
      protocol: TCP
  selector:
    web: nginx-2
---
apiVersion: apps/v1
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc-3
  labels:
    web: nginx-3
spec:
  ports:
    - port: 80
      name: http
      targetPort: 80
      protocol: TCP
  selector:
    web: nginx-3
---
apiVersion: v1 
kind: Service
metadata: 
  name: nginx-svc 
  labels:
    app: nginx
spec: 
  ports: 
    - port: 80
      name: http
      targetPort: 80
      protocol: TCP 
  selector: 
    app: nginx
[root@k8s-node-1 istio]# kubectl apply -f <(istioctl kube-inject -f nginx-test.yaml)
deployment.apps/nginx-deployment created

#查看生成的pod
[root@master demo-file]# kubectl get po
NAME                              READY   STATUS    RESTARTS   AGE
nginx-1-6cf586866c-5gj2n          2/2     Running   0          5h53m
nginx-2-dffbd7fc4-jcs62           2/2     Running   0          5h53m
nginx-3-58db9d749-jk52v           2/2     Running   0          5h35m

#观察边车服务过程注入
[root@master demo-file]# kubectl describe po nginx-1-6cf586866c-5gj2n
#略

#查看 istio 对外服务的端口以及相关进程
#可以发现除了80端口还有其他5个额外的端口
[root@master demo-file]# kubectl exec -it nginx-1-6cf586866c-5gj2n -c istio-proxy -- netstat -ntlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 0.0.0.0:15006           0.0.0.0:*               LISTEN      15/envoy            
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      -                   
tcp        0      0 0.0.0.0:15090           0.0.0.0:*               LISTEN      15/envoy            
tcp        0      0 127.0.0.1:15000         0.0.0.0:*               LISTEN      15/envoy            
tcp        0      0 0.0.0.0:15001           0.0.0.0:*               LISTEN      15/envoy            
tcp6       0      0 :::15020                :::*                    LISTEN      1/pilot-agent 

#查看配置的三个 service 的 endpoints
[root@master demo-file]# kubectl get ep
NAME           ENDPOINTS                                          AGE
ceph.com-rbd   <none>                                             2d23h
kubernetes     172.24.49.78:6443                                  4d8h
nginx-svc      10.254.65.113:80,10.254.70.81:80,10.254.70.82:80   6h
nginx-svc-1    10.254.70.81:80                                    6h
nginx-svc-2    10.254.65.113:80                                   6h
nginx-svc-3    10.254.70.82:80                                    5h41m
[root@master demo-file]# cat nginx-test-load.yaml 
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: nginx-svc-vs
spec:
  hosts: 
  - "*"
  gateways:
  - istio-system/ingressgateway
  http:
  - route:
    - destination:
        host: nginx-svc-1.default.svc.cluster.local
      weight: 20
    - destination:
        host: nginx-svc-2.default.svc.cluster.local
      weight: 50
    - destination:
        host: nginx-svc-3.default.svc.cluster.local
      weight: 30

#VirtualService 服务并非是 kubernetes 中实际的 service 服务。
#kubectl get virtualservices 使用这个命令查看 Virtual Service
#创建Virtual Service
kubectl apply -f nginx-test-load.yaml
#查看Virtual Service
[root@master demo-file]# kubectl get virtualservices
NAME           GATEWAYS                        HOSTS   AGE
nginx-svc-vs   [istio-system/ingressgateway]   [*]     6h2m
[root@master demo-file]# cat nginx-gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
  name: app-gateway
spec:
  selector:
    istio: ingressgateway
  servers:
  - port:
      number: 80
      name: http
      protocol: HTTP
    hosts:
    - "*"

[root@master demo-file]# cat nginx-ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  generation: 1
  labels:
    cattle.io/creator: norman
  name: myapp-gateway
  namespace: istio-system
spec:
  rules:
  - host: wp.abc.com
    http:
      paths:
      - backend:
          serviceName: istio-ingressgateway
          servicePort: 80
#创建gateway及ingress
kubectl apply -f nginx-ingress.yaml
kubectl apply -f nginx-gateway.yaml
while true;
do
wget -q -O - http://wp.abc.com/;
done

实战2、实现对特定流量控制

[root@master demo-file]# cat nginx-test-headers-user.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: nginx-svc-vs
spec:
  hosts: 
  #- nginx-svc.default.svc.cluster.local
  - "*"
  gateways:
  - istio-system/ingressgateway
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    route:
    - destination:
        host: nginx-svc-2.default.svc.cluster.local
  - route:
    - destination:
        host: nginx-svc-1.default.svc.cluster.local
#应用配置
kubectl apply -f nginx-test-headers-user.yaml
[root@master demo-file]# curl wp.abc.com
hello nginx-1
[root@master demo-file]# curl wp.abc.com -Hend-user:jason
hello nginx-2

实战3、实现对特定流量控制,并附件其他动作

[root@master demo-file]# cat nginx-test-headers-user-sleep2s.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: nginx-svc-vs
spec:
  hosts: 
  - "*"
  gateways:
  - istio-system/ingressgateway
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    fault:
      delay:
        percent: 100    #触发占比100%
        fixedDelay: 2s
    route:
    - destination:
        host: nginx-svc-2.default.svc.cluster.local
  - route:
    - destination:
        host: nginx-svc-1.default.svc.cluster.local
#应用配置
kubectl apply -f  nginx-test-headers-user-sleep2s.yaml
[root@master demo-file]# curl wp.abc.com
hello nginx-1
[root@master demo-file]# curl wp.abc.com -Hend-user:jason
#等待两秒,返回数据
hello nginx-2

实战4、实现故障注入

[root@master demo-file]# cat nginx-test-headers-user-httpstatus.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: nginx-svc-vs
spec:
  hosts: 
  - "*"
  gateways:
  - istio-system/ingressgateway
  http:
  - fault:
      abort:
        httpStatus: 500
        percentage:
          value: 90      #触发占比90%
    match:
    - headers:
        end-user:
          exact: jason
    route:
    - destination:
        host: nginx-svc-2.default.svc.cluster.local
  - route:
    - destination:
        host: nginx-svc-1.default.svc.cluster.local

#应用配置
kubectl apply -f nginx-test-headers-user-httpstatus.yaml
[root@master demo-file]# curl wp.abc.com
hello nginx-1
[root@master demo-file]# curl wp.abc.com -Hend-user:jason
fault filter abort
#返回状态码为500。

更多实战内容、可从官网获取。

Istio Upgrade

注意事项
升级 Istio 之前, 请确认是否支持升级 istioctl manifest versions 查看支持版本。

升级过程中可能发生流量中断。为了缩短流量中断时间, 请确保每个组件(Citadel 除外)至少运行有两个副本。同时, 确保 PodDistruptionBudgets 配置最小可用性为 1。

确保 istio profile 与 需要升级的版本所配置的 profile 一致。

升级步骤
1. 下载需要升级的 istio 版本 curl -L https://istio.io/downloadIstio | ISTIO_VERSION=1.5.1 sh -

2. 替换 istioctl 二进制文件, 或者 更改 istio 的环境变量PATH路径到新版本的目录中。

3. 如果配置了 istioctl 自动补全,还需要替换为 新的 自动补全脚本。

4. 使用新的 istioctl 导出新版本的 profile 文件 istioctl profile dump demo > demo.yaml

5. 修改 demo.yaml 文件, 将其中 jwtPolicy 身份验证机构修改为 first-party-jwt。Istio 将默认使用第三方令牌。

5.1  验证是否支持 第三方令牌。kubectl get --raw /api/v1 | jq '.resources[] | select(.name | index("serviceaccounts/token"))'

5.1.1 jwtPolicy = third-party-jwt 使用第三方令牌 更安全 Istio 默认使用这个选项。

5.1.2  jwtPolicy = first-party-jwt 使用第一方令牌 属性比较不安全。

6. istioctl upgrade -f demo.yaml 命令进行升级。

7. 观察 kubernets 中 istio-system 的服务更新完成。

8. 重新注入环境中部署的服务, 用以更新注入数据。

8.1 对于自动注入的情况可使用如下命令:

8.1.1 kubectl rollout restart deployment

8.1.2 kubectl rollout restart statefulset

8.1.3 kubectl rollout restart daemonset

8.2 对于手动注入的情况( 需要重新 apply 一下服务) :

8.2.1 kubectl apply -f <(istioctl kube-inject -f nginx-test.yaml)
9. 检查升级, 执行 istioctl version 检查

9.1 client version 版本是否为新版本。

9.2 control plane version 版本是否为新版本。

9.3 data plane version 中是否全部 proxies 都为新版本。

上一篇 下一篇

猜你喜欢

热点阅读