Ansible
ansible是个什么东西呢?官方的title是“Ansible is Simple IT Automation”——简单的自动化IT工具。这个工具的目标有这么几项:让我们自动化部署APP;自动化管理配置项;自动化的持续交付;自动化的(AWS)云服务管理,基于 paramiko 开发。
这个paramiko是什么呢?它是一个纯Python实现的ssh协议库。所以就不需要在远程主机上安装client/agents,因为它们是基于ssh来和远程主机通讯的。
安装
以centos为例
1 | sudo yum install ansible |
安装完成,配置文件默认在/etc/ansible/ansible.cfg
为了方便后续的开发,需要修改配置文件
1 2 3 4 | #失败后不在本地生成retry文件,终端也不输出 retry_files_enabled = False #将执行过程及结果以json形式返回 stdout_callback = json |
Inventory文件
Ansible 可同时操作属于一个组的多台主机,组和主机之间的关系通过 inventory 文件配置. 默认的文件路径为 /etc/ansible/hosts
除默认文件外,你还可以同时使用多个 inventory 文件,也可以从动态源,或云上拉取 inventory 配置信息.
以本次项目为例,我们需要从云端查询线上机器IP列表(例如:阿里云SLB下的具体ECS IP列表),最后以JSON格式返回
1 2 3 4 5 6 7 8 9 10 | $ cat . /hosts .py #!/usr/bin/python import json #为了演示方便,此处使用初始化好的ip文件 list_txt_file= "/home/git/deploylist.txt" f= open (list_txt_file, 'r' ) ips={ "hosts" :[]} for line in f.readlines(): ips[ "hosts" ].append(line.strip()) print json.dumps(ips) |
给文件加上可执行权限
1 | $ chmod +x . /hosts .py |
执行查看输出
1 2 | $ . /hosts .py { "hosts" : [ "192.168.x.x" , "..." ]} |
Playbooks
Playbooks 是 Ansible的配置,部署,编排语言.他们可以被描述为一个需要希望远程主机执行命令的方案,或者一组IT程序运行的命令集合.
如果 Ansible 模块你是工作室中的工具,那么 playbooks 就是你设置的方案计划.
Playbooks使用yaml文件管理ansible命令。
接下来可以编写我们的部署逻辑,检测项目根目录是否存在,不存在则创建,最后更新版本库代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | --- - hosts: all remote_user: git tasks: - name: check www stat: path="{{www_dir}}" register: www_stat - name: init www file: path: "{{www_dir}}" state: directory owner: git group: git recurse: yes when: not www_stat.stat.exists - name: update code git: repo: "{{repo}}" dest: "{{www_dir}}" accept_hostkey: yes version: "{{version}}" update: yes key_file: /home/git/.ssh/id_rsa become_user: git |
此yaml会接收三个参数
www_dir: 部署目标路径
repo: Git版本库
version: Git版本号,可以使具体的版本号,也可以是分支或master
注意:此处git授权使用秘钥,所以git server需要预先设置好对git用户的认证(/home/git/.ssh/id_rsa),一般情况下,所有的线上机器都会使用同一个SSH秘钥,方便机器的SSH管理及GIT管理。
我们使用终端测试功能是否能正常运行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | $ ansible-playbook -i . /hosts .py . /deploy .yml --extra-vars 'version=master&repo=git@gitlab.a.com:test.git&www_dir=/home/git/demo8' { "plays" : [ { "play" : { "id" : "00163e0a-7e89-518c-8220-000000000008" , "name" : "all" }, "tasks" : [ { "hosts" : { ... ], "stats" : { "192.168.x.x" : { "changed" : 3, "failures" : 0, "ok" : 0, "skipped" : 0, "unreachable" : 0 } } } |
我们关注stats ok及failures数据即可。
CGI
接下来我们使用Apache cgi来搭建我们的WEB部署接口。
1 | sudo yum install httpd |
修改apache配置文件,以支持cgi运行
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | $ vi /etc/httpd/conf/httpd .conf Listen 8080 ScriptAlias /cgi/ "/home/git/httpd/cgi/" <Directory "/home/git/httpd/cgi" > # AllowOverride None #Options None Options +ExecCGI # Order allow,deny # Allow from all < /Directory > AddHandler cgi-script .cgi .py LoadModule cgi_module modules /mod_cgi .so LoadModule cgid_module modules /mod_cgid .so DocumentRoot "/home/git/httpd" <Directory "/home/git/httpd" > Options Indexes FollowSymLinks AllowOverride None Order allow,deny Allow from all < /Directory > |
启动并测试Apache运行是否正常,假设服务器内网IP为192.168.0.1
1 2 3 |
最后编写我们的cgi脚本,用来接收POST参数并调用本机的ansible-playbook部署代码并返回执行结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | #!/usr/bin/python #cgi文件必须要声明的mime类型 print "Content-Type:application/json; Charset=utf-8\n\n" import cgi, cgitb, json, sys, commands, time, random default_dir = '/home/git/www' default_ver = 'HEAD' error_log = '/home/git/logs/cgi/%s' form = cgi.FieldStorage() repo = form.getvalue( 'repo' ) www_dir = form.getvalue( 'www_dir' ) version = form.getvalue( 'version' ) if not version: version = default_ver if not www_dir: www_dir = default_dir if not repo: print json.dumps({ "err_code" : 400 , "err_msg" : "Bad Args" }) sys.exit() command = "/usr/local/bin/ansible-playbook -i /home/git/ansible/hosts.py /home/git/ansible/deploy.yml --extra-vars 'repo=%s www_dir=%s version=%s'" % (repo, www_dir, version) status,deploy_ret = commands.getstatusoutput(command) ret_json = json.loads(deploy_ret) if not ret_json.has_key( 'stats' ): print json.dumps({ "err_code" : 500 , "err_msg" : "SysError" , "err_trace" :deploy_ret}) sys.exit() ret = { "success" :{ "list" :[]}, "error" :{ "list" :[], "debug" :[]}} err_count = 0 for ip in ret_json[ 'stats' ]: is_error = ret_json[ 'stats' ][ip][ 'failures' ] if is_error: ret[ 'error' ][ 'list' ].append(ip) ret_json[ 'stats' ][ip][ 'ip' ] = ip ret[ 'error' ][ 'debug' ].append(ret_json[ 'stats' ][ip]) err_count = err_count + 1 else : ret[ 'success' ][ 'list' ].append(ip) if err_count: error_file = error_log % ( time.strftime( "%Y-%m-%d-%H-%M-%S" , time.localtime())) fo = open (error_file, 'a+' ) fo.write(deploy_ret) fo.close() print json.dumps(ret) |
测试接口功能
1 2 | $ curl -d 'version=master&repo=git@gitlab.a.com:test.git&www_dir=/home/git/demo8' 'http://192.168.0.1:8080/cgi/deploy.py' { "success" : { "list" : [ "192.168.x.x" , "192.168.x.x" , "xxx" ]}, "error" : { "debug" : [], "list" : []}} |
接下来我们就可以在前端结合gitlab api以及我们的部署API,进行可视化展示、部署、回滚等操作,这里就不在赘述了。
- 正在加载用户留言,请稍后~