Tetrate Service Bridge 默认情况下会为每个工作区部署一个入口网关。我们这样做是为了保持团队隔离,防止共享故障和以信心实现高速度。然而,在大规模部署中,由于诸如负载均衡器地址过多或网关 Pod 在低流量应用中利用率低等原因,这可能是不可取的。因此,TSB 支持配置共享入口网关部署:换句话说,个别应用团队仍然可以发布自己的配置,但它们在运行时都会配置相同的 Envoy 实例。
什么是网关?
在 Istio 中,“网关” 这个词有点令人困惑,因为它指的是几个不同的事物:
- 作为 Kubernetes 入口网关运行的一组 Envoy,我们将其称为 “网关部署"。
- Istio 配置资源,即 Istio 网关 API — 用于在运行时配置 网关部署 的端口、协议和证书。我们将其称为 “Istio 网关 API 资源"。
- 用于配置 Kubernetes 入口的 Kubernetes 网关 API — 它与 Istio 的 网关 API 资源 做相同的事情,但是是一个原生的 Kubernetes 构造。我们将其称为 “Kubernetes 网关 API 资源"。
网关部署 是一组真正运行的 Envoy,而 Istio 网关 API 资源 和 Kubernetes 网关 API 资源 都是运行 Envoy 的配置。
在本文中,我们只会关注 TSB 应用入口网关,而不是应用边缘网关(有关 “网关术语” 和 “TSB 中的网关” 的更多信息)。
在 TSB 中创建共享网关
当我们配置共享网关时,我们需要做一个基本的决定:谁来管理共享网关,以及应用程序的每个配置存放在哪里?
通常情况下,一个中心团队,如平台或负载均衡组拥有(共享)网关部署,而个别应用团队希望配置它们。我们将共享网关部署称为 “共享网关”,并建议将它们放在自己专用的 Kubernetes 命名空间和 TSB 工作区中。我们将分别称之为 “共享网关命名空间” 和 “共享网关工作区”。
然后我们需要决定应用程序的每个配置存放在哪里:是在共享网关命名空间中与共享网关一起,还是在应用程序的命名空间中与应用程序一起。将配置放在共享网关命名空间中意味着共享网关所有者参与配置更改,并可以帮助防止共享故障中断,但这可能会导致共享网关所有者成为所有网关更改的瓶颈,可能会影响灵活性。将配置放在应用程序的命名空间中意味着它可以像应用程序本身一样快速更改,但由于没有中央所有者审查对共享网关的更改,可能会增加由于配置错误导致的共享故障的风险。
TSB 的桥接模式——网关组,对于使用共享网关更安全(如阻止同一主机名的多个所有者)并且使得在网格中的大多数应用程序使用共享网关变得可行。你还可以使用直连模式—— VirtualServices
,使用原始的 Istio 配置来配置共享网关,但你需要执行规则来防止共享故障(通常通过代码审查来实现)。
最终,大多数组织将稳定性优先于功能速度,因此我们建议将应用程序配置放在共享网关命名空间中,以便由拥有共享网关的团队进行审查。
部署 httpbin
服务
请按照此文档中的说明创建 httpbin
服务。完成该文档中的所有步骤。
部署共享网关
要部署共享网关,我们需要在 TSB 中创建一个工作区来托管我们的共享网关,以及为使用共享网关的应用程序创建工作区。
TSB 设置
首先,我们将创建一个 TSB 租户来保存我们的共享入口示例;在实际部署中,你可以使用现有的租户或为这类用途创建一个共享基础设施租户:
apiversion: api.tsb.tetrate.io/v2
kind: Tenant
metadata:
organization: tetrate
name: shared-ingress-example
spec:
displayName: Shared Ingress Example
description: Tenant for the Shared Ingress example
然后我们将为我们的共享入口创建一个工作区和组:
apiversion: api.tsb.tetrate.io/v2
kind: Workspace
metadata:
organization: tetrate
tenant: shared-ingress-example
name: ingress
spec:
displayName: Shared Ingress
description: Workspace for the shared ingress
namespaceSelector:
names:
- "*/shared-ingress-ns"
---
apiVersion: gateway.tsb.tetrate.io/v2
kind: Group
metadata:
organization: tetrate
tenant: shared-ingress-example
workspace: ingress
name: shared-app-gateway
spec:
configMode: BRIDGED
namespaceSelector:
names:
- "*/shared-ingress-ns"
tctl apply
所有这些文件。
每个共享网关实例
最后我们部署共享网关本身:
apiVersion: install.tetrate.io/v1alpha1
kind: IngressGateway
metadata:
name: shared-gateway
namespace: shared-ingress-ns
spec:
kubeSpec:
service:
type: LoadBalancer
你需要在要托管共享入口网关部署的每个集群中运行 kubectl apply
命令来应用此文件。
配置共享网关
现在我们可以继续配置共享网关部署,可以通过以下方式之一完成:
- 在共享网关工作区中发布配置
或者
- 在应用程序工作区中发布配置
在这两种情况下,我们都会使用 workloadSelector
来定位网关。在应用程序工作区的情况下,我们还需要在网关部署上进行一些额外的配置。
在共享网关工作区中发布配置
对于任何给定应用程序,其共享网关配置将应用于 共享网关工作区。
以下是创建我们将在接下来的示例中使用的 secret 的示例:
kubectl -n shared-ingress-ns create secret tls httpbin-certs \
--key certs/httpbin.key \
--cert certs/httpbin.crt
选择 一种 方法来通过共享网关配置应用程序入口:
- 通过 IngressGateway 进行桥接模式配置
- 通过 Istio Gateway 和 VirtualService 进行直连模式配置
通过 IngressGateway 进行桥接模式配置
我们可以在 TSB 中配置一个 IngressGateway
,以将流量从共享网关路由到我们的应用程序:
apiVersion: gateway.tsb.tetrate.io/v2
kind: IngressGateway
metadata:
organization: tetrate
tenant: shared-ingress-example
workspace: ingress
group: shared-app-gateway
name: ingress-httpbin
spec:
# Use the namespace from our IngressGateway with an app label that matches the `name`.
workloadSelector:
namespace: shared-ingress-ns
labels:
app: shared-gateway # `name` from our IngressGateway
http:
- name: httpbin
port: 443
hostname: httpbin.tetrate.com
tls:
mode: SIMPLE
secretName: httpbin-certs
routing:
rules:
- match:
- headers:
":method":
exact: "GET"
route:
host: httpbin/httpbin.httpbin.svc.cluster.local
请运行 tctl apply
命令来应用上述配置,从而通过共享网关实现对 httpbin.tetrate.com
到 httpbin
服务的路由。
你可以使用以下命令发送一些流量到我们的 httpbin 以验证 TSB 配置。
export GATEWAY_IP=$(kubectl -n shared-ingress-ns get service shared-gateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
curl -k --resolve httpbin.tetrate.com:443:$GATEWAY_IP https://httpbin.tetrate.com/
直接模式:使用 VirtualServices 配置
我们也可以通过 Istio 配置直接配置共享网关,方法是创建一个 Gateway
和一个 VirtualService
。在许多环境中,Gateway
将由中央团队管理,你只需要发布 VirtualService
– 你可以通过运行 kubectl get gateway --namespace shared-ingress-ns
来进行检查:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: httpbin-shared-gateway
namespace: shared-ingress-ns
annotations:
tsb.tetrate.io/organization: tetrate
tsb.tetrate.io/tenant: shared-ingress-example
tsb.tetrate.io/workspace: ingress
tsb.tetrate.io/gatewayGroup: shared-app-gateway
spec:
selector:
app: shared-gateway # `name` from our IngressGateway
servers:
- port:
number: 443
name: https
protocol: HTTPS
hosts:
- "httpbin.tetrate.com"
tls:
mode: SIMPLE
credentialName: httpbin-certs
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: httpbin
namespace: shared-ingress-ns
annotations:
tsb.tetrate.io/organization: tetrate
tsb.tetrate.io/tenant: shared-ingress-example
tsb.tetrate.io/workspace: ingress
tsb.tetrate.io/gatewayGroup: shared-app-gateway
spec:
hosts:
- "httpbin.tetrate.com"
gateways:
- httpbin-shared-gateway
http:
- match:
- uri:
prefix: /get
- method:
exact: "GET"
route:
- destination:
host: httpbin.httpbin
请运行 tctl apply
上述命令以应用配置,从而通过共享网关实现对 httpbin.tetrate.com
到 httpbin
服务的路由。
你可以使用以下命令发送一些流量到我们的 httpbin 以验证 TSB 配置。
export GATEWAY_IP=$(kubectl -n shared-ingress-ns get service shared-gateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
curl -k --resolve httpbin.tetrate.com:443:$GATEWAY_IP https://httpbin.tetrate.com/
在应用工作区中发布配置
要启用跨命名空间的网关配置(我们在这里使用它允许应用程序从其自己的命名空间配置共享网关),我们需要更新共享网关部署以接收来自其他命名空间的配置。
以下是我们将在接下来的示例中使用的创建密钥的示例:
kubectl -n shared-ingress-ns create secret tls httpbin-certs \
--key certs/httpbin.key \
--cert certs/httpbin.crt
由于 TSB 默认使用基于工作区的入口网关方法,我们需要应用该覆盖。Istio 将从应用程序工作区中发现网关对象,而不仅仅是从共享入口命名空间中发现。
apiVersion: install.tetrate.io/v1alpha1
kind: ControlPlane
metadata:
name: controlplane
namespace: istio-system
spec:
components:
istio:
kubeSpec:
overlays:
- apiVersion: install.istio.io/v1alpha1
kind: IstioOperator
name: tsb-istiocontrolplane
patches:
- path: spec.components.pilot.k8s.env[-1]
value:
name: PILOT_SCOPE_GATEWAY_TO_NAMESPACE
value: "false"
TSB 设置
通常,应用团队将在 Kubernetes 中拥有自己的工作区。在这种情况下,继续 httpbin
示例,我们假设该应用部署在 httpbin
命名空间中。因此,我们有了 httpbin
工作区来存储我们的配置:
apiversion: api.tsb.tetrate.io/v2
kind: Workspace
metadata:
organization: tetrate
tenant: shared-ingress-example
name: httpbin
spec:
displayName: Httpbin Workspace
namespaceSelector:
names:
- "*/httpbin"
请运行 tctl apply
上述命令以确保示例应用的工作区存在。
配置路由
启用了我们网关的跨命名空间发现后,配置方式与上述步骤完全相同,唯一的区别是我们的所有配置都发布到应用命名空间中,而不是共享网关命名空间 (shared-ingress-ns
)。
请选择以下一种方法来通过共享网关配置应用程序入口:
- 通过 IngressGateway 使用 Bridged 模式
- 通过 Istio Gateway 和 VirtualService 使用 Direct 模式
使用 IngressGateway 进行 Bridged 模式配置
我们可以通过在 TSB 中配置一个 IngressGateway
来将流量从共享网关路由到我们的应用程序:
# Ensure we have a GatewayGroup to hang our config on
apiVersion: gateway.tsb.tetrate.io/v2
kind: Group
metadata:
organization: tetrate
tenant: shared-ingress-example
workspace: httpbin
name: httpbin-gateway
spec:
configMode: BRIDGED
namespaceSelector:
names:
- "*/httpbin"
---
apiVersion: gateway.tsb.tetrate.io/v2
kind: IngressGateway
metadata:
organization: tetrate
tenant: shared-ingress-example
workspace: httpbin # changed vs shared config
group: httpbin-gateway # changed vs shared config
name: ingress-httpbin
spec:
# Use the namespace from our IngressGateway with an app label that matches the `name`.
workloadSelector:
namespace: shared-ingress-ns
labels:
app: shared-gateway # `name` from our IngressGateway
http:
- name: httpbin
port: 443
hostname: httpbin.tetrate.com
tls:
mode: SIMPLE
secretName: httpbin-certs
routing:
rules:
- match:
- headers:
":method":
exact: "GET"
route:
host: httpbin/httpbin.httpbin.svc.cluster.local
请运行 tctl apply
上述命令以应用配置,从而通过共享网关实现对 httpbin.tetrate.com
到 httpbin
服务的路由。
你可以使用以下命令发送一些流量到我们的 httpbin 以验证 TSB 配置。
export GATEWAY_IP=$(kubectl -n shared-ingress-ns get service shared-gateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
curl -k --resolve httpbin.tetrate.com:443:$GATEWAY_IP https://httpbin.tetrate.com/
使用 VirtualServices 进行 Direct 模式配置
我们也可以通过 Istio 配置直接配置共享网关,方法是创建一个 Gateway
和一个 VirtualService
。在许多环境中,Gateway
将由中央团队管理,你只需要发布 VirtualService
:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: httpbin-gateway
namespace: httpbin # changed vs shared config
annotations:
tsb.tetrate.io/organization: tetrate
tsb.tetrate.io/tenant: shared-ingress-example
tsb.tetrate.io/workspace: httpbin
tsb.tetrate.io/gatewayGroup: httpbin-gateway
spec:
selector:
app: shared-gateway # `name` from our IngressGateway
servers:
- port:
number: 443
name: https
protocol: HTTPS
hosts:
- "httpbin.tetrate.com"
tls:
mode: SIMPLE
credentialName: httpbin-certs
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: httpbin
namespace: httpbin # changed vs shared config
annotations:
tsb.tetrate.io/organization: tetrate
tsb.tetrate.io/tenant: shared-ingress-example
tsb.tetrate.io/workspace: httpbin
tsb.tetrate.io/gatewayGroup: httpbin-gateway
spec:
hosts:
- "httpbin.tetrate.com"
gateways:
- httpbin-gateway # changed vs shared config
http:
- match:
- uri:
prefix: /get
- method:
exact: "GET"
route:
- destination:
host: httpbin.httpbin
请运行上述命令以应用配置,从而通过共享网关实现对 httpbin.tetrate.com
到 httpbin
服务的路由。
你可以使用以下命令发送一些流量到我们的 httpbin 以验证 TSB 配置。
export GATEWAY_IP=$(kubectl -n shared-ingress-ns get service shared-gateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
curl -k --resolve httpbin.tetrate.com:443:$GATEWAY_IP https://httpbin.tetrate.com/