说下需求:
我的服务器上运行着十几个 service,是用 c#和 GO 写的可执行文件,当前用 supervisor 来管理,目前更新 service 我是先在 supervisor 里停止它,然后用 FTP 上传新的可执行文件,上传完成后在 supervisor 里启动它.
如果偶尔更新,这样操作问题不大,现在的问题是经常要更新多个 service,感觉这样效率太低.
有没有这种方案:
1 上传新的可执行文件时不需要在 supervisor 先停止 service
2 上传完成后 service 会自动重启
3 不太需要优雅的"不中断服务更新",短时间停止一下问题不大.
如果能用 supervisor 实现最好,其它的也可以考虑.
不熟悉 linux 运营这块,请指点...

用 systemd 代理 supervisor ,语法更简单,ftp 建议换成脚本
go build xxx
scp xx [email protected]:/xxx
ssh [email protected] "
tar ...
mv ...
rm ...
systemctl restart xxx
....
"
echo "手工"

简单搞得话很容易,你可以使用 git 仓库来存储代码,然后你在服务器起一个定时任务,写个 shell ,1 分钟拉取一次 git 代码,判断 git 代码有更新,就执行 build 和重启命令。

如果你不抗拒新东西的话,弄个单节点 k8s ,比方说 k3s 这种轻量发行版,然后每次发版本打个新镜像往 k8s 一丢就了事了。

这是一个示例脚本:
CGO_ENABLED=0 go build -o my_service -a -ldflags '-extldflags "-static"' .
scp service [email protected]:/root/my_service
ssh [email protected] "bash /root/update_service.sh"
其中在部署机器上的 /root/update_service.sh 内容为:
systemctl stop my_service
rm -rf /usr/local/bin/my_service
cp my_service /usr/local/bin
chmod +x /usr/local/bin/my_service
systemctl start my_service
此外需要在编译的机器上添加待部署机器上的 ssh 私钥,以及在待部署机器上写 systemctl 的 my_service.service 文件

[program:bin]
command=/opt/bin

$ mv /opt/bin /tmp/
$ mv ~/newbin /opt/bin

$ supervisorctl restart bin

linux 文件占用是用的 inode ,而非路径,所以可以把正在执行的文件 move 到其他目录,然后把新版本的执行文件 mv 到正确目录,然后 restart

如果是十多个 supervisor 服务, 完全可以把执行文件放到一个目录里, 然后替换目录

再一次性
$ supervisorctl reload

虽然 linux 不允许覆盖正在运行的程序,但是你可以先删除了再上传同名文件(

显然用 k8s 更容易搞定。搞很多脚本,脚本维护也是问题。后续系统继续扩展也是问题。

以为挺常见的场景, 结果楼上给的都不是我常见的...

gunicorn gracefully restart - Google 搜索 - www.google.com/search?q=gunicorn+gracefully+restart&oq=gunicorn+gracefully+restart&aqs=chrome..69i57.7670j0j7&sourceid=chrome&ie=UTF-8

搜索关键词主要就是 gracefully restart, 可以参考上面 gunicorn 通过 HUP 信号做的那种

以前也见过 nginx 切换流量的做法, 反代指向的本地服务多个版本是多个进程实例和端口的, 这种也是不宕机直接切换流量的路子

如果其他的云原生那边的就不提了, 饿了吃饭去了

jenkins 写脚本

用 docker 来运行
Git+Drone 自动化部署

ansible 没人提么?我们之前 supervisor 管理 python 跟 golang ,都用 supervisor 发布。

ansible 发布……

docker

k8s +1

我是自己用 go 写了个程序, 负责服务停止, 替换, 服务启动, 监听一个 rpc 服务用来接收需要替换的文件压缩包, 把多个服务的路径什么的维护起来. 然后配合 WinForm 客户端, 更新服务的时候就基本上两步就行, 选择服务->点击部署. 另外 WinSCP 可以支持即使 systemd 服务运行着也照样替换 golang 可执行文件, 这个的话也挺方便, 找到目录->拖拽覆盖->重启服务

Jenkins 装一个,每个 service 配一个 job 。哪个有更新点一下哪个 job 的构建就完事。

K8s 滚动更新

如果是我来做这个方案的话:
1 做一个 http 的中心化软件下载地址
2 做一个脚本 , 通过 cron 定期从中心化节点下载文件(假设为 xxx), 并且命名为 xxx.update (这一步通过 cron 做更稳定无脑)
3 另一个脚本检查 xxx.update 和 本地 xxx md5 是否一致, 如果不一致就删除 xxx , 然后将 xxx.update 修改为 xxx, 并且运行重启脚本: pkill xxx && chmod+x xxx && nohup ./xxx &
4 如果 md5 一致, 就删除 xxx.update

= =!这不就是 docker-composer 干的事么。。。

公司有一些这种很简单,没必要 k8s 的。。。
平常升级就是 docker-compose up --force-recreate ,简单可依赖

运行环境是 虚拟机
brew 自定义 tap
egoist/bget 下载 github rel

转换成 容器
可以用 dokku 的 Paas 持续部署

运行环境是 容器
docker-compose
docs.docker.com/compose/
短链 dc.moz.one

k8s
kubernetes.io/docs/reference/kubectl/docker-cli-to-kubectl
短链: dtk.moz.one