第10章:深入浅出Ansible
1.Ansible介绍
1).Ansible的优点
Ansible是一个简单的自动化引擎,可完成配置管理、引用部署、服务编排以及其他各种IT需求
Ansible是Python开发并实现的开源软件,其依赖Jinja2,paramiko和PyYAML这几个Python库
安装部署简单
基于SSH进行配置管理
Ansible不需要守护进程
日志集中存储
Ansible简单易用
Ansible功能强大
Ansible设计优秀
Ansible对云计算和大数据平台都有很好的支持
2).Ansible与Fabric之间比较
Fabric像是一个工具箱,提供了很多好用的工具用于在远程服务器执行命令
Ansible提供了一套简单的流程,只需要按照它的流程来做就能轻松完成任务
Fabric是库,Ansible是框架
Fabric简单,Ansible复杂
Fabric通过SSH执行简单的命令,Ansible将模块拷贝到远程服务器后执行,执行完以后删除模块
Fabric需要Python编程背景,Ansible不需要
Fabric需要写代码,Ansible只需要编写YAML格式的配置文件来描述要做的事情
Fabric提供了基本的接口,业务逻辑需要用户自己实现,Ansible提供了大量模块,用户只需要学习模块的用法即可
3).Ansible与SaltStack之间比较
Ansible安装部署简单,SaltStack需要安装客户端接收服务端发过来的命令
SaltStack相应速度更快,Ansible使用标准SSH连接,而SaltStack使用ZeroMQ进行通信和传输
Ansible更安全,Ansible使用标准SSH连接传输数据,不需要在远程主机上启动守护进程
SaltStack对Windows支持比较友好
Ansible自身运维比较简单,SaltStack需要在Master和Minion主机启动一个守护进程
2.Ansible使用入门
1).安装Ansible
pip install ansible
2).Ansible的架构
Ansible的编排引擎由Inventory、API、Modules(模块)和Plugins组成
工程师将需要在远程服务器执行的操作写在Ansible Playbook中,然后使用Ansible执行Playbook中的操作
3).Ansible的运行环境
Ansible会默认读取/etc/ansible/hosts文件中配置的远程服务器列表 # mkdir /etc/ansible # cat /etc/ansible/hosts [test] 192.168.1.101 192.168.1.102 192.168.1.103 # ansible test -m ping 192.168.1.101 | SUCCESS => { "changed": false, "ping": "pong" } 192.168.1.102 | SUCCESS => { "changed": false, "ping": "pong" } 192.168.1.103 | SUCCESS => { "changed": false, "ping": "pong" }
4).Ansible的ad-hoc模式
Ansible的ad-hoc模式,通过ansible命令执行操作的方式,称为ad-hoc # ansible test -m command -a "hostname" # ansible test -m command -a "whoami" 将本地文件拷贝到服务器中: # ansible test -m copy -a "src=/etc/ansible/hosts dest=/tmp/hosts" 修改文件的所有者和权限: # ansible all -m file -a "dest=/tmp/hosts mode=500 owner=mysql group=mysql" -become -become参数类似于Linux命令下的sudo 在远程服务器中安装软件: # ansible test -m yum -a "name=git state=present" -become
5).使用playbook控制服务器
在实际的生产环境中,我们一般将远程服务器需要做的事情写在一个YAML配置文件中 YAML文件称为Ansible Playbook # cat test_playbook.yaml --- - hosts : test become : yes become_method : sudo tasks : - name : copy file copy : src=/etc/ansible/hosts dest=/tmp/data.txt - name : change mode file : dest=/tmp/data.txt mode=500 owner=mysql group=mysql - name : ensure packages installed yum : pkg="{{ item }}" state=present with_items : - git # ansible-playbook test_playbook.yaml
3.Inventory管理
1).hosts文件位置
在Ansible中,将可管理的服务器集合称为Inventory Inventory管理便是服务器管理 默认读取/etc/ansible/hosts文件 通过命令行参数的-i指定hosts文件 通过ansible.cfg文件中的inventory选项指定hosts文件
2).动态Inventory获取
# cat hosts.py import argparse import json from collections import defaultdict from contextlib import contextmanager import pymysql def to_json(in_dict): return json.dumps(in_dict, sort_keys=True, indent=2) @contextmanager def get_conn(**kwargs): conn = pymysql.connect(**kwargs) try: yield conn finally: conn.close() def parse_args(): parser = argparse.ArgumentParser(description='OpenStack Inventory Module') group = parser.add_mutually_exclusive_group(required=True) group.add_argument('--list', action='store_true', help='List active servers') group.add_argument('--host', help='List details about the specific host') return parser.parse_args() def list_all_hosts(conn): hosts = defaultdict(list) with conn as cur: cur.execute('select * from hosts') rows = cur.fetchall() for row in rows: no, host, group, user, port = row hosts[group].append(host) return hosts def get_host_detail(conn, host): details = {} with conn as cur: cur.execute("select * from hosts where host='{0}'".format(host)) rows = cur.fetchall() if rows: no, host, group, user, port = rows[0] details.update(ansible_user=user, ansible_port=port) return details def main(): parser = parse_args() with get_conn(host='127.0.0.1', user='root', passwd='msds007', db='test') as conn: if parser.list: hosts = list_all_hosts(conn) print(to_json(hosts)) else: details = get_host_detail(conn, parser.host) print(to_json(details)) if __name__ == '__main__': main()
4.YAML语法
1).语法规则
YAML文件的第一行为"---",表示是一个YAML文件 YAML中的字段大小写敏感 YAML与Python一样,使用缩进表示层级关系 YAML的缩进不允许使用Tab键,只允许使用空格,且空格的数目不重要,只要相同层次的元素左对齐即可 :冒号前后要有空格 #表示注释,从这个字符一直到行尾都会被解析器忽略
2).支持的数据格式
对象:键值对的集合,又称为映射,类似于Python中的字典
数组:一组按次序排列的值,又称为序列(sequence),类似于Python中的列表
纯量:单个的、不可再分的值,如字符串、布尔值于数字
3).解析
pip install PyYAML 使用PyYAML库解析YAML文件非常简单 import yaml with open('data.yaml') as f: print(yaml.load(f)) # cat data.yaml --- name : Example Developer job : Developer skill : Elite employed : True foods: - Apple - Orange - Strawberry - Mango languages: ruby : Elite python : Elite dotnet : Lame
5.Ansible模块
1).Ansible的模块工作原理
1)将模块拷贝到远程服务器 2)执行模块定义的操作,完成对服务器的修改 3)在远程服务器中删除模块
2).常用的Ansible模块
1.ping 2.远程命令模块command 3.file 4.copy 5.user/group 6.yum 7.get_url 8.unarchive 9.git
3).模块的返回值
changed
failed
6.Playbook
1).Playbook的定义
在Ansible中,将各个模块组合起来的文件是一个YAML格式的配置文件,这个配置文件,在Ansible中称为Playbook
Ansible中的Playbook类似于Linux下的Shell脚本文件
2).使用ansible-playbook
# cat test_playbook.yaml --- - hosts : test become : yes become_method : sudo tasks : - name : copy file copy : src=/py/data.txt dest=/tmp/data.txt - name : change mode file : dest=/tmp/data.txt mode=500 owner=mysql group=mysql - name : ensure packages installed yum : pkg="{{ item }}" state=present with_items : - git # ansible-playbook test_playbook.yaml
3).Playbook的详细语法
1.权限 在Ansible中,默认使用当前用户连接远程服务器执行操作,我们可以在ansible.cfg文件中配置连接远程服务器的默认用户 2.通知 3.变量 4.Facts变量 Facts变量是Ansible执行远程部署之前从远程服务器中获取的系统信息,包括服务器的名称、IP地址、操作系统、分区信息、硬件信息等 Facts变量可以配合Playbook实现更加个性化的功能需求 访问复杂变量的Playbook: --- - hosts : test gather_facts : yes tasks : - shell : echo {{ ansible_eth0 ["ipv4"] ["address"] }} register : myecho - debug : var=myecho.stdout_lines - shell : echo {{ ansible_eth0.ipv4.address }} register : myecho - debug : var=myecho.stdout_lines 5.循环 # cat test_playbook.yaml --- - hosts : test become : yes become_method : sudo tasks : - name : Installed MySQL Package yum : pkg="{{ item }}" state=installed with_items : - mysql-server - MySQL-python - libselinux-python - libsemanage-python # ansible-playbook test_playbook.yaml 6.条件 在Playbook中可以通过when选项执行条件语句,when类似于if语句 7.任务执行策略
4).使用Playbook部署ngix
# cat deploy_nginx.yaml --- - hosts: test become: yes become_method: sudo vars: worker_processes: 4 worker_connections: 768 max_open_files: 65506 tasks: - name: install nginx yum: name=nginx update_cache=yes state=present - name: copy nginx config file template: src=/py/nginx.conf.j2 dest=/etc/nginx/nginx.conf - name: copy index.html template: src: /py/index.html.j2 dest: /usr/share/nginx/html/index.html mode: 0644 notify: restart nginx handlers: - name: restart nginx service: name=nginx state=restarted # ansible-playbook depoly_nginx.yml
5).使用Playbook部署MongoDB
# cat mongo.yml --- - hosts: test become: yes become_method: sudo vars: mongodb_datadir_prefix: /data mongod_port: 27018 tasks: - name: Create the mongodb user user: name=mongodb comment="MongoDB" - name: Create the data directory for the namenode metadata file: path={{ mongodb_datadir_prefix }} owner=mongodb group=mongodb state=directory - name: Install the mongodb package yum: name={{ item }} state=installed with_items: - mongodb-server - mongodb - name: create data directory for mongodb file: path: "{{ mongodb_datadir_prefix }}/mongo-{{ ansible_hostname }}" state: directory owner: mongodb group: mongodb - name: create log directory for mongodb file: path=/var/log/mongo state=directory owner=mongodb group=mongodb - name: Create the mongodb startup file template: src=mongod.j2 dest=/etc/init.d/mongod-{{ ansible_hostname }} mode=0655 - name: Create the mongodb configuration file template: src=mongod.conf.j2 dest=/etc/mongod-{{ ansible_hostname }}.conf - name: Copy the keyfile for authentication copy: src=secret dest={{ mongodb_datadir_prefix }}/secret owner=mongodb group=mongodb mode=0400 - name: Start the mongodb service command: creates=/var/lock/subsys/mongod-{{ ansible_hostname }} /etc/init.d/mongod-{{ ansible_hostname }} start # ansible-playbook mongo.yml
7.role的定义与使用
role并不是某一个具体的东西,而是一个规范与抽象,是一种将复杂的Playbook分割成多个文件的机制
Ansible从复杂的Playbook中抽象出了role的概念,并在Playbook提供了roles选项来使用role,在命令行提供了ansible-galaxy命令来创建、删除和查看role
所谓role,只是一种规范的文件组织方式。每个Ansible的role都会有一个名字,比如mongodb,与mongodb role相关的文件都存放在/etc/ansible/roles/mongodb目录下
8.Ansible的配置文件
1).配置文件的查找路径
配置文件的查找路径 Ansible命令行工具使用的配置文件是/etc/ansible/ansible.cfg文件 一般将所有的role、Playbook、Inventory文件、ansible.cfg文件保存在一个版本控制的库中 在Ansible中,可以有多种方式使用ansible.cfg文件。Ansible查找ansible.cfg文件的顺序如下: 1)ANSIBLE_CONFIG环境变量指定的配置文件 2)当前目录下的ansible.cfg文件 3)当前用户home目录下的.ansible.cfg文件 4)Ansible默认的/etc/ansible/ansible.cfg文件
2).Ansible中的常用配置
1.默认配置 inventory remote_user remote_port private_key_file roles_path log_path host_key_checking forks gathering 2.ssh连接配置 ssh_args pipelining control_path 3.权限提升配置 become become_method become_user become_ask_pass