Mender中心发布与多地区服务器升级完整实践
前言
本文记录如何使用 Mender 建立一套“总部统一发布版本,各地区服务器主动获取并升级”的系统。
目标场景如下:
- 总部维护一个 Mender Server;
- 前端、后端等业务服务通过 Docker Compose 运行;
- 每个地区有一台或多台 Linux 服务器;
- 地区服务器只需要主动访问总部的 HTTPS 地址,不开放升级端口;
- 总部可以按地区分组、灰度发布、查看结果并停止异常批次;
- 发布制品必须经过签名,地区服务器拒绝未签名或被篡改的制品;
- 应用升级失败时能够回退容器版本;
- 涉及数据库变更时,由业务脚本完成备份、迁移和恢复。
本文重点介绍 Docker Compose 应用升级。Mender 的 A/B 根文件系统适合操作系统整体升级,但需要磁盘分区、bootloader 和系统镜像适配,不能通过安装一个客户端直接获得,文末会单独说明。
本文版本和环境
Mender 的软件仓库、Chart 和命令会继续变化。本文固定以下示例环境,实际部署前应再次检查官方 Supported releases 页面。
| 项目 | 示例值 | 部署位置 |
|---|---|---|
| Mender Server | v4.1.0 评估环境 | 总部测试服务器 |
| Mender Helm Chart | 安装时选择稳定版本并固定版本号 | 总部 Kubernetes |
| Mender Client | 6.x,使用 mender-client4 元包安装 | 每台地区服务器 |
| Docker Compose Update Module | 1.0.0 | 每台地区服务器 |
| 地区服务器系统 | Ubuntu Server 24.04 amd64 | 各地区 |
| 容器运行环境 | Docker Engine + Compose v2 | 各地区 |
| 构建环境 | Ubuntu 24.04 amd64 | 总部 CI/CD Runner |
| 对外域名 | mender.example.com | 指向总部入口 |
| 设备类型 | region-server-amd64 | Artifact 与客户端保持一致 |
文中的域名、账号、Bucket、密钥、镜像地址和地区编号都是示例,不能原样用于生产。
Mender各组件分别做什么
先明确 Mender 中几个容易混淆的概念。
| 组件或概念 | 作用 |
|---|---|
| Mender Server | 保存设备、Release、Deployment 和执行状态,向设备提供更新指令 |
| Mender Client | 周期性连接 Server,下载、验签、安装制品并上报结果 |
| Mender Artifact | 后缀为 .mender 的发布制品,包含负载、兼容信息、版本和可选脚本 |
| Release | Mender Server 中可供发布的软件版本,可以包含适配不同设备类型的 Artifact |
| Deployment | 一次具体发布任务,定义把哪个 Release 发给哪些设备 |
| Device Type | 设备兼容类型,Artifact 只会安装到匹配的设备上 |
| Inventory | 设备上报的地区、环境、架构和当前版本等属性 |
| Device Group | 设备集合,作为 Deployment 的发布目标 |
| Update Module | Mender Client 的扩展,负责解释和安装某一种 Artifact 负载 |
| State Script | 在下载、安装、提交、回滚等生命周期执行的自定义脚本 |
| Mender Gateway | 企业版地区代理和 Artifact 缓存,不是独立发布中心 |
mender-artifact | 创建、读取、签名和验证 .mender 文件的命令行工具 |
mender-cli | 上传 Artifact、调用服务端能力的命令行工具 |
在本文场景中,每台地区服务器都作为一台 Mender Device。总部创建 Deployment 后,地区服务器在下一次轮询时收到任务。
推荐架构
flowchart TB
subgraph HQ[总部]
GIT[业务代码仓库] --> CI[CI/CD Runner]
CI --> BUILD[构建容器镜像和 Compose]
BUILD --> ART[生成并签名 .mender]
ART --> MS[Mender Server]
MS --> DB[(MongoDB)]
MS --> OBJ[(S3 对象存储)]
MS --> CACHE[(Redis)]
MS --> MQ[(NATS)]
end
MS -->|HTTPS 443| E1[华东地区服务器\nMender Client + Compose Module]
MS -->|HTTPS 443| E2[华南地区服务器\nMender Client + Compose Module]
MS -->|HTTPS 443| E3[西北地区服务器\nMender Client + Compose Module]
E1 --> D1[Docker Compose 业务服务]
E2 --> D2[Docker Compose 业务服务]
E3 --> D3[Docker Compose 业务服务]
Mender Client 主动发起所有通信,因此地区服务器只需要出站访问总部 443/TCP。总部不需要 SSH 到地区服务器,地区防火墙也不需要为 Mender Client 开放入站端口。
这里的“同步升级”是同一 Deployment 内的批量升级,不代表所有服务器在同一秒开始。设备何时拿到任务取决于自己的轮询周期。生产环境也不建议同时升级全部地区,而应该先试点再逐步扩大。
部署位置规划
| 位置 | 必须部署 | 可选部署 |
|---|---|---|
| 总部 Kubernetes | Mender Server、Ingress | Prometheus、日志平台 |
| 总部基础设施 | MongoDB、Redis、NATS、对象存储 | KMS、Vault、企业 SSO |
| 总部 CI/CD Runner | Docker、Skopeo、mender-artifact、mender-cli、Artifact 生成器 | HSM 或云 KMS 客户端 |
| 每台地区服务器 | Docker、Compose、Mender Client、Compose Update Module、验签公钥 | 数据库备份工具、业务预检脚本 |
| 每个地区出口节点 | 无 | Mender Gateway,适合设备多或出口受限的地区 |
如果使用 Hosted Mender,总部 Kubernetes、MongoDB、Redis、NATS 和对象存储都由 Mender 官方维护。企业只需要部署 CI/CD 工具、地区客户端和业务升级脚本。
从哪里下载
所有组件都应从官方地址获取。
| 内容 | 官方地址 |
|---|---|
| Hosted Mender 注册 | mender.io/signup |
| Mender 文档 | docs.mender.io |
| Mender Server 源码和评估 Compose | mendersoftware/mender-server |
| Mender Helm Chart | mendersoftware/mender-helm |
| 设备端 APT 仓库 | Device components |
| 工作站 APT 仓库 | Workstation tools |
| Compose Update Module | mender-container-modules |
| CI/CD 工具镜像 | mendersoftware/mender-ci-tools |
| Helm Chart 仓库 | https://charts.mender.io |
生产环境不要使用 experimental APT 源、main 镜像标签或不固定版本的安装脚本输出。应先在测试环境验证,再固定具体软件和 Chart 版本。
第一阶段:搭建Mender Server评估环境
第一次接触 Mender 时,建议先用 Docker Compose 搭建一次评估环境,熟悉设备接入、上传 Artifact 和创建 Deployment。这个环境配置简单,但证书、依赖和资源配置都不符合生产要求。
准备总部测试服务器
官方评估环境最低要求为:
x86_64或arm64;- 16 GiB 内存;
- 2 个 vCPU;
- 50 GiB 可用磁盘;
- Docker Engine;
- Docker Compose 2.23.1 或更新版本。
确认环境:
1 | docker version |
这一步的作用是确认容器运行环境和磁盘满足 Mender 多个微服务同时启动的要求。
配置评估域名
在测试服务器的 /etc/hosts 中增加:
1 | 127.0.0.1 docker.mender.io |
官方评估环境内置证书使用这两个域名。该配置只是让本机能够把域名解析到评估环境,不能作为生产 DNS 方案。
下载并启动评估服务器
1 | git clone -b v4.1.0 \ |
每条命令的作用如下:
git clone -b v4.1.0:下载固定版本的官方 Compose 和配置;MENDER_IMAGE_TAG:指定各个 Mender 服务使用的镜像版本;docker compose up -d:后台启动 API Gateway、UI、设备认证、部署、库存和存储等服务。
检查容器:
1 | docker compose ps |
只有所有关键容器都正常运行后,才继续创建管理员。
创建管理员
1 | export MENDER_USERNAME='admin@docker.mender.io' |
useradm 是 Mender 的用户管理服务。这条命令直接在服务端创建第一个管理用户。
浏览器访问:
1 | https://localhost |
评估环境使用自签名证书,浏览器会提示不受信任。这个警告只能在隔离测试环境临时接受,生产环境必须配置有效证书。
停止和清理评估环境
只停止容器并保留数据:
1 | docker compose stop |
删除容器、Volume 和全部测试数据:
1 | docker compose down -v --remove-orphans |
第二条命令会删除设备、用户、Artifact、Deployment 和日志,不能在需要保留数据的环境执行。
第二阶段:生产部署Mender Server
生产环境官方推荐使用 Kubernetes + Helm。经过官方验证和支持的 Kubernetes 环境主要是 EKS、AKS 和 GKE;本地 k3s 可以用于 PoC,但不能因为 Helm 安装成功就视为完整生产集群。
生产依赖
Mender Server 生产环境至少需要:
| 依赖 | 作用 | 生产建议 |
|---|---|---|
| Kubernetes | 运行 Mender 微服务 | 多节点、独立维护、定期升级 |
| MongoDB | 保存用户、设备、认证、库存和发布元数据 | 使用副本集并建立备份 |
| Redis | 临时数据和缓存 | 使用高可用实例 |
| NATS | Mender 服务间消息通信 | 高可用场景启用 JetStream 副本 |
| S3 兼容对象存储 | 保存 .mender Artifact | 开启版本化、备份和生命周期策略 |
| Ingress 或 Load Balancer | 对外提供 HTTPS API 和 UI | 只开放 HTTPS,HTTP 跳转 HTTPS |
| DNS 和 TLS | 让客户端验证总部服务器身份 | 使用企业 CA 或公开可信 CA |
官方 Chart 内可以带 MongoDB、Redis 和 NATS 子 Chart,但这些更适合测试或 PoC。生产环境应使用独立维护的服务。
Mender Server 本身的参考资源为:
| 设备规模 | Mender 服务资源,不含数据库和对象存储 |
|---|---|
| 100 台以内 | 8 GiB RAM、4 vCPU |
| 1 万台以内 | 16 GiB RAM、8 vCPU |
| 10 万台以内 | 24 GiB RAM、16 vCPU |
准备Kubernetes和Helm
如果只是验证 Helm 流程,可以在 Ubuntu 测试机安装 k3s:
1 | curl -sfL https://get.k3s.io -o install-k3s.sh |
先下载并审查脚本,再以 root 执行。kubectl get nodes 出现 Ready 表示控制面可用。
安装 Helm:
1 | curl -fsSL \ |
生产环境应使用企业已经维护的 Kubernetes 集群,不应照搬单节点 k3s。
准备域名和TLS
将以下域名解析到 Kubernetes Ingress 或 Load Balancer:
1 | mender.example.com |
Ingress 必须满足:
- HTTP 自动跳转 HTTPS;
- 对
mender.example.com提供有效 TLS 证书; - 大文件上传超时足够长;
- 如果负载均衡器要求健康检查,使用
/ui; - Artifact 上传大小不能被 Ingress 默认限制拦截。
可以使用 cert-manager 自动申请证书:
1 | helm repo add jetstack https://charts.jetstack.io |
这一步的作用是让 Kubernetes 自动申请、保存和续期 X.509 证书。实际使用 Let’s Encrypt 还是企业 CA,应由网络和安全策略决定。
准备对象存储
生产环境建议使用 AWS S3、Cloudflare R2、Google Cloud Storage 的 S3 兼容接口或 Azure Blob Storage。对象存储负责保存真正体积较大的 .mender 文件,MongoDB 只保存元数据。
准备以下信息:
1 | export STORAGE_BUCKET='mender-artifacts-prod' |
生产中不要把密钥写进 Shell 历史或提交到 Git,应放在 Kubernetes Secret、Vault 或云 Secret Manager 中。示例使用环境变量只是为了说明 Chart 需要哪些值。
准备Mender Helm配置
先添加 Mender Chart 仓库并查看可用版本:
1 | helm repo add mender https://charts.mender.io |
创建 mender-values.yml:
1 | ingress: |
这份配置完成三件事:
- 通过 Ingress 暴露 Mender UI 和 API;
- 告诉 Mender 自己的外部访问地址;
- 指定 Artifact 保存到哪个对象存储。
不同云厂商、Ingress Controller 和对象存储的配置不完全相同。上面的文件是结构示例,生产部署应按实际服务修改,并将凭据改为 Secret 引用。
使用外部MongoDB
创建保存连接串的 Secret:
1 | kubectl create namespace mender |
在 mender-values.yml 中增加以下内容;如果文件已经存在 global,必须把 mongodb 合并到原有 global 下,不能再创建一个同级重复键:
1 | global: |
existingSecret 让 Mender 服务读取外部 MongoDB 连接;mongodb.enabled: false 禁用 Chart 内置的评估数据库。
Redis、NATS 和对象存储也应采用同样原则:连接企业维护的外部服务,并关闭对应的测试子 Chart。具体字段随 Chart 版本变化,应以安装版本的 values.yaml 为准:
1 | helm show values mender/mender > mender-default-values.yml |
安装Mender Server
前面已经添加过 Mender Chart 仓库。先确认列表,从中选择经过测试的版本,然后固定 Chart:
1 | export MENDER_CHART_VERSION='Replace-With-Verified-Chart-Version' |
不要在生产中省略 --version。固定 Chart 可以避免某次重新部署时自动拿到不兼容的新版本。
检查部署:
1 | kubectl -n mender get pods |
所有核心 Pod 应为 Running 或完成预期 Job,Ingress 应显示正确域名和地址。
创建第一个管理员
1 | USERADM_POD=$(kubectl -n mender get pod \ |
浏览器访问:
1 | https://mender.example.com |
如果页面打不开,依次检查 DNS、Ingress 地址、TLS Secret、Ingress 日志和 Mender Pod 状态。
生产备份
Mender Server 至少需要分别备份:
- MongoDB:设备身份、用户、库存、Deployment 和发布元数据;
- 对象存储:全部
.menderArtifact; - Kubernetes Secret:服务连接串、证书和部署配置;
- Helm values:去除明文密钥后纳入配置版本管理。
只备份 MongoDB 不能恢复 Artifact 文件,只备份对象存储也不能恢复设备和发布记录。恢复演练必须验证 UI 登录、设备认证、Artifact 下载和历史 Deployment 查询。
第三阶段:安装地区服务器Mender Client
下面的操作在每一台地区服务器执行。
检查网络和时间
1 | getent hosts mender.example.com |
这一步验证三个前提:
- DNS 能解析总部域名;
- 出站 HTTPS 可用;
- 系统时间正确,TLS 和 Artifact 有效期判断不会出错。
地区服务器无需开放 Mender 入站端口。
安装Docker和Compose
按照 Docker 官方 Ubuntu 安装文档安装 Docker Engine 和 Compose 插件,然后验证:
1 | docker version |
Compose Update Module 会调用本机 Docker,因此 Docker 必须由 systemd 正常管理。
安装Mender Client
下面两种方式二选一。最快的方式是官方便利脚本,适合 PoC;先下载、审查,再执行:
1 | curl -fLsS https://get.mender.io -o get-mender.sh |
只传入 mender-client4,可以避免便利脚本额外安装 Remote Terminal 和 Configure 插件。
生产环境更推荐显式配置官方 device-components APT 仓库并固定软件版本。Ubuntu 24.04 可以执行:
1 | sudo apt-get update |
从 apt-cache 输出中选定经过测试的版本。首次验证时可以安装仓库当前稳定版:
1 | sudo apt-get install --assume-yes mender-client4 |
完成兼容性验证后,应在自动化安装清单中记录实际包版本,并通过 APT preference 或版本参数锁定,避免地区服务器在不同日期安装到不同客户端版本。
官方仓库签名密钥指纹应核对为:
1 | E6C8 5734 5575 F921 8396 5662 2407 2B80 A1B2 9B00 |
安装后检查:
1 | mender-update --version |
mender-authd 负责设备认证和令牌,mender-updated 负责轮询、下载和安装更新。
配置连接总部
定义设备类型和服务器地址:
1 | export DEVICE_TYPE='region-server-amd64' |
device-type 必须和后面生成 Artifact 时的兼容类型完全一致。不同 CPU 架构或部署形态应使用不同类型,例如:
1 | region-server-amd64 |
生产环境不要使用 --demo-polling,它会产生比默认值更频繁的请求。
如果使用 Hosted Mender,不传 --server-url,而是从 Organization 设置中取得 Tenant Token:
1 | export DEVICE_TYPE='region-server-amd64' |
Tenant Token 能让新设备向组织申请接入,必须作为 Secret 管理,不能写入镜像、Git 或日志。Hosted 和自建 Server 两种配置方式同样是二选一。
配置轮询和证书
Mender Client 主配置位于:
1 | /etc/mender/mender.conf |
默认更新轮询周期是 1800 秒,Inventory 上报周期是 28800 秒。可以调整为:
1 | { |
这只是最小结构示例。编辑时要保留 mender-setup 已写入的其他字段,不能直接覆盖整份配置。
UpdatePollIntervalSeconds: 300:设备最多约 5 分钟发现新任务;InventoryPollIntervalSeconds: 3600:每小时上报一次地区和版本信息;- 轮询越频繁,总部服务端压力越大。
如果总部使用公开可信 CA,客户端使用系统 CA 即可。如果使用企业私有 CA,应把 CA 证书放到客户端,例如:
1 | /etc/mender/server.crt |
然后在配置中增加:
1 | { |
不要在生产环境启用跳过 TLS 验证。
重新启动客户端:
1 | sudo systemctl restart mender-authd mender-updated |
在服务端接纳设备
客户端第一次运行时会生成自己的密钥:
1 | /var/lib/mender/mender-agent.pem |
然后向 Server 提交认证请求。在 Mender UI 中进入 Devices,找到 Pending 设备,核对设备 ID、公钥和主机信息后选择 Accept。
只有 Accepted 设备才能进入 Deployment。生产环境设备多时,可以使用预授权 API 或企业版 mTLS 自动接纳,但不能在没有身份校验的情况下自动接受任意设备。
第四阶段:上报地区Inventory并建立分组
Mender 会执行 /usr/share/mender/inventory 中所有以 mender-inventory- 开头的可执行文件,并把脚本标准输出解析为 Inventory。
在华东服务器创建:
1 | sudo tee /usr/share/mender/inventory/mender-inventory-region >/dev/null <<'EOF' |
手工检查脚本输出:
1 | sudo /usr/share/mender/inventory/mender-inventory-region |
这些属性用于搜索、筛选和分组,不用于唯一识别设备。site_id 也不应代替 Mender Device ID。
等待 Inventory 上报后,在 UI 中可以:
- 建立静态组
pilot,手工加入试点服务器; - 建立静态组
production-east、production-south等地区组; - 企业版可根据
region和environment建立动态组。
静态组在创建 Deployment 时会固化设备列表。Deployment 创建后再向组里增加设备,不会把新设备自动加入正在执行的任务。
第五阶段:安装Docker Compose Update Module
只安装 Mender Client 还不能理解 docker-compose Artifact。需要在每台地区服务器安装对应 Update Module。
下载并安装模块
1 | sudo apt-get update |
这些命令的作用分别是:
- 下载固定版本的官方容器更新模块;
make将模板和公共 Shell 逻辑生成可执行模块;make install-docker-compose安装到 Mender 的 Update Module 目录。
验证:
1 | test -x /usr/share/mender/modules/v3/docker-compose |
Update Module 的文件名就是 Artifact payload type。客户端收到 docker-compose 类型负载时,会调用这个文件完成安装、提交或回滚。
规划Docker持久化目录
如果未来还要做 A/B 操作系统升级,Docker 镜像和业务数据不能留在会被整体替换的根分区。应把 Docker data-root 放到持久化数据分区,例如:
1 | { |
文件位置:
1 | /etc/docker/daemon.json |
修改后需要重启 Docker:
1 | sudo systemctl restart docker |
只做应用更新时也建议将数据库、上传文件、运行时配置和备份放在明确的持久化目录,不能依赖容器可写层。
第六阶段:在构建机安装Mender工具
下面的操作在总部 CI/CD Runner 或独立签名机构执行,不是在地区服务器执行。
配置工作站APT仓库
安装依赖并导入官方签名密钥:
1 | sudo apt-get update |
确认指纹为官方公布的:
1 | E6C8 5734 5575 F921 8396 5662 2407 2B80 A1B2 9B00 |
Ubuntu 24.04 添加工作站工具源:
1 | echo "deb [arch=$(dpkg --print-architecture)] https://downloads.mender.io/repos/workstation-tools ubuntu/noble/stable main" \ |
验证:
1 | mender-artifact --version |
mender-artifact 处理 .mender 文件,mender-cli 与 Mender Server API 通信,skopeo 在不运行容器的情况下下载不同架构的镜像。
也可以直接使用官方 CI 工具镜像:
1 | docker pull mendersoftware/mender-ci-tools:1.0.0 |
下载Compose Artifact生成器
1 | sudo curl -fL \ |
生成器负责解析 Compose、通过 Skopeo 下载镜像,再把 Compose 和镜像归档成 Mender Artifact。
第七阶段:准备业务Compose发布包
创建发布目录:
1 | mkdir -p release/manifests release/output |
示例 manifests/compose.yaml:
1 | services: |
发布前需要完成以下应用改造:
- 镜像使用不可变版本标签,正式环境最好同时记录 digest;
- 地区差异配置通过 Volume 在运行时挂载;
- 前端提供
/healthz和/version.json; - 后端提供
/health/live、/health/ready和/version; - 数据库、用户上传和业务文件位于宿主持久化目录或外部服务;
- Compose 设置明确的 restart 和 healthcheck;
- 同一个镜像可以部署到所有地区,不能为每个地区重新构建。
如果私有 Registry 需要认证,先在构建机登录:
1 | skopeo login registry.example.com |
认证只用于构建机下载镜像。因为最终 Artifact 可以包含镜像归档,地区服务器不一定需要访问 Registry。
第八阶段:生成Mender Artifact
先检查镜像支持的架构:
1 | gen_docker-compose \ |
生成 amd64 Artifact:
1 | gen_docker-compose \ |
参数作用如下:
| 参数 | 作用 |
|---|---|
--artifact-name | 设备安装后上报的软件版本名 |
--device-type | 限制只有相同类型的设备能够安装 |
--architecture | 指定下载哪个 CPU 架构的容器镜像 |
--manifests-dir | Compose 文件目录 |
--project-name | Compose 项目名,决定服务集合的管理范围 |
--output-path | 最终 .mender 文件位置 |
--software-filesystem | 声明容器镜像所在持久化文件系统 |
生成器会得到两个主要负载:
images.tar.gz:Compose 引用的容器镜像;manifests.tar:Compose 文件和相关清单。
读取 Artifact 信息:
1 | mender-artifact read output/factory-release-2026.08.1.mender |
重点检查:
- Artifact name;
- Compatible devices;
- payload type 是否为
docker-compose; - 架构是否正确;
- Compose 项目名和软件文件系统是否正确。
第九阶段:签名并在客户端启用强制验签
TLS 保护传输过程,Artifact 签名则保证制品本身来自受信发布方。两者不能互相替代。
生成签名密钥
在独立签名机生成 RSA 3072 位密钥:
1 | openssl genpkey \ |
private.key:只保存在签名机、KMS、Vault 或 HSM,不能进入 Git 和地区服务器;public.key:部署到所有地区服务器,用于验证签名。
签名Artifact
1 | mender-artifact sign \ |
验证:
1 | mender-artifact validate \ |
只有本地验证成功,才能上传到生产 Mender Server。
客户端安装验签公钥
在每台地区服务器执行:
1 | sudo install -o root -g root -m 0644 \ |
在 /etc/mender/mender.conf 的现有 JSON 中加入:
1 | { |
重新启动:
1 | sudo systemctl restart mender-updated |
一旦启用 ArtifactVerifyKey,客户端会拒绝未签名 Artifact 和签名不匹配的 Artifact。公钥轮换期间可以使用 ArtifactVerifyKeys 同时配置新旧公钥,确认全部设备获得新公钥后再删除旧公钥。
第十阶段:加入数据库备份、迁移和健康检查
Mender 能触发回滚,但它不知道数据库语义,也不会自动撤销 State Script 对数据库做出的修改。数据库升级必须自己设计。
State Script命名
Artifact State Script 使用以下格式:
1 | <STATE_NAME>_<ACTION>_<ORDER>_<DESCRIPTION> |
典型脚本:
1 | ArtifactInstall_Enter_10_backup-database |
脚本退出码:
| 退出码 | 含义 |
|---|---|
0 | 成功,继续升级 |
1 | 失败,进入回滚或失败流程 |
21 | 稍后重试,受重试间隔和总超时限制 |
脚本必须满足:
- 幂等,多次运行结果一致;
- 有明确超时;
- 诊断信息写到标准错误;
- 不把密码打印到日志;
- 备份放在持久化目录;
- 每次备份与 Deployment 或 release ID 关联;
- 实际验证备份可恢复,而不是只判断命令退出码。
健康检查示例
ArtifactCommit_Enter_10_health-check:
1 |
|
将健康检查放在 ArtifactCommit_Enter,可以在 Mender 正式提交版本之前阻止错误版本。返回 1 后,Mender 会执行 Update Module 回滚流程。
将脚本放进Artifact
给脚本执行权限:
1 | chmod 755 scripts/ArtifactInstall_Enter_10_backup-database |
生成 Artifact 时,将 --script 参数透传给 mender-artifact:
1 | gen_docker-compose \ |
再次读取 Artifact,确认 State scripts 已被打包:
1 | mender-artifact read output/factory-release-2026.08.1.mender |
数据库迁移的准确执行时机必须根据业务确定。某些 Compose 安装流程会先启动新容器,因此更稳妥的方案可能是把迁移做成一次性 Compose service,并让业务服务在迁移成功后启动。不可逆迁移不应进入无人值守升级通道。
第十一步:上传Release
使用UI上传
进入 Mender UI:
1 | Releases -> Upload |
选择签名后的文件:
1 | factory-release-2026.08.1-signed.mender |
上传后展开 Artifact 信息,再次检查设备类型、版本、payload type 和签名状态。
使用mender-cli上传
在 Mender UI 的个人资料页面创建 Personal Access Token。Token 只显示一次,应存入 CI Secret。
1 | export MENDER_SERVER_URL='https://mender.example.com' |
PAT 是长期凭据,权限继承创建它的用户。CI 应使用权限最小化的专用账号,并设置过期和轮换策略。
第十二步:创建灰度Deployment
推荐发布顺序:
- 开发环境;
- 测试地区;
pilot试点组;- 一个低风险生产地区;
- 10% 生产设备;
- 全量地区。
在 Mender UI 创建 Deployment:
- 选择
factory-release-2026.08.1Release; - 目标选择
pilot静态组; - 设置开始时间或立即开始;
- 检查设备数量;
- 创建 Deployment;
- 观察下载、安装、成功和失败状态;
- 试点观察期结束后,再创建下一批 Deployment。
sequenceDiagram
participant CI as 总部CI/CD
participant MS as Mender Server
participant MC as 地区Mender Client
participant APP as Docker Compose服务
CI->>MS: 上传已签名Artifact
CI->>MS: 创建试点Deployment
MC->>MS: 按轮询周期检查更新
MS-->>MC: 返回Artifact和Deployment信息
MC->>MC: 下载并验证签名、设备类型
MC->>APP: 备份、安装Compose、执行迁移
MC->>APP: 调用健康检查
alt 健康检查成功
MC->>MS: 上报success
else 安装或检查失败
MC->>APP: 回滚Compose并恢复数据库
MC->>MS: 上报failure和日志
end
Mender Server 不会让所有地区在同一秒执行。默认更新轮询为 30 分钟,本文示例改为 5 分钟,所以设备一般会在 5 分钟窗口内陆续开始。
中止和回滚不是同一操作
发现故障时,应先在 UI 或 API 中停止仍在进行的 Deployment,防止更多设备领取任务。中止任务不会自动把已经成功升级的设备降回旧版本。
需要人工回滚已经升级成功的设备时,应保留并重新发布上一版签名 Artifact,例如 factory-release-2026.07.4,再为受影响设备创建一个新的 Deployment。数据库只有在旧应用仍兼容当前 schema,或已执行经过验证的向下迁移、备份恢复后,才允许回退应用。
自动回滚只发生在当前安装流程尚未成功提交,并且 Update Module 或 State Script 报错的情况下。已经标记成功的 Deployment 不能依靠“中止”恢复旧版本。
第十三步:观察状态和排查失败
地区服务器日志
查看认证日志:
1 | sudo journalctl -u mender-authd -n 200 --no-pager |
查看更新日志:
1 | sudo journalctl -u mender-updated -n 200 --no-pager |
实时跟踪:
1 | sudo journalctl -u mender-updated -f |
失败 Deployment 的详细日志还会保存在:
1 | /var/lib/mender/deployments.*.log |
Mender 默认保留最近若干部署日志,并在失败时上传日志到服务端。
查看设备当前软件信息
1 | sudo mender-update show-provides |
应能看到当前 Artifact 和 Compose 软件版本。服务端 UI 中也可以从 Device 和 Release 页面交叉核对。
常见故障
设备一直Pending
检查:
- 管理员是否在 UI 接受设备;
mender-authd日志是否有 TLS 或认证错误;- 设备时间是否正确;
- 是否错误复制了另一台服务器的
/var/lib/mender。
每台设备必须拥有独立身份。克隆服务器模板时,应在首次启动前清理模板中的 Mender 私钥和状态,再让每台机器自行生成。
certificate signed by unknown authority
表示客户端不信任总部 TLS 证书。使用公开 CA 时更新系统 ca-certificates;使用私有 CA 时,将正确 CA 放入 /etc/mender/server.crt 并配置 ServerCertificate。
不能通过关闭证书验证掩盖问题。
Artifact显示noartifact
通常是 Artifact 的 compatible device type 与客户端 Device Type 不一致。检查:
1 | cat /var/lib/mender/device_type |
两边的值必须完全相同。
签名验证失败
检查:
- 上传的是签名后文件,不是原始文件;
- 客户端配置指向正确公钥;
- 签名后没有再次修改 Artifact;
- 公钥轮换期间新旧密钥配置是否完整。
Compose安装失败
检查:
1 | docker compose version |
常见原因包括磁盘不足、镜像架构错误、端口冲突、Volume 路径不存在、Compose 语法错误和健康检查命令缺失。
版本出现_INCONSISTENT
这表示上一次部署失败,并且回滚失败或 Update Module 无法完成回滚。此时不能继续自动发布,应先读取设备 Deployment 日志,确认容器、配置和数据库实际处于哪个版本。
可选:每个地区部署Mender Gateway
当一个地区有很多设备,或者只有地区出口服务器能访问总部时,可以部署 Mender Gateway。
flowchart LR
MS[总部Mender Server] <-->|HTTPS| GW[地区Mender Gateway]
GW -->|局域网HTTPS| D1[服务器1]
GW -->|局域网HTTPS| D2[服务器2]
GW -->|局域网HTTPS| D3[服务器3]
GW --> CACHE[(地区Artifact缓存)]
Gateway 可以:
- 代理设备到总部的 Mender API 请求;
- 把 Artifact 下载地址替换为地区网关地址;
- 第一次下载后缓存在本地,后续设备复用;
- 为网关后的设备统一增加
region等 Inventory; - 配合 mTLS 自动接纳持有有效客户端证书的设备。
Mender Gateway 属于 Enterprise 能力。它不是一套独立地区 Mender Server,也不会在总部上传 Release 后立即主动同步全部 Artifact;缓存通常在设备实际请求时产生。
示例 /etc/mender/mender-gateway.conf:
1 | { |
部署时还要完成:
- 从企业下载区取得与系统匹配的
mender-gatewayDebian 包; - 为 Gateway 配置受信 TLS 证书;
- 为缓存准备独立磁盘或 Volume;
- 将
DomainWhitelist限制为真实 Artifact 存储域名; - 把地区设备
ServerURL指向 Gateway; - Gateway 2.2.0 或更新版本可启用 Prometheus
/metrics,应只监听127.0.0.1:9102或受信管理网; - 监控缓存磁盘、请求错误率和到总部的连通性。
如果每个地区只有一台服务器并且网络稳定,Gateway 的收益很低,可以先不部署。
如果每个地区必须有独立Mender Server
有些企业要求地区断开总部后仍能独立创建发布。此时可以在每个地区部署完整 Mender Server,但这已经是多套独立控制面。
需要额外开发或建设:
- 总部 Artifact 向各地区对象存储复制;
- Release 元数据同步;
- 地区 Deployment 创建和状态汇总;
- API Token、账号和权限管理;
- 失败补偿和重复同步幂等;
- 总部与地区版本冲突处理;
- 断网期间操作审计合并。
Mender Gateway 不能替代这套联邦控制逻辑。除非有明确的地区自治或长期断网要求,否则优先使用一个中心 Mender Server 加多个 Gateway。
操作系统A/B升级与Compose升级的区别
本文安装 Debian 包的方式只能直接获得应用更新能力,不能自动获得完整操作系统回滚。
| 更新方式 | 更新内容 | 是否需要重启 | 集成成本 | 回滚能力 |
|---|---|---|---|---|
| Docker Compose Update Module | 前端、后端、容器和 Compose | 通常不需要整机重启 | 较低 | 由模块和业务脚本共同保证 |
| 自定义 Update Module | 文件、安装包、业务组件 | 取决于实现 | 中等 | 必须自己实现 |
| A/B rootfs | 整个 Linux 根文件系统 | 需要 | 高 | 启动失败可切回旧分区 |
A/B rootfs 需要:
- 两个根文件系统分区;
- 持久化数据分区;
- GRUB 或 U-Boot 集成;
- Mender 化的 Debian/Yocto 镜像;
- 启动成功确认和 boot counter;
- 重新刷写或迁移现有服务器磁盘布局。
对于已经运行 Docker Compose 的普通服务器,建议第一期只做应用升级;操作系统补丁继续使用现有的系统运维工具。等应用发布链路稳定后,再单独评估 rootfs OTA。
哪些是安装配置,哪些必须自己开发
| 工作 | 类型 | 说明 |
|---|---|---|
| Mender Server、Client、CLI 安装 | 现成组件 | 按官方方式部署和配置 |
| 设备认证、静态分组、Deployment、状态上报 | 现成能力 | Open Source 已覆盖基础流程 |
| Gateway、mTLS、动态组、RBAC、审计 | 企业能力 | 取决于购买方案 |
| Compose Artifact 生成和安装 | 官方工具 | 使用 gen_docker-compose 和 Update Module |
| Artifact 签名和客户端验签 | 官方工具 | 仍需企业管理私钥和公钥轮换 |
| CI 上传和创建 Deployment | 流水线脚本 | 调用 mender-cli 或 REST API |
| 前后端健康和版本接口 | 业务开发 | Mender 不知道业务是否真正可用 |
| 运行时配置外置 | 业务改造 | 确保一个镜像能部署到所有地区 |
| 数据库备份、迁移和恢复 | 必须自研 | 针对实际数据库和业务 schema |
| 不可逆迁移审批 | 流程建设 | 不应自动回滚或无人值守执行 |
| 严格同一秒跨地区切换 | 自定义协调 | Mender 客户端轮询不保证同时开始 |
| 多套地区 Mender Server 联邦同步 | 自定义平台 | Gateway 不提供独立控制面同步 |
使用 Mender 的主要价值,是省掉设备注册、轮询协议、制品存储、部署状态机、基础重试和管理 UI。真正需要自己开发的部分集中在业务健康、Compose 约束、数据库和企业发布流程。
生产上线清单
正式启用无人值守更新前,至少确认:
- Mender Server 使用固定 Chart 和镜像版本;
- MongoDB、Redis、NATS 和对象存储有明确维护责任;
- MongoDB 与 Artifact 存储已经完成恢复演练;
- 总部入口只提供 HTTPS,证书续期有监控;
- 每台地区服务器身份唯一;
- 地区服务器只需要出站 HTTPS;
- Artifact 强制签名验证;
- 私钥不在构建机工作目录、Git 或地区服务器;
- Device Type、架构和 Compose 项目名有统一规范;
- 镜像使用不可变版本并保留 digest;
- 前端、后端和数据库 schema 使用同一个
releaseId; - 配置、数据库和用户数据位于持久化目录;
- 数据库备份和恢复在真实测试库演练通过;
- State Script 幂等并有超时;
- 健康检查失败能触发 Compose 和数据库回退;
- 保留至少 N-1 版本所需制品和数据恢复点;
- 发布按试点、灰度、全量执行;
- 有人工暂停、终止、回滚和现场恢复手册;
- 日志中不包含密码、私钥、Token 和业务敏感数据。
总结
使用 Mender 实现中心发布、多地区服务器升级,最合理的职责划分是:
- 总部 Mender Server 管理设备、Release、Deployment 和状态;
- 总部 CI/CD 构建 Compose、打包镜像、生成并签名 Artifact;
- 地区 Mender Client 主动轮询、下载、验签和调用 Update Module;
- 官方 Compose Update Module 负责容器和 Compose 安装流程;
- 企业自己负责业务健康检查、数据库备份、迁移和恢复;
- 设备较多或出口受限的地区使用 Mender Gateway 做代理和缓存;
- 只有明确要求地区自治时,才部署多套 Mender Server 并开发同步平台。
Mender 不是把所有升级问题自动解决,而是提供一套可靠的通用分发和设备状态基础。把 Artifact 验签、灰度发布、业务健康和数据库恢复四部分同时做好,才能把“能够远程更新”提升为“可以在生产环境无人值守更新”。
