如何让你的Service Mesh不再像个玩具?

社区版本Istio是一个迭代很快的开源项目,几乎每周都在发布小版本,目前最新的版本已经到了1.4。


追不动了?那就别追了,跑生产又不是看美剧,考虑用红帽企业版的Istio!

如何让你的Service Mesh不再像个玩具?



相比于SpringCloud,Istio的可视化管理要强不少。但是,当Istio面向运维的时候,Virtual service和destination rule都需要手工书写yaml文件,如果想变更的话,需要手工修改这些文件,再重新oc replace。这带来了几个问题:


  1. 如果virtual service和destination rule比较多的话,我们在apply或者replace之前,需要人工检查里面的配置,然后再进操作。

  2. 当微服务数量很多的时候,我们很很难判断一个微服务到底哪个virtual service和destination rule处于生效状态,可能需要结合几条命令行查看。


此外,被istio管理,还会牵扯到sidecar注入的问题。我们需要在pod的dc或者deployments中书写注释,如果pod多了,很容易搞混。


实际上,书写和修改yaml文件,本身不是一件很难的事情,尤其在poc的时候。但当istio面向生产的时候,数百个yaml文件让运维人员去判断,是不是很头疼?如果一个方案,只合适于PoC,那岂不是像个玩具一样?


这些问题,在红帽最新企业版Istio中得以解决。


一.Istio红帽企业版与社区版的区别

OpenShift目前最新的版本是OpenShift 4.3.1,对应的Istio是1.1.8。

Istio上游社区最新的版本目前是1.4。


红帽Istio的基本功能,与社区版没有太大区别,主要体现在技术支持、安装方式上。具体而言,区别在于:

 

1.安装方式

社区版本的Isito可以基于Ansible或者Helm方式安装。红帽企业级Istio采用Operator的方式安装。


2.多租户支持

OpenShift 4.2默认以OVS Multi-Tenant模式安装,红帽Istio支持网络多租户。


3.Sidecar注入方式

社区版本Istio将Sidecar自动注入设置为基于Namespace的Label实现,这样Namespace里所有的Pod都会被自动注入Sidecar。

红帽企业级Istio不会自动注入Sidecar到任何项目,而是在创建应用时使用sidecar.istio.io/inject的注释设定是否注入Sidecar(避免不必要注入的pod被自动注入sidecar)。


4.基于角色的访问控制(RBAC)的功能

基于角色的访问控制(RBAC)提供了一种机制,以实现对Service的访问控制。我们可以通过多种方式实现Istio的RBAC,如通过用户名或一组属性。

社区版本Istio还可以通过匹配访问请求头(header)中的通配符( wildcards),或者检查header中是否包含特定的前后缀的方法来实现RBAC。

apiVersion: "rbac.istio.io/v1alpha1"

kind: ServiceRoleBinding

metadata:

  name:httpbin-client-binding

  namespace: httpbin

spec:

  subjects:

  - user:"cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account"

    properties:

     request.headers[<header>]: "value"

红帽企业版Istio在匹配访问请求头(header)方面做了增强,可以使用正则表达式。使用request.regex.headers的属性键。

apiVersion: "rbac.istio.io/v1alpha1"

kind: ServiceRoleBinding

metadata:

  name:httpbin-client-binding

  namespace: httpbin

spec:

  subjects:

  - user:"cluster.local/ns/istio-system/sa/istio-ingressgateway-service-account"

    properties:

     request.regex.headers[<header>]: "<regularexpression>"


5.自动创建路由

红帽企业级Istio自动管理Istio入口网关(Ingressgateway)的OpenShift路由。在Istio中创建、更新或删除IstioGateway时,将创建、更新或删除匹配的OpenShift路由(OpenShiftRouter中的Istio网关路由)。

例如我们用如下配置创建Istio网关:

apiVersion: networking.istio.io/v1alpha3

kind: Gateway

metadata:

  name: gateway1

spec:

  selector:

    istio: ingressgateway

  servers:

  - port:

      number: 80

      name: http

      protocol: HTTP

    hosts:

    - www.bookinfo.com

- bookinfo.example.com

Istio网关创建完毕后,OpenShift的Router上会自动创建Istio网关的路由,这些路由支持TLS。

# oc get routes -nistio-system

NAME              HOST/PORT            SERVICES               PORT

gateway1-lvlfn    bookinfo.example.com       istio-ingressgateway         <all>

gateway1-scqhv    www.bookinfo.com         istio-ingressgateway          <all>


6.SSL支持

OpenShiftService Mesh用OpenSSL替代BoringSSL。


7.Kiali和Jaeger的启用

默认情况下,OpenShiftService Mesh中启用了Kiali和Jaeger


新版本的Istio的安装,先依次安装四个Operator:Elasticsearch Operator、Jaeger Operator、Kiali Operator、OpenShift ServiceMesh Operator。这几个Operator可以安装在openshift-operators项目中,这样这几个组件就是全局可用的。



如何让你的Service Mesh不再像个玩具?


如何让你的Service Mesh不再像个玩具?


最后,再安装Istio的控制平面即可:

# cat istio-installation.yaml

apiVersion: maistra.io/v1

kind: ServiceMeshControlPlane

metadata:

  name: full-install

spec:

 

  istio:

    global:

      proxy:

        resources:

          requests:

            cpu: 100m

            memory: 128Mi

          limits:

            cpu: 500m

            memory: 128Mi

 

    gateways:

      istio-egressgateway:

        autoscaleEnabled:false

     istio-ingressgateway:

        autoscaleEnabled:false

 

    mixer:

      policy:

        autoscaleEnabled:false

 

      telemetry:

        autoscaleEnabled: false

        resources:

          requests:

            cpu: 100m

            memory: 1G

          limits:

            cpu: 500m

            memory: 4G

 

    pilot:

      autoscaleEnabled:false

      traceSampling: 100

 

    kiali:

      enabled: true

 

    grafana:

      enabled: true

 

    tracing:

      enabled: true

      jaeger:

        template:all-in-one

关于具体的参数含义,由于篇幅有限,请参照红帽官方文档。

执行以下命令,部署控制平面。

# oc create -nistio-system -f istio-installation.yaml

servicemeshcontrolplane.maistra.io/full-install created


安装完毕后,更新更新Mixer policy。

# oc get cm -n istio-system istio -o jsonpath='{.data.mesh}' | grep disablePolicyChecks

disablePolicyChecks:true

如果disablePolicyChecks:true,则编辑ServiceMesh ConfigMap:

#oc edit cm -n istio-system istio

将配置文件中对应配置改成如下设置(共有两处),然后保存退出。


二. 打造生产可运维的Istio

那么,笔者为什么说这个版本的Istio是生产可运维呢?

我们知道,在Istio中,控制微服务路由的两个重要概念是:Virtual service和Destination Rules。


Istio中Virtual Services的作用是:定义微服务的请求的路由规则,控制请求如何被Istio路由。Virtual Services既可以将请求路由到一个应用的不同版本,也可以将请求路由到其他的应用上。VirtualService支持基于条件路由请求,如请求的源和目的地、HTTP Path和Header 以及各个版本服务的权重等等。


在Destination Rules定义了在路由发生后(Virtual Services定义路由规则)的目标服务,以及应用于目标服务的流量策略,例如熔断、限流等。Destination Rules必须与Virtual services匹配使用,也就是说Virtual Service中引用的目标服务必须在Destination Rules中定义。

如果举个简单的生活例子:从回龙观到首都机场,你走机场北线还是走五环,这是Virtual Services定的。选了走五环以后,你车能跑多快、红绿灯有几个,这是Destination Rules定的。


在此前版本的Istio中,Virtual Services和Destination Rules都是通过配置yaml文件,然后使用oc apply让其生效的。如果要修改策略,修改配置文件,然后用oc apply即可。


这种配置方式对于做开源的同学而言,没有太高的技术难度。但问题在于,一旦这种模式运行在生产上,运维起来就很不方便。试想针对1个Virtual Services有20个配置模板,一共有100个Virtual Services,那是不是有点崩溃?


基于OCP4.3的Istio实现了Virtual Services和Destination Rules的可视化管理。


我们还以Istio里经典的bookinfo程序做展示。

bookinfo安装好以后:

如何让你的Service Mesh不再像个玩具?

对bookinfo访问请求,然后查看kiali,可以看到productpage对reviews的三个版本访问,只有v1和v3有流量。

如何让你的Service Mesh不再像个玩具?

为什么会这样的呢?我们查看reviews的virtual services:

如何让你的Service Mesh不再像个玩具?

如何让你的Service Mesh不再像个玩具?

我们在线调整,将到V2的流量调整为100%,然后update:

如何让你的Service Mesh不再像个玩具?

再次发起请求,查看kiali,流量就只到review V2了:

如何让你的Service Mesh不再像个玩具?

除此之外,在更新virtualservice的位置,还可以配置TLS(Disable、Istio_mutual、Simple三种模式)、增加gateway:

Destination Rules目前还无法实现全部图形化拖拽管理(也没这个必要),可以在图形化中看到生效的Destination Rules,并在线进行管理。

我们可以就此进行修改,然后保存。

修改后:

保存后再查看destination rules,就没有V3了:


是不是比以前方便了很多?



此外,在OCP4.3中,sidecar的注入和以前也有所区别。

ServiceMeshMemberRoll列出了属于控制平面的项目。只有ServiceMeshMemberRoll中列出的项目才受控制平面的影响。在将项目添加到特定控制平面部署的成员卷之前,该项目不属于服务网格。我们必须在与ServiceMeshControlPlane相同的项目中创建一个名为default的ServiceMeshMemberRoll资源。


#oc edit smmr -n istio-system

在下图红框的位置进行修改,增加项目名称,如下图所示:

如何让你的Service Mesh不再像个玩具?

也就是说,在上图红框标注的项目中的pod,将会被自动注入sidecar。如下图所示:

如何让你的Service Mesh不再像个玩具?

所以,我们要将一个项目的pod注入sidecar,需要在项目中创建pod之前,将项目的名称添加到smmr中。


如果在创建pod以后,才将项目的名称添加到smmr中,那也不必删除项目重建,利用现有的deployments重新部署pod就可以了:


以下两个图展示的意思是:原本没有加入smmr的bookinfo1项目,在部署了pods以后,我修改smmr,将bookinfo1加入到列表里。加入完以后,pod并不会自动重建,进行sidecar注入。但我将details-v1这个pod删除以后,它再重建,就会被注入sidecar。原理是修改smmr以后,对应的deployments会被增加自动inject sidecar的注释。

如何让你的Service Mesh不再像个玩具?

如何让你的Service Mesh不再像个玩具?

本质上,修改smmr的方式,是在pod的deployments中加入了以下注释:

[root@lb.weixinyucluster ~]# oc describe deployments details-v1  |grep -i inject

  Annotations:  sidecar.istio.io/inject: true


这和之前版本的Istio原理没有区别,不过配置起来就比以前方便多了。



看到这里,读者有没有觉得这个版本的Istio已经具备了生产可运维的能力?

使用红帽企业版Istio和OpenShift(两者都有企业级支持),让你的Service Mesh不再像个玩具!



上一篇:istio组件mixer初学篇


下一篇:可行性验证:API管理与ServiceMesh的集成