istio 的基本概念: Gateways
Gateways 管理南北向流量,也就是从外部流入网格,和从网格流出到外部的流量。它影响网格边界的 envoy ,边界 envoy 通常被分成两组:
- 一组处理外部流入网格的流量,称为 ingress gateway
- 一组处理网格流向外部的流量,称为 egress gateway
Gateway 详细内容见 Envoy Gateway Detail。
允许外部访问集群内服务
下面的配置会被转换成边界 envoy(带有 app: my-gateway-controller 标签的 envoy pod)中的配置:允许访问集群内的 ext-host。
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: ext-host-gwy
spec:
selector:
app: my-gateway-controller
servers:
- port:
number: 443
name: https
protocol: HTTPS
hosts:
- ext-host
tls:
mode: SIMPLE
serverCertificate: /tmp/tls.crt
privateKey: /tmp/tls.key
selector 筛选要作用的 envoy pod,上面的配置的意思是:指示带有 app: my-gateway-controller
标签的 envoy pod (通常是 ingress gateway 的 pod)监听 443端口,放行 host 为 ext-host 的请求。
更复杂的配置
Envoy Gateway Detail 中给出了一个更复杂的示例,同时监听多个端口,每个端口放行不同的请求:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: my-gateway
namespace: some-config-namespace
spec:
selector:
app: my-gateway-controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- uk.bookinfo.com
- eu.bookinfo.com
tls:
httpsRedirect: true # sends 301 redirect for http requests
- port:
number: 443
name: https-443
protocol: HTTPS
hosts:
- uk.bookinfo.com
- eu.bookinfo.com
tls:
mode: SIMPLE # enables HTTPS on this port
serverCertificate: /etc/certs/servercert.pem
privateKey: /etc/certs/privatekey.pem
- port:
number: 9443
name: https-9443
protocol: HTTPS
hosts:
- "bookinfo-namespace/*.bookinfo.com"
tls:
mode: SIMPLE # enables HTTPS on this port
credentialName: bookinfo-secret # fetches certs from Kubernetes secret
- port:
number: 9080
name: http-wildcard
protocol: HTTP
hosts:
- "*"
- port:
number: 2379 # to expose internal service via external port 2379
name: mongo
protocol: MONGO
hosts:
- "*"
在 VirtualService 中使用 Gateway
Gateway 指示边界 envoy 监听端口、放行请求,但是没有告诉边界 envoy 如何转发这些从外部进来的请求,转发规则在 VirtualService 中定义。
Gateway 只有被 VirtualService 引用了,才知道将流入的请求转发到哪里,VirtualService 通过 gateways 字段绑定 Gateway.
将从 some-config-namespace/my-gateway 进来的、目地端口为 27017 的流量转发到 mongo.prod.svc.cluster.local:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo-Mongo
namespace: bookinfo-namespace
spec:
hosts:
- mongosvr.prod.svc.cluster.local # name of internal Mongo service
gateways:
- some-config-namespace/my-gateway # can omit the namespace if gateway is in same
# namespace as virtual service.
tcp:
- match:
- port: 27017
route:
- destination:
host: mongo.prod.svc.cluster.local
port:
number: 5555
VirtualService 可以绑定多个 gateway,例如绑定 some-config-namespace/my-gateway 和网格内部(mesh):
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: bookinfo-rule
namespace: bookinfo-namespace
spec:
hosts:
- reviews.prod.svc.cluster.local
- uk.bookinfo.com
- eu.bookinfo.com
gateways:
- some-config-namespace/my-gateway
- mesh # applies to all the sidecars in the mesh
http:
- match:
- headers:
cookie:
exact: "user=dev-123"
route:
- destination:
port:
number: 7777
host: reviews.qa.svc.cluster.local
- match:
- uri:
prefix: /reviews/
route:
- destination:
port:
number: 9080 # can be omitted if it's the only port for reviews
host: reviews.prod.svc.cluster.local
weight: 80
- destination:
host: reviews.qa.svc.cluster.local
weight: 20
这里的 mesh 是一个特殊的存在,它是代表整个网格。
限定 Gateway 的引用范围
如果在 Gateway 中设置了 hosts,那么只能被包含同样的 host 的 VirtualService 绑定:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: my-gateway
namespace: some-config-namespace
spec:
selector:
app: my-gateway-controller
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "ns1/*"
- "ns2/foo.bar.com"
ns1/*
:名为 ns1 的 namespace 中的所有 VirtualService 都可以绑定 my-gateway。ns2/foo.bar.com
:名为 ns2 的namespace 中包含 foo.bar.com 的 VirtualService 可以绑定 my-gateway。