本页面介绍如何使用各种安全功能保护 Gateway:
SSL 政策,可确保 Gateway 使用所需的安全协议和算法
证书,可使用 TLS 保护客户端到网关和网关到后端的流量
Google Cloud Armor 安全政策,可保护 Service 免受 DDoS 攻击
- Identity-Aware Proxy (IAP),在允许访问 Service 之前提供一道身份验证和授权防线。
如需详细了解 Gateway 安全性,请参阅 Gateway 安全性。
准备工作
在开始之前,请确保您已执行以下任务:
- 启用 Google Kubernetes Engine API。 启用 Google Kubernetes Engine API
- 如果您要使用 Google Cloud CLI 执行此任务,请安装并初始化 gcloud CLI。 如果您之前安装了 gcloud CLI,请运行
gcloud components update
以获取最新版本。
GKE Gateway Controller 要求
- 对于标准版,需要 GKE 1.24 或更高版本。
- 对于 Autopilot,需要 GKE 1.26 或更高版本。
- Google Cloud CLI 407.0.0 版或更高版本。
- 仅 VPC 原生集群支持 Gateway API。
- 如果您使用的是内部 GatewayClass,则必须启用代理专用子网。
- 集群必须启用
HttpLoadBalancing
插件。 - 如果您使用的是 Istio,则必须将 Istio 升级到以下版本之一:
- 1.15.2 或更高版本
- 1.14.5 或更高版本
- 1.13.9 或更高版本。
- 如果您使用的是共享 VPC,则需要在宿主项目中将
Compute Network User
角色分配给服务项目的 GKE 服务账号。
限制和局限
关于 Gateway 安全性,除了 GKE Gateway Controller 的限制和局限之外,还存在以下特定限制:
- GKE 1.28.4-gke.1083000 版不支持在网关上使用 SSL 证书或 Certificate Manager 的 TLS 配置。请使用 Kubernetes Secret 作为此 GKE 版本的解决方法。
- 您不能在同一 Gateway 资源上将
networking.gke.io/certmap
注释与tls.certificateRefs
一起使用。如果您在 Gateway 中引用CertificateMap
,GKE 会将其视为错误。
- Certificate Manager 支持自行管理和 Google 管理的证书。Google 管理的证书与区域网关(在预览版中可用)和全球网关兼容。
使用 Google 管理的 SSL 证书时,您必须先在 GKE 外部创建 SSL 证书,然后才能将其附加到 Gateway。
Google 管理的 SSL 证书与区域 Gateway 不兼容。 如需详细了解每个 GatewayClass 的 TLS 终止方法,请参阅 GatewayClass TLS 支持。
如果您在
GCPBackendPolicy
中引用 Google Cloud Armor 后端安全政策,则无法将同一服务用作区域和全球网关的后端。您必须为此用例创建两个单独的服务和政策。Gateway Controller 不支持
ManagedCertificate
资源。Gateway Controller 不支持
networking.gke.io/managed-certificates
注解。Service 配置中的
appProtocol
字段仅接受将大写字母用于协议值(HTTP
、HTTPS
或HTTP2
)。使用小写字母会导致将 HTTP 作为协议来用于后端。
使用 Kubernetes Secret 保护 Gateway 安全
在此示例中,您将使用 Kubernetes Secret 配置 Gateway。
将证书存储在 Kubernetes Secret 中
您可以使用证书授权机构 (CA) 颁发并验证的证书,也可以创建自签名证书。以下步骤使用自签名证书。
创建私钥:
openssl genrsa -out PRIVATE_KEY_FILE 2048
将
PRIVATE_KEY_FILE
替换为您的私钥文件的名称,例如private-key.pem
。如需了解详情,请参阅选择或创建私钥。创建 OpenSSL 配置文件。
cat <<EOF >CONFIG_FILE [req] default_bits = 2048 req_extensions = extension_requirements distinguished_name = dn_requirements prompt = no [extension_requirements] basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectAltName = @sans_list [dn_requirements] 0.organizationName = example commonName = store.example.com [sans_list] DNS.1 = store.example.com EOF
将
CONFIG_FILE
替换为新配置文件的名称,例如config-file.cnf
。创建证书签名请求 (CSR) 文件:
openssl req -new -key PRIVATE_KEY_FILE \ -out CSR_FILE \ -config CONFIG_FILE
将
CSR_FILE
替换为新 CSR 文件的名称,例如cert.pem
。如需了解详情,请参阅创建 CSR。为 CSR 签名:
openssl x509 -req \ -signkey PRIVATE_KEY_FILE \ -in CSR_FILE \ -out CERTIFICATE_FILE \ -extfile CONFIG_FILE \ -extensions extension_requirements \ -days 30
将
CERTIFICATE_FILE
替换为命令生成的文件的路径和名称,例如cert-file.pem
。如需了解详情,请参阅为 CSR 签名。使用您创建的密钥和证书文件创建 Kubernetes TLS Secret:
kubectl create secret tls store-example-com \ --cert=CERTIFICATE_FILE \ --key=PRIVATE_KEY_FILE
GKE 会将证书和密钥保存为 Kubernetes 资源,您可以将其附加到 Gateway。
创建 Gateway 和 HTTPRoute
将以下清单保存为
external-gateway.yaml
:kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: external-http spec: gatewayClassName: gke-l7-global-external-managed listeners: - name: https protocol: HTTPS port: 443 tls: mode: Terminate certificateRefs: - name: store-example-com
此清单描述了具有以下属性的 Gateway:
gatewayClassName: gke-l7-global-external-managed
:部署全球外部应用负载均衡器。protocol: HTTPS
和port: 443
:启用 TLS 时需要。tls
:引用上一步创建的 Kubernetes Secret。
将清单应用于集群:
kubectl apply -f external-gateway.yaml
将以下清单保存为
store-external-route.yaml
:kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: store-external labels: gateway: external-http spec: parentRefs: - name: external-http hostnames: - "store.example.com" rules: - backendRefs: - name: store-v1 port: 8080
此清单描述了一个 HTTPRoute,它将流量匹配到
store.example.com
并将其发送到store-v1
Service。将清单应用于集群:
kubectl apply -f store-external-route.yaml
验证 Gateway
通过互联网发送请求来验证 Gateway 是否正常工作。
获取 Gateway 的 IP 地址:
kubectl get gateway external-http -o=jsonpath="{.status.addresses[0].value}"
输出类似于以下内容:
203.0.113.12
此输出是一个公共 IP 地址,这意味着任何可以访问互联网的客户端都可以连接到该 IP 地址。
使用
curl
访问 Gateway 的网域:curl https://store.example.com --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert CERTIFICATE_FILE -v
请替换以下内容:
GATEWAY_IP_ADDRESS
:Gateway 负载均衡器的 IP 地址。CERTIFICATE_FILE
:您生成的证书文件。您必须将此文件保存在用于连接到 Gateway 的机器上。由于 Gateway 使用自签名证书,因此需要证书来对 Gateway 进行身份验证。
--resolve
选项会将域名解析为网关的 IP 地址,因为此网域未配置 DNS,因此您必须执行此操作输出类似于以下内容:
... * TLSv1.2 (OUT), TLS handshake, Client hello (1): * TLSv1.2 (IN), TLS handshake, Server hello (2): * TLSv1.2 (IN), TLS handshake, Certificate (11): * TLSv1.2 (IN), TLS handshake, Server key exchange (12): * TLSv1.2 (IN), TLS handshake, Server finished (14): * TLSv1.2 (OUT), TLS handshake, Client key exchange (16): * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.2 (OUT), TLS handshake, Finished (20): * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1): * TLSv1.2 (IN), TLS handshake, Finished (20): * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305 * ALPN, server accepted to use h2 * Server certificate: * subject: O=example; CN=store.example.com * start date: Apr 19 15:54:50 2021 GMT * expire date: Apr 19 15:54:50 2022 GMT * common name: store.example.com (matched) * issuer: O=example; CN=store.example.com * SSL certificate verify ok. ... { "cluster_name": "gw", "host_header": "store.example.com", "metadata": "store-v1", "node_name": "gke-gw-default-pool-51ccbf30-yya8.c.agmsb-k8s.internal", "pod_name": "store-v1-84b47c7f58-tj5mn", "pod_name_emoji": "😍", "project_id": "agmsb-k8s", "timestamp": "2021-04-19T16:30:08" # Several lines of output omitted here. }
此输出包括成功的 TLS 握手,然后是来自应用的响应。TLS 连接在 Gateway 上终止,并且应用会安全地响应客户端。
使用 SSL 证书保护 Gateway 安全
在此示例中,您将使用 Google 管理的 SSL 证书配置 Gateway。
创建 SSL 证书
创建 Google 管理的全局
SslCertificate
资源:gcloud compute ssl-certificates create store-example-com \ --domains=store.example.com \ --global
创建 Gateway 和 HTTPRoute
将以下清单保存为
external-gateway.yaml
:kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: external-http spec: gatewayClassName: gke-l7-global-external-managed listeners: - name: https protocol: HTTPS port: 443 tls: mode: Terminate options: networking.gke.io/pre-shared-certs: store-example-com
此清单描述了具有以下属性的 Gateway:
gatewayClassName: gke-l7-global-external-managed
:部署全球外部应用负载均衡器。protocol:HTTPS
和port:443
:启用 TLS 时需要。tls.mode:Terminate
:使用您的 SSL 证书终止 TLS。
将清单应用到您的集群:
kubectl apply -f external-gateway.yaml
将以下 HTTPRoute 清单保存为
store-external-route.yaml
:kind: HTTPRoute apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: store-external labels: gateway: external-http spec: parentRefs: - name: external-http hostnames: - "store.example.com" rules: - backendRefs: - name: store-v1 port: 8080
在集群中部署 HTTPRoute:
kubectl apply -f store-external-route.yaml
GKE 部署 Gateway 可能需要几分钟时间。
验证 Gateway
获取 Gateway 的 IP 地址:
kubectl get gateway external-http -o=jsonpath="{.status.addresses[0].value}"
输出类似于以下内容:
203.0.113.12
此输出是一个公共 IP 地址,这意味着任何可以访问互联网的客户端都可以连接到该 IP 地址。
更新 A 或 AAAA 记录,将您的网域定向到 Gateway 的 IP 地址。
只有在配置 Google 管理的 SSL 证书时才需要执行此步骤。如果要配置自行管理的证书,则可以跳过此步骤。
更新 DNS 记录后,负载均衡器最多可能需要 10 分钟才能开始使用 Google 管理的证书。
使用
curl
通过互联网发送请求来验证 Gateway 是否正常工作:curl https://store.example.com -v
输出类似于以下内容:
... * TLSv1.2 (OUT), TLS handshake, Client hello (1): * TLSv1.2 (IN), TLS handshake, Server hello (2): * TLSv1.2 (IN), TLS handshake, Certificate (11): * TLSv1.2 (IN), TLS handshake, Server key exchange (12): * TLSv1.2 (IN), TLS handshake, Server finished (14): * TLSv1.2 (OUT), TLS handshake, Client key exchange (16): * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.2 (OUT), TLS handshake, Finished (20): * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1): * TLSv1.2 (IN), TLS handshake, Finished (20): * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305 * ALPN, server accepted to use h2 * Server certificate: * subject: O=example; CN=store.example.com * start date: Apr 19 15:54:50 2021 GMT * expire date: Apr 19 15:54:50 2022 GMT * common name: store.example.com (matched) * issuer: O=example; CN=store.example.com * SSL certificate verify ok. ... { "cluster_name": "gw", "host_header": "store.example.com", "metadata": "store-v1", "node_name": "gke-gw-default-pool-51ccbf30-yya8.c.agmsb-k8s.internal", "pod_name": "store-v1-84b47c7f58-tj5mn", "pod_name_emoji": "😍", "project_id": "agmsb-k8s", "timestamp": "2021-04-19T16:30:08", "zone": "us-west1-a" }
此输出包含成功的 TLS 握手和来自应用的响应。TLS 在 Gateway 上正确终止,并且应用会安全地响应客户端。
使用 Certificate Manager 保护 Gateway 安全
在此示例中,您将使用 Certificate Manager 配置 Gateway。
创建 Certificate
全球网关
如需创建全球网关,您需要引用包含一个或多个证书的证书映射资源。您必须至少创建一个证书,并将其作为条目添加到证书映射。
如需创建证书,请先创建私钥和证书文件。
通过加载自行管理的证书和密钥来创建
Certificate
资源:gcloud certificate-manager certificates create store-example-com-cert \ --certificate-file="cert.pem" \ --private-key-file="PRIVATE_KEY_FILE"
创建
CertificateMap
:gcloud certificate-manager maps create store-example-com-map
创建用于将证书分配给
CertificateMap
的CertificateMapEntry
:gcloud certificate-manager maps entries create store-example-com-map-entry \ --map=store-example-com-map \ --hostname=store.example.com \ --certificates=store-example-com-cert
区域网关
对于区域网关,您需要创建 Certificate
,在创建网关时直接指定。与全球网关不同,您无需创建将证书分配给的 CertificateMap
。
创建私钥和证书文件。
通过上传证书文件和密钥来创建
Certificate
资源:
gcloud certificate-manager certificates create "CERTIFICATE_NAME" \
--certificate-file="CERTIFICATE_FILE" \
--private-key-file="PRIVATE_KEY_FILE" \
--location="REGION"
替换以下内容:
CERTIFICATE_NAME
:您的证书的名称,例如store-example-com-cert
。CERTIFICATE_FILE
:证书文件的名称,例如cert.pem
。PRIVATE_KEY_FILE
:您的私钥文件的名称,例如private-key.pem
。如需了解详情,请参阅选择或创建私钥。REGION
:要在其中配置网关的区域的名称,例如us-central1
。
创建 Gateway 和 HTTPRoute
全球网关
如需创建全球网关,请完成以下步骤:
将以下清单保存为
cert-map-gateway.yaml
:kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: external-http annotations: networking.gke.io/certmap: store-example-com-map spec: gatewayClassName: gke-l7-global-external-managed listeners: - name: https protocol: HTTPS port: 443
此清单描述了具有以下属性的 Gateway:
gatewayClassName: gke-l7-global-external-managed
:部署全球外部应用负载均衡器。protocol: HTTPS
和port: 443
:启用 TLS 时需要。
没有 TLS 部分,因为 TLS 是使用注释
networking.gke.io/certmap
来配置 Certificate Manager 的。将清单应用于集群:
kubectl apply -f cert-map-gateway.yaml
GKE 部署 Gateway 可能需要几分钟时间。
如需创建 HTTPRoute,请将以下清单保存为
cert-map-http-route.yaml
:apiVersion: gateway.networking.k8s.io/v1beta1 kind: HTTPRoute metadata: name: foo namespace: default spec: parentRefs: - name: external-http hostnames: - foo.example.com rules: - matches: - path: value: / backendRefs: - name: foo-v1 port: 8080
将清单应用于集群:
kubectl apply -f cert-map-http-route.yaml
区域网关
创建区域级网关时,您可以指定由 Certificate Manager 管理的证书和由 Compute Engine 管理的证书。
如需创建区域级外部网关,请将以下清单保存为
external-gateway.yaml
:kind: Gateway apiVersion: gateway.networking.k8s.io/v1beta1 metadata: name: gateway namespace: corp spec: gatewayClassName: gke-17-regional-external-managed listeners: - name: gateway-pre-shared-certmap protocol: HTTPS port: 443 tsl: mode: Terminate options: networking.gke.io/cert-manager-certs: store-example-com-cert1, store-example-com-cert2 allowedRoutes: kinds: - kind: HTTPRoute namespaces: from: All
此清单描述了具有以下属性的 Gateway:
gatewayClassName
:gke-l7-regional-external-managed
:部署区域级外部应用负载均衡器。protocol: HTTPS
和port: 443
:启用 TLS 时需要。options
:networking.gke.io/cert-manager-certs
:由 Certificate Manager 管理的证书。
如需创建区域级内部网关,请在前面的示例中将
gatewayClassName
的值更改为gke-17-rilb
。这将部署内部应用负载均衡器。将清单应用于集群:
kubectl apply -f external-gateway.yaml
如需创建 HTTPRoute,请将以下清单保存为
store-external-route.yaml
:apiVersion: gateway.networking.k8s.io/v1beta1 kind: HTTPRoute metadata: name: store-external labels: gateway: external-http spec: parentRefs: - name: external-http hostnames: - "store.example.com" rules: backendRefs: - name: store-v1 port: 8080
此清单描述了一个与
store.example.com
的流量匹配并将流量转发到store-v1
Service 的 HTTPRoute。将清单应用于集群:
kubectl apply -f store-external-route.yaml
验证 Gateway
获取 Gateway 的 IP 地址:
kubectl get gateway external-http -o=jsonpath="{.status.addresses[0].value}"
输出类似于以下内容:
203.0.113.12
此输出是一个公共 IP 地址,这意味着任何可以访问互联网的客户端都可以连接到该 IP 地址。
更新 A 或 AAAA 记录,将您的网域定向到 Gateway 的 IP 地址。
只有在配置 Google 管理的 SSL 证书时才需要执行此步骤。如果要配置自行管理的证书,则可以跳过此步骤。
更新 DNS 记录后,负载均衡器最多可能需要 10 分钟才能开始使用 Google 管理的证书。
使用
curl
访问 Gateway 的网域:curl https://store.example.com --resolve store.example.com:443:GATEWAY_IP_ADDRESS --cacert CERTIFICATE_FILE -v
请替换以下内容:
GATEWAY_IP_ADDRESS
:Gateway 负载均衡器的 IP 地址。CERTIFICATE_FILE
:您生成的证书文件。您必须将此文件保存在用于连接到 Gateway 的机器上。由于 Gateway 使用自签名证书,因此需要证书来对 Gateway 进行身份验证。
输出类似于以下内容:
... * TLSv1.2 (OUT), TLS handshake, Client hello (1): * TLSv1.2 (IN), TLS handshake, Server hello (2): * TLSv1.2 (IN), TLS handshake, Certificate (11): * TLSv1.2 (IN), TLS handshake, Server key exchange (12): * TLSv1.2 (IN), TLS handshake, Server finished (14): * TLSv1.2 (OUT), TLS handshake, Client key exchange (16): * TLSv1.2 (OUT), TLS change cipher, Change cipher spec (1): * TLSv1.2 (OUT), TLS handshake, Finished (20): * TLSv1.2 (IN), TLS change cipher, Change cipher spec (1): * TLSv1.2 (IN), TLS handshake, Finished (20): * SSL connection using TLSv1.2 / ECDHE-RSA-CHACHA20-POLY1305 * ALPN, server accepted to use h2 * Server certificate: * subject: O=example; CN=store.example.com * start date: Apr 19 15:54:50 2021 GMT * expire date: Apr 19 15:54:50 2022 GMT * common name: store.example.com (matched) * issuer: O=example; CN=store.example.com * SSL certificate verify ok. ... { "cluster_name": "gw", "host_header": "store.example.com", "metadata": "store-v1", "node_name": "gke-gw-default-pool-51ccbf30-yya8.c.agmsb-k8s.internal", "pod_name": "store-v1-84b47c7f58-tj5mn", "pod_name_emoji": "😍", "project_id": "agmsb-k8s", "timestamp": "2021-04-19T16:30:08", "zone": "us-west1-a" }
此输出包含成功的 TLS 握手和来自应用的响应。TLS 在 Gateway 上正确终止,并且应用会安全地响应客户端。
使用 TLS 保护负载均衡器到应用的流量
您可以使用 ports[].appProtocol
字段加密从负载均衡器到后端 Pod 的流量。支持的 appProtocol
字段为:HTTP
、HTTPS
和 HTTP2
。
以下清单描述了一个指定负载均衡器必须使用 HTTPS 流量与后端 Pod 通信的 Service:
apiVersion: v1
kind: Service
metadata:
name: store-v2
spec:
selector:
app: store
version: v2
ports:
- port: 8080
targetPort: 8080
appProtocol: HTTPS
负载均衡器不会验证后端 Pod 使用的证书。您需要负责确保后端 Pod 上使用的证书有效。
使用 SSL 政策保护客户端到负载均衡器的流量
当您的应用通过使用 HTTPS 的外部 Gateway 公开时,请务必使用最新协议或指定最低 SSL 或 TLS 版本。您可以使用 SSL 政策保护客户端到负载均衡器的流量。
如需详细了解可附加到 Gateway 的 SSL 政策以及如何创建这些政策,请参阅配置 SSL 政策以保护客户端到负载均衡器的流量。
使用 Google Cloud Armor 保护您的后端
Google Cloud Armor 安全政策可帮助保护您的负载均衡应用免遭 Web 攻击。配置 Google Cloud Armor 安全政策后,您可以在应用于 Kubernetes Service 的 GCPBackendPolicy
中引用该政策。
如需使用 Gateway 配置 Google Cloud Armor 政策,请参阅配置 Google Cloud Armor 安全政策以保护后端服务。
使用 Identity-Aware Proxy 对发送到后端的请求进行身份验证
Identity-Aware Proxy 会对向您的应用发送请求的客户端进行身份验证并强制执行基于角色的流量授权,从而帮助您保护后端免受不必要的流量的影响。启用 Identity-Aware Proxy for GKE 后,您可以在应用于 Kubernetes 服务的 GCPBackendPolicy
中引用您的 OAuth 凭据。
如需使用 Gateway 配置 Identity-Aware Proxy,请参阅配置 Identity-Aware Proxy。
后续步骤
- 详细了解 Gateway 安全性。