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治理微服务入门

Istio微服务治理网格基本使用以及与Kubernetes集成的架构

Istio微服务治理网格的全方面可视化监控(微服务架构展示资源监控流量监控链路监控)

小米开源 Istio 工具 Naftis

微服务治理框架Spring Cloud与Istio对比

Spring Cloud vs Istio微服务治理框架对比