首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >边缘设备也搞蓝绿部署?真正难的不是“切流”,而是“切错了怎么活”

边缘设备也搞蓝绿部署?真正难的不是“切流”,而是“切错了怎么活”

原创
作者头像
Echo_Wish
发布2026-08-26 08:17:51
发布2026-08-26 08:17:51
180
举报

边缘设备也搞蓝绿部署?真正难的不是“切流”,而是“切错了怎么活”

我是 Echo_Wish。

提到蓝绿部署,很多人的第一反应是:

“不就是准备两套环境,然后一键切换吗?”

在 Kubernetes、云服务器上,这事确实已经相当成熟。

但如果把场景换成边缘设备——工厂里的工业网关、摄像头、AGV、边缘服务器、门店终端、IoT 网关……

事情一下就没那么简单了。

因为云端部署失败,大不了回滚。

边缘设备部署失败,可能连回滚命令都发不进去。

这就是我今天特别想聊的一个问题:

在边缘设备上实现蓝绿部署,真正难的不是“怎么切换”,而是“切换失败以后,设备还能不能自己活下来”。


一、先别急着搞蓝绿,先搞清楚边缘环境有多“野”

传统服务器的部署流程可能是:

代码语言:text
复制
Git
 ↓
CI/CD
 ↓
构建镜像
 ↓
部署服务器
 ↓
健康检查
 ↓
流量切换

而边缘设备往往是:

代码语言:text
复制
云端
  ↓
互联网 / 5G / 专线
  ↓
边缘网关
  ↓
工控机
  ↓
设备

中间随便一个环节都有可能出问题。

比如:

  • 网络突然断了
  • 设备突然重启
  • 磁盘空间不足
  • 新版本启动失败
  • CPU 被打满
  • 内存泄漏
  • MQTT 连接不上
  • Docker 拉镜像失败
  • 设备正在执行关键任务
  • 云端下发升级命令,但是设备没收到
  • 收到了升级命令,但升级过程中断电

所以边缘部署和云端部署有一个非常大的区别:

云端部署默认“控制面在线”,边缘部署必须默认“控制面随时可能失联”。

这也是蓝绿部署设计的第一原则。

不要把边缘设备当成一台永远在线的服务器。


二、所谓蓝绿部署,其实就是给自己留一条退路

我们假设设备当前运行的是:

代码语言:text
复制
Application V1

这就是蓝环境。

现在准备升级:

代码语言:text
复制
Application V2

我们不要直接:

代码语言:text
复制
停止 V1
 ↓
启动 V2

而是:

代码语言:text
复制
        ┌── Blue:V1
设备 ───┤
        └── Green:V2

V1继续提供服务。

V2在旁边启动。

然后进行健康检查。

只有 V2:

代码语言:text
复制
启动成功
+
业务正常
+
依赖正常
+
运行稳定

之后,才把流量切过去。

最终:

代码语言:text
复制
        ┌── Blue:V1
设备 ───┤
        └── Green:V2 ← 当前流量

如果 V2出问题:

代码语言:text
复制
Green挂了
   ↓
流量切回Blue
   ↓
V1继续工作

这就是蓝绿部署最核心的价值:

不是让升级更快,而是让升级失败时损失更小。


三、边缘设备蓝绿部署,我更推荐“目录 + 软链接”

如果你的边缘设备并没有 Kubernetes,也没有复杂的容器编排平台,其实完全没必要为了蓝绿部署硬上 K8s。

一个非常朴素的方法:

代码语言:text
复制
/opt/myapp/
├── releases/
│   ├── v1.0.0/
│   ├── v1.1.0/
│   └── v1.2.0/
│
├── blue -> releases/v1.1.0
├── green -> releases/v1.2.0
└── current -> blue

比如当前:

代码语言:text
复制
current -> blue
blue -> v1.1.0
green -> v1.2.0

服务启动时永远从:

代码语言:text
复制
/opt/myapp/current

读取程序。

这样升级的时候:

代码语言:bash
复制
ln -sfn releases/v1.2.0 green

启动 Green。

测试完成以后:

代码语言:bash
复制
ln -sfn green current

切换完成。

如果出现问题:

代码语言:bash
复制
ln -sfn blue current

马上回滚。

这个方案看起来甚至有点“土”。

但我反而觉得:

边缘环境里,越简单的方案,越容易活得久。


四、真正关键的地方:不要“启动成功”就认为部署成功

这是很多系统最容易踩的坑。

比如:

代码语言:bash
复制
./myapp

进程起来了。

然后:

代码语言:text
复制
部署成功!

这其实非常危险。

因为:

进程活着 ≠ 服务正常。

比如:

代码语言:text
复制
进程:正常
HTTP:正常
数据库:连接失败
MQTT:连接失败
摄像头:无法访问
模型:加载失败

这个时候如果你直接切流:

代码语言:text
复制
V1
 ↓
V2

那就是主动把生产环境送进坑里。

所以我建议至少设计三层健康检查。


第一层:进程检查

代码语言:bash
复制
pgrep -f myapp

确认进程还活着。


第二层:接口检查

代码语言:bash
复制
curl -f http://127.0.0.1:8080/health

例如返回:

代码语言:json
复制
{
    "status": "UP"
}

第三层:业务检查

这个才是最重要的。

比如工业边缘设备:

代码语言:http
复制
GET /health/business

返回:

代码语言:json
复制
{
    "status": "UP",
    "database": "UP",
    "mqtt": "UP",
    "device": "UP",
    "model": "UP"
}

只有全部正常,才允许切换。

代码可以简单写成:

代码语言:bash
复制
check_health() {
    for i in {1..30}
    do
        if curl -fs http://127.0.0.1:8081/health/business
        then
            echo "Green health check success"
            return 0
        fi

        sleep 2
    done

    echo "Green health check failed"
    return 1
}

这个思路非常重要:

部署系统负责“启动”,业务系统负责告诉部署系统“我到底能不能干活”。


五、别忘了:边缘设备最怕“半升级”

假设设备正在升级:

代码语言:text
复制
下载 V2
 ↓
解压
 ↓
停止 V1
 ↓
启动 V2

突然:

代码语言:text
复制
断电!

设备重新启动。

结果可能变成:

代码语言:text
复制
V1没了
V2也没装完整

这时候就比较刺激了。

所以升级包千万不要直接覆盖当前版本。

错误方式:

代码语言:bash
复制
rm -rf /opt/myapp/*
tar -xzf app-v2.tar.gz -C /opt/myapp

正确方式应该是:

代码语言:text
复制
下载
 ↓
临时目录
 ↓
校验
 ↓
完整解压
 ↓
健康检查
 ↓
切换

比如:

代码语言:bash
复制
mkdir -p /opt/myapp/releases/v1.2.0.tmp

tar -xzf app-v1.2.0.tar.gz \
    -C /opt/myapp/releases/v1.2.0.tmp

然后校验:

代码语言:bash
复制
sha256sum -c checksum.sha256

确认没问题以后再:

代码语言:bash
复制
mv /opt/myapp/releases/v1.2.0.tmp \
   /opt/myapp/releases/v1.2.0

永远不要直接碰正在运行的版本。


六、边缘蓝绿部署还有一个坑:配置文件

程序可以蓝绿。

但配置怎么办?

比如:

代码语言:text
复制
V1
数据库地址:DB_A

V2
数据库地址:DB_B

你切版本的时候,程序切过去了,但是配置没跟着切,就可能直接翻车。

所以我比较推荐:

代码语言:text
复制
/opt/myapp/
├── releases/
├── config/
│   ├── common.yaml
│   ├── blue.yaml
│   └── green.yaml

程序启动:

代码语言:bash
复制
./myapp \
  --config=/opt/myapp/config/green.yaml

配置和程序版本最好做到可追踪、可回滚

更进一步,可以让每个 Release 自己带配置:

代码语言:text
复制
v1.1.0/
├── app
├── config.yaml
└── manifest.json

v1.2.0/
├── app
├── config.yaml
└── manifest.json

这样:

代码语言:text
复制
程序版本
+
配置版本
+
依赖版本

可以一起回滚。


七、我特别建议加一个“自动回滚”

这是整个边缘蓝绿部署里,我认为最值钱的功能。

比如:

代码语言:text
复制
Green启动
 ↓
健康检查
 ↓
通过
 ↓
切流
 ↓
观察5分钟
 ↓
发现异常
 ↓
自动回滚Blue

可以简单定义:

代码语言:bash
复制
deploy_green

if ! check_health; then
    rollback
    exit 1
fi

switch_to_green

sleep 300

if ! check_business_metrics; then
    rollback
fi

这里有个细节非常重要:

健康检查通过以后,也不能立刻认为部署成功。

为什么?

因为很多问题只有运行一段时间才暴露。

例如:

代码语言:text
复制
内存持续上涨
连接池泄漏
消息堆积
线程数不断增长
磁盘日志暴涨

所以最好设计:

代码语言:text
复制
启动检查
+
切流检查
+
观察窗口

三个阶段。


八、别把“蓝绿”理解成必须同时跑两套完整业务

这是很多人容易误解的地方。

边缘设备资源往往很有限。

比如:

代码语言:text
复制
CPU:4核
RAM:4GB
磁盘:64GB

你让 V1 和 V2 同时完整跑起来:

代码语言:text
复制
V1:2GB
V2:2GB
系统:1GB

直接把自己逼到 OOM。

所以实际工程中可以做成:

代码语言:text
复制
Blue:完整生产实例
Green:候选实例

Green启动时可以:

  • 不接收生产流量
  • 不启动部分高耗能模块
  • 只进行核心业务验证
  • 使用 Shadow Traffic
  • 做关键接口测试

确认没问题之后,再正式切流。

也就是说:

蓝绿部署的核心是“隔离版本”,而不是“必须浪费两倍资源”。


九、如果用 Docker,其实会更舒服

如果边缘设备资源允许,Docker 会让这套方案更加清晰。

例如:

代码语言:text
复制
myapp:1.1.0
myapp:1.2.0

启动 Blue:

代码语言:bash
复制
docker run -d \
  --name myapp-blue \
  -p 8081:8080 \
  myapp:1.1.0

启动 Green:

代码语言:bash
复制
docker run -d \
  --name myapp-green \
  -p 8082:8080 \
  myapp:1.2.0

然后通过 Nginx 控制流量。

Blue:

代码语言:nginx
复制
upstream backend {
    server 127.0.0.1:8081;
}

切到 Green:

代码语言:nginx
复制
upstream backend {
    server 127.0.0.1:8082;
}

然后:

代码语言:bash
复制
nginx -s reload

这样就形成:

代码语言:text
复制
                 ┌── Blue :8081
Client → Nginx ──┤
                 └── Green :8082

回滚也非常简单。


十、但是边缘设备最关键的问题,其实不是技术,而是“失联”

假设:

代码语言:text
复制
云端
 ↓
升级指令
 ↓
边缘设备

升级到一半:

代码语言:text
复制
网络断开

怎么办?

我的答案是:

升级流程必须设计成“无需云端继续参与,也能完成或者回滚”。

也就是说,云端只负责:

代码语言:text
复制
告诉设备:
“你可以升级到 V2”

设备自己负责:

代码语言:text
复制
下载
 ↓
校验
 ↓
安装
 ↓
启动
 ↓
健康检查
 ↓
切换
 ↓
回滚

而不是:

代码语言:text
复制
云端:
下一步

设备:
收到

云端:
继续

设备:
收到

这种方式一旦断网,整套流程就卡死了。


十一、我比较推荐的边缘蓝绿部署架构

最终可以设计成这样:

代码语言:text
复制
                  云端控制平台
                       │
                发布升级任务
                       │
                       ▼
              ┌────────────────┐
              │ Edge Agent     │
              │ 升级代理        │
              └───────┬────────┘
                      │
             ┌────────┴────────┐
             ▼                 ▼
        Blue V1.1          Green V1.2
             │                 │
             │                 │
             └──────┬──────────┘
                    ▼
               Health Check
                    │
              ┌─────┴─────┐
              ▼           ▼
            Success      Failed
              │           │
              ▼           ▼
          Switch Green   Rollback
              │
              ▼
          Observe 5min
              │
         ┌────┴────┐
         ▼         ▼
       Stable    Abnormal
         │         │
         ▼         ▼
      Complete   Rollback

这里面其实有四个核心组件:

1. Edge Agent

负责升级、启动、停止、回滚。

2. Version Manager

负责管理:

代码语言:text
复制
当前版本
目标版本
上一个稳定版本

3. Health Checker

负责判断:

代码语言:text
复制
程序是不是活着
业务是不是正常

4. Watchdog

负责发现:

代码语言:text
复制
升级后异常

然后自动回滚。


十二、最后聊聊我对边缘蓝绿部署的一个看法

我一直觉得,很多工程师做部署系统的时候,特别喜欢追求“高级”。

什么:

代码语言:text
复制
Kubernetes
Service Mesh
Istio
GitOps
Multi Cluster
Progressive Delivery

这些东西当然好。

但是到了边缘场景,我反而建议大家先问自己三个问题:

设备断网怎么办?

设备断电怎么办?

新版本启动失败怎么办?

如果这三个问题还没有答案,那么你上再多平台,其实都只是把复杂度包装得更漂亮。

真正靠谱的边缘部署,我认为应该满足一个非常朴素的原则:

代码语言:text
复制
升级成功 → 新版本运行

升级失败 → 老版本继续运行

升级中断 → 重启后还能恢复

云端失联 → 设备还能自己完成流程

设备断电 → 不至于变砖

这才是边缘部署真正的“工程味”。


写在最后

蓝绿部署看起来是一个发布技术,实际上它解决的是一个更底层的问题:

我们有没有能力,让一次错误的发布,不至于变成一次事故?

云服务器可以靠人工救。

边缘设备往往不行。

尤其是那些部署在工厂、仓库、道路、矿区、门店甚至偏远地区的设备,你很难要求运维人员发现问题以后,立刻跑过去插根网线。

所以我越来越觉得:

边缘计算时代,部署系统的第一目标不是“发布得多快”,而是“出问题以后还能不能自己恢复”。

蓝绿部署只是手段。

真正值得追求的,其实是:

让设备拥有“犯错以后自己活下来”的能力。

这才是边缘运维真正该有的底气。

—— Echo_Wish

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 边缘设备也搞蓝绿部署?真正难的不是“切流”,而是“切错了怎么活”
    • 一、先别急着搞蓝绿,先搞清楚边缘环境有多“野”
  • 二、所谓蓝绿部署,其实就是给自己留一条退路
  • 三、边缘设备蓝绿部署,我更推荐“目录 + 软链接”
  • 四、真正关键的地方:不要“启动成功”就认为部署成功
    • 第一层:进程检查
    • 第二层:接口检查
    • 第三层:业务检查
  • 五、别忘了:边缘设备最怕“半升级”
  • 六、边缘蓝绿部署还有一个坑:配置文件
  • 七、我特别建议加一个“自动回滚”
  • 八、别把“蓝绿”理解成必须同时跑两套完整业务
  • 九、如果用 Docker,其实会更舒服
  • 十、但是边缘设备最关键的问题,其实不是技术,而是“失联”
  • 十一、我比较推荐的边缘蓝绿部署架构
  • 十二、最后聊聊我对边缘蓝绿部署的一个看法
    • 写在最后
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档