Kubernetes ↗ 是一种容器编排工具,用于将应用程序部署到物理或虚拟机上,对部署进行缩放以满足流量需求,并在零停机的情况下推送更新。运行应用程序实例的 Kubernetes 集群(或环境)内部通过私有网络连接。您可以在 Kubernetes 集群内部安装 cloudflared 守护程序,以便将集群内部的应用程序连接到 Cloudflare。
本指南将介绍如何使用 远程管理 的 Cloudflare Tunnel 将 Kubernetes 服务公开到公共互联网。在本例中,我们将在 Google Kubernetes Engine (GKE) 中与 cloudflared 一起部署一个基础的 Web 应用程序。相同的原理适用于任何其他可以让 cloudflared 连接到 Cloudflare 网络的 Kubernetes 环境(例如 minikube、kubeadm 或基于云的 Kubernetes 服务)。

如图所示,我们建议将 cloudflared 设置为与应用程序部署相邻的 deployment ↗。为 cloudflared 准备一个单独的 Kubernetes 部署,可以让您独立于应用程序对 cloudflared 进行缩放。在 cloudflared 部署中,您可以启动运行相同 Cloudflare Tunnel 的 多个副本 — 无需为每个 cloudflared pod 创建专属的隧道。每个 cloudflared 副本/pod 都可以访问集群中的所有 Kubernetes 服务。
一旦集群连接到 Cloudflare,您就可以配置 Cloudflare Tunnel 路由,以控制 cloudflared 如何将流量代理到集群内的服务。例如,您可能希望将某些 Kubernetes 应用程序发布到互联网,并将其他应用程序限制为仅供内部 Cloudflare One Client 用户访问。
要完成以下步骤,您需要:
在 Google Cloud 中创建新的 Kubernetes 集群:
-
打开 Google Cloud ↗ 并转到 Kubernetes Engine(Kubernetes 引擎)。
-
在 Clusters(集群) 中,选择 Create(创建)。
-
为集群命名。在本例中,我们将其命名为
cloudflare-tunnel。 -
(可选)选择您需要的区域和其他集群规格。在本例中,我们将使用默认规格。
-
选择 Create(创建)。
-
连接到集群:
- 选择三点菜单。
- 选择 Connect(连接)。
- 选择 Run in Cloud Shell(在 Cloud Shell 中运行) 以在浏览器中打开终端。
- 选择 Authorize(授权)。
- 按
Enter键运行预先填写的gcloud命令。 - (推荐)在 Cloud Shell 菜单中,选择 Open Editor(打开编辑器) 以启动内置的 IDE。
-
在 Cloud Shell 终端中,运行以下命令以检查集群状态:
kubectl get allNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/kubernetes ClusterIP 34.118.224.1 <none> 443/TCP 15m
Pod 代表集群中运行进程的实例。在本例中,我们将部署包含两个 pod 的 httpbin ↗ 应用程序,并使这些 pod 在集群内部可通过 httpbin-service:80 访问。
-
为您的 Kubernetes 清单文件创建一个文件夹:
mkdir tunnel-example -
进入该目录:
cd tunnel-example -
在
tunnel-example目录中,创建一个名为httpbin.yaml的新文件。该文件定义了 httpbin 应用的 Kubernetes 部署。httpbin.yamlyaml apiVersion: apps/v1 kind: Deployment metadata: name: httpbin-deployment namespace: default spec: replicas: 2 selector: matchLabels: app: httpbin template: metadata: labels: app: httpbin spec: containers: - name: httpbin image: kennethreitz/httpbin:latest imagePullPolicy: IfNotPresent ports: - containerPort: 80 -
创建一个全新的
httpbinsvc.yaml文件。该文件定义了一个 Kubernetes 服务,允许集群中的其他应用(例如cloudflared)访问 httpbin pod 集。httpbinsvc.yamlyaml apiVersion: v1 kind: Service metadata: name: httpbin-service namespace: default spec: type: LoadBalancer selector: app: httpbin ports: - port: 80 targetPort: 80 -
使用以下命令在集群内运行该应用程序:
kubectl create -f httpbin.yaml -f httpbinsvc.yaml -
检查部署的状态:
kubectl get allNAME READY STATUS RESTARTS AGE pod/httpbin-deployment-bc6689c5d-b5ftk 1/1 Running 0 79s pod/httpbin-deployment-bc6689c5d-cbd9m 1/1 Running 0 79s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/httpbin-service LoadBalancer 34.118.225.147 34.75.201.60 80:31967/TCP 79s service/kubernetes ClusterIP 34.118.224.1 <none> 443/TCP 24h NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/httpbin-deployment 2/2 2 2 79s NAME DESIRED CURRENT READY AGE replicaset.apps/httpbin-deployment-bc6689c5d 2 2 2 79s
要创建 Cloudflare Tunnel:
在 Cloudflare 仪表板中,转到 Networking(网络) > Tunnels(隧道)。
选择 Create a tunnel(创建隧道)。
输入您的隧道名称(例如
gke-tunnel)。选择 Create Tunnel(创建隧道)。
选择您的操作系统并选择 Docker(Docker)。
在 Kubernetes 中运行应用程序之前,必须先将其打包为容器镜像。因此,我们将使用
cloudflaredDocker 容器镜像在 Kubernetes 中部署隧道。不要运行整个安装命令,只需复制其中的 Token 值,而不是整个命令。Token 值的格式为
eyJhIjoiNWFiNGU5Z...。您在编写 Kubernetes 清单文件时会需要此 Token。
在我们将精力集中在 Kubernetes 部署上时,请保持 Cloudflare Tunnel 浏览器标签页处于打开状态。
cloudflared 使用隧道令牌来运行远程管理的 Cloudflare Tunnel。您可以将隧道令牌存储在 Kubernetes secret ↗ 中。
-
在 GKE Cloud Shell 中,创建一个包含以下内容的
tunnel-token.yaml文件。请务必将<YOUR_TUNNEL_TOKEN>替换为您的隧道令牌 (eyJhIjoiNWFiNGU5Z...)。tunnel-token.yamlyaml apiVersion: v1 kind: Secret metadata: name: tunnel-token stringData: token: <YOUR_TUNNEL_TOKEN> -
创建该 secret:
kubectl create -f tunnel-token.yaml -
检查新建的 secret:
kubectl get secretsNAME TYPE DATA AGE tunnel-token Opaque 1 100s
在 Kubernetes 中运行 Cloudflare Tunnel:
-
为远程管理的 Cloudflare Tunnel 创建一个 Kubernetes 部署:
tunnel.yamlyaml apiVersion: apps/v1 kind: Deployment metadata: name: cloudflared-deployment namespace: default spec: replicas: 2 selector: matchLabels: pod: cloudflared template: metadata: labels: pod: cloudflared spec: securityContext: sysctls: # Allows ICMP traffic (ping, traceroute) to resources behind cloudflared. - name: net.ipv4.ping_group_range value: "65532 65532" containers: - image: cloudflare/cloudflared:latest name: cloudflared env: # Defines an environment variable for the tunnel token. - name: TUNNEL_TOKEN valueFrom: secretKeyRef: name: tunnel-token key: token command: # Configures tunnel run parameters - cloudflared - tunnel - --no-autoupdate - --loglevel - info - --metrics - 0.0.0.0:2000 - run livenessProbe: httpGet: # Cloudflared has a /ready endpoint which returns 200 if and only if # it has an active connection to Cloudflare's network. path: /ready port: 2000 failureThreshold: 1 initialDelaySeconds: 10 periodSeconds: 10 -
将
cloudflared部署到集群中:kubectl create -f tunnel.yamlKubernetes 将在两个 pod 上安装
cloudflared镜像,并使用cloudflared tunnel --no-autoupdate --loglevel info --metrics 0.0.0.0:2000 run命令运行隧道。cloudflared将使用来自TUNNEL_TOKEN环境变量的隧道令牌。 -
检查集群的状态:
kubectl get allNAME READY STATUS RESTARTS AGE pod/cloudflared-deployment-6d5f9f9666-85l5w 1/1 Running 0 21s pod/cloudflared-deployment-6d5f9f9666-wb96x 1/1 Running 0 21s pod/httpbin-deployment-bc6689c5d-b5ftk 1/1 Running 0 3m36s pod/httpbin-deployment-bc6689c5d-cbd9m 1/1 Running 0 3m36s NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/httpbin-service LoadBalancer 34.118.225.147 34.75.201.60 80:31967/TCP 3m36s service/kubernetes ClusterIP 34.118.224.1 <none> 443/TCP 24h NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/cloudflared-deployment 2/2 2 2 22s deployment.apps/httpbin-deployment 2/2 2 2 3m37s NAME DESIRED CURRENT READY AGE replicaset.apps/cloudflared-deployment-6d5f9f9666 2 2 2 22s replicaset.apps/httpbin-deployment-bc6689c5d 2 2 2 3m37s
您应该会看到两个处于 Running 状态的 cloudflared pod 和两个 httpbin pod。如果您的 cloudflared pod 持续重启,请检查 tunnel.yaml 中的 command 语法,并确保 隧道运行参数 顺序正确。
打印某个 cloudflared 实例的日志:
kubectl logs pod/cloudflared-deployment-6d5f9f9666-85l5w2025-06-11T22:00:47Z INF Starting tunnel tunnelID=64c359b6-e111-40ec-a3a9-199c2a656613
2025-06-11T22:00:47Z INF Version 2025.6.0 (Checksum 72f233bb55199093961bf099ad62d491db58819df34b071ab231f622deff33ce)
2025-06-11T22:00:47Z INF GOOS: linux, GOVersion: go1.24.2, GoArch: amd64
2025-06-11T22:00:47Z INF Settings: map[loglevel:debug metrics:0.0.0.0:2000 no-autoupdate:true token:*****]
2025-06-11T22:00:47Z INF Generated Connector ID: aff7c4a0-85a3-4ac9-8475-1e0aa1af8d94
2025-06-11T22:00:47Z DBG Fetched protocol: quic
2025-06-11T22:00:47Z INF Initial protocol quic
...现在隧道已启动并运行,我们可以通过隧道路由 httpbin 服务。
在 Cloudflare 仪表板中,转到 Networking(网络) > Tunnels(隧道)并选择您的隧道。
在 Routes(路由)标签页上,选择 Add route(添加路由) > Published application(已发布应用程序)。
输入该应用程序的主机名(例如
httpbin.<your-domain>.com)。在 Service(服务)下,输入
http://httpbin-service。httpbin-service是在httpbinsvc.yaml中定义的 Kubernetes 服务的名称。选择 Add route(添加路由)。
要进行测试,请打开一个新的浏览器标签页并转到 httpbin.<your-domain>.com。您应该会看到 httpbin 主页。
您还可以选择添加 Cloudflare Access 来控制谁可以访问该服务。