2020-05-18【Istio服务治理,K8S各个组件】
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2020-05-18【Istio服务治理,K8S各个组件】相关的知识,希望对你有一定的参考价值。
参考技术A今日鸡汤:
愿你能遇到了解你的人:)
Istio流量治理的目标是什么?
以基础设施的方式提供给用户非侵入的流量治理能力,用户只需要关注自己的业务逻辑开发,无须关注服务访问管理。
Istio流量治理的方式是什么?
在控制面:管理员通过命令或API创建流量规则,Pilot将该规则转换为Envoy标准形式后下发给Envoy。
在数据面:Envoy拦截Pod本地容器的Inbound和Outbound流量,在流量经过Envoy时执行对应的流量规则,进行治理。
服务发现和负载均衡的工作流程是什么?
第一步,服务注册,各服务将服务名和服务实例注册到服务注册中心;
第二步,服务发现,客户端发起服务访问时,从服务注册中心获取服务对应的实例;
第三步,负载均衡,从实例列表中选择一个服务实例。
Pilot将服务发现数据通过Envoy的标准接口发给数据面,Envoy根据配置的负载均衡策略选择一个实例转发请求。
为什么需要服务熔断?
防止网络和服务调用故障级联发生,限制故障的影响范围,防止故障蔓延导致系统整体性能下降或雪崩。
在Istio中提供了连接池和故障实例隔离的能力。
-连接池:在Istio中通过限制某个客户端对目标服务的连接数、访问请求数等,避免对一个服务的过量访问,如果超过配置阈值,则快速断路请求。
-故障实例隔离:如果某个服务频繁超时或出错,则将该实例隔离。
什么是故障注入?
使用一种手段在待测试的系统中引入故障,从而测试其健壮性和应对故障的能力。
灰度发布的场景?
第一种,蓝绿发布。新版本部署在另一套独立的资源上,当可用时,直接将所有流量从老版本切换到新版本,当有问题时,快速切回老版本。
第二种,AB测试。同时在线上部署A和B两个对等的版本来接受流量,收集反馈,最终决定用哪个版本。
第三种,金丝雀发布。上线一个新版本,从老版本切一部分流量到新版本上来判定新版本在生产环境的实际表现,没有问题的话,逐步增加切换比例直到全部切换完成。
Istio的服务访问入口是什么?
在Istio中通过Gateway访问网格内的数据,也是一个Envoy,从Istio的控制面板接受配置,统一执行配置规则,Gateway一般为LoadBalancer类型的service。
在Istio中怎么接入外部服务?
通过一个ServiceEntry的资源对象将网格外的服务注册到网格上,然后像对网格内的普通服务一样对网格外的服务访问进行治理。
推荐一篇文章: 换个角度入门K8S ,从业务演进的角度讲K8S的各个组件功能,总结一下:
运行编排系统的服务器叫做 master节点 ,运行业务容器的服务器叫做 worker节点 。
master节点上提供管理接口的组件叫 kube apiserver 。
与api server交互的客户端中,提供给集群运维管理员使用的叫做 kubectl ,提供给worker节点使用的叫做 kubelet 。
运维人员可以通过kubelet向master发送命令,master收到请求后,根据集群中worker节点的资源信息进行调度,然后把创建指令下发到对应的worker上,负责调度的叫 kube scheduler 。
每个worker上的kubelet会周期性的上报节点资源和容器运行情况,然后master把数据存储到 etcd 的开源系统中。
为了与其他worker节点通信,每个worker节点需要有容器ip的路由转发信息,由一个专门负责监听并调整路由转发配置的组件来负责,叫 kube proxy 。
Istio微服务治理网格基本使用以及与Kubernetes集成的架构
Istio微服务治理网格基本使用以及与Kubernetes集成的架构
文章目录
1.Pod应用程序注入Sidecar代理程序
Istio在程序中注入Sidecar的方式有两种:分别是手动注入和自动注入。
手动注入是通过Istio命令将Sidecar Proxy程序注入到已经存在的资源编排YAML文件里,手动注入通常适用于程序已经在K8S集群中部署的环境,可以通过istioctl kube-inject
命令将Proxy的YAML参数与程序的YAML进行结合,然后执行kubectl apply
命令将已经部署的Pod资源手动注入Sidecar Proxy。
自动注入与命名空间namespace有关,通过指定的命名空间打上Sidecar自动注入的标签,当在该命名空间下再次创建Pod资源时会自动注入Proxy代理程序。
程序注入Sidecar的原理:创建Pod的请求交给apiserver—>Istio通过k8s的准入控制将proxy容器再Pod中添加—>将信息同步到etcd数据库。
即使应用程序注入了Sidecar,以网格环境运行,也是可以通过service的服务发现地址直接连接到应用程序,越过代理程序。
程序接入Istio服务网格后的访问流程如下图所示:用户通过nodeport端口映射访问到Istio的ingressgateway服务,由ingressgateway将请求转发到应用程序对应的gateway资源,然后通过配置的virtualservice资源,将请求转发到应用程序的service资源,最后由程序容器提供应用服务,程序之间的流量请求都是通过Istio-proxy完成。
Istio的samples/目录中提供了一些测试用例,便于我们研究Istio服务,注入Sidecar就以samples目录中的httpbin程序为例实现。
1.1.为应用程序手动注入Sidecar
通过istioctl kube-inject
命令指定已存在的资源编排YAML文件,会将Sidecar代理程序注入到YAML文件中,但是不会直接覆盖原有YAML文件,而是直接输出到终端,我们可以通过重定向的方式将注入Sidecar后的YAML重新写入到新的文件,也可以直接交给kubectl命令执行。
1)首先在K8S集群中部署httpbin服务
主要是为了查看注入前和注入后的区别。
1.创建httpbin资源
[root@k8s-master httpbin]# kubectl create -f httpbin-nodeport.yaml
service/httpbin created
deployment.apps/httpbin created
2.查看资源的状态
[root@k8s-master httpbin]# kubectl get Pod,svc
NAME READY STATUS RESTARTS AGE
Pod/httpbin-84cddc85d4-pf6hs 1/1 Running 0 20m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/httpbin NodePort 10.102.187.192 <none> 8000:30187/TCP 20m
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 4d3h
#可以看到httpbind的Pod资源中只有一个容器,传统的在K8S中部署的方式。
2)手动为httpbin服务注入Sidecar代理程序
1.查看注入Sidecar的配置参数
[root@k8s-master httpbin]# istioctl kube-inject -f httpbin-nodeport.yaml
增加了sidercar proxy代理程序的容器。
2.为应用程序注入Sidecar代理
[root@k8s-master httpbin]# kubectl apply -f <(istioctl kube-inject -f httpbin-nodeport.yaml)
service/httpbin configured
deployment.apps/httpbin configured
3.观察注入Sidecar后Pod资源的变量
[root@k8s-master httpbin]# kubectl get Pod
NAME READY STATUS RESTARTS AGE
httpbin-d6f4f66c6-sgglh 2/2 Running 0 20m
#可以看到Pod中运行的容器数量明显变成了2个,一个是程序容器一个是proxy代理程序。
4.进入proxy的容器
[root@k8s-master httpbin]# kubectl exec -it httpbin-d6f4f66c6-sgglh -c istio-proxy bash
Istio-proxy@httpbin-d6f4f66c6-sgglh:/$ ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
Istio-p+ 1 0.1 0.9 763560 38292 ? Ssl 07:51 0:02 /usr/local/bin/pilot-agent proxy Sidecar --domain default.svc.cluster.local --serviceCluster httpbin.default --proxyLogLevel=warning --proxyComponen
Istio-p+ 12 0.4 1.0 187524 42440 ? Sl 07:51 0:05 /usr/local/bin/envoy -c etc/Istio/proxy/envoy-rev0.json --restart-epoch 0 --drain-time-s 45 --parent-shutdown-time-s 60 --service-cluster httpbin.de
#可以看到proxy容器中运行了两个程序,pilot-agent进程主要负责热更新envoy的配置内容,envoy就是Sidecar代理程序,负责流量的管理,当在控制中心更新了proxy的配置,pilot-agent就会加载最新的配置内容然后通知envoy更新配置。
1.2.为应用程序自动注入Sidecar
为应用程序自动注入Sidecar是通过namespace中的标签实现的,打完注入标签后,新创建的Pod资源会自动注入Sidecar,打标签之前的Pod资源是不会注入Sidecar。
1)将namespace设置自动注入
1.创建namespace
[root@k8s-master ~]# kubectl create ns sidecar-test
namespace/Sidecar-test created
2.为namespace添加Sidecar自动注入的标签
[root@k8s-master ~]# kubectl label namespace sidecar-test istio-injection=enabled
namespace/sidecar-test labeled
#enabled为开启自动注入 #disabled为关闭自动注入
3.查看namespace的标签
[root@k8s-master httpbin]# kubectl get ns --show-labels
NAME STATUS AGE LABELS
default Active 4d5h <none>
Istio-system Active 3d5h istio-injection=disabled
kube-node-lease Active 4d5h <none>
kube-public Active 4d5h <none>
kube-system Active 4d5h <none>
sidecar-test Active 5m18s istio-injection=enabled #开启自动注入
2)创建Pod资源验证是否自动注入Sidecar
1.创建pod资源
[root@k8s-master httpbin]# kubectl create deploy nginx-1 --image=nginx:1.15 --replicas=1 -n sidecar-test
deployment.apps/nginx-1 created
2.查看pod资源
[root@k8s-master httpbin]# kubectl get pod -n sidecar-test
NAME READY STATUS RESTARTS AGE
nginx-1-d4c8f4989-bzw2n 2/2 Running 0 64s
3.查看pod资源中的容器列表
[root@k8s-master httpbin]# kubectl get pod nginx-1-d4c8f4989-bzw2n -n sidecar-test -o jsonpath=.spec.containers[*].name
nginx Istio-proxy
#运行的应用程序自动会注入sidecar的容器
1.3.在集群外部访问服务网格中的程序
应用程序注入Sidecar之后,所有的流量通信都会经过Sidecar代理程序,程序已经在网格中部署了,想要在集群外部访问到网格中的应用程序,就需要通过Istio的ingressgateway资源了。
首先需要为应用程序创建一个Gateway资源,然后创建一个VirtualService资源,关联Gateway以及应用程序的Service资源,即可完成从外界访问服务网格中的程序。
大致流程:
1)请求—>Istio ingressgateway—>创建的Gateway以及VirtualService资源会将转发规则配置在IngressGateway中。
2)首先转发到Virtual Service资源—>根据VirtualService资源绑定的Gateway资源设置的端口—>最后将请求转发到对应的Service资源上。
1)httpbin程序Gateway以及VirtualService资源编排文件内容
[root@k8s-master httpbin]# vim httpbin-gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: Gateway #资源类型为Gateway
metadata:
name: httpbin-gateway #资源的名称
spec:
selector: #定义选择器
istio: ingressgateway #关联istio的ingressgateway
servers: #定义服务列表
- port: #定义服务使用的端口号
number: 80 #端口号为80
name: http #端口的名称
protocol: HTTP #端口的协议
hosts: #允许进入的主机
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: httpbin
spec:
hosts: #定义流量要发送的主机
- "*"
gateways: #关联gateway资源
- httpbin-gateway
http: #定义http流量路由有序列表规则
- route: #默认规则,可以重定向或者转发流量
- destination: #定义流量转发的目标
host: httpbin #将流量转发到应用程序的service资源,在这里指定程序的service资源
port: #指定service资源的端口号
number: 8001
2)创建httpbin程序的gateway以及virtualservice资源
1.创建资源
[root@k8s-master httpbin]# kubectl apply -f httpbin-gateway.yaml
gateway.networking.istio.io/httpbin-gateway created
virtualservice.networking.istio.io/httpbin created
2.查看资源的状态
[root@k8s-master httpbin]# kubectl get gateway,virtualservice
NAME AGE
gateway.networking.istio.io/httpbin-gateway 16s
NAME GATEWAYS HOSTS AGE
virtualservice.networking.istio.io/httpbin ["httpbin-gateway"] ["*"] 16s
3)通过Istio的ingressgateway访问应用程序
我们创建的gateway资源使用的是80端口,因此需要访问Istio的ingressgateway资源映射出80端口的nodeport端口。
[root@k8s-master httpbin]# kubectl get svc -n Istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
Istio-ingressgateway LoadBalancer 10.107.107.206 <pending> 15021:32381/TCP,80:31105/TCP,443:30793/TCP,15012:32259/TCP,15443:31377/TCP 3d5h
Istiod ClusterIP 10.109.130.252 <none> 15010/TCP,15012/TCP,443/TCP,15014/TCP 3d5h
#80映射的端口80:31105/TCP
浏览器输入http://192.168.20.10:31105/
地址访问网格中的httpbin程序,使用IP访问只能请求一个服务,后面会使用域名访问。
2.Istio与K8S集成的架构图
Istio服务网格中也有很多类似于K8S的控制器资源,Istio在K8S集群中部署完成后,会通过服务发现的方式将Istio的控制器资源类型注入到K8S的Apiserver中,因此我们就可以通过kubectl命令将Istio的资源在K8S集群中创建。
使用istioctl或者kubectl创建的pod资源会通过apiserver部署在K8S集群中,并将信息存储在Etcd。
当pod资源注入了Sidecar proxy代理程序之后,那么Pod中的应用程序就是以网格的模式部署了,程序之间的调用都是通过proxy代理程序完成,通过为应用程序创建Istio的virtualservice资源将资源转发规则写入到Istio的ingressgateway组件之后,我们就可以通过ingressgateway映射的端口访问到网格中的应用程序。
以上是关于2020-05-18【Istio服务治理,K8S各个组件】的主要内容,如果未能解决你的问题,请参考以下文章
Istio微服务治理网格基本使用以及与Kubernetes集成的架构