本页面介绍了如何在 Google Kubernetes Engine (GKE) VPC 原生集群中创建由可用区 GCE_VM_IP_PORT
网络端点组 (NEG) 提供支持的 Kubernetes Service。
如需了解容器原生负载均衡的优势、要求和限制,请参阅容器原生负载均衡。
概览
NEG 表示一组端点。GKE 支持 GCE_VM_IP_PORT
类型的独立 NEG。GCE_VM_IP_PORT
NEG 支持使用虚拟机主要内部 IP 地址或其某一别名 IP 范围内的 IP 地址的端点。
在使用独立 NEG 的 GKE VPC 原生集群的上下文中,每个端点都是一个 Pod IP 地址和目标端口。Pod IP 地址源自节点的 Pod 的别名 IP 地址范围,该范围来自集群的 Pod 的子网次要 IP 地址范围。
GKE 提供一个 NEG 控制器来管理 GCE_VM_IP_PORT
NEG 的成员资格。您可以将它创建的 NEG 作为后端添加到您在 GKE API 之外配置的负载均衡器的后端服务。
下图描述了 Kubernetes API 对象与 Compute Engine 对象之间的对应关系。
使用 NEG 的 Ingress
将 NEG 与 GKE Ingress 搭配使用时,Ingress 控制器会协助创建负载均衡器的所有方面。这包括创建虚拟 IP 地址、转发规则、健康检查、防火墙规则等等。
建议借助 Ingress 来使用容器原生负载均衡,因为它的许多功能都可简化 NEG 的管理。如果 Ingress 管理的 NEG 不符合您的应用场景,则可以选择使用独立 NEG。
独立 NEG
如果没有使用由 Ingress 预配的负载均衡器来部署 NEG ,则会被视为独立 NEG。独立 NEG 通过 NEG 控制器部署和管理,但转发规则、健康检查和其他负载均衡对象都需要手动部署。
独立 NEG 不会与已启用 Ingress 的容器原生负载均衡发生冲突。
下图展示了负载均衡对象在每种场景下的部署方式差异:
防止泄露 NEG
使用独立 NEG 时,您需要负责管理 NEG 的生命周期以及构成负载均衡器的资源。您可能会通过以下方式泄露 NEG:
- 删除 GKE 服务时,如果后端服务仍引用 NEG,则不会对关联的 NEG 进行垃圾回收。从后端服务解引用 NEG,以便能够删除 NEG。
- 删除集群时,独立 NEG 不会被删除。
独立 NEG 的使用场景
独立 NEG 有多种关键用途。独立 NEG 非常灵活。 这与 Ingress(搭配或不搭配 NEG)形成了对比,Ingress 定义了一组经过精选的特定负载均衡对象,目的是方便使用。
独立 NEG 的使用场景包括:
容器和虚拟机的异构服务
NEG 可以同时包含虚拟机和容器 IP 地址。这意味着单个虚拟 IP 地址可指向同时包含 Kubernetes 和非 Kubernetes 工作负载的后端。这也可用于将现有工作负载迁移到 GKE 集群。
独立 NEG 可以指向虚拟机 IP,从而可以手动将负载均衡器配置为指向由同一服务 VIP 的虚拟机和容器组成的后端。
自定义 Ingress 控制器
您可以使用自定义 Ingress 控制器(或者不使用 Ingress 控制器)来配置针对独立 NEG 的负载均衡器。
将 Traffic Director 与 GKE 搭配使用
您可以将 Traffic Director 与 GKE 搭配使用。Traffic Director 使用独立 NEG 为托管式服务网格提供容器原生负载均衡。
将外部代理网络负载均衡器与 GKE 搭配使用
您可以使用独立 NEG,通过没有 Kubernetes/GKE 原生支持的外部代理网络负载均衡器直接均衡容器负载。
Pod 就绪性
就绪性门控是 Kubernetes 的一项扩展功能,能够向 PodStatus 注入额外的反馈或信号,以允许 Pod 转换为就绪状态。NEG 控制器管理着自定义就绪性门控,以确保从 Compute Engine 负载均衡器到 Pod 的整条网络路径能正常工作。容器原生负载均衡中介绍了 GKE 内的 Pod 就绪性门控。
使用 NEG 的 Ingress 代表负载均衡器部署和管理 Compute Engine 健康检查。不过,独立 NEG 不会对 Compute Engine 健康检查做任何假设,因为它们预期会单独进行部署和管理。Compute Engine 健康检查应始终与负载均衡器一起配置,以防止流量发送到尚未准备好接收的后端。如果没有与 NEG 相关联的健康检查状态(通常是因为未配置任何健康检查),则 NEG 控制器会在其对应端点在 NEG 中编程时将 Pod 就绪性门控的值标记为 True。
使用要求
您的集群必须是 VPC 原生集群。如需了解详情,请参阅创建 VPC 原生集群。
集群必须启用 HttpLoadBalancing
插件。GKE 集群默认启用了 HttpLoadBalancing
插件。
准备工作
在开始之前,请确保您已执行以下任务:
- 启用 Google Kubernetes Engine API。 启用 Google Kubernetes Engine API
- 如果您要使用 Google Cloud CLI 执行此任务,请安装并初始化 gcloud CLI。 如果您之前安装了 gcloud CLI,请运行
gcloud components update
以获取最新版本。
使用独立 NEG
以下说明展示了如何在 GKE 上将独立 NEG 与外部 HTTP 负载均衡器配合使用。
您必须创建以下对象:
- 用于创建和管理 Pod 的 Deployment。
- 用于创建 NEG 的 Service。
- 使用 Compute Engine API 创建的负载均衡器。这与通过使用 NEG 的 Ingress 创建的负载均衡器不同;在后一种情况下,Ingress 会为您创建并配置负载均衡器。使用独立 NEG 时,您负责关联 NEG 和后端服务,以将 Pod 连接到负载均衡器。负载均衡器由几个组件组成,如下图所示:
创建 VPC 原生集群
默认情况下,Autopilot 集群是 VPC 原生集群,因此您可以跳至部署工作负载。
对于 Standard 集群,请在 us-central1-a
可用区中创建 VPC 原生集群:
gcloud container clusters create neg-demo-cluster \
--create-subnetwork="" \
--network=default \
--zone=us-central1-a
创建 Deployment
以下示例清单指定运行容器化 HTTP 服务器的三个实例的 Deployment。该 HTTP 服务器使用应用服务器的主机名(运行服务器所在的 Pod 的名称)来响应请求。
我们建议您使用利用 Pod 就绪性反馈的工作负载。
使用 Pod 就绪性反馈
apiVersion: apps/v1 kind: Deployment metadata: labels: run: neg-demo-app # Label for the Deployment name: neg-demo-app # Name of Deployment spec: replicas: 3 selector: matchLabels: run: neg-demo-app template: # Pod template metadata: labels: run: neg-demo-app # Labels Pods from this Deployment spec: # Pod specification; each Pod created by this Deployment has this specification containers: - image: registry.k8s.io/serve_hostname:v1.4 # Application to run in Deployment's Pods name: hostname
使用硬编码延迟
apiVersion: apps/v1 kind: Deployment metadata: labels: run: neg-demo-app # Label for the Deployment name: neg-demo-app # Name of Deployment spec: minReadySeconds: 60 # Number of seconds to wait after a Pod is created and its status is Ready replicas: 3 selector: matchLabels: run: neg-demo-app template: # Pod template metadata: labels: run: neg-demo-app # Labels Pods from this Deployment spec: # Pod specification; each Pod created by this Deployment has this specification containers: - image: registry.k8s.io/serve_hostname:v1.4 # Application to run in Deployment's Pods name: hostname
将此清单保存为 neg-demo-app.yaml
,然后通过运行以下命令创建 Deployment:
kubectl apply -f neg-demo-app.yaml
创建一个 Service
以下清单指定了一个 Service,其中:
- 具有
run: neg-demo-app
标签的任何 Pod 都是此 Service 的成员。 - 该 Service 具有一个 ServicePort 字段,相应端口为 80。
cloud.google.com/neg
注释指定端口 80 将与 NEG 关联。可选的name
字段指定 NEG 将命名为NEG_NAME
。如果省略name
字段,系统会自动生成一个唯一名称。如需了解详情,请参阅为 NEG 命名。- 每个成员 Pod 必须有一个监听 TCP 端口 9376 的容器。
apiVersion: v1
kind: Service
metadata:
name: neg-demo-svc
annotations:
cloud.google.com/neg: '{"exposed_ports": {"80":{"name": "NEG_NAME"}}}'
spec:
type: ClusterIP
selector:
run: neg-demo-app # Selects Pods labelled run: neg-demo-app
ports:
- port: 80
protocol: TCP
targetPort: 9376
将 NEG_NAME
替换为 NEG 的名称。NEG 名称在其区域中必须是唯一的。
将此清单保存为 neg-demo-svc.yaml
,然后通过运行以下命令创建 Service:
kubectl apply -f neg-demo-svc.yaml
在创建 Service 后的几分钟内,将创建一个 NEG。
Service 类型
虽然此示例使用的是 ClusterIP
Service,但所有五种 Service 类型都支持独立 NEG。我们建议您使用默认类型 ClusterIP
。
为 NEG 命名
在 GKE 1.18.18-gke.1200 及更高版本中,您可以为 NEG 指定一个自定义名称,GKE 也可以自动生成名称。以前版本的 GKE 仅支持自动生成的 NEG 名称。
GKE 会在集群使用的每个可用区中创建一个 NEG。NEG 全部使用相同的名称。
指定名称
指定自定义 NEG 名称有助于简化负载均衡器的配置,因为您事先知道 NEG 的名称和可用区。 自定义 NEG 名称必须符合以下要求:
- 对于可用区级集群而言,该名称在集群的可用区中是唯一的;对于区域级集群而言,该名称在区域中是唯一的。
- 不得与并非由 GKE NEG 控制器创建的任何现有 NEG 的名称相匹配。
- 不得包含下划线。
使用 Service 的 cloud.google.com/neg
注释中的 name
字段指定 NEG 名称:
cloud.google.com/neg: '{"exposed_ports": {"80":{"name": "NEG_NAME"}}}'
将 NEG_NAME
替换为 NEG 的名称。NEG 名称在其区域中必须是唯一的。
使用自动生成的名称
自动生成的 NEG 名称必须是唯一的。 如需使用自动生成的名称,请省略 name
字段:
cloud.google.com/neg: '{"exposed_ports": {"80":{}}}'
自动生成的名称采用以下格式:
k8s1-CLUSTER_UID-NAMESPACE-SERVICE-PORT-RANDOM_HASH
将端口映射到多个 NEG
一个 Service 可以监听多个端口。根据定义,NEG 只有一个 IP 地址和端口。这意味着,如果您指定具有多个端口的 Service,则会为每个端口创建一个 NEG。
cloud.google.com/neg
注释的格式如下:
cloud.google.com/neg: '{
"exposed_ports":{
"SERVICE_PORT_1":{},
"SERVICE_PORT_2":{},
"SERVICE_PORT_3":{},
...
}
}'
在此示例中,SERVICE_PORT_N
的每个实例都是不同的端口号,它们引用 Service 的现有 Service 端口。对于列出的每个 Service 端口,NEG 控制器会在集群占用的每个区域中创建一个 NEG。
检索 NEG 状态
使用以下命令可检索集群的 Service 的状态:
kubectl get service neg-demo-svc -o yaml
输出内容类似如下:
cloud.google.com/neg-status: '{
"network-endpoint-groups":{
"SERVICE_PORT_1": "NEG_NAME_1",
"SERVICE_PORT_2": "NEG_NAME_2",
...
},
"zones":["ZONE_1", "ZONE_2", ...]
}
在此输出中,network-endpoint-groups
映射中的每个元素都是一个 Service 端口(例如 SERVICE_PORT_1
)以及相应的托管 NEG 的名称(例如 NEG_NAME_1
)。 zones
列表包含具有 NEG 的每个地区(如 ZONE_1
)。
输出类似于以下内容:
apiVersion: v1
kind: Service
metadata:
annotations:
cloud.google.com/neg: '{"exposed_ports": {"80":{}}}'
cloud.google.com/neg-status: '{"network_endpoint_groups":{"80":"k8s1-cca197ad-default-neg-demo-app-80-4db81e02"},"zones":["ZONE_1", "ZONE_2"]}'
labels:
run: neg-demo-app
name: neg-demo-app
namespace: default
selfLink: /api/v1/namespaces/default/services/neg-demo-app
...
spec:
clusterIP: 10.0.14.252
ports:
- port: 80
protocol: TCP
targetPort: 9376
selector:
run: neg-demo-app
sessionAffinity: None
status:
loadBalancer: {}
此示例的注解表明,Service 端口 80 已开放给名为 k8s1-cca197ad-default-neg-demo-app-80-4db81e02
的 NEG。
验证 NEG 创建
在创建 Service 后的几分钟内,将创建一个 NEG。如果存在与 Service 清单中指定的标签匹配的 Pod,则 NEG 在创建时将包含 Pod 的 IP 地址。
有两种方法可以验证 NEG 是否已创建并正确配置。在 GKE 1.18.6-gke.6400 及更高版本中,自定义资源 ServiceNetworkEndpointGroup
会存储由 Service Controller 创建的 NEG 的状态信息。在以前的版本中,您必须直接检查 NEG。
ServiceNetworkEndpointGroup
资源
通过获取所有 ServiceNetworkEndpointGroup
资源来列出集群中的 NEG:
kubectl get svcneg
通过检查 ServiceNetworkEndpointGroup
资源的状态来观察 NEG 的状态:
kubectl get svcneg NEG_NAME -o yaml
将 NEG_NAME
替换为您要检查的单个 NEG 的名称。
此命令的输出内容包括状态部分,该部分可能包含错误消息。某些错误报告为服务事件。您可以通过查询 Service 对象找到更多详细信息:
kubectl describe service SERVICE_NAME
将 SERVICE_NAME
替换为相关 Service 的名称。
如需验证 NEG 控制器是否已成功同步 NEG,请检查包含 type:Synced
的条件的 ServiceNetworkEndpointGroup
资源的状态字段。最近一次同步的时间位于 status.lastSyncTime
字段中。
ServiceNetworkEndpointGroup
资源仅存在于 GKE 1.18 及更高版本中。
直接检查 NEG
验证该 NEG 是否存在,方法是列出 Google Cloud 项目中的 NEG,并检查是否有 NEG 与您创建的 Service 相匹配。该 NEG 的名称采用以下格式:
k8s1-CLUSTER_UID-NAMESPACE-SERVICE-PORT-RANDOM_HASH
使用以下命令列出 NEG:
gcloud compute network-endpoint-groups list
输出内容类似如下:
NAME LOCATION ENDPOINT_TYPE SIZE
k8s1-70aa83a6-default-my-service-80-c9710a6f ZONE_NAME GCE_VM_IP_PORT 3
此输出表明 NEG 的 SIZE
是 3,这意味着它有三个端点,分别对应于 Deployment 中的三个 Pod。
使用以下命令标识各个端点:
gcloud compute network-endpoint-groups list-network-endpoints NEG_NAME
将 NEG_NAME
替换为要为其显示各个端点的 NEG 的名称。
输出显示了三个端点,每个端点都有一个 Pod 的 IP 地址和端口:
INSTANCE IP_ADDRESS PORT
gke-cluster-3-default-pool-4cc71a15-qlpf 10.12.1.43 9376
gke-cluster-3-default-pool-4cc71a15-qlpf 10.12.1.44 9376
gke-cluster-3-default-pool-4cc71a15-w9nk 10.12.2.26 9376
将外部应用负载均衡器连接到独立 NEG
您可以使用 Compute Engine API 将 NEG 用作外部应用负载均衡器的后端。
创建防火墙规则。 负载均衡器需要访问集群端点才能执行健康检查。以下命令会创建一条防火墙规则以允许访问:
gcloud compute firewall-rules create fw-allow-health-check-and-proxy \ --network=NETWORK_NAME \ --action=allow \ --direction=ingress \ --target-tags=GKE_NODE_NETWORK_TAGS \ --source-ranges=130.211.0.0/22,35.191.0.0/16 \ --rules=tcp:9376
替换以下内容:
NETWORK_NAME
:运行集群的网络。GKE_NODE_NETWORK_TAGS
:GKE 节点上的网络标记。
如果您没有为节点创建自定义网络标记,则 GKE 会自动为您生成标记。您可以通过运行以下命令来查找这些生成的标记:
gcloud compute instances describe INSTANCE_NAME
将
INSTANCE_NAME
替换为运行 GKE 节点的主机 Compute Engine 虚拟机实例的名称。例如,上一部分中的输出在 GKE 节点的INSTANCE
列中显示实例名称。 对于 Standard 集群,您还可以运行gcloud compute instances list
来列出项目中的所有实例。为负载均衡器创建全局虚拟 IP 地址:
gcloud compute addresses create hostname-server-vip \ --ip-version=IPV4 \ --global
创建健康检查。负载均衡器会使用健康检查来检测 NEG 中各个端点的活跃度。
gcloud compute health-checks create http http-basic-check \ --use-serving-port
创建后端服务,指明这是一个全球外部应用负载均衡器:
gcloud compute backend-services create my-bes \ --protocol HTTP \ --health-checks http-basic-check \ --global
为负载均衡器创建网址映射和目标代理。这个示例非常简单直接,因为本指南中使用的
serve_hostname
应用只有一个端点,且不包含网址。gcloud compute url-maps create web-map \ --default-service my-bes
gcloud compute target-http-proxies create http-lb-proxy \ --url-map web-map
创建转发规则。 这个过程会创建负载均衡器。
gcloud compute forwarding-rules create http-forwarding-rule \ --address=HOSTNAME_SERVER_VIP \ --global \ --target-http-proxy=http-lb-proxy \ --ports=80
将
HOSTNAME_SERVER_VIP
替换为用于负载均衡器的 IP 地址。如果省略--address
,GKE 会自动分配一个临时 IP 地址。 您也可以预留新的静态外部 IP 地址。
Checkpoint
下面列出了到目前为止您已创建的资源:
- 外部虚拟 IP 地址
- 转发规则
- 防火墙规则
- 目标 HTTP 代理
- 网址映射
- 后端服务
- Compute Engine 健康检查
这些资源之间的关系如下图所示:
这些资源共同构成了负载均衡器。在下一步中,您将向负载均衡器添加后端。
此处所示的独立 NEG 的优势之一在于,负载均衡器和后端的生命周期可以完全独立。负载均衡器可在应用、相关 Service 或 GKE 集群删除后继续运行。您可以向负载均衡器添加新的 NEG 或移除多个 NEG,而无需更改任何前端负载均衡器对象。
向负载均衡器添加后端
使用 gcloud compute backend-services
add-backend
将 NEG 连接到负载均衡器,方法是将其添加为 my-bes
后端服务的后端:
gcloud compute backend-services add-backend my-bes \
--global \
--network-endpoint-group=NEG_NAME \
--network-endpoint-group-zone=NEG_ZONE \
--balancing-mode RATE --max-rate-per-endpoint 5
替换以下内容:
NEG_NAME
:您的网络端点组的名称。名称是创建 NEG 时指定的名称,或自动生成的名称。如果您没有为 NEG 指定名称,请参阅下面的说明以查找自动生成的名称。NEG_ZONE
:网络端点组所在的可用区。请参阅以下说明查找此值。
使用以下命令获取 NEG 的名称和位置:
gcloud compute network-endpoint-groups list
输出类似于以下内容:
NAME LOCATION ENDPOINT_TYPE SIZE
k8s1-70aa83a6-default-my-service-80-c9710a6f ZONE_NAME GCE_VM_IP_PORT 3
在此示例输出中,NEG 的名称为 k8s1-70aa83a6-default-my-service-80-c9710a6f
。
您可以将多个 NEG 添加到同一后端服务。全局后端服务(如 my-bes
)可在不同地区具有 NEG 后端,而地区后端服务只能在单个地区中具有后端。
验证负载均衡器是否正常运行
有两种方法可以验证您设置的负载均衡器是否正常运行:
- 验证健康检查是否已正确配置且通过报告表明它运行正常。
- 访问应用并验证其响应。
验证健康检查
检查后端服务是否与健康检查和网络端点组相关联,以及各个端点是否运行正常。
使用以下命令检查后端服务是否与您的健康检查和网络端点组相关联:
gcloud compute backend-services describe my-bes --global
输出内容类似如下:
backends:
- balancingMode: RATE
capacityScaler: 1.0
group: ... /networkEndpointGroups/k8s1-70aa83a6-default-my-service-80-c9710a6f
...
healthChecks:
- ... /healthChecks/http-basic-check
...
name: my-bes
...
接下来,检查各个端点的运行状况:
gcloud compute backend-services get-health my-bes --global
输出的 status:
部分如下所示:
status:
healthStatus:
- healthState: HEALTHY
instance: ... gke-cluster-3-default-pool-4cc71a15-qlpf
ipAddress: 10.12.1.43
port: 50000
- healthState: HEALTHY
instance: ... gke-cluster-3-default-pool-4cc71a15-qlpf
ipAddress: 10.12.1.44
port: 50000
- healthState: HEALTHY
instance: ... gke-cluster-3-default-pool-4cc71a15-w9nk
ipAddress: 10.12.2.26
port: 50000
访问应用
通过负载均衡器的 IP 地址访问应用,以确认是否一切正常。
首先,获取负载均衡器的虚拟 IP 地址:
gcloud compute addresses describe hostname-server-vip --global | grep "address:"
输出将包含 IP 地址。接下来,向该 IP 地址(在此示例中为 34.98.102.37
)发送请求:
curl 34.98.102.37
来自 serve_hostname
应用的响应应为 neg-demo-app
。
将内部应用负载均衡器连接到独立 NEG
您可以使用 NEG 为在独立 GKE Pod 中运行的服务配置内部应用负载均衡器。
配置代理专用子网
代理专用子网用于负载均衡器的区域中的所有区域级内部应用负载均衡器。
控制台
如果您使用的是 Google Cloud 控制台,则可以稍后再创建代理专用子网。
gcloud
使用 gcloud compute networks subnets create 命令创建代理专用子网。
gcloud compute networks subnets create proxy-only-subnet \
--purpose=REGIONAL_MANAGED_PROXY \
--role=ACTIVE \
--region=COMPUTE_REGION \
--network=lb-network \
--range=10.129.0.0/23
将 COMPUTE_REGION
替换为子网的 Compute Engine 区域。
API
使用 subnetworks.insert
方法创建代理专用子网。
POST https://compute.googleapis.com/compute/projects/PROJECT_ID/regions/COMPUTE_REGION/subnetworks
{
"name": "proxy-only-subnet",
"ipCidrRange": "10.129.0.0/23",
"network": "projects/PROJECT_ID/global/networks/lb-network",
"region": "projects/PROJECT_ID/regions/COMPUTE_REGION",
"purpose": "REGIONAL_MANAGED_PROXY",
"role": "ACTIVE"
}
替换以下内容:
PROJECT_ID
:您的项目 ID。COMPUTE_REGION
:子网的 Compute Engine 区域。
配置防火墙规则
此示例使用以下防火墙规则:
fw-allow-ssh
:入站流量规则,它适用于负载均衡实例,允许从任何地址到 TCP 端口 22 的传入 SSH 连接。您可以为此规则选择限制性更高的来源 IP 地址范围。例如,您可以仅指定要从中启动 SSH 会话的系统的 IP 地址范围。此示例使用目标标记allow-ssh
来标识防火墙规则应该应用到的虚拟机。fw-allow-health-check
:适用于负载均衡实例的入站流量规则,该规则允许来自 Google Cloud 健康检查系统(130.211.0.0/22
和35.191.0.0/16
)的所有 TCP 流量。此示例使用目标标记load-balanced-backend
来标识它应该应用到的实例。fw-allow-proxies
:适用于负载均衡实例的入站流量规则,该规则允许从内部 HTTP(S) 负载均衡器的托管式代理发送到端口9376
的 TCP 流量。此示例使用目标标记load-balanced-backend
来标识它应该应用到的实例。
如果不使用上述防火墙规则,则默认拒绝入站规则会阻止传入后端实例的流量。
控制台
转到 Google Cloud 控制台中的防火墙政策页面。
点击创建防火墙规则
,以创建允许传入 SSH 连接的规则:- 名称:
fw-allow-ssh
- 网络:
lb-network
- 流量方向:入站
- 对匹配项执行的操作:允许
- 目标:指定的目标标记
- 目标标记:
allow-ssh
- 来源过滤条件:
IPv4 ranges
- 来源 IPv4 范围:
0.0.0.0/0
- 协议和端口:
- 选择指定的协议和端口。
- 选中
tcp
复选框并指定端口22
。
- 名称:
点击创建。
再次点击创建防火墙规则
以创建允许 Google Cloud 健康检查的规则:- 名称:
fw-allow-health-check
- 网络:
lb-network
- 流量方向:入站
- 对匹配项执行的操作:允许
- 目标:指定的目标标记
- 目标标记:
load-balanced-backend
- 来源过滤条件:
IPv4 ranges
- 来源 IPv4 范围:
130.211.0.0/22
和35.191.0.0/16
- 协议和端口:
- 选择指定的协议和端口
- 选中
tcp
复选框并指定端口80
。最佳做法是将此规则限制为仅使用与健康检查所使用的协议和端口匹配的协议和端口。如果您使用tcp:80
协议和端口,则 Google Cloud 可以使用 HTTP 协议通过端口 80 联系您的虚拟机,但无法使用 HTTPS 协议通过端口 443 联系这些虚拟机。
- 名称:
点击创建。
再次点击创建防火墙规则
,以创建允许负载均衡器的代理服务器连接后端的规则:- 名称:
fw-allow-proxies
- 网络:
lb-network
- 流量方向:入站
- 对匹配项执行的操作:允许
- 目标:指定的目标标记
- 目标标记:
load-balanced-backend
- 来源过滤条件:
IPv4 ranges
- 来源 IPv4 范围:
10.129.0.0/23
- 协议和端口:
- 选择指定的协议和端口。
- 选中
tcp
复选框并指定端口9376
。
- 名称:
点击创建。
gcloud
创建
fw-allow-ssh
防火墙规则,允许通过 SSH 连接到网络标记为allow-ssh
的虚拟机。如果省略source-ranges
,Google Cloud 会将规则解释为表示所有来源。gcloud compute firewall-rules create fw-allow-ssh \ --network=lb-network \ --action=allow \ --direction=ingress \ --target-tags=allow-ssh \ --rules=tcp:22
创建
fw-allow-health-check
规则以允许 Google Cloud 健康检查。本示例允许来自健康检查探测工具的所有 TCP 流量;但是,您可以根据自己的需求配置较小范围的端口集。gcloud compute firewall-rules create fw-allow-health-check \ --network=lb-network \ --action=allow \ --direction=ingress \ --source-ranges=130.211.0.0/22,35.191.0.0/16 \ --target-tags=load-balanced-backend \ --rules=tcp
创建
fw-allow-proxies
规则以允许内部 HTTP(S) 负载均衡器的代理连接到您的后端。gcloud compute firewall-rules create fw-allow-proxies \ --network=lb-network \ --action=allow \ --direction=ingress \ --source-ranges=10.129.0.0/23 \ --target-tags=load-balanced-backend \ --rules=tcp:9376
API
向 firewalls.insert
方法发出 POST
请求,以创建 fw-allow-ssh
防火墙规则。
POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/firewalls
{
"name": "fw-allow-ssh",
"network": "projects/PROJECT_ID/global/networks/lb-network",
"sourceRanges": [
"0.0.0.0/0"
],
"targetTags": [
"allow-ssh"
],
"allowed": [
{
"IPProtocol": "tcp",
"ports": [
"22"
]
}
],
"direction": "INGRESS"
}
将 PROJECT_ID
替换为您的项目 ID。
向 firewalls.insert
方法发出 POST
请求,以创建 fw-allow-health-check
防火墙规则。
POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/firewalls
{
"name": "fw-allow-health-check",
"network": "projects/PROJECT_ID/global/networks/lb-network",
"sourceRanges": [
"130.211.0.0/22",
"35.191.0.0/16"
],
"targetTags": [
"load-balanced-backend"
],
"allowed": [
{
"IPProtocol": "tcp"
}
],
"direction": "INGRESS"
}
通过 firewalls.insert
方法创建 fw-allow-proxies
防火墙规则,以允许代理子网内的 TCP 流量。
POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/global/firewalls
{
"name": "fw-allow-proxies",
"network": "projects/PROJECT_ID/global/networks/lb-network",
"sourceRanges": [
"10.129.0.0/23"
],
"targetTags": [
"load-balanced-backend"
],
"allowed": [
{
"IPProtocol": "tcp",
"ports": [
"9376"
]
}
],
"direction": "INGRESS"
}
将 PROJECT_ID
替换为您的项目 ID。
配置负载均衡器
对于转发规则的 IP 地址,请使用后端子网。如果您尝试使用代理专用子网,则无法创建转发规则。
控制台
选择负载均衡器类型
- 转到 Google Cloud 控制台中的创建负载均衡器页面。 转到创建负载均衡器
- 在 HTTP(S) 负载均衡下,点击开始配置。
- 选择“仅在我的虚拟机之间”。此设置表示负载均衡器是内部的。
- 点击继续。
准备负载均衡器
- 对于负载均衡器的名称,请输入
l7-ilb-gke-map
。 - 对于区域,选择创建子网的区域。
- 对于网络,请选择
lb-network
。
预留代理专用子网
预留代理专用子网:
- 点击 Reserve a Subnet(预留子网)。
- 为名称输入
proxy-only-subnet
。 - 对于 IP 地址范围,请输入
10.129.0.0/23
。 - 点击添加。
配置后端服务
- 点击后端配置。
- 在创建或选择后端服务菜单中,选择创建后端服务。
- 将后端服务的名称设置为
l7-ilb-gke-backend-service
。 - 对于后端类型,选择网络端点组。
- 在后端部分的新建后端卡片中执行以下操作:
- 将网络端点组设置为由 GKE 创建的 NEG。如需获取 NEG 名称,请参阅验证 NEG 创建。
- 对于 RPS 上限,指定每个端点的最大速率 (
5
RPS)。必要时 Google Cloud 将超过此上限。 - 点击完成。
- 从健康检查下拉列表中,选择创建健康检查,然后指定以下参数:
- 名称:
l7-ilb-gke-basic-check
- 协议:HTTP
- 端口指定:正在服务的端口
- 点击保存并继续。
- 名称:
- 点击创建。
配置网址映射
- 点击路由规则。确保 l7-ilb-gke-backend-service 是任何不匹配的主机和任何不匹配的路径的唯一后端服务。
配置前端
点击前端配置并执行以下步骤:
对于 HTTP:
- 点击前端配置。
- 点击添加前端 IP 和端口。
- 将名称设置为 l7-ilb-gke-forwarding-rule。
- 将协议设置为 HTTP。
- 将子网设置为 backend-subnet。
- 在内部 IP 下,选择“预留静态内部 IP 地址”。
- 在显示的面板中提供以下详细信息:
- 名称:
l7-ilb-gke-ip
- 在静态 IP 地址部分,选择“让我选择”。
- 在自定义 IP 地址部分,输入
10.1.2.199
。 - 点击预留。
- 名称:
- 将端口设置为
80
。 - 点击完成。
对于 HTTPS:
如果您在客户端和负载均衡器之间使用 HTTPS,则需要一个或多个 SSL 证书资源来配置代理。请参阅 SSL 证书,了解如何创建 SSL 证书资源。内部 HTTP(S) 负载均衡器不支持由 Google 管理的证书。
- 点击前端配置。
- 点击添加前端 IP 和端口。
- 在名称字段中,输入
l7-ilb-gke-forwarding-rule
。 - 在协议字段中,选择
HTTPS (includes HTTP/2)
。 - 将子网设置为 backend-subnet。
- 在内部 IP 下,选择“预留静态内部 IP 地址”。
- 在显示的面板中提供以下详细信息:
- 名称:
l7-ilb-gke-ip
- 在静态 IP 地址部分,选择“让我选择”。
- 在自定义 IP 地址部分,输入
10.1.2.199
。 - 点击预留。
- 名称:
- 确保将端口设置为
443
,以允许 HTTPS 流量。 - 点击证书下拉列表。
- 如果您已经拥有要用作主要 SSL 证书的自行管理的 SSL 证书资源,请从下拉菜单中选择该证书。
- 否则,请选择创建新证书。
- 填写名称
l7-ilb-cert
。 - 在相应字段中上传您的 PEM 格式的文件:
- 公钥证书
- 证书链
- 私钥
- 点击创建。
- 填写名称
- 如需添加除了主要 SSL 证书资源之外的其他证书资源,请执行以下操作:
- 点击添加证书。
- 从证书列表中选择一个证书,或点击创建新证书并按照说明操作。
- 点击完成。
完成配置
点击创建。
gcloud
使用 gcloud compute health-checks create http 命令定义 HTTP 健康检查。
gcloud compute health-checks create http l7-ilb-gke-basic-check \ --region=COMPUTE_REGION \ --use-serving-port
使用 gcloud compute backend-services create 命令定义后端服务。
gcloud compute backend-services create l7-ilb-gke-backend-service \ --load-balancing-scheme=INTERNAL_MANAGED \ --protocol=HTTP \ --health-checks=l7-ilb-gke-basic-check \ --health-checks-region=COMPUTE_REGION \ --region=COMPUTE_REGION
设置
DEPLOYMENT_NAME
变量:export DEPLOYMENT_NAME=NEG_NAME
将
NEG_NAME
替换为 NEG 的名称。使用 gcloud compute backend-services add-backend 命令将 NEG 后端添加到后端服务。
gcloud compute backend-services add-backend l7-ilb-gke-backend-service \ --network-endpoint-group=$DEPLOYMENT_NAME \ --network-endpoint-group-zone=COMPUTE_ZONE-b \ --region=COMPUTE_REGION \ --balancing-mode=RATE \ --max-rate-per-endpoint=5
使用 gcloud compute url-maps create 命令创建网址映射。
gcloud compute url-maps create l7-ilb-gke-map \ --default-service=l7-ilb-gke-backend-service \ --region=COMPUTE_REGION
创建目标代理。
对于 HTTP:
使用 gcloud compute target-http-proxies create 命令。
gcloud compute target-http-proxies create l7-ilb-gke-proxy \ --url-map=l7-ilb-gke-map \ --url-map-region=COMPUTE_REGION \ --region=COMPUTE_REGION
对于 HTTPS:
请参阅 SSL 证书,了解如何创建 SSL 证书资源。内部 HTTP(S) 负载均衡器不支持由 Google 管理的证书。
将文件路径分配给变量名称。
export LB_CERT=PATH_TO_PEM_FORMATTED_FILE
export LB_PRIVATE_KEY=PATH_TO_PEM_FORMATTED_FILE
使用 gcloud compute ssl-certificates create 命令创建区域性 SSL 证书。
gcloud compute ssl-certificates create
gcloud compute ssl-certificates create l7-ilb-cert \ --certificate=$LB_CERT \ --private-key=$LB_PRIVATE_KEY \ --region=COMPUTE_REGION
使用区域性 SSL 证书,通过 gcloud compute target-https-proxies create 命令创建目标代理。
gcloud compute target-https-proxies create l7-ilb-gke-proxy \ --url-map=l7-ilb-gke-map \ --region=COMPUTE_REGION \ --ssl-certificates=l7-ilb-cert
创建转发规则。
对于自定义网络,必须在转发规则中引用子网。请注意,这是虚拟机子网,而非代理子网。
对于 HTTP:
使用带有正确标志的 gcloud compute forwarding-rules create 命令。
gcloud compute forwarding-rules create l7-ilb-gke-forwarding-rule \ --load-balancing-scheme=INTERNAL_MANAGED \ --network=lb-network \ --subnet=backend-subnet \ --address=10.1.2.199 \ --ports=80 \ --region=COMPUTE_REGION \ --target-http-proxy=l7-ilb-gke-proxy \ --target-http-proxy-region=COMPUTE_REGION
对于 HTTPS:
使用带有正确标志的 gcloud compute forwarding-rules create 命令。
gcloud compute forwarding-rules create l7-ilb-gke-forwarding-rule \ --load-balancing-scheme=INTERNAL_MANAGED \ --network=lb-network \ --subnet=backend-subnet \ --address=10.1.2.199 \ --ports=443 \ --region=COMPUTE_REGION \ --target-https-proxy=l7-ilb-gke-proxy \ --target-https-proxy-region=COMPUTE_REGION
API
向 regionHealthChecks.insert
方法发出 POST
请求,以创建健康检查。
POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/COMPUTE_REGION/healthChecks
{
"name": "l7-ilb-gke-basic-check",
"type": "HTTP",
"httpHealthCheck": {
"portSpecification": "USE_SERVING_PORT"
}
}
将 PROJECT_ID
替换为项目 ID。
向 regionBackendServices.insert
方法发出 POST
请求,以创建地区后端服务。
POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/COMPUTE_REGION/backendServices
{
"name": "l7-ilb-gke-backend-service",
"backends": [
{
"group": "https://www.googleapis.com/compute/v1/projects/PROJECT_ID/zones/COMPUTE_ZONE/networkEndpointGroups/NEG_NAME",
"balancingMode": "RATE",
"maxRatePerEndpoint": 5
}
],
"healthChecks": [
"projects/PROJECT_ID/regions/COMPUTE_REGION/healthChecks/l7-ilb-gke-basic-check"
],
"loadBalancingScheme": "INTERNAL_MANAGED"
}
替换以下内容:
PROJECT_ID
:项目 ID。NEG_NAME
:NEG 的名称。
向 regionUrlMaps.insert
方法发出 POST
请求,以创建网址映射。
POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/COMPUTE_REGION/urlMaps
{
"name": "l7-ilb-gke-map",
"defaultService": "projects/PROJECT_ID/regions/COMPUTE_REGION/backendServices/l7-ilb-gke-backend-service"
}
将 PROJECT_ID
替换为项目 ID。
向 regionTargetHttpProxies.insert
方法发出 POST
请求,以创建目标 HTTP 代理。
POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/COMPUTE_REGION/targetHttpProxy
{
"name": "l7-ilb-gke-proxy",
"urlMap": "projects/PROJECT_ID/global/urlMaps/l7-ilb-gke-map",
"region": "COMPUTE_REGION"
}
将 PROJECT_ID
替换为项目 ID。
向 forwardingRules.insert
方法发出 POST
请求,以创建转发规则。
POST https://compute.googleapis.com/compute/v1/projects/PROJECT_ID/regions/COMPUTE_REGION/forwardingRules
{
"name": "l7-ilb-gke-forwarding-rule",
"IPAddress": "10.1.2.199",
"IPProtocol": "TCP",
"portRange": "80-80",
"target": "projects/PROJECT_ID/regions/COMPUTE_REGION/targetHttpProxies/l7-ilb-gke-proxy",
"loadBalancingScheme": "INTERNAL_MANAGED",
"subnetwork": "projects/PROJECT_ID/regions/COMPUTE_REGION/subnetworks/backend-subnet",
"network": "projects/PROJECT_ID/global/networks/lb-network",
"networkTier": "PREMIUM",
}
将 PROJECT_ID
替换为项目 ID。
测试
在地区中创建虚拟机实例以测试连接:
gcloud compute instances create l7-ilb-client \
--image-family=debian-9 \
--image-project=debian-cloud \
--zone=COMPUTE_ZONE \
--network=lb-network \
--subnet=backend-subnet \
--tags=l7-ilb-client,allow-ssh
登录客户端实例,检查是否可以使用内部应用负载均衡器的转发规则 IP 地址访问后端的 HTTP(S) 服务,以及流量是否正在 NEG 中的端点之间进行负载均衡。
使用 SSH 连接到每个客户端实例:
gcloud compute ssh l7-ilb-client \
--zone=COMPUTE_ZONE-b
验证 IP 是否提供其主机名:
curl 10.1.2.199
对于 HTTPS 测试,请运行以下命令:
curl -k -s 'https://test.example.com:443' --connect-to test.example.com:443:10.1.2.199:443
-k
标志会导致 curl
跳过证书验证。
运行 100 个请求并确认它们已进行负载均衡。
对于 HTTP:
{
RESULTS=
for i in {1..100}
do
RESULTS="$RESULTS:$(curl --silent 10.1.2.199)"
done
echo "***"
echo "*** Results of load-balancing to 10.1.2.199: "
echo "***"
echo "$RESULTS" | tr ':' '\n' | grep -Ev "^$" | sort | uniq -c
echo
}
对于 HTTPS:
{
RESULTS=
for i in {1..100}
do
RESULTS="$RESULTS:$(curl -k -s 'https://test.example.com:443' --connect-to test.example.com:443:10.1.2.199:443
)"
done
echo "***"
echo "*** Results of load-balancing to 10.1.2.199: "
echo "***"
echo "$RESULTS" | tr ':' '\n' | grep -Ev "^$" | sort | uniq -c
echo
}
实现异构服务(虚拟机和容器)
负载均衡器可以作为混合 Kubernetes 和非 Kubernetes 工作负载的前端。这可能是从虚拟机到容器的迁移的一部分,也可能是受益于共享负载均衡器的永久架构。这可以通过创建针对不同类型的后端(包括独立 NEG 在内)的负载均衡器来实现。
同一后端服务中的虚拟机和容器
此示例展示了如何创建指向运行某工作负载的现有虚拟机的 NEG,以及如何将此 NEG 添加为现有 backendService
的另一个后端。这样,单个负载均衡器就可以均衡虚拟机与 GKE 容器之间的负载。
此示例拓展了使用外部 HTTP 负载均衡器的上一个示例。
由于所有端点都由同一 backendService
分组,因此,虚拟机和容器端点会被视为同一服务。这意味着主机或路径匹配将根据网址映射规则以完全相同的方式处理所有后端。
在将 NEG 用作后端服务的后端时,该后端服务中的所有其他后端也必须是 NEG。您不能将实例组和 NEG 用作同一后端服务的后端。此外,容器和虚拟机不能作为端点存在于同一 NEG 中,因此,它们必须始终配置单独的 NEG。
使用以下命令将虚拟机部署到 Compute Engine:
gcloud compute instances create vm1 \ --zone=COMPUTE_ZONE \ --network=NETWORK \ --subnet=SUBNET \ --image-project=cos-cloud \ --image-family=cos-stable --tags=vm-neg-tag
替换以下内容:
COMPUTE_ZONE
:区域的名称。NETWORK
:网络的名称。SUBNET
:与网络关联的子网的名称。
将应用部署到虚拟机:
gcloud compute ssh vm1 \ --zone=COMPUTE_ZONE \ --command="docker run -d --rm --network=host registry.k8s.io/serve_hostname:v1.4 && sudo iptables -P INPUT ACCEPT"
此命令会将之前示例中的那个示例应用部署到虚拟机。为简单起见,应用作为 Docker 容器运行,但这不是必需的。如需允许防火墙访问正在运行的容器,必须使用
iptables
命令。验证应用是否在端口 9376 上运行并且通过报告表明它正在 vm1 上运行:
gcloud compute ssh vm1 \ --zone=COMPUTE_ZONE \ --command="curl -s localhost:9376"
服务器会返回
vm1
响应。创建一个能与虚拟机端点配合使用的 NEG。容器和虚拟机可以均为 NEG 端点,但单个 NEG 不能同时具有虚拟机和容器端点。
gcloud compute network-endpoint-groups create vm-neg \ --subnet=SUBNET \ --zone=COMPUTE_ZONE
将虚拟机端点连接到 NEG:
gcloud compute network-endpoint-groups update vm-neg \ --zone=COMPUTE_ZONE \ --add-endpoint="instance=vm1,ip=VM_PRIMARY_IP,port=9376"
将
VM_PRIMARY_IP
替换为虚拟机的主要 IP 地址。确认 NEG 具有虚拟机端点:
gcloud compute network-endpoint-groups list-network-endpoints vm-neg \ --zone COMPUTE_ZONE
使用用于添加容器后端的命令将 NEG 附加到后端服务:
gcloud compute backend-services add-backend my-bes --global \ --network-endpoint-group vm-neg \ --network-endpoint-group-zone COMPUTE_ZONE \ --balancing-mode RATE --max-rate-per-endpoint 10
打开防火墙以允许执行虚拟机健康检查:
gcloud compute firewall-rules create fw-allow-health-check-to-vm1 \ --network=NETWORK \ --action=allow \ --direction=ingress \ --target-tags=vm-neg-tag \ --source-ranges=130.211.0.0/22,35.191.0.0/16 \ --rules=tcp:9376
通过发送测试流量,验证负载均衡器是否正将流量转发到新的 vm1 后端和现有容器后端:
for i in `seq 1 100`; do curl ${VIP};echo; done
您应该会看到来自容器 (
neg-demo-app
) 和虚拟机 (vm1
) 端点的响应。
不同后端服务的虚拟机和容器
此示例展示了如何创建指向运行某工作负载的现有虚拟机的 NEG,以及如何将此 NEG 添加为新 backendService
的后端。如果容器和虚拟机是不同的 Service,但需要共用同一 L7 负载均衡器(例如,Service 共用同一 IP 地址或域名),则此方法非常有用。
此示例扩展了上文中在与容器后端相同的后端服务中具有虚拟机后端的那个示例。此示例重复使用了那个虚拟机。
由于容器和虚拟机端点被分组到不同的后端服务中,因此它们被视为不同的 Service。这意味着,网址映射会匹配后端,并根据主机名将流量引导至虚拟机或容器。
下图显示了单个虚拟 IP 地址如何与两个主机名对应,继而又对应于基于容器的后端服务和基于虚拟机的后端服务。
下图展示了上一部分中介绍的架构:
为虚拟机创建新的后端服务:
gcloud compute backend-services create my-vm-bes \ --protocol HTTP \ --health-checks http-basic-check \ --global
将虚拟机的 NEG
vm-neg
附加到后端服务:gcloud compute backend-services add-backend my-vm-bes \ --global \ --network-endpoint-group vm-neg \ --network-endpoint-group-zone COMPUTE_ZONE \ --balancing-mode RATE --max-rate-per-endpoint 10
向网址映射添加一条主机规则,以将对
container.example.com
主机的请求引导至容器后端服务:gcloud compute url-maps add-path-matcher web-map \ --path-matcher-name=container-path --default-service=my-bes \ --new-hosts=container.example.com --global
向网址映射添加另一条主机规则,以将对
vm.example.com
主机的请求引导至虚拟机后端服务:gcloud compute url-maps add-path-matcher web-map \ --path-matcher-name=vm-path --default-service=my-vm-bes \ --new-hosts=vm.example.com --global
验证负载均衡器是否根据请求的路径将流量发送到虚拟机后端:
curl -H "HOST:vm.example.com" VIRTUAL_IP
将
VIRTUAL_IP
替换为虚拟 IP 地址。
独立 NEG 所受的限制
- 注释验证错误通过 Kubernetes 事件向用户显示。
- NEG 所受的限制也适用于独立 NEG。
- 独立 NEG 不适用于旧版网络。
- 独立 NEG 只能与兼容的网络服务一起使用,包括 Traffic Director 和兼容的各类负载均衡器。
价格
如需详细了解负载均衡器的价格,请参阅价格页面的负载均衡部分。NEG 不会额外产生费用。
问题排查
本部分介绍了您在使用独立 NEG 时可能会遇到的常见问题的问题排查步骤。
未配置独立 NEG
具体情况:未创建 NEG。
可能的解决方法:
- 检查与 Service 相关联的事件,并查找错误消息。
- 验证独立 NEG 注释是否为格式正确的 JSON,以及显示的端口是否与服务规范中的现有端口匹配。
- 验证 NEG 状态注释,并查看预期的服务端口是否具有相应的 NEG。
- 使用命令
gcloud compute network-endpoint-groups list
验证是否在预期的地区中创建了 NEG。 - 如果使用 GKE 1.18 或更高版本,请检查 Service 的
svcneg
资源是否存在。如果存在,请检查Initialized
条件中是否存在任何错误信息。 - 如果您使用的是自定义 NEG 名称,请确保其中每个 NEG 名称在其区域中是唯一的。
流量未到达端点
具体情况:出现 502 错误或连接被拒。
可能的解决方法:
- 配置 Service 后,如果新端点能够响应健康检查,那么在将新端点附加到 NEG 后,通常就可以访问新端点。
- 如果在此之后,流量仍然无法到达端点,从而导致出现 HTTP(S) 的 502 错误代码或 TCP/SSL 负载均衡器的连接被拒,请检查以下内容:
- 验证防火墙规则是否允许传入的 TCP 流量传输到以下范围内的端点:
130.211.0.0/22
和35.191.0.0/16
。 - 使用 Google Cloud CLI 或者通过在
backendService
上调用getHealth
API 或在 NEG 上调用 listEndpoints API 并将 showHealth 参数设置为SHOW
,验证端点是否健康。
- 验证防火墙规则是否允许传入的 TCP 流量传输到以下范围内的端点:
停止发布
具体情况:发布更新后 Deployment 的操作处于停止状态,并且最新副本的数量与所选的副本数量不一致。
可能的解决方法:
Deployment 的健康检查失败。容器映像可能已损坏,或者健康检查的配置可能有误。Pod 的滚动替换会等待新启动的 Pod 通过其 Pod 就绪性门控。仅当 Pod 正在响应负载均衡器健康检查时,才会出现这种情况。如果 Pod 没有响应,或者健康检查的配置有误,则无法满足就绪性门控条件,并且无法继续发布。
如果您使用的是 kubectl 1.13 或更高版本,则可以使用以下命令检查 Pod 就绪性门控的状态:
kubectl get my-Pod -o wide
查看 READINESS GATES 列。
kubectl 1.12 及更低版本中不存在此列。标记为 READY 状态的 Pod 的就绪性门控可能已失败。如需就此进行验证,请使用以下命令:
kubectl get my-pod -o yaml
输出中会列出就绪性门控及其状态。
验证 Deployment 的 Pod 规范中的容器映像是否正常运行,以及是否能够响应健康检查。
验证健康检查是否已正确配置。
NEG 并非处于垃圾回收状态
症状:应该删除的 NEG 仍然存在。
可能的解决方法:
- 如果后端 Service 引用了 NEG,则 NEG 并非处于垃圾回收状态。如需了解详情,请参阅防止泄露 NEG。
- 如果使用 1.18 或更高版本,则可以使用服务 NEG 过程检查
ServiceNetworkEndpointGroup
资源中的事件。 - 检查服务是否仍需要 NEG。检查与 NEG 相对应的服务的
svcneg
资源,并检查 Service 注释是否存在。
NEG 未与 Service 同步
症状:NEG 中不存在预期 (Pod IP) 端点、NEG 未同步或出现错误 Failed to sync NEG_NAME (will not retry):
neg name NEG_NAME is already in use, found a custom named neg with an empty
description
可能的解决方法:
如果您使用的是 GKE 1.18 或更高版本,请查看 svcneg
资源,了解相关信息:
- 检查
status.lastSyncTime
值以验证 NEG 最近是否同步。 - 检查
Synced
条件,了解在最近同步期间遇到的任何错误。
如果您使用的是 GKE 1.19.9 或更高版本,请检查是否存在这样一个 NEG,它的名称和可用区与 GKE NEG 控制器需要创建的 NEG 的名称和可用区相匹配。例如,您可能已使用 gcloud CLI 或 Google Cloud 控制台在集群的可用区(或集群的某个可用区)中创建 NEG 控制器需要使用其名称的 NEG。在这种情况下,您必须删除现有的 NEG,然后 NEG 控制器才能同步其端点。独立 NEG 的创建和成员资格根据设计由 NEG 控制器管理。