Isito与API管理
整体而言:
API管理层主要涉及南北流量。Service Mesh主要涉及东西方流量。
两者的的具体区别见下表:
API管理保护应用程序的边界,控制应用程序如何使其自身可用于企业内外的其他应用程序。它允许消费者通过直接的门户浏览可用的API,并为他们要使用的API订阅适当的使用计划。然后,在运行时,它使我们能够识别、控制甚至为不同类型的API使用者开账单。它确保所有使用者都是可识别的,并且可以在流量,访问控制等方面进行单独管理。它还确保底层实现与最终暴露API的方式保持抽象,并在此过程中执行任何必要的路由和转换。
简而言之,API管理功能可以保护和控制一组微服务组件的外部边界。微服务“应用程序”的边界,如下图所示:
主流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上。
禁用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管理策略应用于服务网格流量,需要在混合器中启用策略评估。
$ 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)。
在服务网格控制平面名称空间中查看3scale Istio Adapter组件:
oc get all -l app=3scale-istio-adapter -n $SM_CP_NS
配置Adapter
在上面的步骤中,我们已经部署了3scale Istio Adapter,需要将Adapter配置为将API策略应用于向一个叫incident 的微服务的通信。
INCIDENT_SERVICE_API_KEY
INCIDENT_SERVICE_ID
SYSTEM_PROVIDER_URL
API_ADMIN_ACCESS_TOKEN
# handler for adapter threescale
apiVersion: "config.istio.io/v1alpha2"
kind: handler
metadata:
name: threescale
spec:
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 authorization
apiVersion: "config.istio.io/v1alpha2"
kind: instance
metadata:
name: threescale-authorization
spec:
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 threescalehandler
apiVersion: "config.istio.io/v1alpha2"
kind: rule
metadata:
name: threescale
spec:
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是可以查看到的
sed -i "s/system_url: .*/system_url: \"https:\/\/$SYSTEM_PROVIDER_URL\"/" \ $HOME/lab/istio-integration/istio/threescale-adapter-config.yaml
$ sed -i "s/access_token: .*/access_token: \"$API_ADMIN_ACCESS_TOKEN\"/" \ $HOME/lab/istio-integration/istio/threescale-adapter-config.yaml
$ 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集成,如下图所示:
这样从外部访问应用时,输入应用的route地址。router接收到后,会转到ingressgateway,然后找到servervice。
对接以后,我们可以在3Scale进行API的策略配置,这样会限制API的GET和POST数量
然后这个策略就会在ingressgateway上生效。
Istio在OpenShift上多租户的实现的关键点
在Istio on OCP实现多租户的关键点是
(1)使用项目范围的RoleBinding
(2)使用networkpolicy
在OCP中实现Istio多租户的一个关键点是使用项目范围的RoleBinding而不是集群范围的
ClusterRoleBinding。如下图所示:
红帽OpenShift服务网格对每个成员项目进行配置,以确保其自身、控制平面和其他成员项目之间的网络访问。
在多租户模式下,Red Hat Service Mesh使用NetworkPolicy资源为每个Mesh实例创建一个隔离的网络。网格中的Pod可以彼此通信,也可以与数据平面中的Pod通信。不允许在不同网格中的Pod之间进行通信。
在被Isito纳管的项中,会自动创建istio-mesh和istio-expose-route这两个networkpolicy:
先查看istio-mesh策略:
[root@repo ~]# oc get NetworkPolicy istio-mesh
NAME POD-SELECTOR AGE
istio-mesh <none> 26h
查看istio-expose-route策略:
oc get networkpolicy istio-expose-route -n $ERDEMO_NS -o yaml
该策略允许在标有network.openshift.io/policy-group的项目之间进行入口流量:入口和标记为maistra.io/expose-route:'true'的Pod。openshift-ingress名称空间(运行OpenShift路由器Pod的名称空间)的标签为network.openshift.io/policy-group:ingress,因此可以通过路由到达带注释的Pod。
我们查看Istio管理平面的networkpolicy,我们看到也有被管理项目的两个策略:istio-mesh和istio-expose-route
istio-ingressgateway策略允许所有其他项目的入口流量。
其他几个策略也是不限制ingress。因为控制平面是对整个OCP集群全局有效的。
查看没有被istio纳管项目的默认策略。第一个策略是允许所有项目的入口流量。
第二个策略是允许network-policy=global标签的项目入口流量: