Gateway在istio中是一个比较重要的对象, 一般用于管理南北流量,即集群外向集群内的访问及集群内需要访问集群外的这部分流量.
同样, 还是以官方的示例: book-info做为例子
Gateway
从ingressgateway容器的启动命令中可以看到,启动跟envoy的启动命令很像
同样 pilot-agent为1号启动进程, 负责envoy的启动及托管, 还负责envoy的配置更新
envoy启动的proxy 后面是sidecar,而ingressgateway启动的proxy后面是router
启动命令
Pilot-agent启动命令:
1 | /usr/local/bin/pilot-agent proxy router --domain istio-system.svc.cluster.local --proxyLogLevel=warning --proxyComponentLogLevel=misc:error --log_output_level=default:info --drainDuration 45s --parentShutdownDuration 1m0s --connectTimeout 10s --serviceCluster istio-egressgateway --zipkinAddress zipkin.istio-system:9411 --proxyAdminPort 15000 --statusPort 15020 --controlPlaneAuthPolicy NONE --discoveryAddress istio-pilot.istio-system:15010 --trust-domain=cluster.local |
envoy的启动命令:
1 | /usr/local/bin/envoy -c /etc/istio/proxy/envoy-rev1.json --restart-epoch 1 --drain-time-s 45 --parent-shutdown-time-s 60 --service-cluster istio-ingressgateway --service-node router~10.244.0.4~istio-ingressgateway-6d759478d8-pxbn9.istio-system~istio-system.svc.cluster.local --max-obj-name-len 189 --local-address-ip-version v4 --log-format [Envoy (Epoch 1)] [%Y-%m-%d %T.%e][%t][%l][%n] %v -l warning --component-log-level misc:error |
gateway
1 | apiVersion: networking.istio.io/v1alpha3 |
上面指定了istio: ingressgateway,即所有从80端口的任一域名的http协议都由ingressgateway进入, 这样就保证了所有外部流量的统一治理。
gateway一般与virtualService一起共用.
和 Kubernetes Ingress 不同,Istio Gateway 只配置四层到六层的功能(例如开放端口或者 TLS 配置)。绑定一个 VirtualService到 Gateway 上,就可以使用标准的 Istio 规则来控制进入的 HTTP 和 TCP 流量
为上面的gateway定义virtualservice:
1 | apiVersion: networking.istio.io/v1alpha3 |
这样,就可以在集群外部访问productpage服务了
engressgateway跟Ingressgateway其实一样,只不过一个管理出口流量,一个管理进口流量,engressgateway的作用完全可以由ingressgateway替代, 不过为了区分,让两者独立管理罢了.
engressgateway还有一个好外是将所有的对外网访问控制engressgateway这一个范围, 而不必对每个需要访问外网的应用开启外网权限,起到一个安全的作用
ServiceEntry
上面gateway用于集群外需要访问集群内的服务, 而serviceEntry则是用于要访问的服务不在集群内部, 使用serviceEntry同样可以把这部分的请求流量治理起来.
serivceEntry通常搭配engress 一起使用, 当然 , serviceEntry没有engress也可以,只不过为了统一管理/治理外出流量,因此将所有定义的serviceEntry的请求都统一转到engress向外转发
serviceEntry跟Kubernetes在Servicesubset的subset中指定endpoint作用相同
典型的serviceEntry的例子如下:
1 | apiVersion: networking.istio.io/v1alpha3 |
通过host字段来指定外部目标, 通过80/443就能够在meseh内部访问www.googleapis.com了
当然,还可以通过virtualservice来对这次访问进行控制, 比如给上面的访问加上个10s超时
1 | apiVersion: networking.istio.io/v1alpha3 |
流量的重定向和转发、定义重试和超时以及错误注入策略都支持外部目标。然而由于外部服务没有多版本的概念,因此权重(基于版本)路由就无法实现了
问题
假如在kubernetes中已经存在了一个service访问外部ip, yaml文件如下:
1 |
|
190.64.31.232这个是外部mysql的地址,在kubernetes中, 即可直接通过external-db直接访问数据库
如果这时,需要通过istio统一管理外向流量,则可通过以下方式:
保存上面的Headless service不变
创建一个serviceEntry:
1 | apiVersion: networking.istio.io/v1alpha3 |
注意, 这里的resolution为STATIC, 因为kubernetes中已经存在了有external-db的域名(上面headless的定义),不需要再进行解析就可以直接转到endpoint(190.64.31.232)
当然 如果mysql本身存在域名且在网格之外可以解析, 那就无需在kubernetes定义svc, 直接创建一个serviceEntry即可
1 | apiVersion: networking.istio.io/v1alpha3 |