本页面介绍如何部署跨多个 GKE 集群提供应用的 Ingress。如需详细了解多集群 Ingress,请参阅多集群 Ingress。
如需查看多集群 Ingress (MCI)、多集群网关 (MCG) 与使用独立网络端点组(LB 和独立 NEG)的负载均衡器之间的详细比较,请参阅选择适用于 GKE 的多集群负载均衡 API。
部署教程
在以下任务中,您将在两个集群中部署一个名为 whereami
的虚构应用和一个 MultiClusterIngress
。Ingress 为应用部署提供共享虚拟 IP (VIP) 地址。
本页面基于您在设置多集群 Ingress 中完成的工作(也就是创建并注册了两个集群)构建。确认您有两个集群也已注册到队列:
gcloud container clusters list
输出内容类似如下:
NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS
gke-eu europe-west1-b 1.16.8-gke.9 *** e2-medium 1.16.8-gke.9 2 RUNNING
gke-us us-central1-b 1.16.8-gke.9 *** e2-medium 1.16.6-gke.13 * 2 RUNNING
创建命名空间
由于队列具有命名空间相同性的属性,我们建议您跨集群协调命名空间的创建和管理,以便相同的命名空间由同一群组拥有和管理。您可以按团队、环境、应用或应用组件创建命名空间。只要一个集群中的命名空间 ns1
与另一个集群中的 ns1
具有相同的含义和使用情况,命名空间就可以根据需要进行细化。
在此示例中,您将为每个集群中的每个应用创建一个 whereami
命名空间。
创建一个名为
namespace.yaml
且包含以下内容的文件:apiVersion: v1 kind: Namespace metadata: name: whereami
切换到 gke-us 上下文:
kubectl config use-context gke-us
创建命名空间:
kubectl apply -f namespace.yaml
切换到 gke-eu 上下文:
kubectl config use-context gke-eu
创建命名空间:
kubectl apply -f namespace.yaml
输出内容类似如下:
namespace/whereami created
部署应用
创建一个名为
deploy.yaml
且包含以下内容的文件:apiVersion: apps/v1 kind: Deployment metadata: name: whereami-deployment namespace: whereami labels: app: whereami spec: selector: matchLabels: app: whereami template: metadata: labels: app: whereami spec: containers: - name: frontend image: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1.2.20 ports: - containerPort: 8080
切换到 gke-us 上下文:
kubectl config use-context gke-us
部署
whereami
应用:kubectl apply -f deploy.yaml
切换到 gke-eu 上下文:
kubectl config use-context gke-eu
部署
whereami
应用:kubectl apply -f deploy.yaml
验证
whereami
应用是否已在每个集群中成功部署:kubectl get deployment --namespace whereami
两个集群中的输出应如下所示:
NAME READY UP-TO-DATE AVAILABLE AGE whereami-deployment 1/1 1 1 12m
通过配置集群进行部署
在跨 gke-us
和 gke-eu
部署应用后,您将通过在配置集群中部署 MultiClusterIngress
和 MultiClusterService
资源来部署负载均衡器。它们是 Ingress 和 Service 资源的多集群等效项。
在设置指南中,您已将 gke-us
集群配置为配置集群。配置集群用于跨所有集群部署和配置 Ingress。
将上下文设置为配置集群。
kubectl config use-context gke-us
MultiClusterService
创建一个名为
mcs.yaml
且包含以下内容的文件:apiVersion: networking.gke.io/v1 kind: MultiClusterService metadata: name: whereami-mcs namespace: whereami spec: template: spec: selector: app: whereami ports: - name: web protocol: TCP port: 8080 targetPort: 8080
部署与
whereami
应用匹配的MultiClusterService
资源:kubectl apply -f mcs.yaml
验证
whereami-mcs
资源是否已成功部署到配置集群中:kubectl get mcs -n whereami
输出内容类似如下:
NAME AGE whereami-mcs 9m26s
此
MultiClusterService
会在每个集群中创建一个将 Pod 与app: whereami
进行比对的派生无头服务。您可以看到gke-us
集群kubectl get service -n whereami
中存在一项这样的服务。输出内容类似如下:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE mci-whereami-mcs-svc-lgq966x5mxwwvvum ClusterIP None <none> 8080/TCP 4m59s
gke-eu
中也将存在一个类似的无头服务。这些本地服务用于动态选择 Pod 端点,以通过后端对全局 Ingress 负载均衡器进行编程。
MultiClusterIngress
创建一个名为
mci.yaml
且包含以下内容的文件:apiVersion: networking.gke.io/v1 kind: MultiClusterIngress metadata: name: whereami-ingress namespace: whereami spec: template: spec: backend: serviceName: whereami-mcs servicePort: 8080
请注意,此配置会将所有流量都路由到
whereami
命名空间中存在的MultiClusterService
(名为whereami-mcs
)。部署将
whereami-mcs
作为后端进行引用的MultiClusterIngress
资源:kubectl apply -f mci.yaml
输出内容类似如下:
multiclusteringress.networking.gke.io/whereami-ingress created
请注意,
MultiClusterIngress
与 Kubernetes Ingress 具有相同的架构。Ingress 资源语义也相同,但backend.serviceName
字段除外。
MultiClusterIngress
中的 backend.serviceName
字段引用 Fleet API 中的 MultiClusterService
,而不是 Kubernetes 集群中的 Service。这意味着 Ingress 的任何设置(如 TLS 终止)都可以采用相同的方式进行配置。
验证部署状态是否为成功
Google Cloud 负载均衡器部署可能需要几分钟才能完成新负载均衡器的部署。更新现有负载均衡器的速度更快,因为不需要部署新资源。MultiClusterIngress
资源详细说明了代表 MultiClusterIngress
创建的底层 Compute Engine 资源。
验证部署是否成功:
kubectl describe mci whereami-ingress -n whereami
输出内容类似如下:
Name: whereami-ingress Namespace: whereami Labels: <none> Annotations: kubectl.kubernetes.io/last-applied-configuration: {"apiVersion":"networking.gke.io/v1","kind":"MultiClusterIngress","metadata":{"annotations":{},"name":"whereami-ingress","namespace":"whe... API Version: networking.gke.io/v1 Kind: MultiClusterIngress Metadata: Creation Timestamp: 2020-04-10T23:35:10Z Finalizers: mci.finalizer.networking.gke.io Generation: 2 Resource Version: 26458887 Self Link: /apis/networking.gke.io/v1/namespaces/whereami/multiclusteringresses/whereami-ingress UID: 62bec0a4-8a08-4cd8-86b2-d60bc2bda63d Spec: Template: Spec: Backend: Service Name: whereami-mcs Service Port: 8080 Status: Cloud Resources: Backend Services: mci-8se3df-8080-whereami-whereami-mcs Firewalls: mci-8se3df-default-l7 Forwarding Rules: mci-8se3df-fw-whereami-whereami-ingress Health Checks: mci-8se3df-8080-whereami-whereami-mcs Network Endpoint Groups: zones/europe-west1-b/networkEndpointGroups/k8s1-e4adffe6-whereami-mci-whereami-mcs-svc-lgq966x5m-808-88670678 zones/us-central1-b/networkEndpointGroups/k8s1-a6b112b6-whereami-mci-whereami-mcs-svc-lgq966x5m-808-609ab6c6 Target Proxies: mci-8se3df-whereami-whereami-ingress URL Map: mci-8se3df-whereami-whereami-ingress VIP: 34.98.102.37 Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ADD 3m35s multi-cluster-ingress-controller whereami/whereami-ingress Normal UPDATE 3m10s (x2 over 3m34s) multi-cluster-ingress-controller whereami/whereami-ingress
有几个字段指示此 Ingress 部署的状态:
首先检查
Events
。如果发生错误,则会在这里列出。Cloud Resource
列出了多集群 Ingress 控制器创建的 Compute Engine 资源,例如转发规则、后端服务和防火墙规则。如果未列出,则表示尚未创建。您可以使用控制台或gcloud
命令检查各个 Compute Engine 资源以获取其状态。VIP
会列出 IP 地址(如果已分配)。请注意,即使存在 VIP,负载均衡器也可能尚未处理流量。如果您在几分钟后没有看到 VIP,或者负载均衡器在 10 分钟内未提供 200 响应,请参阅问题排查和操作。
如果输出事件为
Normal
,则MultiClusterIngress
部署可能是成功的,但确定完整流量路径是否正常运行的唯一方法是对其进行测试。验证应用是否正在通过
/ping
端点在 VIP 上提供服务:curl INGRESS_VIP/ping
将
INGRESS_VIP
替换为虚拟 IP (VIP) 地址。输出内容类似如下:
{ "cluster_name": "gke-us", "host_header": "34.120.175.141", "pod_name": "whereami-deployment-954cbf78-mtlpf", "pod_name_emoji": "😎", "project_id": "my-project", "timestamp": "2021-11-29T17:01:59", "zone": "us-central1-b" }
输出应指明应用的地区和后端。
您还可以转到浏览器中的
http://INGRESS_VIP
网址,查看应用的图形版本,其中显示了应用的来源地区。流量要转发到哪个集群取决于您的位置。GCLB 旨在将客户端流量转发到距离最近并且有可用容量的后端。
资源规范
MultiClusterService 规范
MultiClusterService
定义由两部分组成:
template
部分,定义要在 Kubernetes 集群中创建的 Service。请注意,虽然template
部分包含典型 Service 中支持的字段,但MultiClusterService
仅支持两个字段:selector
和ports
。其他字段会被忽略。可选的
clusters
部分,定义哪些集群接收流量以及每个集群的负载均衡属性。如果未指定clusters
部分,或者未列出任何集群,则默认使用所有集群。
以下清单描述了一个标准 MultiClusterService
:
apiVersion: networking.gke.io/v1
kind: MultiClusterService
metadata:
name: NAME
namespace: NAMESPACE
spec:
template:
spec:
selector:
app: POD_LABEL
ports:
- name: web
protocol: TCP
port: PORT
targetPort: TARGET_PORT
替换以下内容:
NAME
:MultiClusterService
的名称。此名称由MultiClusterIngress
资源中的serviceName
字段引用。NAMESPACE
:在其中部署了MultiClusterService
的 Kubernetes 命名空间。它必须与舰队内所有集群中的MultiClusterIngress
和 Pod 位于同一命名空间中。POD_LABEL
:一个标签,用于确定在舰队的所有集群中选择哪些 pod 作为此MultiClusterService
的后端。PORT
:必须与引用此MultiClusterService
的MultiClusterIngress
所引用的端口匹配。TARGET_PORT
:用于从 GCLB 将流量发送到 Pod 的端口。系统会在每个集群中创建一个 NEG,并将此端口用作其服务端口。
MultiClusterIngress 规范
以下 mci.yaml
描述了负载均衡器前端:
apiVersion: networking.gke.io/v1
kind: MultiClusterIngress
metadata:
name: NAME
namespace: NAMESPACE
spec:
template:
spec:
backend:
serviceName: DEFAULT_SERVICE
servicePort: PORT
rules:
- host: HOST_HEADER
http:
paths:
- path: PATH
backend:
serviceName: SERVICE
servicePort: PORT
替换以下内容:
NAME
:MultiClusterIngress
资源的名称。NAMESPACE
:在其中部署了MultiClusterIngress
的 Kubernetes 命名空间。它必须与舰队中所有集群的MultiClusterService
和 Pod 位于同一命名空间中。DEFAULT_SERVICE
:充当与任何主机或路径规则不匹配的所有流量的默认后端。这是必填字段,即使配置了其他主机或路径匹配项,也必须在MultiClusterIngress
中指定默认后端。PORT
:任何有效的端口号。此字段必须与MultiClusterService
资源的port
字段匹配。HOST_HEADER
:按 HTTP 主机标头字段匹配流量。host
字段为可选字段。PATH
:按 HTTP 网址的路径匹配流量。path
字段为可选字段。SERVICE
:与此MultiClusterIngress
部署在同一命名空间和配置集群中的MultiClusterService
的名称。
多集群 Ingress 功能
本部分介绍如何配置其他多集群 Ingress 功能。
集群选择
默认情况下,源自多集群 Ingress 的 Service 会安排在每个成员集群上。不过,您可能需要将入站流量规则应用于特定集群。一些使用场景包括:
- 将多集群 Ingress 应用于除配置集群以外的所有集群,以隔离配置集群。
- 以蓝绿部署方式在集群之间迁移工作负载。
- 路由到仅存在于部分集群中的应用后端。
- 使用单个 L7 VIP 将主机或路径路由到不同集群上的后端。
借助集群选择功能,您可以在 MultiClusterService
对象中按区域或名称选择集群。这将控制您的 MultiClusterIngress
指向哪些集群以及将在哪些位置安排派生的 Service。同一舰队和区域中的集群不得同名,这样就可以独一无二地引用集群。
打开
mcs.yaml
apiVersion: networking.gke.io/v1 kind: MultiClusterService metadata: name: whereami-mcs namespace: whereami spec: template: spec: selector: app: whereami ports: - name: web protocol: TCP port: 8080 targetPort: 8080
此规范会在所有集群中创建派生 Service,这是默认行为。
在“clusters”部分附加以下几行:
apiVersion: networking.gke.io/v1 kind: MultiClusterService metadata: name: whereami-mcs namespace: whereami spec: template: spec: selector: app: whereami ports: - name: web protocol: TCP port: 8080 targetPort: 8080 clusters: - link: "us-central1-b/gke-us" - link: "europe-west1-b/gke-eu"
此示例仅在 gke-us 和 gke-eu 集群中创建派生 Service 资源。您必须选择集群才能有选择地应用入站流量规则。如果未指定
MultiClusterService
的“clusters”部分,或未列出任何集群,则会解释为默认的“所有”集群。
HTTPS 支持
Kubernetes Secret 支持 HTTPS。在启用 HTTPS 支持之前,您必须先创建静态 IP 地址。此静态 IP 允许 HTTP 和 HTTPS 共享同一 IP 地址。如需了解详情,请参阅创建静态 IP 地址。
创建静态 IP 地址后,您就可以创建 Secret 了。
创建 Secret:
kubectl -n whereami create secret tls SECRET_NAME --key PATH_TO_KEYFILE --cert PATH_TO_CERTFILE
替换以下内容:
- 将
SECRET_NAME
替换为您的 Secret 名称。 - 将
PATH_TO_KEYFILE
替换为 TLS 密钥文件的路径。 - 将
PATH_TO_CERTFILE
替换为 TLS 证书文件的路径。
- 将
使用 Secret 名称更新
mci.yaml
文件:apiVersion: networking.gke.io/v1 kind: MultiClusterIngress metadata: name: whereami-ingress namespace: whereami annotations: networking.gke.io/static-ip: STATIC_IP_ADDRESS spec: template: spec: backend: serviceName: whereami-mcs servicePort: 8080 tls: - secretName: SECRET_NAME
将
SECRET_NAME
替换为您的 Secret 的名称。STATIC_IP_ADDRESS
是您在创建静态 IP 部分中所分配的地址的 IP 地址或者完整网址。重新部署
MultiClusterIngress
资源:kubectl apply -f mci.yaml
输出内容类似如下:
multiclusteringress.networking.gke.io/whereami-ingress configured
BackendConfig 支持
借助以下 BackendConfig CRD,您可以自定义 Compute Engine BackendService 资源的设置:
apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
name: whereami-health-check-cfg
namespace: whereami
spec:
healthCheck:
checkIntervalSec: [int]
timeoutSec: [int]
healthyThreshold: [int]
unhealthyThreshold: [int]
type: [HTTP | HTTPS | HTTP2 | TCP]
port: [int]
requestPath: [string]
timeoutSec: [int]
connectionDraining:
drainingTimeoutSec: [int]
sessionAffinity:
affinityType: [CLIENT_IP | CLIENT_IP_PORT_PROTO | CLIENT_IP_PROTO | GENERATED_COOKIE | HEADER_FIELD | HTTP_COOKIE | NONE]
affinityCookieTtlSec: [int]
cdn:
enabled: [bool]
cachePolicy:
includeHost: [bool]
includeQueryString: [bool]
includeProtocol: [bool]
queryStringBlacklist: [string list]
queryStringWhitelist: [string list]
securityPolicy:
name: ca-how-to-security-policy
logging:
enable: [bool]
sampleRate: [float]
iap:
enabled: [bool]
oauthclientCredentials:
secretName: [string]
如需使用 BackendConfig,请使用注解将其附加到 MultiClusterService
资源:
apiVersion: networking.gke.io/v1
kind: MultiClusterService
metadata:
name: whereami-mcs
namespace: whereami
annotations:
cloud.google.com/backend-config: '{"ports": {"8080":"whereami-health-check-cfg"}}'
spec:
template:
spec:
selector:
app: whereami
ports:
- name: web
protocol: TCP
port: 8080
targetPort: 8080
如需详细了解 BackendConfig 语义,请参阅将 Service 端口与 BackendConfig 进行关联。
gRPC 支持
在多集群 Ingress 中配置 gRPC 应用需要非常具体的设置。以下提示可帮您确保正确配置负载均衡器:
- 确保从负载均衡器到您的应用的流量是 HTTP/2。请使用应用协议进行配置。
- 由于这是 HTTP/2 的要求,因此请确保您的应用已针对 SSL 进行了正确的配置。请注意,您可以使用自签名证书。
- 您必须关闭应用上的 mTLS,因为系统不支持 mTLS 用于 L7 外部负载均衡器。
资源生命周期
配置变更
MultiClusterIngress
和 MultiClusterService
资源作为标准 Kubernetes 对象运行,因此对象的变更会异步反映在系统中。任何导致配置无效的变更都会导致关联的 Google Cloud 对象保持不变,并在对象事件流中引发错误。与配置相关的错误将报告为事件。
管理 Kubernetes 资源
删除 Ingress 对象会删除 HTTP(S) 负载均衡器,以便不再将流量转发到任何已定义的 MultiClusterService
。
删除 MultiClusterService
即会移除每个集群中关联的派生 Service。
管理集群
可通过在舰队中添加集群或从舰队中移除集群来更改负载均衡器所定位的那组集群。
例如,如需移除 gke-eu
集群的资格,使其不再是 Ingress 的后端,请运行以下命令:
gcloud container fleet memberships unregister CLUSTER_NAME \
--gke-uri=URI
替换以下内容:
CLUSTER_NAME
:您的集群的名称。URI
:GKE 集群的 URI。
如需在欧洲添加集群,请运行以下命令:
gcloud container fleet memberships register europe-cluster \
--context=europe-cluster --enable-workload-identity
您可以在注册 GKE 集群中找到有关集群注册选项的更多信息。
请注意,注册或取消注册集群后,它的状态将发生变化,它将不再是所有 Ingress 的后端。取消注册 gke-eu
集群会移除其资格,使其不再是您创建的所有 Ingress 的可用后端。注册新集群的效果正好相反。
停用多集群 Ingress
在停用多集群 Ingress 之前,您必须先删除 MultiClusterIngress
和 MultiClusterService
资源,并验证所有关联的网络资源都已删除。
然后,如需停用多集群 Ingress,请使用以下命令:
gcloud container fleet ingress disable
如果您没有在停用多集群 Ingress 之前删除 MultiClusterIngress
和 MultiClusterService
资源,则可能会遇到如下所示的错误:
Feature has associated resources that should be cleaned up before deletion.
如果要强制停用多集群 Ingress,请使用以下命令:
gcloud container fleet ingress disable --force
注释
MultiClusterIngress
和 MultiClusterService
资源支持以下注解。
MultiClusterIngress 注解
注解 | 说明 |
---|---|
networking.gke.io/frontend-config | 引用与 MultiClusterIngress 资源相同的命名空间中的 FrontendConfig 资源。 |
networking.gke.io/static-ip | 引用全局静态 IP 地址的文本 IP 地址。 |
networking.gke.io/pre-shared-certs | 引用全局 SSLCertificate 资源。 |
MultiClusterService 注解
注解 | 说明 |
---|---|
networking.gke.io/app-protocols | 使用此注解可设置负载均衡器与应用之间的通信协议。可能的协议有 HTTP、HTTPS 和 HTTP/2。 请参阅负载均衡器与应用之间的 HTTPS 和使用 Ingress 进行负载均衡的 HTTP/2。 |
cloud.google.com/backend-config | 使用此注解配置与 servicePort 关联的后端服务。如需了解详情,请参阅 Ingress 配置。 |
SSL 政策和 HTTPS 重定向
您可以使用 FrontendConfig 资源配置 SSL 政策和 HTTPS 重定向。通过 SSL 政策,您可以指定负载均衡器接受的加密套件和 TLS 版本。通过 HTTPS 重定向,您可以强制执行从 HTTP 或端口 80 到 HTTPS 或端口 443 的重定向。以下步骤将配置 SSL 政策和 HTTPS 重定向。请注意,可单独配置它们。
创建 SSL 政策,以拒绝使用低于 TLS v1.2 的版本的请求。
gcloud compute ssl-policies create tls-12-policy \ --profile MODERN \ --min-tls-version 1.2 \ --project=PROJECT_ID
将
PROJECT_ID
替换为在其中运行 GKE 集群的项目的 ID。查看您的政策以确保它已创建。
gcloud compute ssl-policies list --project=PROJECT_ID
输出类似于以下内容:
NAME PROFILE MIN_TLS_VERSION tls-12-policy MODERN TLS_1_2
为
foo.example.com
创建证书,如示例所示。获取key.pem
和cert.pem
后,请将这些凭据存储为将由 MultiClusterIngress 资源引用的 Secret。kubectl -n whereami create secret tls SECRET_NAME --key key.pem --cert cert.pem
将以下 FrontendConfig 资源保存为
frontendconfig.yaml
。如需详细了解 FrontendConfig 中支持的字段,请参阅配置 FrontendConfig 资源。apiVersion: networking.gke.io/v1beta1 kind: FrontendConfig metadata: name: frontend-redirect-tls-policy namespace: whereami spec: sslPolicy: tls-12-policy redirectToHttps: enabled: true
此 FrontendConfig 将启用 HTTPS 重定向,以及强制执行最低 TLS 版本 1.2 的 SSL 政策。
将
frontendconfig.yaml
部署到配置集群中。kubectl apply -f frontendconfig.yaml --context MCI_CONFIG_CLUSTER
将
MCI_CONFIG_CLUSTER
替换为您的配置集群的名称。将以下 MultiClusterIngress 保存为
mci-frontendconfig.yaml
。apiVersion: networking.gke.io/v1 kind: MultiClusterIngress metadata: name: foo-ingress namespace: whereami annotations: networking.gke.io/frontend-config: frontend-redirect-tls-policy networking.gke.io/static-ip: STATIC_IP_ADDRESS spec: template: spec: backend: serviceName: default-backend servicePort: 8080 rules: - host: foo.example.com http: paths: - backend: serviceName: whereami-mcs servicePort: 8080 tls: - secretName: SECRET_NAME
- 将
STATIC_IP_ADDRESS
替换为已预配的静态全球 IP 地址。 - 将
SECRET_NAME
替换为存储foo.example.com
证书的 Secret。
启用 HTTPS 重定向时有两个要求:
- 必须通过
spec.tls
字段或预共享证书注解networking.gke.io/pre-shared-certs
启用 TLS。如果启用了 HTTPS 重定向,但未启用 HTTPS,则不会部署 MultiClusterIngress。 - 必须通过
networking.gke.io/static-ip
注解引用静态 IP 地址。在 MultiClusterIngress 上启用 HTTPS 时需要静态 IP 地址。
- 将
将 MultiClusterIngress 部署到配置集群。
kubectl apply -f mci-frontendconfig.yaml --context MCI_CONFIG_CLUSTER
等待一两分钟,然后检查
foo-ingress
。kubectl describe mci foo-ingress --context MCI_CONFIG_CLUSTER
成功的输出如下所示:
Cloud Resources
状态填充了资源名称VIP
字段使用负载均衡器 IP 地址填充
Name: foobar-ingress Namespace: whereami ... Status: Cloud Resources: Backend Services: mci-otn9zt-8080-whereami-bar mci-otn9zt-8080-whereami-default-backend mci-otn9zt-8080-whereami-foo Firewalls: mci-otn9zt-default-l7 Forwarding Rules: mci-otn9zt-fw-whereami-foobar-ingress mci-otn9zt-fws-whereami-foobar-ingress Health Checks: mci-otn9zt-8080-whereami-bar mci-otn9zt-8080-whereami-default-backend mci-otn9zt-8080-whereami-foo Network Endpoint Groups: zones/europe-west1-b/networkEndpointGroups/k8s1-1869d397-multi-cluste-mci-default-backend-svc--80-9e362e3d zones/europe-west1-b/networkEndpointGroups/k8s1-1869d397-multi-cluster--mci-bar-svc-067a3lzs8-808-89846515 zones/europe-west1-b/networkEndpointGroups/k8s1-1869d397-multi-cluster--mci-foo-svc-820zw3izx-808-8bbcb1de zones/us-central1-b/networkEndpointGroups/k8s1-a63e24a6-multi-cluste-mci-default-backend-svc--80-a528cc75 zones/us-central1-b/networkEndpointGroups/k8s1-a63e24a6-multi-cluster--mci-bar-svc-067a3lzs8-808-36281739 zones/us-central1-b/networkEndpointGroups/k8s1-a63e24a6-multi-cluster--mci-foo-svc-820zw3izx-808-ac733579 Target Proxies: mci-otn9zt-whereami-foobar-ingress mci-otn9zt-whereami-foobar-ingress URL Map: mci-otn9zt-rm-whereami-foobar-ingress VIP: 34.149.29.76 Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal UPDATE 38m (x5 over 62m) multi-cluster-ingress-controller whereami/foobar-ingress
通过
curl
发送 HTTP 请求来验证 HTTPS 重定向是否正常运行。curl VIP
将
VIP
替换为 MultiClusterIngress IP 地址。输出应显示请求已重定向到 HTTPS 端口,这表示重定向正常运行。
使用 TLS 1.1 版发送 HTTPS 请求来验证 TLS 政策是否正常运行。由于没有为此网域配置 DNS,因此请使用
--resolve
选项指示curl
直接解析 IP 地址。curl https://foo.example.com --resolve foo.example.com:443:VIP --cacert CERT_FILE -v
此步骤需要使用用于保护 MultiClusterIngress 的证书 PEM 文件。成功的输出将如下所示:
... * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305 * ALPN, server accepted to use h2 * Server certificate: * subject: O=example; CN=foo.example.com * start date: Sep 1 10:32:03 2021 GMT * expire date: Aug 27 10:32:03 2022 GMT * common name: foo.example.com (matched) * issuer: O=example; CN=foo.example.com * SSL certificate verify ok. * Using HTTP2, server supports multi-use * Connection state changed (HTTP/2 confirmed) * Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0 * Using Stream ID: 1 (easy handle 0x7fa10f00e400) > GET / HTTP/2 > Host: foo.example.com > User-Agent: curl/7.64.1 > Accept: */* > * Connection state changed (MAX_CONCURRENT_STREAMS == 100)! < HTTP/2 200 < content-type: application/json < content-length: 308 < access-control-allow-origin: * < server: Werkzeug/1.0.1 Python/3.8.6 < date: Wed, 01 Sep 2021 11:39:06 GMT < via: 1.1 google < alt-svc: clear < {"cluster_name":"gke-us","host_header":"foo.example.com","metadata":"foo","node_name":"gke-gke-us-default-pool-22cb07b1-r5r0.c.mark-church-project.internal","pod_name":"foo-75ccd9c96d-dkg8t","pod_name_emoji":"👞","project_id":"mark-church-project","timestamp":"2021-09-01T11:39:06","zone":"us-central1-b"} * Connection #0 to host foo.example.com left intact * Closing connection 0
响应代码为 200,并且使用了 TLSv1.2,这表示一切正常。
接下来,您可以通过尝试与 TLS 1.1 连接来验证 SSL 政策是否强制执行正确的 TLS 版本。您的 SSL 政策必须至少配置为 1.2 版,才能执行此步骤。
发送上一步中的相同请求,但强制执行 TLS 版本 1.1。
curl https://foo.example.com --resolve foo.example.com:443:VIP -v \ --cacert CERT_FILE \ --tls-max 1.1
成功的输出将如下所示:
* Added foo.example.com:443:34.149.29.76 to DNS cache * Hostname foo.example.com was found in DNS cache * Trying 34.149.29.76... * TCP_NODELAY set * Connected to foo.example.com (34.149.29.76) port 443 (#0) * ALPN, offering h2 * ALPN, offering http/1.1 * successfully set certificate verify locations: * CAfile: cert.pem CApath: none * TLSv1.1 (OUT), TLS handshake, Client hello (1): * TLSv1.1 (IN), TLS alert, protocol version (582): * error:1400442E:SSL routines:CONNECT_CR_SRVR_HELLO:tlsv1 alert protocol version * Closing connection 0 curl: (35) error:1400442E:SSL routines:CONNECT_CR_SRVR_HELLO:tlsv1 alert protocol version
如果未能完成 TLS 握手,则表示 SSL 政策已成功阻止 TLS 1.1。
创建静态 IP 地址
分配静态 IP 地址:
gcloud compute addresses create ADDRESS_NAME --global
将
ADDRESS_NAME
替换为要分配的静态 IP 地址的名称。输出包含您创建的地址的完整网址,如下所示:
Created [https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/addresses/ADDRESS_NAME].
查看您刚创建的 IP 地址:
gcloud compute addresses list
输出内容类似如下:
NAME ADDRESS/RANGE TYPE STATUS ADDRESS_NAME STATIC_IP_ADDRESS EXTERNAL RESERVED
此输出包括:
- 您定义的
ADDRESS_NAME
。 - 已分配
STATIC_IP_ADDRESS
。
- 您定义的
使用静态 IP 地址更新
mci.yaml
文件:apiVersion: networking.gke.io/v1 kind: MultiClusterIngress metadata: name: whereami-ingress namespace: whereami annotations: networking.gke.io/static-ip: STATIC_IP_ADDRESS spec: template: spec: backend: serviceName: whereami-mcs servicePort: 8080
将
STATIC_IP_ADDRESS
替换为:- 分配的 IP 地址,类似于:
34.102.201.47
- 您创建的地址的完整网址,类似于:
"https://www.googleapis.com/compute/v1/projects/PROJECT_ID/global/addresses/ADDRESS_NAME"
STATIC_IP_ADDRESS
不是资源名称 (ADDRESS_NAME
)。- 分配的 IP 地址,类似于:
重新部署
MultiClusterIngress
资源:kubectl apply -f mci.yaml
输出内容类似如下:
multiclusteringress.networking.gke.io/whereami-ingress configured
按照验证成功部署状态中的步骤操作,验证部署是否正在
STATIC_IP_ADDRESS
上提供服务。
预共享证书
预共享证书是上传到 Google Cloud 以供负载均衡器用于 TLS 终止的证书,而不是存储在 Kubernetes Secret 中的证书。这些证书会从 GKE 带外上传到 Google Cloud,并由 MultiClusterIngress
资源引用。此外,系统还支持多份证书(通过预共享证书或 Kubernetes Secret 形式)。
在多集群 Ingress 中使用证书需要使用 networking.gke.io/pre-shared-certs
注解和证书名称。为给定的 MultiClusterIngress
指定多种证书时,系统会按照预定顺序控制向客端户呈现哪种证书。
您可以通过运行以下命令列出可用的 SSL 证书:
gcloud compute ssl-certificates list
以下示例描述了流向与预共享证书的公用名匹配的一个指定主机的客户端流量,因此,系统将呈现与域名匹配的相应证书。
kind: MultiClusterIngress
metadata:
name: shopping-service
namespace: whereami
annotations:
networking.gke.io/pre-shared-certs: "domain1-cert, domain2-cert"
spec:
template:
spec:
rules:
- host: my-domain1.gcp.com
http:
paths:
- backend:
serviceName: domain1-svc
servicePort: 443
- host: my-domain2.gcp.com
http:
paths:
- backend:
serviceName: domain2-svc
servicePort: 443
Google 管理的证书
MultiClusterIngress
支持通过 networking.gke.io/pre-shared-certs
注解使用 Google 管理的证书。多集群 Ingress 支持将 Google 管理的证书附加到 MultiClusterIngress
资源,但与单集群 Ingress 不同,Kubernetes ManagedCertificate
资源的声明式生成不受 MultiClusterIngress
资源支持。您必须通过 compute ssl-certificates create
API 直接完成 Google 管理的证书的原始创建,然后才能将其附加到 MultiClusterIngress
。具体步骤如下:
按照第 1 步中的说明创建 Google 管理的证书。请勿转到第 2 步,因为多集群 Ingress 会为您附加此证书。
gcloud compute ssl-certificates create my-google-managed-cert \ --domains=my-domain.gcp.com \ --global
使用
networking.gke.io/pre-shared-certs
注解在MultiClusterIngress
中引用证书的名称。kind: MultiClusterIngress metadata: name: shopping-service namespace: whereami annotations: networking.gke.io/pre-shared-certs: "my-google-managed-cert" spec: template: spec: rules: - host: my-domain.gcp.com http: paths: - backend: serviceName: my-domain-svc servicePort: 8080
上述清单将证书附加到 MultiClusterIngress
,以便终止后端 GKE 集群的流量。Google Cloud 会在证书到期之前自动续订证书。续订以透明方式进行,不需要对多集群 Ingress 进行任何更新。
应用协议
默认情况下,从负载均衡器代理到应用的连接使用 HTTP。使用 networking.gke.io/app-protocols
注解,您可以将负载均衡器配置为在将请求转发到应用时使用 HTTPS 或 HTTP/2。在以下示例的 annotation
字段中,http2
表示 MultiClusterService
端口名称,HTTP2
表示负载均衡器使用的协议。
kind: MultiClusterService
metadata:
name: shopping-service
namespace: whereami
annotations:
networking.gke.io/app-protocols: '{"http2":"HTTP2"}'
spec:
template:
spec:
ports:
- port: 443
name: http2
BackendConfig
请参阅上述部分,了解如何配置注解。