借助cloudflare 进行服务部署

630 阅读4分钟

启动服务

我们可以购买云服务器进行服务部署,也可以在本机部署

借助docker进行服务器部署。

好处:不需要复杂的环境配置,轻量部署、轻装上阵。

cloudflare

后续的域名购买、dns解析(域名映射)、cdn加速、s3存储、边缘函数计算、worker处理等等均借助cloudflare完成。

域名购买

image

dns解析(域名映射)

通过Zero Trust建立Tunnels,将域名与服务器进行链接

Cloudflare Tunnels的实现原理1 Tunnels: 本地下载一个cloudflare程序,它会启动一个websocket链接,会连接cloudflare的边缘服务器,而这个服务器上会存在实际的路由映射表,tunnelId和ip的对映,相同于进行了一层代理转发。

image​选择操作系统类型,安装并运行连接器

image

服务映射

通过不同主机名进行同一服务器下不同服务的映射

image

cdn加速

内容分发网络,dns解析时,自动匹配最近的空闲服务节点

s3存储

S3是一种对象存储服务,不同于传统的文件系统存储。

我们将图片、文件等一些静态资源存放在一些网络服务商的网络磁盘中,而不需要实际占用我们的实际服务器空间资源。

  • 创建一个存储桶(bucket)类似于磁盘的概念

image

可以定义bucket的对外域名

image

r2/s3是一套完整的文件系统,具备完整的文件系统能力

上传完成后,会生成访问链接

imageimage

此外,我们可以借助sdk、api调用的形式,接入我们的应用程序

image

todo: s3存储的静态资源的cdn加速配置

边缘函数计算

边缘函数的一种实现方式:worker

当我们有一些独立且轻量的函数或者api调用,同时我们对服务器要求不是很高时,可以将它们部署到worker上。

与传统的部署不同,我们不需要提供实际的服务器,而是将代码托管到了网络服务商的云服务器中,同时也支持我们指定子域名及路由进行不同边缘函数。

image

Footnotes

  1. Cloudflare Tunnels的实现原理

    Tunnels基本概念

    Cloudflare Tunnels(原名Argo Tunnel)是一种安全的连接方式,它创建了一个从你的服务器到Cloudflare边缘网络的加密隧道。

    实现原理架构

    Internet用户 → Cloudflare边缘 → 加密隧道 → 你的服务器(无需公网IP)
    

    1. 隧道建立过程

    // 简化的隧道建立流程
    const tunnelSetup = {
      step1: "cloudflared客户端启动",
      step2: "与Cloudflare API进行身份验证", 
      step3: "建立WebSocket/HTTP2连接到最近的Cloudflare数据中心",
      step4: "注册隧道路由信息",
      step5: "开始代理流量"
    }
    

    2. 核心组件

    cloudflared守护进程
    # 安装和运行示例
    cloudflared tunnel create my-tunnel
    cloudflared tunnel route dns my-tunnel app.example.com
    cloudflared tunnel run my-tunnel
    
    配置文件示例
    # config.yml
    tunnel: my-tunnel-id
    credentials-file: /path/to/credentials.json
    
    ingress:
      - hostname: app.example.com
        service: http://localhost:3000
      - hostname: api.example.com
        service: http://localhost:8080
      - service: http_status:404
    

    详细工作流程

    1. 出站连接建立

    // 模拟隧道连接过程
    class TunnelConnection {
      constructor(tunnelId, credentials) {
        this.tunnelId = tunnelId;
        this.credentials = credentials;
        this.connections = [];
      }
    
      async establishConnection() {
        // 1. 认证
        const authToken = await this.authenticate();
          
        // 2. 建立多个并发连接(通常4个)
        for(let i = 0; i < 4; i++) {
          const conn = await this.createConnection(authToken);
          this.connections.push(conn);
        }
          
        // 3. 保持连接活跃
        this.startHeartbeat();
      }
    
      createConnection(token) {
        return new WebSocket('wss://region.argotunnel.com', {
          headers: {
            'Authorization': `Bearer ${token}`,
            'Cf-Tunnel-Token': this.tunnelId
          }
        });
      }
    }
    

    2. 流量代理机制

    // 简化的流量处理逻辑
    class TrafficProxy {
      handleIncomingRequest(request) {
        // 1. Cloudflare边缘接收用户请求
        const userRequest = this.parseRequest(request);
          
        // 2. 通过隧道转发到本地服务
        const tunnelRequest = {
          method: userRequest.method,
          url: userRequest.url,
          headers: userRequest.headers,
          body: userRequest.body,
          metadata: {
            'CF-Connecting-IP': userRequest.clientIP,
            'CF-Ray': generateRayID()
          }
        };
          
        // 3. 发送到cloudflared客户端
        return this.forwardThroughTunnel(tunnelRequest);
      }
    
      forwardThroughTunnel(request) {
        // 选择可用的隧道连接
        const connection = this.selectAvailableConnection();
          
        // 通过WebSocket发送请求
        return connection.send(JSON.stringify(request));
      }
    }
    

    安全特性

    1. 加密传输

    // 所有隧道流量都经过TLS加密
    const securityFeatures = {
      encryption: "TLS 1.3",
      authentication: "Mutual TLS + API Token",
      integrity: "Message authentication codes",
      firewall: "无需入站端口开放"
    }
    

    2. 身份验证

    // 隧道认证流程
    const authFlow = {
      clientCertificate: "cloudflared客户端证书",
      apiToken: "Cloudflare API令牌", 
      tunnelCredentials: "隧道专用凭据文件",
      domainValidation: "域名所有权验证"
    }
    

    网络流量处理

    1. HTTP/HTTPS处理

    // HTTP请求转发示例
    app.get('/api/data', (req, res) => {
      // 本地服务正常处理请求
      // cloudflared会自动代理这些请求
    
      // 可以获取原始客户端IP
      const clientIP = req.headers['cf-connecting-ip'];
      const rayID = req.headers['cf-ray'];
    
      res.json({
        message: "通过Tunnel访问成功",
        clientIP: clientIP,
        rayID: rayID
      });
    });
    

    2. WebSocket支持

    // WebSocket通过隧道的处理
    const WebSocket = require('ws');
    
    const wss = new WebSocket.Server({ port: 8080 });
    
    wss.on('connection', (ws, req) => {
      // WebSocket连接也会通过隧道代理
      console.log('WebSocket连接建立,客户端IP:', req.headers['cf-connecting-ip']);
    
      ws.on('message', (message) => {
        // 处理WebSocket消息
        ws.send(`Echo: ${message}`);
      });
    });
    

    高可用性设计

    1. 多连接冗余

    const redundancyConfig = {
      connectionsPerTunnel: 4,  // 每个隧道4个连接
      failoverTime: "数秒内",   // 故障切换时间
      loadBalancing: "自动负载均衡",
      healthCheck: "连接健康检查"
    }
    

    2. 故障恢复

    class TunnelManager {
      constructor() {
        this.reconnectInterval = 5000;
        this.maxRetries = 10;
      }
    
      async handleConnectionLoss() {
        let retries = 0;
          
        while(retries < this.maxRetries) {
          try {
            await this.reestablishConnection();
            console.log('隧道重连成功');
            break;
          } catch(error) {
            retries++;
            console.log(`重连失败,${this.reconnectInterval}ms后重试`);
            await this.sleep(this.reconnectInterval);
          }
        }
      }
    }
    

    与传统VPN的区别

    特性Cloudflare Tunnels传统VPN
    安装复杂度简单(一个二进制文件)复杂(需要配置服务器)
    网络要求仅需出站连接需要入站端口开放
    安全性应用层安全网络层安全
    性能Cloudflare全球网络加速取决于VPN服务器位置
    可见性详细的流量分析有限的日志记录

    实际部署示例

    # docker-compose.yml
    version: '3.8'
    services:
      app:
        build: .
        ports:
          - "3000:3000"
          
      cloudflared:
        image: cloudflare/cloudflared:latest
        command: tunnel --config /etc/cloudflared/config.yml run
        volumes:
          - ./cloudflared:/etc/cloudflared
        depends_on:
          - app
    

    Cloudflare Tunnels通过建立安全的出站连接,实现了无需公网IP和开放入站端口的安全远程访问,这对于现代应用部署和安全架构设计具有重要意义。