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

Isito与API管理


  • 整体而言:
    API管理层主要涉及南北流量。

  • Service Mesh主要涉及东西方流量。

两者的的具体区别见下表:

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

API管理保护应用程序的边界,控制应用程序如何使其自身可用于企业内外的其他应用程序。它允许消费者通过直接的门户浏览可用的API,并为他们要使用的API订阅适当的使用计划。然后,在运行时,它使我们能够识别、控制甚至为不同类型的API使用者开账单。它确保所有使用者都是可识别的,并且可以在流量,访问控制等方面进行单独管理。它还确保底层实现与最终暴露API的方式保持抽象,并在此过程中执行任何必要的路由和转换。


简而言之,API管理功能可以保护和控制一组微服务组件的外部边界。微服务“应用程序”的边界,如下图所示:

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

主流API管理工具通常将数据平面和管理平面分开。而所谓的API“金银铜”策略,最终是作用到了API网关上(例如NGINX上)。流量通过API网关的认证和策略后,才能访问被Istio管理的微服务。




而我们知道,Istio本身有Ingressgateway,这就牵扯到两个网关如何取舍的问题。





3Scale与Istio集成



红帽3scale API团队与红帽服务Istio团队合作,为API管理创建了ServiceMesh Mixer Adapter,它可将Red Hat 3scale API管理策略直接应用于服务网格中服务之间发生的通信。我们知道,3Scale有两个Gateway:Staging和Production gateway。集成的方式是首先将ServiceMesh Mixer Adapter与3Scale对接(通过注入参数),然后用ingressgateway替换3Scale中的production gateway(Staging gateway可以不替换)。我们将OCP中一个服务与3scale集成的方式,会变成:将Service的FQDN与staging和ingressgateway集成起来(后面会介绍)。这样,3Scale中制定的API策略,就会下发到Ingressgateway和staging gateway上。



具体架构如下图所示:我们从左向右看。从外部发起的、对微服务的访问请求,会先经过OpenShift的HAProxy。然后这个请求会到Istio ingressgateway

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


禁用3Scale Production网关的步骤:

$ oc scale dc/prod-apicast --replicas=0 -n $GW_PROJECT
红帽服务网格提供了一个称3scale Istio Mixer Adapter架构如下图所示,它分为gRPC和HTTP两部分。前者负责与Istio集成,后者负责与3Scale API通讯。


  • 3scale-istio-adapter:接受来自Istio入口的gRPC调用,并路由到Pod中的另一个sidecar:

  • 3scale-istio-httpclient:接受来自3scale-istio-adapter的调用,并调用远程Red Hat 3scale API Management Manager的系统提供者和后端侦听器端点。

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

为了将API管理策略应用于服务网格流量,需要在混合器中启用策略评估。

默认情况下,服务网格中的PolicyChecks是禁用的。要启用策略检查,请使用oc客户端在控制平面名称空间中编辑ServiceMeshControlPlane资源:


$ oc edit servicemeshcontrolplane full-install -n $SM_CP_NS
   global:      disablePolicyChecks: false

使用3Scale组件更新ServiceMeshControlPlane资源,通过修改控制平面的ConfigMap

$ oc patch smcp/full-install -n $SM_CP_NS --type=json -p \'[    {        "op": "replace",        "path": "/spec/threeScale/enabled",        "value": true    },    {        "op": "add",        "path": "/spec/threeScale/image",        "value": "3scale-istio-adapter-rhel8"    },    {        "op": "add",        "path": "/spec/threeScale/tag",        "value": "1.0.0"    },    {        "op": "add",        "path": "/spec/threeScale/PARAM_THREESCALE_LISTEN_ADDR",        "value": 3333    },    {        "op": "add",        "path": "/spec/threeScale/PARAM_THREESCALE_LOG_LEVEL",        "value": "debug"    },    {        "op": "add",        "path": "/spec/threeScale/PARAM_THREESCALE_LOG_JSON",        "value": true    },    {        "op": "add",        "path": "/spec/threeScale/PARAM_THREESCALE_LOG_GRPC",        "value": false    },    {        "op": "add",        "path": "/spec/threeScale/PARAM_THREESCALE_REPORT_METRICS",        "value": true    },    {        "op": "add",        "path": "/spec/threeScale/PARAM_THREESCALE_METRICS_PORT",        "value": 8080    },    {        "op": "add",        "path": "/spec/threeScale/PARAM_THREESCALE_CACHE_TTL_SECONDS",        "value": 300    },    {        "op": "add",        "path": "/spec/threeScale/PARAM_THREESCALE_CACHE_REFRESH_SECONDS",        "value": 180    },    {        "op": "add",        "path": "/spec/threeScale/PARAM_THREESCALE_CACHE_ENTRIES_MAX",        "value": 1000    },    {        "op": "add",        "path": "/spec/threeScale/PARAM_THREESCALE_CACHE_REFRESH_RETRIES",        "value": 1    },    {        "op": "add",        "path": "/spec/threeScale/PARAM_THREESCALE_ALLOW_INSECURE_CONN",        "value": false    },    {        "op": "add",        "path": "/spec/threeScale/PARAM_THREESCALE_CLIENT_TIMEOUT_SECONDS",        "value": 10    },    {        "op": "add",        "path": "/spec/threeScale/PARAM_THREESCALE_GRPC_CONN_MAX_SECONDS",        "value": 60    }]'

请注意,以上配置启用了3Scale Mixer插件,并且还指定了要提取的3scale-istio-adapter Image的确切标签(上面标黄部分,registery.redhat.io)。


因为对ServiceMeshControlPlane进行了更改,所以希望Red Hat Service Mesh Operator能够检测到此更改,以便自动开始3scale-istio-adapter部署。
在服务网格控制平面名称空间中查看3scale Istio Adapter组件:
oc get all -l app=3scale-istio-adapter -n $SM_CP_NS


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





配置Adapter


在上面的步骤中,我们已经部署了3scale Istio Adapter,需要将Adapter配置为将API策略应用于向一个叫incident 的微服务的通信。


配置中,需要指定3scale的system-provider 端点的URL以及相应的访问token,以便Istio Mixer可以从3scale API Manager中提取API代理详细信息(类似于3scale API Gateway所做的事情)。


在本小节中,将修改如下四个参数:
  • INCIDENT_SERVICE_API_KEY

  • INCIDENT_SERVICE_ID

  • SYSTEM_PROVIDER_URL

  • API_ADMIN_ACCESS_TOKEN


以如下模板为基础进行修改:
# handler for adapter threescaleapiVersion: "config.istio.io/v1alpha2"kind: handlermetadata:  name: threescalespec:  adapter: threescale  params:    service_id: "123456"    system_url: "http://127.0.0.1:8090"    access_token: "secret-token"  connection:    address: "threescale-istio-adapter:3333"---
# instance for template authorizationapiVersion: "config.istio.io/v1alpha2"kind: instancemetadata:  name: threescale-authorizationspec:  template: threescale-authorization  params:    subject:      user: request.query_params["user_key"] | request.headers["x-user-key"] | ""      properties:        app_id: request.query_params["app_id"] | request.headers["x-app-id"] | ""        app_key: request.query_params["app_key"] | request.headers["x-app-key"] | ""        client_id: request.auth.claims["azp"] | ""    action:      path: request.url_path      method: request.method | "get"---
# rule to dispatch to handler threescalehandlerapiVersion: "config.istio.io/v1alpha2"kind: rulemetadata:  name: threescalespec:  match: destination.labels["service-mesh.3scale.net"] == "true"  actions:    - handler: threescale.handler      instances:        - threescale-authorization.instance---


调整如下:



(1)修改ServiceID:
sed -i "s/service_id: .*/service_id: \"$INCIDENT_SERVICE_ID\"/" \      $HOME/lab/istio-integration/istio/threescale-adapter-config.yaml
这个Service ID是在3Scale创建application是可以查看到的



(2)修改3Scale的SYSTEM_PROVIDER_URL地址。修改配置文件中访问3Scale的。   
sed -i "s/system_url: .*/system_url: \"https:\/\/$SYSTEM_PROVIDER_URL\"/" \      $HOME/lab/istio-integration/istio/threescale-adapter-config.yaml


(3)修改访问3Scale的token:
$ sed -i "s/access_token: .*/access_token: \"$API_ADMIN_ACCESS_TOKEN\"/" \      $HOME/lab/istio-integration/istio/threescale-adapter-config.yaml


(4)修改配置文件中被管理server的名称为$ERDEMO_USER-incident-service
$ sed -i "s/match: .*/match: destination.service.name == \"$ERDEMO_USER-incident-service\"/" \      $HOME/lab/istio-integration/istio/threescale-adapter-config.yaml


然后应用配置:
oc create -f $HOME/lab/istio-integration/istio/threescale-adapter-config.yaml -n $SM_CP_NS
handler.config.istio.io/threescale created instance.config.istio.io "threescale-authorization" created rule.config.istio.io "threescale" created





API集成


应用与3Scale做集成的时候,以前是应用的Service FQDN与Staging和Production两个API Gateway集成,现在是与Staging APIGateway和Istio Ingressgateway集成,如下图所示:

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

这样从外部访问应用时,输入应用的route地址。router接收到后,会转到ingressgateway,然后找到servervice。



对接以后,我们可以在3Scale进行API的策略配置,这样会限制API的GET和POST数量

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

然后这个策略就会在ingressgateway上生效。




Istio在OpenShift上多租户的实现的关键点


在Istio on OCP实现多租户的关键点是

(1)使用项目范围的RoleBinding

(2)使用networkpolicy


在OCP中实现Istio多租户的一个关键点是使用项目范围的RoleBinding而不是集群范围的

ClusterRoleBinding。如下图所示:

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

红帽OpenShift服务网格对每个成员项目进行配置,以确保其自身、控制平面和其他成员项目之间的网络访问。


在多租户模式下,Red Hat Service Mesh使用NetworkPolicy资源为每个Mesh实例创建一个隔离的网络。网格中的Pod可以彼此通信,也可以与数据平面中的Pod通信。不允许在不同网格中的Pod之间进行通信。


在被Isito纳管的项中,会自动创建istio-mesh和istio-expose-route这两个networkpolicy:

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


先查看istio-mesh策略:

[root@repo ~]# oc get NetworkPolicy istio-mesh

NAME         POD-SELECTOR   AGE

istio-mesh   <none>         26h

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


查看istio-expose-route策略:

oc get networkpolicy istio-expose-route -n $ERDEMO_NS -o yaml

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

该策略允许在标有network.openshift.io/policy-group的项目之间进行入口流量:入口和标记为maistra.io/expose-route:'true'的Pod。openshift-ingress名称空间(运行OpenShift路由器Pod的名称空间)的标签为network.openshift.io/policy-group:ingress,因此可以通过路由到达带注释的Pod。

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



我们查看Istio管理平面的networkpolicy,我们看到也有被管理项目的两个策略:istio-mesh和istio-expose-route

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

istio-ingressgateway策略允许所有其他项目的入口流量。

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

其他几个策略也是不限制ingress。因为控制平面是对整个OCP集群全局有效的。


查看没有被istio纳管项目的默认策略。第一个策略是允许所有项目的入口流量。

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

第二个策略是允许network-policy=global标签的项目入口流量:

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

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


上一篇:如何让你的Service Mesh不再像个玩具?


下一篇:Service Mesh对比:Istio与Linkerd