1. 云服务器>阿里云 >

腾讯云服务器自动化部署:从 GitLab CI 到 CVM 的发布流水线

腾讯云服务器自动化部署:从 GitLab CI 到 CVM 的发布流水线

正文

如果你的发布流程是"三个人同时 ssh 上去 git pull、手动覆盖目录、再重启进程",那出事只是时间问题。我做腾讯云服务器自动化部署这几年,印象最深的一次是两个运维同时操作,目录只覆盖了一半,站点白屏了两个小时,那晚的订单损失老板到现在还念叨。根子不在技术难,而是没把"部署"当成一件要工程化的事。下面这条路径可以直接抄:代码提交后,GitLab CI 把构建好的制品推到腾讯云服务器 CVM(行业里常叫 ECS)上,全程免密、幂等、可回滚、可复现,中小团队一两天就能搭起来。

先把一条大命令拆成三层

新手最容易写的脚本长这样:拉代码、装依赖、编译、scp、重启,一大串塞进一个 deploy.sh。跑得通,但它有三个致命问题——构建环境依赖开发机、制品没有版本、失败了一半不知道停在哪。工程化的第一刀,是把流程切成三层:构建、制品、发布。

构建层负责把源码变成可执行产物,跑在 CI 的 Runner 里,环境用镜像固定,依赖锁定版本;制品层负责给这次产物一个唯一标识,通常是提交短 SHA 加时间戳,产物统一丢到对象存储 COS 或制品库;发布层只做一件事——把某个确定的制品放到目标机、切换、重启、健康检查。三层分离之后,每一层都能单独重跑,出问题能一眼定位是没构建出来,还是推不上去。

我见过太多团队把构建放在生产机上做的,机器一换系统版本,Node 或 Python 版本不一致,产物就变样。构建环境必须在 CI 侧固定,生产机上只允许出现制品,不允许出现编译动作。

构建层还有两个细节值得说。一是缓存,像 node_modules、Maven 本地仓库这类目录,用 GitLab CI 的 cache 按分支缓存后,构建时间能从几分钟压到几十秒,但缓存键要带上依赖锁定文件的哈希,否则依赖改了还在用旧缓存,会出现"本地能跑、线上报错"的怪事。二是构建矩阵,多环境、多架构的产物应该在构建层一次性产出,生产机只负责运行,绝不现场编译。

Runner 放哪儿:托管 Runner 还是自建,内网怎么通

GitLab Runner 是执行任务的进程。托管 Runner 省事,但默认跑在公网环境,要和你的 CVM 内网互访就得把机器暴露到公网、或走公网 IP 加安全组放行,安全面一下就大了。

我更推荐在有条件时自建 Runner:把 Runner 装在一台同地域、同私有网络 VPC 的 CVM 上,规模小的直接用轻量应用服务器 Lighthouse 也行,只要能进同一个 VPC。这样 Runner 到目标机走内网,天然不通公网,安全组只需放行内网网段。接入时给 Runner 打标签(tag),比如 prod-cn、web,gitlab-ci.yml 里用 tags 指定,避免任务被随便一台机器执行。

踩过的坑说一个:Runner 执行用户如果是 root,它写出来的文件后面很难被普通服务账号接管,权限会打架。正确做法是给 Runner 一个专用系统账号,和目标应用账号解耦,用 sudo 白名单只允许它执行那几条重启命令,别给全量 sudo。这一步做对了,后面无论加多少台机器,权限模型都是清晰的。

选执行器也有讲究。shell 执行器最省资源,但多个任务共用系统环境,容易互相污染;docker 执行器隔离好、复现性强,代价是每次要拉镜像、启动容器。机器少、任务简单就用 shell,要求环境一致就上 docker。另外 Runner 的并发数别开太大,一台机器同时跑好几个构建,内存和磁盘 IO 会互相抢,反而更慢,出错时日志也乱成一团。

免密发布:CAM 子账号加 SSH 密钥,权限只给到需要的那台

免密有两层含义:CI 连目标机免密,以及脚本调云 API 时不用主账号密钥。

连目标机这一层,用 SSH 密钥对,把公钥放到目标机对应用户的 authorized_keys,私钥作为 GitLab CI 的受保护变量(masked 加 protected),只在受保护分支的流水线里注入。千万不要把私钥写进仓库,也不要 commit 到 .gitlab-ci.yml 里,哪怕是私有仓库——历史记录里的密钥删不干净。

调云 API 这一层更要克制。不要在流水线里塞主账号 SecretId 与 SecretKey,而是新建一个 CAM 子账号,按最小权限给策略:只允许它对指定实例执行重启、只允许它读写某个 COS 桶、只允许它拉取某个镜像仓库。腾讯云 CAM 的策略语法里,resource 写到具体实例 ID 或桶名,action 只勾必要的那几个,别图省事挂 QcloudAll。我经手过的一个客户,就是把主账号密钥写在 Jenkins 的环境变量里,结果密钥泄露,攻击者拿它开了一批按量计费的高配机器挖矿,账单出来才知道。

还有一点常被忽略:密钥要能换、换得起。把 SecretId、SecretKey 和 SSH 私钥都当成有保质期的凭证,设定轮换周期,并且保证轮换过程不影响流水线——比如用两把密钥并行一段时间再下线旧的。最忌讳的是某把密钥在很多地方被写死,谁都不敢动,最后变成一颗定时炸弹。

幂等与回滚:同一条命令跑十次,结果必须一样

幂等是自动化部署的底线:同一条发布命令,跑一次和跑十次,系统状态应该完全一致。做到这点,要满足三个条件——制品唯一、目标状态明确、中间态可清理。

具体做法是版本目录加软链:每次发布解压到类似 releases/20261003-a1b2c3/ 的目录,然后用 ln -sfn 原子地把 current 指向新目录,服务通过 current 启动。回滚就是把软链指回上一个版本再重启,秒级完成,不需要重新构建。注意 ln 要加 -n 配合 -f 才能原子替换已有软链;mv 整个目录也行,但别用先 rm -rf current 再 ln 的写法,中间会留下一个软链不存在的窗口,请求正好打进来就是 502。

数据库迁移是幂等的天敌。改表结构的迁移脚本要做到跑两次也不报错,能用 IF NOT EXISTS、ADD COLUMN IF NOT EXISTS 就用,并且把迁移和发布解耦:先让新结构兼容旧代码,再上代码,最后才清理旧字段。这样即使发布到一半回滚,数据库也不会被卡死。

发布脚本里还有两个动作不能省:健康检查和失败即停。切换软链后,脚本要主动请求一个健康检查接口,返回非 200 就把软链切回去、退出非零码,让流水线明确标红;不要随便 curl 一下首页就算通过。失败即停则要求脚本开头写 set -e,任何一步出错立即中止,避免带着半成品继续往下跑。我见过不写健康检查的团队,发布显示绿灯、服务其实起不来,最后靠用户投诉才发现。

不管用哪种发布方式,回滚都要提前演练。很多团队的回滚脚本只在脑子里跑过,真出事才发现旧制品早被清理、或者数据库迁移不可逆。每季度挑一台非核心机器,走一遍完整的发布加回滚,把耗时记下来,这才是能写进值班手册的东西。

蓝绿、灰度与制品分发:怎么选才不翻车

有条件的团队可以上蓝绿:准备两套环境,负载均衡 CLB 把流量全指向绿组,发布时先更新蓝组、健康检查通过后再把权重切过去,出问题一秒切回。代价是峰值资源翻倍,预算紧的团队慎用。

预算有限就用灰度:多台机器分批发,先放一台、观察日志和监控指标,没问题再放剩下的。关键是指标要可观测——错误率、响应时间、CPU、连接数,至少看这几个。没有监控的灰度等于闭眼发版,出问题时你连是哪一步坏的都不知道。

发布相关的指标也别只看机器 CPU,至少要有部署成功率、平均发布时间、回滚次数、健康检查失败率。这几个指标连着看一段时间,能判断流水线是在变好还是变差,而不是靠感觉。

至于制品怎么分发到机器上,不同规模的团队别硬套同一套方案,这张表是我实际用下来比较靠谱的取舍。

发布方式 实现要点 回滚速度 适用场景 注意事项

rsync 增量直传 CI 用 rsync 把制品同步到目标机,软链切换 秒级 单机或少量实例 依赖 SSH 免密,注意保留文件权限与属主

制品包加对象存储 制品传 COS,目标机用内网域名下载解压 中,需保留上一版包 多实例跨可用区 桶权限要收敛,走内网避免流量费

自定义镜像重建 把应用打进自定义镜像,批量重建实例 慢,分钟级 环境一致性要求极高 重建会换系统盘,业务数据要放独立数据盘

容器加容器服务 TKE 镜像推镜像仓库,滚动更新 秒到分钟 已有容器平台的团队 学习与运维成本高,小团队别硬上

蓝绿双环境切流 新旧两组机器,CLB 切权重 秒级回切 要求零停机 峰值资源双份,成本翻倍

版本目录加软链 版本目录加 current 软链加 systemd 单元 秒级 传统单体应用 脚本要保证软链原子切换

选的时候有个顺序:先看团队有没有容器平台,有就优先容器加滚动更新,别重复造轮子;没有就用版本目录加软链这一套,简单、透明、任何运维都看得懂。别一上来就为了"先进"上蓝绿,结果两套环境的一致性都维护不好。我的经验是,机器台数在个位数的业务,rsync 或制品包加软链足够撑到几十万日活;真正逼你换架构的,通常不是并发,而是发布频率和回滚要求的提高。

判断标准很简单:没有监控、没有唯一制品、没有一键回滚,这三个缺一个,就别急着谈 CI/CD。

FAQ

Q:GitLab Runner 一定要装在被部署的那台 CVM 上吗?

A:不必。Runner 只是执行者,可以放在同 VPC 的另一台机器甚至轻量应用服务器上,通过内网连目标机,真正被部署的是目标机。放独立机器还有好处:部署工具和应用环境隔离,一台 Runner 能管多台目标机。

Q:没有 Kubernetes,能不能做蓝绿或灰度?

A:可以。蓝绿用两台机器加一个负载均衡 CLB 切权重即可;灰度更简单,按机器分批发布,先在低权重的一台上验证。容器只是实现手段,不是前提。

Q:流水线里的密钥怎么管才安全?

A:私钥和云 API 密钥都存成 GitLab CI 的受保护变量,限制只在受保护分支和受保护标签下注入;云侧用 CAM 子账号加最小权限策略,别用主账号密钥;定期轮换,出问题时第一时间禁用而不是删除。

Q:回滚是重新构建旧版本,还是保留旧制品?

A:保留旧制品。回滚要快,重新构建既慢又可能因为依赖漂移构建出不一样的东西。制品库里至少保留最近几个版本,配合软链就能秒级回滚。

结语

落地顺序我建议这样:先做一件事——把当前能在生产跑通的部署步骤,原样写成一个脚本并提交到仓库;再把它搬进 gitlab-ci.yml,加上制品版本号;然后补上 CAM 最小权限子账号、SSH 免密和软链回滚;最后接监控和灰度。别想着一步到位上蓝绿,先把免密、幂等、可回滚这三件事做实。评估做得对不对,看一个场景就够了——凌晨两点告警响起,值班的人敢不敢一个人照着流程重发一次;敢,这套腾讯云服务器自动化部署才算真正可信。如果团队自己搭运维能力有限,也可以让腾讯云代理协助梳理流水线边界,把账号权限和网络打底,剩下的工程活你们自己掌握,才不会被供应商锁死。

如果需要更深入咨询了解可以联系全球代理上TG:jinniuge 他们在云平台领域有更专业的知识和建议,他们有国际阿里云,国际腾讯云,国际华为云,aws亚马逊,谷歌云一级代理的渠道,客服1V1服务,支持免实名、免备案、免绑卡。开通即享专属VIP优惠、充值秒到账、官网下单享双重售后支持。不懂找他们就对了。


本文由不代表本站立场,转载联系作者并注明出处。