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 创建专属的 Tunnel。每个 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 仪表板中,转到 Networking(网络) > Tunnels(隧道)。
选择 Create a tunnel(创建隧道)。
输入您的 Tunnel 名称(例如
gke-tunnel)。选择 Create Tunnel(创建隧道)。
选择您的操作系统并选择 Docker(Docker)。
在 Kubernetes 中运行应用程序之前,必须先将其打包为容器镜像。因此,我们将使用
cloudflaredDocker 容器镜像在 Kubernetes 中部署 Tunnel。不要运行整个安装命令,只需复制其中的 Token 值,而不是整个命令。Token 值的格式为
eyJhIjoiNWFiNGU5Z...。您在编写 Kubernetes 清单文件时会需要此 Token。
在我们将精力集中在 Kubernetes 部署上时,请保持 Cloudflare Tunnel 浏览器标签页处于打开状态。
cloudflared 使用 Tunnel Token 来运行远程管理的 Cloudflare Tunnel。您可以将 Tunnel Token 存储在 Kubernetes secret ↗ 中。
-
在 GKE Cloud Shell 中,创建一个包含以下内容的
tunnel-token.yaml文件。请务必将<YOUR_TUNNEL_TOKEN>替换为您的 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命令运行 Tunnel。cloudflared将使用来自TUNNEL_TOKEN环境变量的 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 语法,并确保 Tunnel 运行参数 顺序正确。
打印某个 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
...现在 Tunnel 已启动并运行,我们可以通过 Tunnel 路由 httpbin 服务。
在 Cloudflare 仪表板中,转到 Networking(网络) > Tunnels(隧道)并选择您的 Tunnel。
在 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 来控制谁可以访问该服务。