Ansible 多机房自动部署发布

一、面临的问题

一个完整的程序开发流程少不了部署发布这个环节,而部署发布是一个重复的过程,最基本的操作包含停止系统服务、更新软件包、重启系统服务,复杂的还需要做好监控、灰度发布、回滚等。在只有少量服务器的情况下,大多数运维人员会选择手动更新,减少自动化部署发布的开发成本。而当服务器数量增加,甚至服务器可能存在于跨地域的不同机房情况下,如何减少部署发布的人力和时间成本,实现自动化部署发布和无缝发布,而且在部署发布期间仍然能够正常提供服务,就成为一个至关重要的问题。

在我们发布风控情报服务的时候,就遇到了自动化部署发布的问题。由于风控服务在用户场景中处于非常重要的地位,对SLA要求极高,需要提供毫秒级别的访问质量,为了达到这一点,消除掉公网的消耗,需要支持多机房服务,而同时带来的问题就是,如何保持各机房的软件版本统一,能够做到快速的统一发布、运维,则成为了一大难题。

二、如何解决问题

目前自动化部署发布领域已经有了比较成熟的方案,中小公司会维护一些自动化脚本或开源软件,而大公司由于复杂的网络环境更多会选择维护一套专属的部署发布系统。而在我们这样的创业型公司,为了减少人力资源成本,首先选择的成熟的开源软件。

(一)工具对比

我们自己的项目后端开发语言为Python,目前主流的开源自动化配置工具有puppet、ansible、saltstack等,ansible和saltstack是基于Python开发,能够很好的支持Python程序发布。在服务器数量不多,不需要考虑大规模并发性能的情况下,我们对比了ansible和saltstack,最终选用了ansible作为部署发布工具。

  1. 通讯方式 ansible 无需安装服务端和客户端,管理机通过ssh协议将命令推送到服务器端执行,只需要管理机上安装ansible,即可实现统一管理,同时ansible也支持使用ZeroMQ、Kerberos、LDAP等方式推送命令。而saltstack需要分别安装master和minion,master和minion之间可以通过ZeroMQ、RAET消息队列进行通信,salt在升级时,master版本需向后兼容,minion版本不能高于master。
  2. 响应速度 saltstack的master和minion是通过ZeroMQ推送命令,而ansible通过标准ssh推送命令,ZeroMQ的传输速度比标准SSH连接会快很多,在大规模服务器并发的情况下,saltstack执行效率会比ansible好,而在一般的运维场景下,ansible可以满足需求。
  3. 二次开发 ansible和saltstack是基于Python开发,支持使用Python进行二次开发。ansible 附带很多可以直接在远端主机或者通过Playbooks执行的模块,用户可以开发自己的模块或者插件,而saltstack也有一些预装的formulas,同样可以执行自定义的formula,而他们都覆盖了常用的软件模块,如文件传输、web服务器、MySQL命令等。
  4. 安全性 ansible使用标准ssh协议通讯,标准ssh是加密传输,并且远程服务器不需要运行守护进程,使得远程服务器不容易受到攻击。而saltstack虽然可以通过数据加密方法配置数据传输加密方式,但是远程服务器必须运行守护进程,暴露了可攻击的点。

在综合考虑了上述几点,结合了项目特点,在不需要维护大规模服务器的情况下,且项目远程服务器部署在公有云上,需要通过访问接口完成服务器的拉出集群、拉入集群操作,我们选用了ansible,开发插件简单,只需要维护一台可以连接到所有远程服务器的管理机,尽量避免暴露网络端口减少被攻击的可能性,并且执行效率可以满足需求。

三、Ansible 总体介绍

(一)Ansible 基础架构

上图为ansible的基础架构图,其由以下部分组成:

l ansible:核心

l core modules:ansible自带的核心模块

l custom modules:自定义模块

l plugins:ansible插件,包括邮件插件、日志插件、连接插件等

l playbooks:剧本,ansible配置、部署、编排语言,定义主机执行的task集合

l host inventory:ansible管理远程主机和组之间的关系清单,记录主机ssh端口、账号密码等

在管理主机上,ansible模块通过标准ssh协议(ZeroMQ、Kerberos)执行inventory文件中的主机对应的playbook task集合。

(二)Ansible 常用命令
  1. ansible

核心命令,用于执行ad-hoc命令,既单条命令,可以通过ansible -h获得帮助。

  1. ansible-doc

该命令用于查看模块信息,参数-l可以列出所有已安装的模块,参数-s可以查看具体某个模块的用户,如想查询ping模块的相关信息。

$ ansible-doc ping

> PING

A trivial test module, this module always returns `pong‘ on successful contact. It does not make sense in playbooks, but it is useful from `/usr/bin/ansible’ to verify the ability to login and that a usable

python is configured. This is NOT ICMP ping, this is just a trivial test module.

EXAMPLES:

# Test we can logon to ‘webservers’ and execute python with json lib.

ansible webservers -m ping

MAINTAINERS: Ansible Core Team, Michael DeHaan
  1. ansible-galaxy

用于从官方站点下载第三方扩展模块,类似于centos的yum、Python的pip指令。

  1. ansible-playbook

该命令是使用最多的命令,通过读取playbook文件,执行相应的操作。

  1. ansible-vault

配置文件中如果包含密码等敏感信息,可以通过ansible-vault加密、解密文件。

四、Ansible 初试

(一)Ansible 安装

官方提供了多种安装方式,可从github的ansible project下载源码编译安装,也可通过yum、apt-get指令安装,这里仅介绍通过pip安装ansible,其他可参考官方网站。

$ sudo pip install ansible
(二)第一条命令

为了避免在建立ssh连接时,重复输入密码,可以设置远程主机免密码登录。

$ ssh-keygen –t rsa –P “

$ ssh-copy-id -i ~/.ssh/id_rsa.pub user@remote_host

编辑(或创建)/etc/ansible/hosts文件,并在其中加入远程主机,例:192.168.1.2

$ ansible all -m ping

192.168.1.2 | SUCCESS => {

“changed”: false,

“ping”: “pong”

}
(三)Inventory 文件

/etc/ansible/hosts文件格式与ini配置文件类似,可以指定连接方式,也可以指定连接用户名。同时,再分配变量时,可以指定主机分配变量,也可以指定组分配变量。变量可以在多个地方定义,有优先级的差别。例如以下代码显示。

mail.example.com

[webservers]

foo.example.com

bar.example.com

[databases]

localhost              ansible_connection=local

other1.example.com     ansible_connection=ssh        ansible_ssh_user=mpdehaan

other2.example.com     ansible_connection=ssh        ansible_ssh_user=mdehaan

[raleigh]

host1 http_port=80 maxRequestsPerChild=808

host2 http_port=303 maxRequestsPerChild=909

[atlanta]

host1

host2

[atlanta:vars]

ntp_server=ntp.atlanta.example.com

proxy=proxy.atlanta.example.com
(四)Playbooks

playbooks的文件格式为yaml,远程主机被定义成不同角色,每个角色需要根据playbook中不同的task执行不同的指令,比如一组主机在inventory文件中被定义成webservers,则可能会执行web服务器重启等操作。

如下playbook,执行一组定义为webservers的主机,使用root账号登录,并且定义了http_port、max_clients变量,会执行三个task,分别为安装最新hhtpd服务、拷贝/srv/httpd.j2文件到远程主机的/etc/httpd.conf、重启httpd服务。’notify‘ action表示在playbook每一个task结束时被触发,只会被触发一次。handlers是一些task列表,通过名字引用。则该playbook中,配置文件拷贝结束后

执行’restart apache’ task。

---

- hosts: webservers

vars:

http_port: 80

max_clients: 200

remote_user: root

tasks:

- name: ensure apache is at the latest version

yum: pkg=httpd state=latest

- name: write the apache config file

template: src=/srv/httpd.j2 dest=/etc/httpd.conf

notify:

- restart apache

- name: ensure apache is running

service: name=httpd state=started

handlers:

- name: restart apache

service: name=httpd state=restarted

五、自动化部署发布示例

简要说明下我们的项目如何使用ansible实现了多个环境的自动化部署发布。

├── group_vars

│   ├── all

│   ├── production

│   │   ├── build_server.yml

│   │   ├── web_server_bj.yml

│   │   └── web_server_sh.yml

│   └── staging

│       ├── build_server.yml

│       ├── web_server_bj.yml

│       └── web_server_sh.yml

├── library

│   ├── slb_op.py

├── roles

│   ├── build

│   │   └── tasks

│   │       └── main.yml

│   └── publish

│       ├── tasks

│       │   └── main.yml

│       └── templates

│           ├── config.conf

│           ├── nginx.conf

│           └── supervisord.conf

├── production

├── production.yml

├── staging

└── staging.yml

如上目录结构,是目前ansible比较受欢迎的实现方式。例如项目有生产和测试环境,则分为两个inventory文件,分别为production、staging,inventory文件中定义对应环境的服务器所在的组,以staging为例,web_server_sh、web_server_bj表示两个机房的主机,build_server为打包机器。

[web_server_sh]

192.168.0.2

[web_server_bj]

192.168.0.3

[build_server]

localhost    ansible_connection=local

而每个inventory对应的playbook则为production.yml、staging.yml,指定不同的组需要执行的角色task。以staging.yml为例,build_server组的主机需要执行build角色的task,并且变量文件为

group_vars/staging/build_server.yml,而web_server_sh、web_server_bj组的主机需要执行publish角色的task,并且指定变量文件不相同。

---
- hosts: build_server

serial: 1

vars_files:

- group_vars/staging/build_server.yml

roles:

- build

- hosts: web_server_sh

remote_user: root

serial: 1

vars_files:

– group_vars/staging/web_server_sh.yml

roles:

- publish

- hosts: web_server_bj

remote_user: root

serial: 1

vars_files:

- group_vars/staging/web_server_bj.yml

roles:

- publish

library目录则为自定义插件,可直接在playbook中使用,slb_op.py为自定义的集群拉入拉出模块。

六、总结

  1. ansible 很好的帮助了我们解决了自动化部署发布的事情,现在项目同步更新到几个机房,已经只需要几分钟就可以完成,节省了许多人力。
  2. 在部署发布工具的选择上,工具没有好坏,应该结合自身项目来选择,都能够很好地提高工作效率。
  3. ansible解决了燃眉之急,而目前已经很好地与jenkins、docker结合,当集群数量越来越多,越来越难以维护时,是否需要更换工具,或是结合最新技术,都是一个考验的难题。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏知晓程序

开发 | 只需一步!教你如何轻松部署小程序后端

利用它,你可以在「微信 web 开发者工具」中,直接完成后端代码编写、腾讯云部署等一系列操作。

5234
来自专栏依乐祝

.NET Core实战项目之CMS 第七章 设计篇-用户权限极简设计全过程

接下来我们就正式进入.NET Core实战项目之CMS的设计篇了。在设计篇呢,我们需要对数据库进行设计,而数据库的设计又分为功能部分设计以及用户权限部分设计。作...

892
来自专栏Java架构

深入理解高并发下分布式事务的解决方案

分布式事务就是指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。以上是百度百科的解释,简单的说,就是一次大的操作...

1092
来自专栏Python攻城狮

GitHub 系列之「团队合作利器 Branch」1.什么是分支?2.分支的常用操作3.基本的团队协作流程4.Git Flow

Git 相比于 SVN 最强大的一个地方就在于「分支」,Git 的分支操作简直不要太方便,而实际项目开发中团队合作最依赖的莫过于分支了,关于分支前面的系列也提到...

801
来自专栏大数据学习笔记

Java软件工程师面试题汇总(持续更新)

实战问题 1、一个请求超过20秒了,你怎么排查和解决; 2、说说你觉得做的比较不错的项目,讲一下项目结构和用到的框架,再说一下为什么要选择这些框架; 3、“商品...

22310
来自专栏游戏杂谈

两块网卡实现多台机器共享上网

组建局域网内部网络,遇到的问题:购买电信的宽带,多人拨号肯定是不行的(貌似同时超过4台机器拨一个号就自动被断开网络了)。

1271
来自专栏JAVA高级架构

高并发面试必问:分布式消息系统Kafka简介

2473
来自专栏Timhbw博客

自用图片压缩工具推荐(优化博客加载速度)

2016-03-2318:22:27 发表评论 609℃热度 之前wordpress写博客时文章里面的图片都是上传到服务器中,以前以为这样省事,都是原图上传,...

45712
来自专栏码匠的流水账

oauth2四种授权方式小结

9062
来自专栏java思维导图

从一笔金币充值去思考分布式事务

考虑支付重构的时候,自然想到原本属于一个本地事务中的处理,现在要跨应用了要怎么处理。拿充值订单举个栗子吧,假设:原本订单模块和账户模块是放在一起的,现在需要做服...

914

扫码关注云+社区

领取腾讯云代金券