如何为 GCE 上的 Envoy 代理启用 HTTPS (使用 Google Cloud Load Balancer)
本文档详细记录了如何为一个运行在 Google Compute Engine (GCE) 虚拟机上的 Envoy 代理,通过配置 Google Cloud 全球外部 HTTPS 负载均衡器和 Google 管理的 SSL 证书来启用 HTTPS。

最终架构
最终的流量路径如下:
用户 -> HTTPS -> [Google 全球外部 HTTPS LB] -> HTTP -> [GCE MIG (Envoy VM)] -> [Cloud Run Services]
架构图 (Mermaid)
Google Cloud Platform - Backend Upstream Cloud Run Services Google Cloud Platform - Global HTTPS Load Balancer Components User & DNS 1. Resolves www.jpgcp.cloud 2. Returns IP: 34.54.9.78 3. HTTPS Request 4. Forwards Encrypted Traffic 5. Decrypts & Sends to Router 6. Routes HTTP Request 7. Load Balances to MIG 8. Routes path /myui 9. Routes path /pyapi Probes Envoy's admin port 9901 Managed Instance Group (MIG)
my-envoy-proxy GCE VM with Envoy Proxy
(Receives HTTP on Port 80) Health Check Cloud Run Service
myui Cloud Run Service
py-api-svc Forwarding Rule (Public IP)
34.54.9.78 Target HTTPS Proxy
(Holds SSL Certificate) URL Map
(L7 Routing Rules) Backend Service
(Manages Backends & Health Checks) End User DNS Provider
介绍:为什么选择这种方式?
在为 GCE 上的服务(如 Envoy)启用 HTTPS 时,我们选择将 SSL 终端(Termination)放在 Google Cloud 全球负载均衡器上,而不是在 Envoy 代理本身。这是一种现代云原生架构中的最佳实践,拥有以下核心优势:
-
简化后端配置与运维 (Simplified Backend Configuration):
- Envoy 无需修改: 最直接的好处是,我们的 Envoy 代理无需进行任何与 SSL/TLS 相关的配置。不需要处理证书文件、私钥、TLS 协议版本、加密套件等复杂配置。Envoy 可以继续以最高效的方式处理纯 HTTP 流量。
- 统一流量入口: 无论后端有多少微服务,SSL 加解密这个"脏活累活"都在统一的入口(LB)处理掉了,后端服务可以更专注于自身业务逻辑。
-
证书全自动生命周期管理 (Automated Certificate Lifecycle):
- 无需手动操作: Google 管理的证书服务会自动处理证书的申请、验证、部署和续期 。您再也无需担心证书过期问题,也无需编写复杂的
certbot续期脚本。 - 高可用性: 证书被部署在全球分布的负载均衡器前端,具备天然的高可用性。
- 无需手动操作: Google 管理的证书服务会自动处理证书的申请、验证、部署和续期 。您再也无需担心证书过期问题,也无需编写复杂的
-
提升安全性 (Enhanced Security):
- 攻击面收敛: 只有负载均衡器暴露在公网上,您可以配置防火墙规则,使得您的 GCE 虚拟机只接受来自负载均衡器IP范围的流量,极大地减少了直接暴露给外部攻击的风险。
- 轻松集成 WAF: 可以在负载均衡器上轻松集成 Google Cloud Armor (Web 应用防火墙),以抵御 DDoS 攻击、SQL 注入、跨站脚本等常见威胁。
-
更优的性能与扩展性 (Better Performance & Scalability):
- 释放后端资源: SSL/TLS 的加解密是计算密集型操作。将这部分计算卸载到专用的负载均衡器上,可以让后端 GCE 虚拟机的 CPU 资源完全用于处理业务逻辑,从而提升应用性能。
- 全球网络加速: 全球外部 HTTPS 负载均衡器使用 Google 的全球高级网络层,可以将用户的连接在全球网络边缘的接入点(PoP)上就近终止,利用 Google 的骨干网回源到您的后端,从而降低延迟,提升用户体验。
- 无缝集成 CDN: 可以一键为后端服务启用 Cloud CDN,将静态内容缓存到全球边缘节点,进一步提升性能。
总而言之,这种架构将专业的网络流量管理(安全、证书、路由、负载均衡)与后端业务逻辑清晰地分离开来,让每一层都做自己最擅长的事情,是构建现代化、可扩展、安全可靠的云应用的标准模式。
前提条件
在开始之前,我们已经具备以下环境:
- 一个名为
my-envoy-proxy-vm-p3d5的 GCE 虚拟机正在运行 Envoy 代理。 - 该虚拟机属于一个名为
my-envoy-proxy的代管实例组 (MIG)。 - Envoy 代理配置为监听
80端口的 HTTP 流量。 - 拥有一个域名
www.jpgcp.cloud,并且可以修改其 DNS 解析记录。
核心架构概念问答 (Q&A)
在深入了解具体操作步骤之前,本节将解答一些关于此架构设计的常见问题。
Q1: 为什么负载均衡器 (LB) 不能直接转发到实例组 (MIG),而需要一个后端服务 (Backend Service)?
这是一个核心的设计理念问题。负载均衡器 (LB) 和实例组 (MIG) 承担着不同的职责,而后端服务 (Backend Service) 在它们之间扮演着不可或缺的**"大脑"和"交通指挥官"**的角色。
这种分层设计实现了"关注点分离",带来了巨大的灵活性和可靠性:
-
后端服务负责管理逻辑: 它定义了流量应该如何被处理。这包括:
- 健康检查: 持续监控 MIG 中的每个虚拟机是否健康,并自动将流量从不健康的实例上移开。
- 负载分发策略: 定义流量如何在健康的虚拟机之间进行分配(例如,基于 CPU 利用率或每秒请求数)。
- 会话亲和性: (可选)确保来自同一用户的请求始终被发送到同一个虚拟机。
- 集成高级功能: 作为集成 Cloud CDN (缓存) 或 Cloud Armor (WAF 防火墙) 的配置点。
-
负载均衡器前端负责接收流量: 转发规则和目标代理只负责接收外部流量、处理 SSL 证书,然后将流量交给后端服务进行智能处理。
简单来说,后端服务将"接收流量"和"处理流量"这两个环节解耦,并负责它们之间所有的智能逻辑。
Q2: 一个后端服务可以管理多个 MIG 吗?
是的,完全可以。 这是一个非常强大且常见的功能,主要用于以下场景:
- 多区域高可用性: 您可以将在不同区域的多个 MIG(例如,一个在美国,一个在欧洲)添加到同一个全局后端服务中。LB 会自动将用户流量导向最近的健康 MIG,并在某个区域发生故障时实现自动故障转移。
- 版本升级与金丝雀部署: 您可以同时将新旧两个版本的 MIG 添加到同一个后端服务,并通过调整流量分配比例,安全地进行版本迭代和测试。
Q3: 后端服务如何区分并向不同 MIG 分发流量?这和 API 网关有什么区别?
这是一个关键点:后端服务 (Backend Service) 本身不根据 URL 路径来区分流量,而是由更上层的网址映射 (URL Map) 来负责。
整个流程是这样的:
- 网址映射 (URL Map) - 负责"宏观"路径路由: 它会检查请求的 URL(例如
/api/*或/images/*),然后根据您设定的规则,决定将请求交给哪一个后端服务 。例如,所有/api的请求都交给api-backend-service。 - 后端服务 (Backend Service) - 负责"微观"后端分发: 在被网址映射选中后,后端服务才开始工作。它在自己所管理的 MIG 内部,找一台健康的虚拟机,并将流量发送过去。它并不关心 URL 路径,只关心它所管理的 VM 的健康状况和负载情况。
与 API 网关的区别:
虽然两者都处理路由,但它们的目的和功能侧重点完全不同。下面的表格清晰地对比了它们的区别:
| 特性 | Google Cloud Load Balancer (带网址映射) | API 网关 (例如 Google API Gateway) |
|---|---|---|
| 主要目的 | 负载均衡和流量路由 为大规模 Web 应用、微服务、静态内容设计,核心是高可用和高性能分发。 | API 的管理和安全 为后端 API 提供一个统一、安全的入口,核心是管控和治理。 |
| 核心功能 | - 全球负载均衡 - SSL 证书卸载 - 基于主机和路径的路由 - 健康检查 - 缓存 (Cloud CDN) - 安全 (Cloud Armor WAF) | - 身份认证和授权 (API 密钥, JWT) - 速率限制和配额 - 请求/响应转换 - 协议转换 (REST 到 gRPC) - 针对 API 消费者的监控和日志 |
| 比喻 | 大型城市的交通指挥中心 根据车辆的目的地(URL 路径),指挥它们上哪条高速公路(哪个后端服务)。 | 办公楼的安全前台 它要检查你的身份证件(认证),告诉你可以去哪个部门(路由),确保你不会骚扰某个部门(速率限制),并记录你的来访(日志)。 |
总结来说: 当你需要大规模、高可用地分发 Web 流量时,选择负载均衡器 。当你需要为 API 提供安全、认证、限流等精细化管理功能时,选择 API 网关。
Q4: 为了节省成本,可以不用后端服务,让 LB 直接转发到 VM 吗?
对于我们正在使用的全局外部 HTTPS 负载均衡器 ,答案是不可以。后端服务是该架构中一个无法省略的核心组件。
关于成本,您无需担心。后端服务本身并非一个独立的昂贵收费项。 HTTPS 负载均衡器的主要费用来自于:
- 转发规则(IP 地址) 的小时费用。
- 处理流量的每 GB 费用。
后端服务的成本已经包含在整个产品服务的定价中了。
虽然 GCP 存在更简单的网络负载均衡器 (L4) 可以不使用后端服务,但它无法处理 HTTPS 流量或管理 SSL 证书,因此不适用于我们当前为网站启用 HTTPS 的场景。
Q5: 我可以用 curl 直接测试健康检查 (Health Check) 或后端服务 (Backend Service) 吗?
不完全可以,但我们可以模拟健康检查的行为来达到测试的目的。
-
为什么不能直接测试?
- 健康检查是由 Google Cloud 的内部系统自动、定期发起的探测行为,我们无法从外部直接触发。
- 后端服务是一个逻辑配置资源,它没有自己可供外部访问的 IP 地址或端点。
-
如何模拟测试?
我们的健康检查 (
envoy-health-check) 配置为探测 Envoy 所在虚拟机的 TCP 端口9901。因此,我们可以直接登录到虚拟机内部,尝试访问这个端口,来验证 Envoy 是否暴露了健康的信号。下面这条命令通过 SSH 登录到 Envoy 虚拟机,并在内部使用
curl访问 Envoy 的管理界面的统计信息端点:bashgcloud compute ssh my-envoy-proxy-vm-p3d5 --zone europe-west2-c --command "curl http://localhost:9901/stats"如果这个命令成功返回了大量的统计数据(而不是连接拒绝或超时),就证明了 Envoy 代理本身是健康的。这也意味着当 GCP 的健康检查探测器进行探测时,同样会得到一个成功的响应,从而将该实例标记为"健康"并向其发送流量。
操作步骤
我们通过以下步骤完成了整个配置过程:
步骤 1: 创建健康检查
负载均衡器需要一种方法来判断后端的 Envoy 代理是否健康。我们创建了一个 TCP 健康检查,用于探测 Envoy 的管理端口 9901。
bash
gcloud compute health-checks create tcp envoy-health-check --port 9901
输出:
Created [https://www.googleapis.com/compute/v1/projects/jason-hsbc/global/healthChecks/envoy-health-check].
NAME PROTOCOL
envoy-health-check TCP
步骤 2: 创建后端服务并关联 MIG
后端服务是负载均衡器的核心,它负责管理后端实例组并应用健康检查。
首先,我们创建一个全局的后端服务:
bash
gcloud compute backend-services create envoy-backend-service \
--health-checks=envoy-health-check \
--port-name=http \
--protocol=HTTP \
--global
输出:
Created [https://www.googleapis.com/compute/v1/projects/jason-hsbc/global/backendServices/envoy-backend-service].
NAME BACKENDS PROTOCOL
envoy-backend-service HTTP
然后,我们将已有的 MIG my-envoy-proxy 添加到这个后端服务中:
bash
gcloud compute backend-services add-backend envoy-backend-service \
--instance-group=my-envoy-proxy \
--instance-group-zone=europe-west2-c \
--global
输出:
Updated [https://www.googleapis.com/compute/v1/projects/jason-hsbc/global/backendServices/envoy-backend-service].
步骤 3: 创建网址映射 (URL Map) - L7 路由规则
网址映射 (URL Map) 是 HTTPS 负载均衡器的应用层路由器 。它的核心作用是检查传入的 HTTP(S) 请求的主机名 和路径,然后根据您设定的规则,决定将该请求转发到哪一个后端服务。
Q: 网址映射是什么到什么的映射?
它建立了从 "一个具体的 URL 请求" 到 "一个具体的后端服务" 的映射关系。
例如,您可以定义如下规则:
- 如果请求的主机是
api.example.com,则发送到api-backend-service。 - 如果请求的路径以
/video开头,则发送到video-backend-service。 - 其他所有请求,都发送到
default-web-backend-service。
在我们的配置中,我们只设置了一条"捕获所有"的默认规则,将所有流量都指向我们唯一的后端服务 envoy-backend-service。
Q: 那么 URL Map 就是一个网关 (Gateway) 吗?
这个理解非常精准。从功能上看,URL Map 扮演了网关(Gateway)中最核心的路由角色 ,但它本身不是一个完整意义上的 API 网关。
一个完整的 API 网关产品在路由的基础上,还捆绑了大量用于管理和保护 API 的功能。
| 特性 | 网址映射 (在负载均衡器内) | API 网关 (独立产品) |
|---|---|---|
| 核心职责 | L7 路径路由 | API 的安全、管理与暴露 |
| 路径路由 | ✅ (核心功能) | ✅ (核心功能之一) |
| SSL 证书卸载 | ✅ (由 LB 的目标代理完成) | ✅ (自身具备) |
| 身份认证/授权 | ❌ (不负责此项) | ✅ (核心功能, 如 API 密钥, JWT) |
| 速率限制/配额 | ❌ (不负责此项) | ✅ (核心功能) |
| 请求/响应转换 | ❌ (不负责此项) | ✅ (核心功能) |
现在,我们来创建网址映射资源。这条命令将创建一条默认规则,把所有流量都路由到 envoy-backend-service:
bash
gcloud compute url-maps create envoy-url-map \
--default-service envoy-backend-service
输出:
Created [https://www.googleapis.com/compute/v1/projects/jason-hsbc/global/urlMaps/envoy-url-map].
NAME DEFAULT_SERVICE
envoy-url-map backendServices/envoy-backend-service
步骤 4: 创建 Google 管理的 SSL 证书
这是实现证书自动管理的关键一步。我们为域名 www.jpgcp.cloud 创建了一个 Google 管理的证书。GCP 会自动处理证书的申请、验证、颁发和续期。
bash
gcloud compute ssl-certificates create envoy-ssl-cert \
--domains=www.jpgcp.cloud \
--global
输出:
Created [https://www.googleapis.com/compute/v1/projects/jason-hsbc/global/sslCertificates/envoy-ssl-cert].
NAME TYPE CREATION_TIMESTAMP EXPIRE_TIME REGION MANAGED_STATUS
envoy-ssl-cert MANAGED 2025-11-20T08:22:52.143-08:00 PROVISIONING
www.jpgcp.cloud: PROVISIONING
此时证书状态为 PROVISIONING,表示正在申请中。
步骤 5: 创建目标 HTTPS 代理 - SSL 终端
目标 HTTPS 代理 (Target HTTPS Proxy) 是负载均衡器的**"HTTPS 协议处理器"** 或 "SSL 终端"。它负责处理所有与 HTTPS 协议相关的复杂工作,是连接"外部加密世界"和"内部 HTTP 路由世界"的关键桥梁。
Q: 目标 HTTPS 代理是做什么的?它和网址映射是什么关系?
它的职责非常专一:
- 持有 SSL 证书: 它是真正使用我们上一步创建的 SSL 证书的组件。
- 处理 SSL 握手: 它负责与客户端(例如浏览器)进行 TLS/SSL 握手。
- 解密流量: 将加密的 HTTPS 流量解密成普通的 HTTP 流量。
它本身不执行路由决策 。它的工作流程是:在完成解密后,将干净的、未加密的 HTTP 请求递交给 它所关联的网址映射 (URL Map),由网址映射来继续执行路由。
Q: 既然有了 HTTPS 代理,为什么还需要负载均衡器 (LB)?
这是一个非常好的问题。答案是:目标 HTTPS 代理本身并不是一个独立的服务,它就是我们所说的"负载均衡器"这个系统中的一个核心零件。
我们可以把整个 HTTPS 负载均衡器比作一辆汽车,而我们创建的各个资源就是汽车的零件:
- 转发规则 (LB 入口): 汽车的方向盘和点火开关。
- 目标 HTTPS 代理: 汽车的发动机,负责处理燃料(HTTPS 流量)并转化为动力(解密的 HTTP 流量)。
- 网址映射 (URL Map): 汽车的GPS 导航系统,负责指引方向(路由)。
- 后端服务 (Backend Service): 汽车的变速箱和传动系统,负责智能地分配动力。
- 实例组 (MIG): 汽车的车轮,最终执行任务。
结论: 您不能说"我不要车了,只要一个发动机"。同样,目标 HTTPS 代理只是整个负载均衡器服务中的一个内部处理引擎,它必须与其他所有零件协同工作,才能构成一个完整、可用的服务。
现在,我们来创建目标 HTTPS 代理资源,它会将我们的 SSL 证书和网址映射关联起来:
bash
gcloud compute target-https-proxies create envoy-https-proxy \
--ssl-certificates=envoy-ssl-cert \
--url-map=envoy-url-map \
--global
输出:
Created [https://www.googleapis.com/compute/v1/projects/jason-hsbc/global/targetHttpsProxies/envoy-https-proxy].
NAME SSL_CERTIFICATES URL_MAP REGION CERTIFICATE_MAP
envoy-https-proxy envoy-ssl-cert envoy-url-map
步骤 6: 创建转发规则 (获取公共 IP)
转发规则是负载均衡器的前端入口。我们创建了一条全局转发规则,它会分配一个公共 IP 地址,并将所有流向该 IP 的 443 端口的流量导向我们的 HTTPS 代理。
创建转发规则:
bash
gcloud compute forwarding-rules create envoy-forwarding-rule \
--target-https-proxy=envoy-https-proxy \
--ports=443 \
--global
输出:
Created [https://www.googleapis.com/compute/v1/projects/jason-hsbc/global/forwardingRules/envoy-forwarding-rule].
获取分配到的 IP 地址:
bash
gcloud compute forwarding-rules describe envoy-forwarding-rule --global --format="value(IPAddress)"
输出:
34.54.9.78
这个 IP 34.54.9.78 是我们负载均衡器的公共 IP 地址。
步骤 7: 更新 DNS 解析
这是唯一一个需要在 GCP 外部操作的步骤。我们需要登录域名注册商的控制台,将 www.jpgcp.cloud 的 A 记录指向负载均衡器的新 IP 地址 34.54.9.78。
- 记录类型:
A - 名称:
www - 值:
34.54.9.78
步骤 8: 验证
在等待 DNS 记录全球生效后,我们进行了最终验证。
首先,检查证书状态,确认其已变为 ACTIVE:
bash
gcloud compute ssl-certificates describe envoy-ssl-cert --global --format="value(managed.status)"
输出:
ACTIVE
然后,检查 DNS 解析是否已指向新 IP:
bash
dig www.jpgcp.cloud +short
输出:
34.54.9.78
最后,通过 curl 模拟客户端访问,测试端到端的 HTTPS 连接:
bash
curl -v https://www.jpgcp.cloud/myui
测试结果显示 SSL certificate verify ok. 并且返回了 HTTP/2 200 状态码和后端 myui 应用的 HTML 内容,表明整个流程配置成功。
结论
通过以上步骤,我们成功地为运行在 GCE 上的 Envoy 代理部署了一个高可用的、全自动管理的 HTTPS 服务。所有的 SSL/TLS 加解密和证书管理工作都由 Google Cloud Load Balancer 负责,大大降低了运维复杂度和潜在的风险。

附录: 常见问题 (FAQ)
Q: 我可以用 GCP 的 API Gateway 产品来代替这个复杂的负载均衡器吗?
这是一个非常关键的架构决策问题。
答案是:对于我们当前**"为一个运行在 GCE 上的 Web 服务启用 HTTPS"这个目标,您不能用 API Gateway 来代替负载均衡器。它们是为解决完全不同**的问题而设计的两种产品。
-
负载均衡器 (Load Balancer) 的核心目的是大规模、高可用地分发流量 。它是一个基础设施层的产品,专为处理海量的 Web 流量(网站、应用、微服务)而生。
-
API 网关 (API Gateway) 的核心目的是管理、保护和暴露 API 。它是一个应用层的产品,专为开发者或合作伙伴安全地调用您的后端 API(通常是 Cloud Functions 或 Cloud Run)而生。
下面的表格可以帮助您在未来的项目中做出选择:
| 决策因素 | 我应该选择... 全局外部 HTTPS 负载均衡器 | 我应该选择... API Gateway |
|---|---|---|
| 我的后端是... | GCE 虚拟机 (MIG), GKE 集群, Cloud Run 服务, 存储桶。这些是运行完整应用或服务的计算资源。 | Cloud Functions, Cloud Run, App Engine 或任何提供业务逻辑的 HTTP 端点。这些是轻量级的、事件驱动的后端。 |
| 我的主要需求是... | 为我的网站/Web 应用提供一个全球统一的入口 IP,并处理 SSL 证书、抵御 DDoS 攻击、缓存静态内容 (CDN)。 | 为我的 API 提供一个受管控的入口 ,并处理身份验证 (API Key, JWT) 、速率限制、监控和开发者门户。 |
| 如果把后端比作一家餐厅... | 我需要的是这家餐厅的**"迎宾、排队和引导系统"**,确保成千上万的食客都能被高效地引导到餐桌上。 | 我需要的是这家餐厅的**"会员制吧台"**,只有持会员卡的顾客(API Key)才能进入,并且每人限点三杯酒(速率限制)。 |
总结: 尽管负载均衡器的配置步骤看起来很多,但这正是其强大和灵活性的体现。对于需要处理通用 Web 流量、自动管理 SSL 证书并具备高可用性的场景,它就是 GCP 提供的标准且最佳的解决方案。
Q2: 文档中哪一句命令真正"创建"了负载均衡器?
这是一个核心特点:"负载均衡器"并非由单一命令创建,而是由多个组件共同组合而成的系统。
不过,如果必须找出一个"点火启动"的关键命令,那一定是 步骤 6 中创建转发规则 (Forwarding Rule) 的命令:
gcloud compute forwarding-rules create envoy-forwarding-rule ...
在此之前,我们创建的后端服务、网址映射、目标代理都只是后台的逻辑配置。创建转发规则这个动作,才首次为所有后台组件分配了一个公共 IP 地址,并将它们连接起来,最终让整个系统"上线"并开始接收外部流量。
Q3: 那么这个负载均衡器的"名字"是什么?
在 GCP 的资源模型中,全局外部 HTTPS 负载均衡器本身没有一个单一的、统一的"名称"。它是一个由多个组件构成的系统。
我们通常通过其前端入口 的名称来识别和管理它,这个入口就是转发规则 (Forwarding Rule) 。
但是实际上被创建出来的lb名字是
envoy-forwarding-rule
bash
gcloud compute forwarding-rules list
NAME REGION IP_ADDRESS IP_PROTOCOL TARGET
envoy-forwarding-rule 34.54.9.78 TCP envoy-https-proxy
gkegw1-bu0s-default-py-api-gateway-2ndb5mh4y7f6 34.111.35.228 TCP gkegw1-bu0s-default-py-api-gateway-6bdwvn1zx5um
gkegw1-bu0s-default-py-api-gateway-e6c3tpani22a 34.111.35.228 TCP gkegw1-bu0s-default-py-api-gateway-rrnx141i3brm
其实gcp并没有一个真正叫Load balancer的产品
而是由多组件共同构成的
例如我们可以查看 urlmap
bash
gateman@MoreFine-S500: langchain-chat$ gcloud compute url-maps list
NAME DEFAULT_SERVICE
envoy-url-map backendServices/envoy-backend-service
gkegw1-bu0s-default-py-api-gateway-6bdwvn1zx5um
gkegw1-bu0s-default-py-api-gateway-rrnx141i3brm
而在gcp网页(上面的图) 显示 的LB实际上是 urlmap的名字