istio-流量管理-服务网格外的流量管理
istio-流量管理-服务网格外的流量管理
这个也一知半解,暂时没用到,放这吧
为了控制服务网格外的服务的流量访问,外部的服务必须首先使用一个ServiceEntry
对象加入到 istio 的内部 service registry 中,服务网格才会知道如何导向这些外部服务的流量。
为了测试这个功能,我们使用 istio 样例中的 sleep 应用来验证改功能,查看 samples/sleep/sleep.yaml 文件内容:
# cat samples/sleep/sleep.yaml # Copyright 2017 Istio Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. ################################################################################################## # Sleep service ################################################################################################## apiVersion: v1 kind: ServiceAccount metadata: name: sleep --- apiVersion: v1 kind: Service metadata: name: sleep labels: app: sleep spec: ports: - port: 80 name: http selector: app: sleep --- apiVersion: apps/v1 kind: Deployment metadata: name: sleep spec: replicas: 1 selector: matchLabels: app: sleep template: metadata: labels: app: sleep spec: serviceAccountName: sleep containers: - name: sleep image: governmentpaas/curl-ssl command: ["/bin/sleep", "3650d"] imagePullPolicy: IfNotPresent ---
这其实就是一个简单的应用,通过 Deployment 进行控制,通过 Service 暴露服务,现在我们来部署该应用:
[root@k8s-master istio-1.3.1]# kubectl apply -f <(istioctl kube-inject -f samples/sleep/sleep.yaml) serviceaccount/sleep created service/sleep created deployment.apps/sleep created [root@k8s-master istio-1.3.1]# [root@k8s-master istio-1.3.1]# kubectl get pod NAME READY STATUS RESTARTS AGE details-v1-74f858558f-qnbfx 2/2 Running 0 3d4h dig 2/2 Running 0 10m nfs-client-provisioner-74bcb5d897-nx8fb 1/1 Running 0 5d3h productpage-v1-8554d58bff-2cng5 2/2 Running 0 3d4h ratings-v1-7855f5bcb9-8lzb5 2/2 Running 0 3d4h reviews-v1-59fd8b965b-fxxxn 2/2 Running 0 3d4h reviews-v2-d6cfdb7d6-rf6nh 2/2 Running 0 3d4h reviews-v3-75699b5cfb-qn4db 2/2 Running 0 3d4h sleep-75c858dc6b-n7k79 2/2 Running 0 38s
待应用部署完成后,我们进入该应用容器内部执行一些测试操作:
[root@k8s-master istio-1.3.1]# export SLEEP_POD=$(kubectl get pod -l app=sleep -o jsonpath={.items..metadata.name}) [root@k8s-master istio-1.3.1]# kubectl exec -it $SLEEP_POD -c sleep -- curl -sL -o /dev/null -D - http://edition.cnn.com/politics HTTP/1.1 503 Service Unavailable content-length: 91 content-type: text/plain date: Mon, 11 Nov 2019 08:24:58 GMT server: envoy
可以看到会返回上面的404
的信息(我的返回503),因为该域名不在当前的服务网格中,默认情况下 istio 不允许访问服务网格外部的 URL,即服务网格中对未知的服务请求会被丢弃。这就需要我们来创建一个 ServiceEntry 对象,将外部的访问服务引入到服务网格中来。
例如下面的规则定义了一个访问 edition.cnn.com 的服务的 ServiceEntry:(cnn-service-entry.yaml)
例如下面的规则定义了一个访问 edition.cnn.com 的服务的 ServiceEntry:(cnn-service-entry.yaml)
apiVersion: networking.istio.io/v1alpha3 kind: ServiceEntry metadata: name: cnn spec: hosts: - edition.cnn.com ports: - number: 80 name: http-port protocol: HTTP - number: 443 name: https protocol: HTTPS resolution: DNS
现在我们来部署上面的 ServiceEntry 资源:
$ istioctl create -f cnn-service-entry.yaml Created config service-entry/default/cnn at revision 32149308 $ istioctl get serviceentry SERVICE-ENTRY NAME HOSTS PORTS NAMESPACE AGE cnn edition.cnn.com HTTP/80,HTTPS/443 default 1m
现在我们再去上面的 sleep 容器中执行上面的测试请求:
[root@k8s-master istio-1.3.1]# kubectl exec -it $SLEEP_POD -c sleep -- curl -sL -o /dev/null -D - http://edition.cnn.com/politics HTTP/1.1 301 Moved Permanently server: envoy retry-after: 0 content-length: 0 cache-control: public, max-age=600 location: https://edition.cnn.com/politics accept-ranges: bytes date: Mon, 11 Nov 2019 08:27:05 GMT via: 1.1 varnish set-cookie: countryCode=CN; Domain=.cnn.com; Path=/ set-cookie: geoData=fengtai|BJ|100036|CN|AS|800|broadband; Domain=.cnn.com; Path=/ x-served-by: cache-hnd18723-HND x-cache: HIT x-cache-hits: 0 x-envoy-upstream-service-time: 250 HTTP/2 200 content-type: text/html; charset=utf-8 x-servedbyhost: ::ffff:127.0.0.1 access-control-allow-origin: * cache-control: max-age=60 content-security-policy: default-src 'self' blob: https://*.cnn.com:* http://*.cnn.com:* *.cnn.io:* *.cnn.net:* *.turner.com:* *.turner.io:* *.ugdturner.com:* courageousstudio.com *.vgtf.net:*; script-src 'unsafe-eval' 'unsafe-inline' 'self' *; style-src 'unsafe-inline' 'self' blob: *; child-src 'self' blob: *; frame-src 'self' *; object-src 'self' *; img-src 'self' data:blob: *; media-src 'self' data: blob: *; font-src 'self' data: *; connect-src 'self' *; frame-ancestors 'self' https://*.cnn.com:* http://*.cnn.com https://*.cnn.io:* http://*.cnn.io:* *.turner.com:* courageousstudio.com; x-content-type-options: nosniff x-xss-protection: 1; mode=block via: 1.1 varnish accept-ranges: bytes date: Mon, 11 Nov 2019 08:27:07 GMT via: 1.1 varnish age: 45 set-cookie: countryCode=CN; Domain=.cnn.com; Path=/ set-cookie: geoData=beijing|BJ|100000|CN|AS|800|broadband; Domain=.cnn.com; Path=/ set-cookie: FastAB=0=1029,1=7669,2=2963,3=3546,4=7780,5=6467,6=4575,7=2654,8=4365,9=7238; Domain=.cnn.com; Path=/; Expires=Thu Jul 01 2021 00:00:00 GMT set-cookie: tryThing00=0488; Domain=.cnn.com; Path=/; Expires=Mon Jul 01 2019 00:00:00 GMT set-cookie: tryThing01=4810; Domain=.cnn.com; Path=/; Expires=Sun Mar 01 2020 00:00:00 GMT set-cookie: tryThing02=3753; Domain=.cnn.com; Path=/; Expires=Wed Jan 01 2020 00:00:00 GMT x-served-by: cache-iad2148-IAD, cache-tyo19934-TYO x-cache: HIT, MISS x-cache-hits: 1, 0 x-timer: S1573460826.227224,VS0,VE913 vary: Accept-Encoding content-length: 1298588
现在我们发现可以正常返回内容了,返回200
,证明请求成功了。
说明:-L
让 curl 跟随连接进行重定向。这里服务器直接返回的 301 重定向响应,要求客户端再使用HTTPS
的方式对 https://edition.cnn.com/politics 地址进行访问,第二次访问才返回了200
的成功码。
除此之外,我们还可以进一步配置egress gateway
,使这些对外部的流量访问经由egress
去到外部。
现在我们在 istio 中定义一个egress gateway
对象来注册允许从服务网格出去的服务,创建一个用于edition.cnn.com 的 egress gateway 对象:(cnn-egress-gateway.yaml)
[root@k8s-master istio-1.3.1]# vim cnn-egress-gateway.yaml [root@k8s-master istio-1.3.1]# cat cnn-egress-gateway.yaml apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: istio-egressgateway spec: selector: istio: egressgateway servers: - port: number: 80 name: http protocol: HTTP hosts: - edition.cnn.com [root@k8s-master istio-1.3.1]# kubectl apply -f cnn-egress-gateway.yaml gateway.networking.istio.io/istio-egressgateway created [root@k8s-master istio-1.3.1]#
除了上面的 engress gateway 对象之外,我们还需要创建 VirtualService 和 DestinationRule 这两个资源对象:(cnn-virtual-rule.yaml)
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: direct-cnn-through-egress-gateway spec: hosts: - edition.cnn.com gateways: - istio-egressgateway - mesh http: - match: - gateways: - mesh port: 80 route: - destination: host: istio-egressgateway.istio-system.svc.cluster.local subset: cnn port: number: 80 weight: 100 - match: - gateways: - istio-egressgateway port: 80 route: - destination: host: edition.cnn.com port: number: 80 weight: 100 --- apiVersion: networking.istio.io/v1alpha3 kind: DestinationRule metadata: name: egressgateway-for-cnn spec: host: istio-egressgateway.istio-system.svc.cluster.local subsets: - name: cnn
下面是一知半解了 代码一直通不过 放这吧