ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet、cfengine、chef、func、fabric)的优点,实现了批量系统配置、批量程序部署、批量运行命令等功能。
ansible是基于模块工作的,本身没有批量部署的能力。真正具有批量部署的是ansible所运行的模块,ansible只是提供一种框架。主要包括:
(1)、连接插件connection plugins:负责和被监控端实现通信;
(2)、host inventory:指定操作的主机,是一个配置文件里面定义监控的主机;
(3)、各种模块核心模块、command模块、自定义模块;
(4)、借助于插件完成记录日志邮件等功能;
(5)、playbook:剧本执行多个任务时,非必需可以让节点一次性运行多个任务。
Ansible结构
1、连接插件`connection plugins`用于连接主机 用来连接被管理端 2、核心模块`core modules`连接主机实现操作, 它依赖于具体的模块来做具体的事情 3、自定义模块`custom modules`根据自己的需求编写具体的模块 4、插件`plugins`完成模块功能的补充 5、剧本`playbook`ansible的配置文件,将多个任务定义在剧本中,由ansible自动执行 6、主机清单`inventor`定义ansible需要操作主机的范围 最重要的一点是 ansible是模块化的 它所有的操作都依赖于模块
Ansible的执行流程
1.Ansible读取playbook剧本,剧本中会记录对哪些主机执行哪些任务。 2.首先Ansible通过主机清单找到要执行的主机,然后调用具体的模块。 3.其次Ansible会通过连接插件连接对应的主机并推送对应的任务列表。 4.最后被管理的主机会将Ansible发送过来的任务解析为本地Shell命令执行。
安装ansible
yum install ansible -y ansible <host-pattren> [options] --version #ansible版本信息 -v #显示详细信息 -i #主机清单文件路径,默认是在/etc/ansible/hosts -m #使用的模块名称,默认使用command模块 -a #使用的模块参数,模块的具体动作 -k #提示输入ssh密码,而不使用基于ssh的密钥认证 -C #模拟执行测试,但不会真的执行 -T #执行命令的超时 主机名 wanip lanip 角色 m01 10.0.1.61 172.16.1.61 控制端 web01 10.0.1.7 172.16.1.7 被控制端 web02 10.0.1.8 172.16.1.8 被控制端
Ansible配置文件读取顺序
[root@m01 ~]# vim /etc/ansible/ansible.cfg # nearly all parameters can be overridden in ansible-playbook # or with command line flags. ansible will read ANSIBLE_CONFIG, # ansible.cfg in the current working directory, .ansible.cfg in # the home directory or /etc/ansible/ansible.cfg, whichever it # finds first [root@m01 ~]# rpm -ql ansible [root@m01 ~]# zcat /usr/share/man/man1/ansible-config.1.gz #要查看完整列表,请访问https://docs.ansibe.com/或使用ansibe-config命令。 For a full list check \fI\%https://docs.ansible.com/\fP\&. or use the \fIansible\-config\fP command. #/etc/ansible/ansible.cfg 配置文件,如果存在则使用 /etc/ansible/ansible.cfg \-\- Config file, used if present #~/.ansible.cfg 用户配置文件,覆盖默认配置(如果存在) ~/.ansible.cfg \-\- User config file, overrides the default config if present #\&/ansible.cfg 本地配置文件(在当前工作目录中)假定为(aqproject-specific)(aq,如果存在,则重写其余文件)。 \&./ansible.cfg \-\- Local config file (in current working directory) assumed to be \(aqproject specific\(aq and overrides the rest if present. #如上所述,ANSIBLE_CONFIG环境变量将覆盖所有其他环境变量。 As mentioned above, the ANSIBLE_CONFIG environment variable will override all others. 1、$ANSIBLE_CONFIG 2、./ansible.cfg 3、~/.ansible.cfg 4、/etc/ansible/ansible.cfg
Ansible配置文件详解
基于密码连接
[root@m01 ~]# cat /etc/ansible/hosts #方式一、IP+端口+用户+密码 [webs] 10.0.0.7 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass='1' 10.0.0.8 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass='1' #方式二、主机名+密码 [webs] web0[1:2] ansible_ssh_pass='123456' #方式三、主机+端口+密码 [webs] web0[1:2] [webs:vars] ansible_ssh_pass='123456' [root@m01 ~]# ansible webs -m ping -i ./hosts 10.0.0.8 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" } 10.0.0.7 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" }
基于密钥连接,需要先创建公钥和私钥,并下发公钥至被控端
#创建秘钥对 [root@m01 ~]# ssh-keygen #推送公钥 [root@m01 ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub root@172.16.1.7 [root@m01 ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub root@172.16.1.8 #方式一、主机+端口+密钥 [webs] 10.0.0.7:22 10.0.0.8 [root@m01 ~]# ansible webs -m ping -i ./hosts 10.0.0.8 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" } 10.0.0.7 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" } #方式二、别名+主机+端口+密钥 [webs] web01 ansible_ssh_host=10.0.0.7 ansible_ssh_port=22 web02 ansible_ssh_host=10.0.0.8 [root@m01 ~]# ansible webs -m ping -i ./hosts web02 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" } web01 | SUCCESS => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": false, "ping": "pong" }
主机组使用方式
[root@m01 ~]# vim hosts [db_group] db01 ansible_ssh_host=10.0.0.51 db02 ansible_ssh_host=10.0.0.52 [web_group] web01 ansible_ssh_host=10.0.0.7 web02 ansible_ssh_host=10.0.0.8 #查看指定组内主机数量 [root@m01 ~]# ansible web_group -m ping -i ./hosts --list-host hosts (2): web01 web02 [root@m01 ~]# ansible db_group -m ping -i ./hosts --list-host hosts (2): db01 db02 #方式一、主机组变量+主机+密码 [db_group] db01 ansible_ssh_host=10.0.0.51 db02 ansible_ssh_host=10.0.0.52 [db_group:vars] ansible_ssh_pass='1' #方式二、主机组变量+主机+密钥 [web_group] web01 ansible_ssh_host=10.0.0.7 web02 ansible_ssh_host=10.0.0.8 #定义多组,多组汇总整合 # lnmp组包括两个子组[db,web] [lnmp:children] db_group web_group #最终配置文件 [root@m01 ~]# cat hosts [db_group] db01 ansible_ssh_host=10.0.0.51 db02 ansible_ssh_host=10.0.0.52 [web_group] web01 ansible_ssh_host=10.0.0.7 web02 ansible_ssh_host=10.0.0.8 [lnmp:children] db_group web_group #查看多组 [root@m01 ~]# ansible all -m ping -i ./hosts --list-host hosts (4): db01 db02 web01 web02 [root@m01 ~]# ansible lnmp -m ping -i ./hosts --list-host hosts (4): db01 db02 web01 web02
ad-hoc模式的命令使用
命令格式 | ansible | web01 | -m | command | -a | free -h |
格式说明 | 命令 | 主机名称 | 指定模块 | 模块名称 | 模块动作 | 具体命令 |
查看磁盘信息
[root@m01 ~ ]# ansible webs -m command -a 'df -h' 10.0.1.8 | CHANGED | rc=0 >> 文件系统 容量 已用 可用 已用% 挂载点 /dev/sda3 20G 1.8G 18G 10% / devtmpfs 477M 0 477M 0% /dev tmpfs 488M 0 488M 0% /dev/shm tmpfs 488M 7.7M 480M 2% /run tmpfs 488M 0 488M 0% /sys/fs/cgroup /dev/sda1 197M 102M 95M 52% /boot tmpfs 98M 0 98M 0% /run/user/0 10.0.1.7 | CHANGED | rc=0 >> 文件系统 容量 已用 可用 已用% 挂载点 /dev/sda3 20G 1.8G 18G 10% / devtmpfs 477M 0 477M 0% /dev tmpfs 488M 0 488M 0% /dev/shm tmpfs 488M 7.7M 480M 2% /run tmpfs 488M 0 488M 0% /sys/fs/cgroup /dev/sda1 197M 102M 95M 52% /boot tmpfs 98M 0 98M 0% /run/user/0
command
# 默认模块, 执行命令 可忽略不写 [root@m01 ~]# ansible webs -a "hostname"
shell
# 如果需要一些管道操作,则使用shell,基本命令 [root@m01 ~]# ansible webs -m shell -a "ps -ef|grep nginx"
script
# 编写脚本 [root@m01 ~]# vim /root/yum.sh #!/usr/bin/bash yum install -y httpd #在本地运行模块,等同于在远程执行,不需要将脚本文件进行推送目标主机执行 [root@m01 ~]# ansible webs -m script -a "/root/yum.sh"
yum
[root@m01 ~]# ansible webs -m yum -a "name=httpd state=present" name httpd #指定要安装的软件包名称 file:// #指定本地安装路径(yum localinstall 本地rpm包) http:// #指定yum源(从远程仓库获取rpm包) state #指定使用yum的方法 installed,present #安装软件包 removed,absent #移除软件包 latest #安装最新软件包 [root@m01 ~]# ansible-doc yum exclude=kernel*,foo* #排除某些包 list=ansible #类似于yum list查看是否可以安装 disablerepo="epel,ol7_latest" #禁用指定的yum仓库 download_only=true #只下载不安装 yum install d
copy
# 推送文件模块 [root@m01 ~]# ansible webs -m copy -a "src=/etc/passwd dest=/tmp/oldboy.txt" # 在推送覆盖远程端文件前,对远端已有文件进行备份,按照时间信息备份 [root@m01 ~]# ansible webs -m copy -a "src=/etc/passwd dest=/tmp/oldboy.txt backup=yes" # 直接向远端文件内写入数据信息,并且会覆盖远端文件内原有数据信息 [root@m01 ~]# ansible webs -m copy -a "content='oldboy' dest=/tmp/oldboy.txt" src #推送数据的源文件信息 dest #推送数据的目标路径 backup #对推送传输过去的文件,进行备份 content #直接批量在被管理端文件中添加内容 group #将本地文件推送到远端,指定文件属组信息 owner #将本地文件推送到远端,指定文件属主信息 mode #将本地文件推送到远端,指定文件权限信息
fetch模块
# 拉取文件模块 [root@m01 ~]# ansible webs -m fetch -a "src=/etc/passwd dest=/tmp/oldboy.txt flat: yes"
service、systemd
#启动httpd并加入开机自启 [root@m01 ~]# ansible webs -m systemd -a "name=httpd state=started enabled=yes" #停止httpd并删除开机自启 [root@m01 ~]# ansible webs -m systemd -a "name=httpd state=stopped enabled=no" name # 定义要启动服务的名称 state # 指定服务状态 started #启动服务 stopped #停止服务 restarted #重启服务 reloaded #重载服务 enabled #开机自启
file⽂件模块
创建文件夹 ansible all -m file -a "path=/opt/ajie state=directory" 创建文件并更改属性 ansible all -m file -a "path=/opt/ajie state=directory owner=ajie group=ajie mode=755" 创建软连接 ansible all -m file -a "src=/opt/ajie dest=/opt/aj state=link" 删除文件夹 ansible all -m file -a "path=/opt/aj state=absent" 递归更改文件权限 ansible all -m file -a "path=/opt/data owner=ajie group=ajie recurse=yes" 参数说明: path: ⽬标⽂件或⽂件夹 state: ⽬标状态 - directory 创建⽬录 - file 创建⽂件 - link 创建软链接 absent: 删除⽂件或⽬录 recurse: 递归修改
group模块
创建⽤户组 ansible all -m group -a "name=www gid='666'"参数说明: name: 组名gid: 指定gidstate: - absent 删除组 - present 创建组
user模块
创建⽤户指定uid,gid,不创建家⽬录也不允许登陆 ansible all -m user -a "name=www uid='666' group=www create_home=no shell=/sbin/nologin" 参数说明: uid #指定⽤户的 uid group #指定⽤户组名称 groups #指定附加组名称 password #给⽤户添加密码 shell #指定⽤户登录 shell create_home #是否创建家⽬录
cron定时任务
创建测试脚本 cat echo_hostname.sh #!/bin/bash echo "$(data +%M:%S) $(hostname)" >>/tmp/hostname.txt ansible使用cron模块创建任务并指定名称 ansible all -m cron -a "name='echo_hostname' job='/bin/bash /opt/echo_hostname.sh'" 修改指定名称的定时任务 ansible all -m cron -a "name=hostnaem minute='*/5' job='/bin/bash /opt/echo_hostname.sh' disabled=yes" 打开⼀条注释的任务 ansible all -m cron -a 'name="echo_hostname" minute="*/5" job="/bin/bash /opt/echo_hostname.sh" disabled=no' 删除指定名称为Node的定时任务 ansible all -m cron -a 'name="None" state=absent' 删除指定名称的定时任务 ansible all -m cron -a 'name="echo_hostname" state=absent
mount模块
shell命令挂载 mount -t nfs 172.17.1.31:/data /data 挂载⼀个⽬录并写⼊fstab ansible web -m mount -a "src=172.16.1.31:/data path=/data fstype=nfs state=mounted" 只写⼊fstab但是不挂载 ansible web -m mount -a "src=172.16.1.31:/data path=/data fstype=nfs state=present" 卸载已经挂载的⽬录并删除fstab条⽬ ansible web -m mount -a "path=/data state=absent" 卸载已经挂载的⽬录但是不删除fstab条⽬ ansible web -m mount -a "path=/data state=unmounted" 参数说明: src NFS服务器远程挂载地址 path 本地挂载⽬录 state: - absent #卸载并删除fstab条⽬ - mounted #挂载并写⼊fstab - present #不挂载,只写⼊fstab - unmounted #卸载设备,但不删除fstab条⽬ - remounted #强制重新挂载
unarchive解压模块
解压远程服务器的压缩包到指定⽬录 将管理机的压缩包解压到⽬标主机指定⽬录 ansible all -m unarchive -a "src=/root/script/txt.tar.gz dest=/opt/" 将⽬标主机⾃⼰本机压缩包解压到⽬标主机指定⽬录 ansible all -m unarchive -a "src=/tmp/txt.tar.gz dest=/tmp/ remote_src=yes"
archive压缩模块
压缩⽂件到指定⽬录 ansible all -m archive -a "path=/opt/*.txt dest=/tmp/opt.tar.gz" 压缩⽂件到指定⽬录并指定格式 ansible all -m archive -a "path=/opt/*.txt dest=/tmp/opt.zip format=zip" 压缩多个⽂件到指定⽬录 ansible all -m archive -a "path=/opt/1.txt,/opt/3.txt dest=/tmp/txt.tar.gz"