istio
服务网格

1.下载


wget https://github.com/istio/istio/releases/download/1.4.5/istio-1.4.5-linux.tar.gz
根据实际需求下载对应版本

2.基础


解压后bin目录为可执行文件 istioctl ,用该工具管理部署在kubernetes集群的istio
PATH=$PATH:/istio/bin #将istio添加到PATH
cp tools/istioctl.bash ~/.istioctl.bash
source ~/.istioctl.bash # 生效istio工具,可以使用istioctl自动补全

  1. istio version #获取版本,默认会到istio集群获取版本信息,如果未安装会报错
  2. istio version --remote=false #仅查看当前版本,不连接到集群

3.安装


istioctl manifest apply —set profile=demo #以demo版的profile安装istio,需要在master节点
istioctl profile list #查看当前可用的profile版本
#安装的本质就是将istio的一些资源文件部署到kubernetes集群

基础组件介绍:
    tracing: 全链路监控的工具 
    pilot: 服务发现和服务配置的工具
    Kiali: 等同于kubernetes的Dashboard,面板
    Prometheus: 监控
    Telemetry: 遥测,展示请求报错
    Galley:istio的配置中心
    IngressGateway: 入口网关
    EgressGateway: 出口网关
    Citadel: 流量加密,身份认证
    policy: 策略
    Injector: 注入

4.检查安装正常


kubectl get all -n istio-system

service/istio-ingressgateway :该资源默认为 LoadBanlance ,一直处于pending状态,需手动修改未nodeport
#一般集群并没有loadbanlance资源,所以需要改为nodeport

5.卸载


istioctl manifest generate —set profile=demo | kubectl delete -f -
#istioctl生成kubernetes的配置文件,打印到标准输出,由kubectl删除

6.子命令


istioctl analyze #分析配置信息,并将结果打印到控制台
#会分析默认命令空间下,有关被istio注入的资源的检查工作,是否由校验问题 -n xxxx 指定检查命名空间

kiali overview #界面展示工具,直接访问istioctl安装的kiali

7.istio profile


istioctl profile dump demo > demo.yaml #获取demo类型的profile配置
istioctl profile lsit #列出可用的profile版本,不同的版本部署的组件跟插件不同

istio 官方推荐在生产环境使用default版本的profile
# empty profile,根据自己的需求开启

8.istio injector


支持注入的资源:
job,daemonset,replicaset,pod,deployment
service,secrets,configmap #注入后不会产生效果

1.手动注入
    touch demo.yaml    #创建资源
    kubectl create ns demo 
    kubectl apply -f demo.yaml -n dmeo 
    istioctl kube-inject -f demo.yaml -o demo-istio.yaml  #模拟注入后的状态查看
    istioctl kube-inject -f demo.yaml | kubectl apply -f - -n demo #真实注入

2.注入后
    会添加一个 istio-proxy容器,一个istio-init容器(init容器完成初始化容器后退出)

    1.istio-init容器    
        初始化网络命名空间
        kubectl exec -it demo_pod -- ifconfig  #在被注入的demo容器执行ifconfig 
                                     netstat -tnlp #查看监听的地址及端口
        kubectl logs demo_pod -c istio-init #打印istio-init做的事情,大都是配置环境变量iptables规则
            修改了iptables nat表,添加了四条链,及相关的规则
            iptables -t nat -vnL #进到istio-proxy容器network namespaces 查看iptables规则
    2.多出5个监听端口
        通过istio注入后,网络端口会多出5个监听(监听进程为istio-proxy容器内 envoy 进程)

    3.网络服务策略改变
        #如禁止,允许某个ip访问该容器,或者阻止某些ip网段访问,通过系统net.filter实现
            #例如 iptables 制定的策略(iptables是客户端,net.filter是服务端)
        istio-init通过运行定义好的脚本 istio-iptables完成网络初始化    

3.容器内进程
    istio-proxy 容器
        1.pilot-agent
        2.envory 
        #pilot-agent生成envory配置,再启动envory进程,并且实时监听envory进程,当envory出错,重启envory进程
        #当配置被修改,pilot-agent会使用新的配置重启envory进程
        #envoy 进程类似于nginx(比nginx轻量的多),负责对流量进程转发

    pilot-agent工作流程:
        1.pilot-agent会实时向管理侧pilot-discovery服务同步策略配置
        2.pilot-agent通过watch的方式实时监听apiserver关于istio策略的修改
        3.用户向apiserver提交一个istio-policy.yaml(自定义的流量配置),apiserver准入后写入etcd
        4.pilot-discovery监听到用户配置的istio策略
        5.pilot-discovery将用户的istio配置转换为envoy配置,并同步给pilot-agent
        6.所有被注入的pod上pilot-agent进程接收到envoy配置,使用新的配置重启envoy进程
        7.envoy使用新的配置进程流量转发

    envoy进程作用
        端口:15000 15001 15090 15020 15006 
        15000仅监听127.0.0.1:port,管理端口,仅能在本容器访问

4.istiod 容器(istio原生组件,在istio-system namespace下的容器)
    pilot-discovery 进程就运行在该容器

5.自动注入
    kubectl label ns demo istio-injection=enabled 
    #为namespace添加label后,该namespace下的资源创建时会自动注入istio

9.istio upgrade


升级计划,升级前置条件,升级步骤
1.升级计划
istioctl,heml两个工具都可以升级istio
2.前置条件
istio version #待升级版本需要与要升级版本最好不要跨大版本
istioctl安装的istio,使用istioctl工具升级
3.升级步骤
1.istioctl自身的升级
a.下载新版本的istio版本压缩包(github.com/istio/)
b.解压新的压缩包
c.将解压后的istioctl 替换之前的istioctl工具(新压缩包下的 tools/istio_bash 也需要重新source)
d.将新版本的 istio 的profile导出
istioctl profile dump demo > demo.yaml #dump 新版本的demo版本profile
e.jetPolicy配置
vim demo.yaml
jwtPolicy: first-party-jwt #如果不修改会出现证书无法挂载的情况
f.升级
istioctl upgrade -f demo.yaml #开始升级
#会升级istio控制组件的镜像 (istiod,该pod 为istio控制面的主要管理者)
g.验证
检查镜像是否更新到新版本

    2.被istio注入过的资源(deployment,sts...)升级istio数据容器
        1.之前是手动注入的
            istioctl kube-inject -f demo.yaml | kubectl apply -f -  #升级数据侧istio
        2.自动注入的
            istioctl rollout restart deployment --namespace namespace_name  #升级namespace下的所有deployment资源

10.istio 流量管理 virtual services


traffic:
流量指的是指定的时间最多可以通过的数据量
traffic management:
流量管理的本质就是采用合理的策略控制流量的方向和多少
网格:
一个资源被注入istio后,就是一个网格
流量走向:
1.ingress traffic 入口流量将流量转发到后端pod的envoy
2.envoy容器将流量转发到pod的业务容器
3.业务容器处理后将流量发送给envoy
4.envoy将收到的流量转发到下一个pod进行处理,直到通过engress traffic出口流量发出

istio架构:
    控制面
        pilot
        citadel 
        galley 
    数据面
        envoy 

istio数据面流量
    istio注入后,各服务之间的流量
istio控制面流量
    istio控制组件之间与数据面组件同步的流量

1.istio流量管理(特指的是数据面的流量,控制面的流量无需管理)
    管理依赖于部署在服务内的envoy代理,网格发送的所有流量以及网格所有接收的流量,都要通过envoy进行代理,可以
    轻松的引导和控制周围的流量,而无需对服务进行更改

    实现:
        通过五种resource
            virtual services
            destination rules 
            gateways 
            service entries
            sidecars

    1.virtual service 
        #client,server两端都需要注入istio网格之内,才能实现流量管控
        1.准备client,server资源(部署nginx作为server,centos作为client、即可)
        2.准备service.yaml配置文件
        3.准备istio-vs.yaml (istio相关配置)
            apiVersion: networking.istio.io/v1alpha3
            kind: VirtualService
            metadata:
              name: web-svc-vs 
            spec:
              hosts:
              - web-svc  #此处host值填写svc的名称,如果不属于同一命名空间,需要加上svc后缀  svc_name.namespace.svc.cluster.local
              http:
              - route:
                - destination:
                    host: tomcat-svc  #80%的流量会进入tomcat-svc servcie,后缀要求同上
                  weight: 80
                - destination:
                    host: http-svc   #20%的流量会进入http-svc service
                  weight: 20

            kubectl get virtualservices.networking.istio.io -n namespace #查看创建的istio virtual service 
        4.将client,service的deployment注入istio,并部署在集群
        5.验证
            在client内访问service(servcie的endpoint是两个服务,一个tomcat,一个httpd)
            验证80%流量在tomcat,20%流量在httpd 

            6.注意:client,与server都要在istio注入内,如果client不在istio注入内,配置的istio virtualservice并不会在该client生效

11.virtual service 理论


1.virtual service作用


在istio网格内实现流量路由

2.virtual service本质
    一段配置片段(对网格内某个目的服务的流量路由配置段)

3.virtual servcie执行
    virtual service配置需要在envoy进程上生效后,才能实现流量路由

4.virtual service语法
    hosts field
        流量需要访问一个在集群内可寻址的访问对象(如果是集群内service资源,集群会做解析,属于可寻址,ingress也可以)
        一般pod不会直接作为目标访问对象,因为pod并不稳定
        一般为:
            1.短服务名 web-svc 
            2.全域名 web-svc.svc.cluster.local  #不同namespace需要加后缀
            3.ingress资源,www.web-svc.com 
            4.*  #跟网关结合使用
    routing rule
        对指定访问目标的访问流量路由规则
        路由规则: #在配置项内越在前面的优先级越高,前面的规则匹配后不会再匹配后面的
            1.匹配条件
                spec:
                    hosts:
                    - "web-svc"
                    http:
                    - match:   #match下为匹配条件,当http请求头部包含 end-user字段,且值为jiuxi,则转发到 httpd-svc,否则转发到tomcat-svc
                      - headers:
                          end-user:
                            exact: jiuxi 
                      route:
                      - destination 
                          host: httpd-svc 
                    - route:
                      - destination:
                          host: tomcat-svc 

                组合规则:
                     http:
                    - match:  
                      - headers:
                          end-user:
                            exact: jiuxi 
                        uri:
                          prefix: "/ratings/v2"  #当请求头end-user的key值为jiuxi,并且请求uri为 /ratings/v2,忽略请求uri大小写,将流量发送到httpd-svc
                        ignoreUriCase: true
                      route:
                      - destination 
                          host: httpd-svc.svc.cluster.local  
            2.路由目的地

10.架构师


1.架构师成长之路
架构师自我修养:
1.知识获取是容易的,但转化成技能却困难(知识需要大量练习才能转换为技能)
2.持续精进(遇到问题尽量往深入学习底层,彻底解决)
3.勤思考,多总结,多体悟才能升华(将学习,实践学到的知识进行思考,总结,知识是死的,解决方案是活的)
4.技术的学习(人的精力是有限的,知识是无限的,要有选择性的深入,其他广泛吸收,兼容并蓄,厚积薄发)
在实际工作中学习和总结,结合实际,学以致用
结合实际,学习基础,底层知识更重要
5.提前预知而非亡羊补牢
6.系统化思考问题
7.技术是硬实力,但晋升需要软实例(越往上晋升越需要软实力)

11.Linux网络命令空间(network namespaces)
网络接口+iptables+routing 构成了Linux系统的网络协议栈
网卡:整个主机的流量汇聚点(进出口)
流量进到网卡后的走向依靠iptables和routing

命令:ip
    ip netns add NAME #新增namespace
    ip netns ls   #查询namespace
    ip netns delete NAME  #删除namespace
    ip netns exec NAME bash #进入namespace
    exit  #退出namespace

    ip netns exec NAME bash -rcfile <(echo "PS1=\"NAME> \"")  #修改namesapce的操作提示符
    ip link #查看当前namespace地址
    route -n  #查看当前namespace路由表
    iptables -vnL -t nat  #查看namespace的iptables

两个不同namespace通信