一、Gateway简介
在Istio中,Gateway控制着网格边缘的服务暴露
Gateway提供的功能
Gateway可以看作是网格的负载均衡器,提供了一下功能:
- L4-L6的负载均衡
- 对外的mTLS (双向TLS)
Istio服务网格中,Gateway可以部署任意多个,可以共用一个,也可以每个租户、namespace单独隔离。
Istio Gateway的种类
Gateway根据流入流出方向分为ingress gateway 和egress gateway
- Ingressgateway:控制外部服务访问网格内服务,配合VirtualService使用
- Egressgateway:控制网格内服务访问外部服务,配合DestinationRule ServiceEntry使用
Gateway的配置
二、Gateway vs kubernetes Ingress
Kubernetes Ingress集群边缘负载均衡,提供集群内部服务的访问入口,仅支持L7负载均衡,功能单一
Istio 1.0以前,利用Kubernetes Ingress实现网格内服务暴露。但是Ingress无法实现很多功能:
- L4-L6负载均衡
- 对外mTLS
- SNI的支持
- 其他istio中已经实现的内部网络功能:
- Fault Injection
- Traffic Shifting
- Circuit Breaking
- Mirroring
为了解决这些问题,Istio在1.0版本设计了新的v1alpha3 API
- Gateway允许管理员制定L4-L6的设置:端口及TLS设置。
- 对于ingress的L7设置,Istio允许将VirtualService与Gateway绑定起来。
- 分离的好处:用户可以像使用传统的负载均衡设备一样管理进入网格内部的流量,绑定虚拟IP到虚拟服务器上。便于传统技术用户无缝迁移到微服务。
Gateway与普通sidecar均是使用Envoy作为proxy实行流量控制。Pilot为不同类型的proxy生成相应的配置,Gateway的类型为router,sidecar的类型为sidecar。
三、Gateway 原理及实现
Ingress Gateway 的启动参数:
/usr/local/bin/pilot-agent proxy router \
--log_outout_level info \
--drainDuration 45s \
--parentShutdownDuration 1m0s \
--connectTimeout 10s \
--serviceCluster istio-ingressgateway \
--zipkinAddress zipkin:9411 \
--proxyAdminPort 15000 \
--controlPlaneAuthPolicy NONE \
--discoveryAddress istio-pilot:15010
/usr/local/bin/envoy -c \
/etc/istio/proxy/envoy-rev0.json \
--restart-epoch 0 \
--drain-time-s 45 \
--parent-shutdown-time-s 60 \
--service-cluster istio-ingressgateway \
--service-node router~172.17.0.30~istio-ingressgateway-558addfasdf-2g296.istio-system~istio-system.svc.cluster.local \
--max-obj-name-len 189 \
--allow-unknown-fields \
-l warning \
--v2-config-only
sidecar 启动参数:
/usr/local/bin/pilot-agent proxy sidecar \
--configPath /etc/istio/proxy \
--binaryPath /usr/local/bin/envoy \
--serviceCluster sleep.default \
--drainDuration 45s \
--parentShutdownDuration 1m0s \
--discoveryAddress istio-pilot.istio-system:15010 \
--zipkinAddress zipkin.istio-system:9411 \
--connectTimeout 10s \
--proxyAdminPort 15000 \
--controlPlaneAuthPolicy NONE \
--statusPort 15020 \
--applicationPorts
/usr/local/bin/envoy -c /etc/istio/proxy/envoy-rev0.json \
--restart-epoch 0 \
--drain-time-s 45 \
--parent-shutdown-time-s 60 \
--service-cluster sleep.default \
--service-node sidecar~172.17.0.7~sleep-asdf234-smfkk.default~default.svc.cluster.local \
--max-obj-name-len 189 \
--allow-unknown-fields \
-l warning --v2-config-only
Pilot如何得知proxy类型?
Envoy发现服务使用的是xDS协议,Envoy向server端pilot发起请求DiscoveryRequest时会携带自身信息node,node有一个ID标识,pilot会解析node标识获取proxy类型。
Envoy的节点标识可以通过静态配置文件指定,也可以通过启动参数 —service-node指定
Gateway对象声明
Gateway对象在Istio中是用CRD声明的,可通过如下命令验证:
kubectl get crd gateways.networking.istio.io
Gateway的配置下发
遵循 make-before-break原则,杜绝规则更新过程中出现503
router类型与sidecar类型的proxy最本质的区别是没有 inbound cluster,endpoint,listener
这也从侧面证明Gateway不是流量的终点只是充当一个代理转发。
四、Gateway demo演示
- 控制Ingress HTTP流量
- 利用HTTPS 保护后端服务
- mTLS
- 控制egress流量
Egress Gateway
Istio网格内默认不能访问外部服务,如果需要访问外部服务,如果需要访问外部服务有三种方式:
- Istio安装时设置: —set global.proxy.includeIPRanges=”10.0.0.1/24”
- 创建应用时制定pod annotation traffic.sidecar.istio.io/includeOutboundIPRanges
: “127.0.0.1/24,10.96.0.1/24” - 创建ServiceEntry
apiVersion: networking.istio.io/v1alpha3
kind: ServiceEntry
metadata:
name: httpbin-ext
spec:
hosts:
- httpbin.org
ports:
- number: 80
name: http
protocol: HTTP
resolution: DNS
location: MESH_EXTERNAL
通过Egress Gateway控制访问外部服务
- 创建ServiceEntry,允许访问edtion.cnn.com
- 创建Gateway,制定egress gateway 监听端口
- 创建VirtualService,制定路由规则
- 创建DestinationRule,制定subset
- Gateway demo演示