跳转到内容
搜索文档

Kubernetes

最后更新 查看 MarkdownAgent 设置

Kubernetes 是一种容器编排工具,用于将应用程序部署到物理或虚拟机上,对部署进行缩放以满足流量需求,并在零停机的情况下推送更新。运行应用程序实例的 Kubernetes 集群(或环境)内部通过私有网络连接。您可以在 Kubernetes 集群内部安装 cloudflared 守护程序,以便将集群内部的应用程序连接到 Cloudflare。

本指南将介绍如何使用 远程管理 的 Cloudflare Tunnel 将 Kubernetes 服务公开到公共互联网。在本例中,我们将在 Google Kubernetes Engine (GKE) 中与 cloudflared 一起部署一个基础的 Web 应用程序。相同的原理适用于任何其他可以让 cloudflared 连接到 Cloudflare 网络的 Kubernetes 环境(例如 minikubekubeadm 或基于云的 Kubernetes 服务)。

架构

显示用户如何通过 Cloudflare Tunnel 连接到 Kubernetes 服务的示意图

如图所示,我们建议将 cloudflared 设置为与应用程序部署相邻的 deployment。为 cloudflared 准备一个单独的 Kubernetes 部署,可以让您独立于应用程序对 cloudflared 进行缩放。在 cloudflared 部署中,您可以启动运行相同 Cloudflare Tunnel 的 多个副本 — 无需为每个 cloudflared pod 创建专属的 Tunnel。每个 cloudflared 副本/pod 都可以访问集群中的所有 Kubernetes 服务。

一旦集群连接到 Cloudflare,您就可以配置 Cloudflare Tunnel 路由,以控制 cloudflared 如何将流量代理到集群内的服务。例如,您可能希望将某些 Kubernetes 应用程序发布到互联网,并将其他应用程序限制为仅供内部 Cloudflare One Client 用户访问。

前提条件

要完成以下步骤,您需要:

1. 创建 GKE 集群

在 Google Cloud 中创建新的 Kubernetes 集群:

  1. 打开 Google Cloud 并转到 Kubernetes Engine(Kubernetes 引擎)

  2. 在 **Clusters(集群)**中,选择 Create(创建)

  3. 为集群命名。在本例中,我们将其命名为 cloudflare-tunnel

  4. (可选)选择您需要的区域和其他集群规格。在本例中,我们将使用默认规格。

  5. 选择 Create(创建)

  6. 连接到集群:

    1. 选择三点菜单。
    2. 选择 Connect(连接)
    3. 选择 **Run in Cloud Shell(在 Cloud Shell 中运行)**以在浏览器中打开终端。
    4. 选择 Authorize(授权)
    5. Enter 键运行预先填写的 gcloud 命令。
    6. (推荐)在 Cloud Shell 菜单中,选择 **Open Editor(打开编辑器)**以启动内置的 IDE。
  7. 在 Cloud Shell 终端中,运行以下命令以检查集群状态:

    kubectl get all
    NAME                 TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
    service/kubernetes   ClusterIP   34.118.224.1   <none>        443/TCP   15m

2. 为 Web 应用创建 pod

Pod 代表集群中运行进程的实例。在本例中,我们将部署包含两个 pod 的 httpbin 应用程序,并使这些 pod 在集群内部可通过 httpbin-service:80 访问。

  1. 为您的 Kubernetes 清单文件创建一个文件夹:

    mkdir tunnel-example
  2. 进入该目录:

    cd tunnel-example
  3. 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
  4. 创建一个全新的 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
  5. 使用以下命令在集群内运行该应用程序:

    kubectl create -f httpbin.yaml -f httpbinsvc.yaml
  6. 检查部署的状态:

    kubectl get all
    NAME                                     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

3. 创建 Tunnel

  1. Cloudflare 仪表板中,转到 Networking(网络) > Tunnels(隧道)。

  2. 选择 Create a tunnel(创建隧道)。

  3. 输入您的 Tunnel 名称(例如 gke-tunnel)。

  4. 选择 Create Tunnel(创建隧道)。

  5. 选择您的操作系统并选择 Docker(Docker)。

    在 Kubernetes 中运行应用程序之前,必须先将其打包为容器镜像。因此,我们将使用 cloudflared Docker 容器镜像在 Kubernetes 中部署 Tunnel。

  6. 不要运行整个安装命令,只需复制其中的 Token 值,而不是整个命令。Token 值的格式为 eyJhIjoiNWFiNGU5Z...。您在编写 Kubernetes 清单文件时会需要此 Token。

在我们将精力集中在 Kubernetes 部署上时,请保持 Cloudflare Tunnel 浏览器标签页处于打开状态。

4. 存储 Tunnel Token

cloudflared 使用 Tunnel Token 来运行远程管理的 Cloudflare Tunnel。您可以将 Tunnel Token 存储在 Kubernetes secret 中。

  1. 在 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>
  2. 创建该 secret:

    kubectl create -f tunnel-token.yaml
  3. 检查新建的 secret:

    kubectl get secrets
    NAME        TYPE     DATA   AGE
    tunnel-token   Opaque   1      100s

5. 为 cloudflared 创建 pod

在 Kubernetes 中运行 Cloudflare Tunnel:

  1. 为远程管理的 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
  2. cloudflared 部署到集群中:

    kubectl create -f tunnel.yaml

    Kubernetes 将在两个 pod 上安装 cloudflared 镜像,并使用 cloudflared tunnel --no-autoupdate --loglevel info --metrics 0.0.0.0:2000 run 命令运行 Tunnel。cloudflared 将使用来自 TUNNEL_TOKEN 环境变量的 Tunnel Token。

  3. 检查集群的状态:

    kubectl get all
    NAME                                          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 运行参数 顺序正确。

6. 验证 Tunnel 状态

打印某个 cloudflared 实例的日志:

kubectl logs pod/cloudflared-deployment-6d5f9f9666-85l5w
2025-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
...

7. 添加 Tunnel 路由

现在 Tunnel 已启动并运行,我们可以通过 Tunnel 路由 httpbin 服务。

  1. Cloudflare 仪表板中,转到 Networking(网络) > Tunnels(隧道)并选择您的 Tunnel。

  2. Routes(路由)标签页上,选择 Add route(添加路由) > Published application(已发布应用程序)。

  3. 输入该应用程序的主机名(例如 httpbin.<your-domain>.com)。

  4. Service(服务)下,输入 http://httpbin-servicehttpbin-service 是在 httpbinsvc.yaml 中定义的 Kubernetes 服务的名称。

  5. 选择 Add route(添加路由)。

8. 测试连接

要进行测试,请打开一个新的浏览器标签页并转到 httpbin.<your-domain>.com。您应该会看到 httpbin 主页。

您还可以选择 创建一个 Access 应用程序 来控制谁可以访问该服务。

这篇文档对您有帮助吗?