Open abbshr opened 7 years ago
正式走入工作岗位一个月, 接着实习的工作内容继续, 还是承担团队的 Develop & Operation & Research 任务, 恰好我个人也比较喜欢什么都接触一些. 目前在应用开发部门设计了一套包括日志处理, 监控报警, 持续集成, 版本发布与回滚, 自动化管理在内的基础平台的架构, 当然这套体系肯定还尚未成熟, 这里经过老大的许可先把项目的部署与回滚架构发上来, 做个记录也方便日后 tuning.
8月初刚过来时我压根没听过 ansible 只知道 puppet, 正好那时团队准备做项目自动化管理相关的工作, 也就把自动化配置管理工具搜了一遍, 列了个优缺点比较表, 发现 ansible 完胜. 至于为什么, 我就一句话: "没有 agent, 没有 server, 用 ssh 批量管理主机". 玩过 puppet 和 chef 的同学应该秒懂了.
另外, ansible 也是 Devops 工具集中蹿升速度最快的配置管理工具之一. 截止至本年度7月份, Devops 使用度&接受度排行榜中前四位分别是 Puppet, Chef, Docker, Ansible. 而后者预计很快将超越前两个工具.
以其配置上的简洁, 使用上的顺手, 功能上的强大, 好了继续下一节.
ansible 的细节这里略过, 单说这套架构, 目前包括如下功能:
接下来从整套机制的架构到细节逐步介绍.
在未引入 Docker 情况下, 为了做到项目(应用程序, 配置信息, 状态数据, 依赖工具链等)之间的隔离, 这里定义了一种项目的目录规范.
线上项目一般都是位于某个目录(比如/opt/app)下面, 不同的子目录用以区分不同的项目, 每个项目目录的基本结构如下:
/opt/app
/uopt/app/example-project ├── current # 指向项目最新发布的版本的软链接 ** 重要 ** ├── releases # 包含所有的历史发布版本(以及当前版本) ** 重要 ** ├── tmp # rsync 临时目录 ├── shared # 发布工具使用的目录 ** 重要 ** ├── log # 日志存放 ├── run # 运行时数据 ├── util # 外部工具 └── node_modules # Node.js Package 形式的外部工具, 如 pm2 ** 重要 **
每个项目可以在这个目录结构上进行扩展, 比如添加其他目录, 但上述标注 * 重要 * 的目录不建议删除或修改.
其中 current 目录指向的就是该项目的原代码, 即开发阶段所熟悉的目录结构.
在使用 ansible 时, current 所指代的代码目录中, 应包含 ansible playbook 的配置目录, 举个例子:
/opt/app/my_app/current/deploy ❯❯❯ tree -a -L 4 # 以下结构参考 ansible 官方给出的最佳实践 . ├── group_vars │ ├── all │ ├── nodes │ │ └── vars │ └── proxy │ └── vars ├── host_vars # 测试环境下只需增加对应主机的变量文件即可覆盖预设变量 │ ├── 10.0.5.130 │ ├── 192.168.1.17 │ │ ├── vars │ │ └── vault # 加密变量 │ ├── 192.168.5.68 │ │ ├── vars │ │ └── vault │ └── 192.168.5.69 │ ├── vars │ └── vault ├── production # 线上环境 inventory ├── roles │ ├── config │ │ ├── tasks │ │ │ └── main.yml │ │ └── templates │ │ ├── config.json.j2 │ │ ├── logstash.conf.j2 │ │ └── macros.j2 │ ├── node │ │ └── tasks │ │ └── main.yml │ ├── proxy │ │ └── tasks │ │ └── main.yml │ ├── schedule │ │ └── tasks │ │ └── main.yml │ └── worker │ └── tasks │ └── main.yml ├── rollback.yml ├── .rsync_ignore # 从代理机到线上机同步时需要忽略的文件/目录列表 ├── site.yml └── staging # 测试环境 inventory
其余文件的解释和作用见 ansible 官方文档.
在执行发布回滚操作上, 我在开源 roles ansistrano 的基础上做了不少改动以适配我们的应用场景, 并以新的 roles 发布在 ansible galaxy 上 (https://github.com/upyun-dev/ansistrano-deploy | https://github.com/upyun-dev/ansistrano-rollback), 具体的代码实现这里就不说了.
来看看怎么用吧:
# 安装依赖 roles $ ansible-galaxy install upyun-dev.ansistrano-deploy $ ansible-galaxy install upyun-dev.ansistrano-rollback
# 在所有机器上执行项目部署, 发布版本并重启服务任务 ansible-playbook -i <staging | production> site.yml # 在所有机器上执行项目回滚并重启服务任务 ansible-playbook -i <staging | production> rollback.yml
但是同构化 proxy 和 nodes 往往不是我们想要的结果, 多数情况下我们可能只把 proxy 作为纯粹的代理机使用, 并不需要模拟线上机器执行部署/回滚. 这种情况可以通过指定 --tag 或者 --limit 来选择要执行的任务:
# tag: proxy, nodes, config # 仅在 proxy 上执行部署发布 ansible-playbook -i hosts site.yml --tag="proxy" # 仅在 proxy 上执行回滚 ansible-playbook -i hosts rollback.yml --tag="proxy" # 仅在 nodes 上执行部署发布以及服务启动 ansible-playbook -i hosts site.yml --tag="nodes" # 只在属于proxy group的主机上执行tasks ansible-playbook -i <staging | production> site.yml --limit=proxy
在本地测试与开发上, ansible playbook 配置目录中的一些变量可能需要稍做修改, 因此你可以创建一个host_var文件,比如:
# 文件: host_vars/localhost # 项目名 app_name: my_app_test # 项目的父级目录 dest_prefix: "/tmp" # 分支/版本 version: test # 代理机的地址 sync_host: ran@127.0.0.1
注意当你选择使用 rsync 的 ssh 模式同步数据时, 一定要保证代理机上的 登录 shell 没有多余的输出(当时被这个坑了...).
由于引入规范化项目结构, 导致了冗余目录的产生以及项目状态数据路径(如 pm2)的变化. 为了屏蔽本地以及线上部署差异, 透明化本地开发, 这里对项目的启动脚本做了修改, 使其根据不同的开发环境判断如何启动项目, 如:
PRJ_DIR=$(cd $APP_ROOT_DIR/../.. && pwd) APP_DIR_PARENT=$(cd $APP_ROOT_DIR/.. && pwd) if [[ -L $APP_DIR_PARENT/current ]]; then PRJ_DIR=$APP_DIR_PARENT elif [[ ! -d $PRJ_DIR/releases || ! -L $PRJ_DIR/current ]]; then PRJ_DIR=${APP_ROOT_DIR} fi PM2_BIN="$PRJ_DIR/node_modules/pm2/bin/pm2" # 指定新的pm2可执行文件路径
最终结果体现为: 如果并没有遵循如上所述的规范化目录结构, 那么将之后的部署作为本地开发环境下的部署. 否则作为线上/测试环境下的部署.
小哥,github怎么404了
@zhuima oh, my fault.. 我把项目名字改了..
https://github.com/upyun-dev/deploy https://github.com/upyun-dev/rollback
谢谢,我去look look
666
正式走入工作岗位一个月, 接着实习的工作内容继续, 还是承担团队的 Develop & Operation & Research 任务, 恰好我个人也比较喜欢什么都接触一些. 目前在应用开发部门设计了一套包括日志处理, 监控报警, 持续集成, 版本发布与回滚, 自动化管理在内的基础平台的架构, 当然这套体系肯定还尚未成熟, 这里经过老大的许可先把项目的部署与回滚架构发上来, 做个记录也方便日后 tuning.
为什么是 ansible?
8月初刚过来时我压根没听过 ansible 只知道 puppet, 正好那时团队准备做项目自动化管理相关的工作, 也就把自动化配置管理工具搜了一遍, 列了个优缺点比较表, 发现 ansible 完胜. 至于为什么, 我就一句话: "没有 agent, 没有 server, 用 ssh 批量管理主机". 玩过 puppet 和 chef 的同学应该秒懂了.
另外, ansible 也是 Devops 工具集中蹿升速度最快的配置管理工具之一. 截止至本年度7月份, Devops 使用度&接受度排行榜中前四位分别是 Puppet, Chef, Docker, Ansible. 而后者预计很快将超越前两个工具.
以其配置上的简洁, 使用上的顺手, 功能上的强大, 好了继续下一节.
自动化管理
ansible 的细节这里略过, 单说这套架构, 目前包括如下功能:
接下来从整套机制的架构到细节逐步介绍.
规范化项目目录结构
在未引入 Docker 情况下, 为了做到项目(应用程序, 配置信息, 状态数据, 依赖工具链等)之间的隔离, 这里定义了一种项目的目录规范.
线上项目一般都是位于某个目录(比如
/opt/app
)下面, 不同的子目录用以区分不同的项目, 每个项目目录的基本结构如下:每个项目可以在这个目录结构上进行扩展, 比如添加其他目录, 但上述标注 * 重要 * 的目录不建议删除或修改.
其中 current 目录指向的就是该项目的原代码, 即开发阶段所熟悉的目录结构.
Ansible Playbook 目录结构
在使用 ansible 时, current 所指代的代码目录中, 应包含 ansible playbook 的配置目录, 举个例子:
其余文件的解释和作用见 ansible 官方文档.
发布和回滚
在执行发布回滚操作上, 我在开源 roles ansistrano 的基础上做了不少改动以适配我们的应用场景, 并以新的 roles 发布在 ansible galaxy 上 (https://github.com/upyun-dev/ansistrano-deploy | https://github.com/upyun-dev/ansistrano-rollback), 具体的代码实现这里就不说了.
来看看怎么用吧:
但是同构化 proxy 和 nodes 往往不是我们想要的结果, 多数情况下我们可能只把 proxy 作为纯粹的代理机使用, 并不需要模拟线上机器执行部署/回滚. 这种情况可以通过指定 --tag 或者 --limit 来选择要执行的任务:
本地测试/开发
在本地测试与开发上, ansible playbook 配置目录中的一些变量可能需要稍做修改, 因此你可以创建一个host_var文件,比如:
注意当你选择使用 rsync 的 ssh 模式同步数据时, 一定要保证代理机上的 登录 shell 没有多余的输出(当时被这个坑了...).
项目启动脚本
由于引入规范化项目结构, 导致了冗余目录的产生以及项目状态数据路径(如 pm2)的变化. 为了屏蔽本地以及线上部署差异, 透明化本地开发, 这里对项目的启动脚本做了修改, 使其根据不同的开发环境判断如何启动项目, 如:
最终结果体现为: 如果并没有遵循如上所述的规范化目录结构, 那么将之后的部署作为本地开发环境下的部署. 否则作为线上/测试环境下的部署.
[WIP] - 执行流程