本页面介绍如何在 Google Kubernetes Engine (GKE) 中设置和使用适用于内部应用负载均衡器的 Ingress。Ingress 通过 GKE Ingress 控制器为内部负载均衡提供内置支持。
如需详细了解适用于内部应用负载均衡器的 Ingress 支持哪些功能,请参阅 Ingress 功能。您也可以参阅适用于内部应用负载均衡器的 Ingress 来详细了解适用于内部应用负载均衡器的 Ingress 的工作原理。
准备工作
在开始之前,请确保您已执行以下任务:
- 启用 Google Kubernetes Engine API。 启用 Google Kubernetes Engine API
- 如果您要使用 Google Cloud CLI 执行此任务,请安装并初始化 gcloud CLI。 如果您之前安装了 gcloud CLI,请运行
gcloud components update
以获取最新版本。
要求
适用于内部应用负载均衡器的 Ingress 具有以下要求:
- 您的集群使用的 GKE 版本必须高于 1.16.5-gke.10。
- 您的集群必须是 VPC 原生集群。
- 集群必须启用
HttpLoadBalancing
插件。默认情况下,此插件处于启用状态。您不得将其停用。 - 您必须使用网络端点组 (NEG) 作为服务的后端。
部署适用于内部应用负载均衡器的 Ingress
以下练习介绍了如何部署适用于内部应用负载均衡器的 Ingress:
- 准备环境。
- 创建集群。
- 部署应用。
- 部署 Service。
- 部署 Ingress。
- 验证部署。
- 删除 Ingress 资源。
准备环境
您必须先准备网络环境,以便将负载均衡器代理部署到指定区域,然后才能通过 Kubernetes Ingress API 部署负载均衡器资源。
创建代理专用子网:
gcloud compute networks subnets create proxy-only-subnet \
--purpose=REGIONAL_MANAGED_PROXY \
--role=ACTIVE \
--region=COMPUTE_REGION \
--network=NETWORK_NAME \
--range=10.129.0.0/23
替换以下内容:
COMPUTE_REGION
:Compute Engine 区域。NETWORK_NAME
:子网的网络名称。
如需了解详情,请参阅配置代理专用子网。
创建防火墙规则
Ingress 控制器不会创建防火墙规则来允许来自代理子网中的负载均衡器代理的连接。您必须手动创建此防火墙规则。但是,Ingress 控制器会创建防火墙规则来允许用于 Google Cloud 健康检查的入站流量。
创建一条防火墙规则以允许从代理专用子网中的负载均衡器代理连接到 pod 监听端口:
gcloud compute firewall-rules create allow-proxy-connection \
--allow=TCP:CONTAINER_PORT \
--source-ranges=10.129.0.0/23 \
--network=NETWORK_NAME
将 CONTAINER_PORT
替换为 Pod 监听的端口的值,例如 9376
。
创建集群
在本部分中,您将创建一个 VPC 原生集群,以便与适用于内部应用负载均衡器的 Ingress 搭配使用。您可以使用 Google Cloud CLI 或 Google Cloud 控制台创建此集群。
gcloud
在代理专用子网所在的网络中创建集群:
gcloud container clusters create-auto CLUSTER_NAME \
--location=COMPUTE_LOCATION \
--network=NETWORK_NAME
替换以下内容:
CLUSTER_NAME
:集群的名称。COMPUTE_LOCATION
:集群的 Compute Engine 位置。您必须使用上一部分中创建的代理子网所在的位置。
控制台
转到 Google Cloud 控制台中的 Google Kubernetes Engine 页面。
点击 add_box 创建。
在 Autopilot 部分中,点击配置。
在集群基本信息部分,完成以下操作:
- 输入集群的名称。
- 在位置类型部分,为集群选择 Compute Engine 区域。您必须使用上一部分中创建的代理子网所在的区域。
在导航窗格中,点击网络。
在网络列表中,选择要在其中创建集群的网络。此网络必须与代理子网位于同一 VPC 网络中。
在节点子网列表中,选择您创建的代理子网
点击创建。
部署 Web 应用
在本部分中,您将创建 Deployment。
如需创建 Deployment,请执行以下操作:
将以下示例清单保存为
web-deployment.yaml
:apiVersion: apps/v1 kind: Deployment metadata: labels: app: hostname name: hostname-server spec: selector: matchLabels: app: hostname minReadySeconds: 60 replicas: 3 template: metadata: labels: app: hostname spec: containers: - image: registry.k8s.io/serve_hostname:v1.4 name: hostname-server ports: - containerPort: 9376 protocol: TCP terminationGracePeriodSeconds: 90
此清单描述了一个在端口 9376 上监听 HTTPS 服务器的 Deployment。此 Deployment 还将为您的应用管理 Pod。每个 Pod 运行一个具有 HTTPS 服务器的应用容器,该 HTTPS 服务器会将应用服务器的主机名作为响应返回。Pod 的默认主机名就是 Pod 的名称。该容器还会处理正常终止。
将清单应用于集群:
kubectl apply -f web-deployment.yaml
将 Service 部署为网络端点组 (NEG)
在本部分中,您将创建 Service 资源。该 Service 资源会根据后端容器的标签选择容器,以便 Ingress 控制器将这些容器编程为后端端点。如需使用适用于内部应用负载均衡器的 Ingress,您必须使用 NEG 作为后端。该功能不支持将实例组用作后端。由于需要使用 NEG 后端,因此在您部署通过 Ingress 公开的 Service 时,必须使用以下 NEG 注解:
annotations:
cloud.google.com/neg: '{"ingress": true}'
如果满足以下所有条件,系统便会自动为您的 Service 添加 cloud.google.com/neg: '{"ingress": true}'
注解:
- 您使用的是 VPC 原生集群。
- 您未使用共享 VPC。
- 您未使用 GKE 网络政策。
系统会使用名为 neg-annotation.config.common-webhooks.networking.gke.io
的 MutatingWebhookConfiguration
自动添加注解。您可以使用以下命令检查 MutatingWebhookConfiguration
是否存在:
kubectl get mutatingwebhookconfigurations
通过使用 NEG,Ingress 控制器可以执行容器原生负载均衡。 流量负载会从 Ingress 代理直接平衡到 Pod IP 地址,而不是遍历节点 IP 地址或 kube-proxy 网络。此外,系统会实施 Pod 就绪性门控措施,以便从负载均衡器的角度(而不仅仅是从 Kubernetes 就绪性和活跃检查角度)确定 Pod 的运行状况。Pod 就绪性门控可确保流量在 Pod 启动、Pod 丢失或节点丢失等生命周期事件期间不会被丢弃。
如果您未添加 NEG 注解,则会在 Ingress 对象上收到警告,其会阻止您配置内部应用负载均衡器。如果未添加 NEG 注解,系统也会在 Ingress 上生成一个 Kubernetes 事件。以下消息是事件消息的示例:
Message
-------
error while evaluating the ingress spec: could not find port "8080" in service "default/no-neg-svc"
在 Ingress 引用该 Service 之前,不会创建 NEG。只有在 Ingress 及其引用的 Service 都已经存在的情况下,NEG 才会出现在 Compute Engine 中。NEG 是一种可用区资源;对于多可用区集群,每个可用区的每项 Service 都将创建一个 NEG。
如需创建 Service,请执行以下操作:
将以下示例清单保存为
web-service.yaml
:apiVersion: v1 kind: Service metadata: name: hostname namespace: default annotations: cloud.google.com/neg: '{"ingress": true}' spec: ports: - name: host1 port: 80 protocol: TCP targetPort: 9376 selector: app: hostname type: ClusterIP
将清单应用于集群:
kubectl apply -f web-service.yaml
部署 Ingress
在本部分中,您将创建一个 Ingress 资源,其可通过 Ingress 控制器触发 Compute Engine 负载均衡器的部署。适用于内部应用负载均衡器的 Ingress 需要以下注释:
annotations:
kubernetes.io/ingress.class: "gce-internal"
您无法使用 ingressClassName
字段指定 GKE Ingress。必须使用 kubernetes.io/ingress.class
注解。如需了解详情,请参阅 GKE Ingress 控制器行为。
如需创建 Ingress,请执行以下操作:
将以下示例清单保存为
internal-ingress.yaml
:apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ilb-demo-ingress namespace: default annotations: kubernetes.io/ingress.class: "gce-internal" spec: defaultBackend: service: name: hostname port: number: 80
将清单应用于集群:
kubectl apply -f internal-ingress.yaml
验证 Ingress 部署状态是否为成功
在本部分中,您将验证部署状态是否为成功。
Ingress 资源可能需要几分钟时间才能完成预配。在此期间,Ingress 控制器会创建诸如转发规则、后端服务、网址映射和 NEG 之类的项目。
如需检索您在上一部分中创建的 Ingress 资源的状态,请运行以下命令:
kubectl get ingress ilb-demo-ingress
输出内容类似如下:
NAME HOSTS ADDRESS PORTS AGE
ilb-demo-ingress * 10.128.0.58 80 59s
ADDRESS
字段填充后,Ingress 即已准备就绪。在此字段中使用的 RFC 1918 地址表示 VPC 中的一个内部 IP 地址。
由于内部应用负载均衡器是区域负载均衡器,因此只能从位于同一区域和 VPC 内的客户端访问虚拟 IP 地址 (VIP)。检索负载均衡器 VIP 后,您可以使用 curl
等工具从 VPC 内部对 VIP 发起 HTTP GET
调用。
如需发起 HTTP GET
调用,请完成以下步骤:
如需从 VPC 内部访问您的 Ingress VIP,请在集群所在的区域和网络中部署虚拟机:
gcloud compute instances create l7-ilb-client \ --image-family=debian-10 \ --image-project=debian-cloud \ --network=NETWORK_NAME \ --subnet=SUBNET_NAME \ --zone=COMPUTE_ZONE \ --tags=allow-ssh
替换以下内容:
SUBNET_NAME
:网络中子网的名称。COMPUTE_ZONE
:区域中的 Compute Engine 可用区。
如需详细了解如何创建实例,请参阅创建和启动虚拟机实例。
如需从虚拟机内访问内部 VIP,请使用
curl
:通过 SSH 连接到您在上一步中创建的虚拟机:
gcloud compute ssh l7-ilb-client \ --zone=COMPUTE_ZONE
使用
curl
访问内部应用 VIP:curl 10.128.0.58 hostname-server-6696cf5fc8-z4788
如果返回成功的 HTTP 响应和一个后端容器的主机名,则表示整个负载均衡路径运行正常。
删除 Ingress 资源
移除 Ingress 和 Service 资源还会移除与其关联的 Compute Engine 负载均衡器资源。为防止资源泄露,请务必移除不再需要的 Ingress 资源。您还必须先删除 Ingress 和 Service 资源,然后才能删除集群,否则 Compute Engine 负载均衡资源将被视为孤立资源。
如需移除 Ingress,请完成以下步骤:
删除 Ingress。例如,如需删除您在此页面中创建的 Ingress,请运行以下命令:
kubectl delete ingress ilb-demo-ingress
删除 Ingress 会移除与此 Ingress 资源关联的转发规则、后端服务和网址映射。
删除 Service。例如,如需删除您在此页面中创建的 Service,请运行以下命令:
kubectl delete service hostname
删除 Service 会移除与其关联的 NEG。
如需在 GKE 上部署应用并使用专用负载均衡 IP 地址公开应用,请参阅基本内部 Ingress。
静态 IP 寻址
内部 Ingress 资源同时支持静态和临时 IP 寻址。如果未指定 IP 地址,则系统会自动从 GKE 节点子网分配可用的 IP 地址。但是,Ingress 资源不会从代理专用子网预配 IP 地址,因为该子网仅供内部代理使用。这些临时 IP 地址将分配给仅适用于内部 Ingress 资源生命周期的 Ingress。如果您删除自己的 Ingress 并从同一清单文件创建新的 Ingress,则无法保证您会获取相同的外部 IP 地址。
如果您希望获取与内部 Ingress 资源生命周期无关的永久 IP 地址,则必须预留区域级静态内部 IP 地址。然后,您可以通过对 Ingress 资源使用 kubernetes.io/ingress.regional-static-ip-name
注解来指定静态 IP 地址。
以下示例展示了如何添加此注解:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
annotations:
kubernetes.io/ingress.regional-static-ip-name: STATIC_IP_NAME
kubernetes.io/ingress.class: "gce-internal"
将 STATIC_IP_NAME
替换为满足下列条件的静态 IP 地址名称:
- 在部署 Ingress 之前,创建静态 IP 地址。存在静态 IP 地址之前不会部署负载均衡器,引用不存在的 IP 地址资源并不会创建静态 IP 地址。如果您修改现有 Ingress 以使用静态 IP 地址而不是临时 IP 地址,则 GKE 可能会在重新创建负载均衡器的转发规则时更改负载均衡器的 IP 地址。
- 在服务项目中为共享 VPC 的服务项目中部署的 Ingress 预留静态 IP。
- 按名称(而非 IP 地址)引用 Google Cloud IP 地址资源。
- 该 IP 地址必须来自 GKE 集群所在区域中的子网。您可以使用区域内的任何可用专用子网(但代理专用子网除外)。不同的 Ingress 资源也可以具有来自不同子网的地址。
客户端和负载均衡器之间的 HTTPS
适用于内部负载均衡的 Ingress 支持向客户端提供 TLS 证书。您可以通过 Kubernetes Secret 或通过 Google Cloud 中预共享的区域级 SSL 证书来提供 TLS 证书。您还可以为每个 Ingress 资源指定多个证书。 GKE 1.25 及更高版本支持同时使用 HTTPS 和 HTTP。如需启用此功能,您需要创建 PURPOSE=SHARED_LOADBALANCER_VIP 的静态 IP 地址,并在 Ingress 上配置该地址。如果未提供静态 IP 地址,则仅允许 HTTPS 流量,您需要遵循停用 HTTP 文档中的说明。
以下步骤详细介绍了如何在 Google Cloud 中创建证书,然后通过 Ingress 向内部客户端提供该证书以供 HTTPS 和 HTTP 流量使用:
创建区域级证书:
gcloud compute ssl-certificates create CERT_NAME \ --certificate CERT_FILE_PATH \ --private-key KEY_FILE_PATH \ --region COMPUTE_REGION
替换以下内容:
CERT_NAME
:您选择的证书名称。CERT_FILE_PATH
:用于创建自行管理的证书的本地证书文件的路径。该证书必须采用 PEM 格式。KEY_FILE_PATH
:本地私钥文件的路径。私钥必须采用 PEM 格式,并且必须使用 RSA 或 ECDSA 加密。COMPUTE_REGION
:证书的 Compute Engine 区域。
按照静态 IP 地址中的说明预留和应用静态 IP 地址。
将以下示例清单保存为
ingress-pre-shared-cert.yaml
:apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ilb-demo-ing namespace: default annotations: ingress.gcp.kubernetes.io/pre-shared-cert: "CERT_NAME" kubernetes.io/ingress.regional-static-ip-name: STATIC_IP_NAME kubernetes.io/ingress.class: "gce-internal" spec: rules: - host: DOMAIN http: paths: - pathType: ImplementationSpecific backend: service: name: SERVICE_NAME port: number: 80
请替换以下内容:
DOMAIN
:您的网域。CERT_NAME
:您在上一部分中创建的证书的名称。SERVICE_NAME
:您的服务的名称。
将清单应用于集群:
kubectl apply -f ingress-pre-shared-cert.yaml
负载均衡器和应用之间的 HTTPS
如果您的应用在 GKE Pod 中运行并且可以接收 HTTPS 请求,您可以将负载均衡器配置为使用 HTTPS 将请求转发给应用。如需了解详情,请参阅负载均衡器和应用之间的 HTTPS (TLS)。
共享 VPC
手动添加 NEG 注解
如果要在其中部署 Ingress 资源的 GKE 位于共享 VPC 服务项目中,则系统不会自动为该服务添加注解 cloud.google.com/neg: '{"ingress": true}'
,因为 MutatingWebhookConfiguration
负责为尚未安装的服务注入注解。
您必须将 NEG 注解添加到通过适用于内部应用负载均衡器的 Ingress 公开的 Service 清单中。
VPC 防火墙规则
如果要在其中部署 Ingress 资源的 GKE 集群位于共享 VPC 服务项目中,并且您希望由 GKE 控制层面来管理宿主项目中的防火墙资源,则必须按照为具有共享 VPC 的集群管理防火墙资源中的要求,为该服务项目的 GKE 服务账号在宿主项目中授予适当的 IAM 权限。这样,Ingress 控制器便可创建防火墙规则,允许用于 Google Cloud 健康检查的入站流量。
以下是 Ingress 资源日志中可能存在的事件示例。如果 Ingress 控制器由于未正确配置权限而无法创建防火墙规则来允许用于 Google Cloud 健康检查的入站流量,则会发生此错误。
Firewall change required by security admin: `gcloud compute firewall-rules update <RULE_NAME> --description "GCE L7 firewall rule" --allow tcp:<PORT> --source-ranges 130.211.0.0/22,35.191.0.0/16 --target-tags <TARGET_TAG> --project <HOST_PROJECT>
如果您希望从宿主项目手动预配防火墙规则,则可以将 networking.gke.io/suppress-firewall-xpn-error: "true"
注解添加到 Ingress 资源,以忽略 firewallXPNError
事件。
内部 Ingress 注解摘要
下表显示了您在为适用于内部应用负载均衡器的 Ingress 创建 Ingress 和 Service 资源时可以添加的注解。
Ingress 注释
注解 | 说明 |
---|---|
kubernetes.io/ingress.class |
对于内部 Ingress,您可以设置为 "gce-internal" 。如果未指定该类,则系统会默认将 Ingress 资源解释为外部 Ingress。
如需了解详情,请参阅 GKE Ingress 控制器行为。 |
kubernetes.io/ingress.allow-http |
您可以允许客户端与 HTTP(S) 负载均衡器之间的 HTTP 流量。可能的值有 true 和 false 。
默认值为 true 。如需了解详情,请参阅停用 HTTP。 |
ingress.gcp.kubernetes.io/pre-shared-cert |
您可以将证书和密钥上传到 Google Cloud 项目。 使用此注解可以引用证书和密钥。如需了解详情,请参阅将多个 SSL 证书与外部应用负载均衡器搭配使用。 |
networking.gke.io/suppress-firewall-xpn-error |
在 GLBC 1.4 及更高版本中,您可以忽略
将 |
kubernetes.io/ingress.regional-static-ip-name |
您可以指定静态 IP 地址来预配内部 Ingress 资源。如需了解详情,请参阅静态 IP 寻址。 |
与 Ingress 相关的服务注释
注解 | 说明 |
---|---|
cloud.google.com/backend-config |
使用此注解配置与 servicePort 关联的后端服务。如需了解详情,请参阅 Ingress 配置。 |
cloud.google.com/neg |
使用此注释指定负载均衡器应使用网络端点组。如需了解详情,请参阅使用容器原生负载均衡。 |
问题排查
如需了解和观察 Ingress 的状态,通常需要检查关联的资源。常见的问题类型包括负载均衡资源未正确创建、流量未到达后端或后端运行状况不佳。
一些常见问题排查步骤包括:
- 验证客户端流量是否来自与负载均衡器相同的区域和 VPC。
- 验证 Pod 和后端是否运行状况良好。
- 验证 VIP 地址和 Compute Engine 健康检查的流量路径,以确保其不会被防火墙规则屏蔽。
- 检查 Ingress 资源事件是否存在错误。
- 描述 Ingress 资源以查看与 Compute Engine 资源的映射。
- 验证 Compute Engine 负载均衡资源是否存在、配置是否正确且未报告错误。
过滤 Ingress 事件
以下查询会过滤集群中所有 Ingress 事件的错误:
kubectl get events --all-namespaces --field-selector involvedObject.kind=Ingress
您还可以按对象或对象名称进行过滤:
kubectl get events --field-selector involvedObject.kind=Ingress,involvedObject.name=hostname-internal-ingress
在以下错误中,您可以看到 Ingress 引用的 Service 不存在:
LAST SEEN TYPE REASON OBJECT MESSAGE
0s Warning Translate ingress/hostname-internal-ingress error while evaluating the ingress spec: could not find service "default/hostname-invalid"
检查 Compute Engine 负载均衡器资源
以下命令会显示 Ingress 资源的完整输出,以便您可以查看由 Ingress 控制器创建的 Compute Engine 资源的映射:
kubectl get ing INGRESS_FILENAME -o yaml
将 INGRESS_FILENAME
替换为您的 Ingress 资源的文件名。
输出内容类似如下:
apiVersion: v1
items:
- apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
ingress.kubernetes.io/backends: '{"k8s1-241a2b5c-default-hostname-80-29269aa5":"HEALTHY"}'
ingress.kubernetes.io/forwarding-rule: k8s-fw-default-ilb-demo-ingress--241a2b5c94b353ec
ingress.kubernetes.io/target-proxy: k8s-tp-default-ilb-demo-ingress--241a2b5c94b353ec
ingress.kubernetes.io/url-map: k8s-um-default-ilb-demo-ingress--241a2b5c94b353ec
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"networking.k8s.io/v1","kind":"Ingress","metadata":{"annotations":{"kubernetes.io/ingress.class":"gce-internal"},"name":"ilb-demo-ingress","namespace":"default"},"spec":{"defaultBackend":{"service":{"name":"hostname"},"port":{"number":80}}}}
kubernetes.io/ingress.class: gce-internal
creationTimestamp: "2019-10-15T02:16:18Z"
finalizers:
- networking.gke.io/ingress-finalizer
generation: 1
name: ilb-demo-ingress
namespace: default
resourceVersion: "1538072"
selfLink: /apis/networking.k8s.io/v1/namespaces/default/ingresses/ilb-demo-ingress
uid: 0ef024fe-6aea-4ee0-85f6-c2578f554975
spec:
defaultBackend:
service:
name: hostname
port:
number: 80
status:
loadBalancer:
ingress:
- ip: 10.128.0.127
kind: List
metadata:
resourceVersion: ""
selfLink: ""
ingress.kubernetes.io/backends
注解会列出后端及其状态。确保您的后端被列为 HEALTHY
。
您可以直接查询 Ingress 创建的 Compute Engine 资源,以了解其状态和配置。运行这些查询在排查问题时也会很有帮助:
如需列出所有 Compute Engine 转发规则,请使用以下命令:
gcloud compute forwarding-rules list
输出内容类似如下:
NAME REGION IP_ADDRESS IP_PROTOCOL TARGET
k8s-fw-default-hostname-internal-ingress--42084f6a534c335b REGION_NAME 10.128.15.225 TCP REGION_NAME/targetHttpProxies/k8s-tp-default-hostname-internal-ingress--42084f6a534c335b
如需列出后端服务的运行状况,请先列出后端服务,然后复制您要检查的后端服务的名称:
gcloud compute backend-services list
输出内容类似如下:
NAME BACKENDS PROTOCOL
k8s1-42084f6a-default-hostname-80-98cbc1c1 REGION_NAME/networkEndpointGroups/k8s1-42084f6a-default-hostname-80-98cbc1c1 HTTP
您现在可以使用后端服务名称来查询其运行状况:
gcloud compute backend-services get-health k8s1-42084f6a-default-hostname-80-98cbc1c1 \
--region COMPUTE_REGION
将 COMPUTE_REGION
替换为后端服务的 Compute Engine 区域。
输出类似于以下内容:
backend: https://www.googleapis.com/compute/v1/projects/user1-243723/zones/ZONE_NAME/networkEndpointGroups/k8s1-42084f6a-default-hostname-80-98cbc1c1
status:
healthStatus:
- healthState: HEALTHY
后续步骤
阅读 GKE 中 Service 的概念性概览。
了解如何在 GKE 上创建内部直通网络负载均衡器。
实现基本内部 Ingress。