ansible自动化管理
主机清单 inventory
没有添加主机清单的报错
在主机清单文件中添加主机 (地址: /etc/ansible/hosts)
vim /etc/ansible/hosts
简单的添加一条主机,输入主机IP 192.168.1.3
保存退出 重新执行命令
由于ansible是通过ssh访问被执行端主机的,因此没有ssh的权限是无法完成任务的,即使这里的命令是ping,但依旧要走ssh的流程
这里的ping并不是linux下的ping ,而是ansible工具下面的ping
如果我们没有具体的key 我们可以使用root用户登录
就和我们使用ssh 远程登录主机一样
ssh root@192.168.1.3
ansible同样也使用了这样的方法 -k使用用户登录
访问多台主机
ansible 192.168.1.3,192.168.1.4 -m ping -k
存在的问题:输账号密码的方式只适用于我们访问单台主机,访问多台主机,如果我们的密码是统一的则没有问题,因为ansible是会对其中的每一个ip都执行一边ansible ip -m ping -k ,但如果密码不一致,则至少会有一台无法访问,因此我们需要是用ssh来统一密钥
使用ansible登录时,他会指定当前用户登录,如果我们需要修改用户,可以使用-u来切换用户
ansible 192.168.1.3 -u root -m ping -k
控制主机清单内的所有主机
主机清单中一旦主机过多,会很麻烦,因此可以使用all
ansible all -m ping
清单分组
对于不同的主机列表,我们可以再清单中对其进行分组
[websevr]
192.168.0.1
192.168.0.2
[dbsevr]
192.168.10.9
192.168.10.10
[appsevr]
192.168.1.10[1:3] --> 表示192.168.1.101,192.168.1.102,192.168.1.103
192.168.1.22:8081
db-[s:f]:example.com
# 根据列表中的组来
ansible appsevr -m ping
ansible 参数选项
使用ansib --help 查看帮助文档
使用ansible-doc --help 查看模块帮助文档
这里我们先来讲一下ansible中的参数选项
-h --help 显示帮助信息
-i INVENTORY 指定inventory文件,多个文件使用逗号分隔,默认为/etc/ansible/hosts
https://www.cnblogs.com/f-ck-need-u/p/7550603.html
ansible中的主配置文件
(地址: /etc/ansible/ansible.cfg)
介绍一些其中的配置内容
其中local_tmp是本地的执行指令,remote_tmp是远程的执行指令,当用户使用ansible控制被控端执行指令的时候,他会先将内容放在local_tmp文件中,然后上传到被控端并生成remote_tmp上执行。执行完成之后会删除这两个tmp文件
#library = /usr/share/my_modules/ 库存放地址
#forks = 5 默认并发数
#sudo_user = root 默认sudo 用户
#ask_sudo_pass = True 每次执行ansible是否询问ssh密码
#ask_pass = True
#remote_port = 22
## ------------建议取消注释
#host_key_checking = False 检查对应服务器的host_key
#log_path=/var/log/ansible.log 日志文件
ansible中的其他工具
ansible中的所有工具都存放再/usr/bin/ 下面
显示帮助模块
ansible-doc [options] [module..]
-a 显示所有模块的文档 参数尽量放在单引号里面
-l --list 列出可用模块
-s --snippet xxx 显示xxx模块的playbook片段
role扩展模块
ansible-galaxy专门有一个网站提供不同用户上传的"角色"
地址:https://galaxy.ansible.com/
# 列出所有已安装的galaxy
ansible-galaxy list
# 安装galaxy
ansible-galaxy install xxx
# 删除galaxy
ansible-galaxy remove xxx
role默认安装路径为/etc/ansible/roles/下
ansible的命令
列出指定组别的host列表
ansible appsevr --list-hosts
列出所有列表的host
ansible all --list-hosts
ansible all --list
支持通配符匹配host
ansible *serv --list
多IP批量执行
ansible 192.168.0.1,192.168.0.2 -m ping
多组别批量执行(逻辑或关系,合并,A和B所有)
ansible websevr:appsevr -m ping
(逻辑与关系,区分,在A中,也在B中)
ansible "websevr:&appsevr" -m ping
(逻辑非,在A中不在B中,此处必须要用单引号)
ansible 'websevr:!appsevr' -m ping
命令格式
ansible
--version 显示版本
-m module 指定模板,默认为command
-v 详细过程 -vv -vvv更详细
--list --list-hosts 显示主机列表,
-k --ask-pass 提示输入ssh连接密码,默认为key验证
-K --ask-become-pass 提示输入sudo时的口令
-C --check 检查,并不执行
-T --timeout=TIMEOUT 执行命令的超时时间,默认为10s
-u --user=REMOTE_USER 执行远程执行的用户
-b --become 代替旧版的sudo切换 (默认为ansible.cfg里面设置的用户,一般为root)
# 切换root用户使用ping命令
ansible -u root -m ping -k
# 使用其他没有模块的指令
ansible -m command -a 'ls -al' -k
ansible -m命令模块
command
在command中,我们可以创建文件,但是对于文件的操作,有一个专门的file模块
# 创建一个文件
ansible -m command -a 'mkdir data'
# 查看文件是否创建成功
ansible -m command -a 'ls -al data'
# 查看command帮助
ansible-doc command
shell
如果-a 后带的参数中出现 $ < > | ; & 等字符,command是不支持的,需要用到shell 模块
# 输出主机名字
ansible 192.168.1.3 -m shell -a 'echo $HOSTNAME'
由于ansible的模块太多,记录在其他文章中
http://noback.top/admin/write-post.php?cid=25
ansible命令执行流程
1.加载自己的配置文件 默认为/etc/ansible/ansible.cfg
2.加载自己对应的模块文件,如command
3.通过ansible将模块或命令生成对应的临时py文件,并将文件传输至远程服务器的对应执行用户$HOME/.ansible/tmp/ansible-tmp-数字/xxx.py文件
4.增加文件的执行权限
5.执行并返回结果
6.删除临时py文件,sleep 0退出
执行状态:
绿色 执行成功并且不需要做改变的操作
黄色 执行成功但是对目标主机做了修改
红色 执行失败
(颜色内容在/etc/ansible.cfg里面修改)
ansible使用命令登录
如果我们没有远端的key,仅仅使用ssh 用户+密码的形式登录主机的话,频繁的输入密码会显得很麻烦
# ansible使用登录被控端执行ping
ansible ho -m ping -k
# 在配置中直接加入密码,在/etc/ansible/hosts下的主机列表中,我们可以将密码加到inventory下的每一个主机后面,如下
[test]
10.0.5.156 ansible_ssh_pass=upyun123
10.0.5.157 ansible_ssh_pass=upyun123
10.0.5.158 ansible_ssh_pass=upyun123
# 如上再执行ansible test -m ping -k时会自动输入密码
生成ssh
ssh-keygen
复制ssh密钥到其他主机
ssh-copy-id 主机ip
ansible模块使用
由于Ansible的模块过多,将近有1378个模块数量,但是每个模块的介绍以及使用方法都存放在/usr/bin/ansible-doc当中
# 查看当前ansible模块数量
ansible-doc -l | wc -l
# ansible-doc的使用方法
ansible-doc [options] [module..]
-a 显示所有模块的文档 参数尽量放在单引号里面
-l --list 列出可用模块
-s --snippet xxx 显示xxx模块的playbook片段
# 使用-m指定模块,默认为command
ansible -m command
command
在command中,我们可以创建文件,但是对于文件的操作,有一个专门的file模块
# 创建一个文件
ansible -m command -a 'mkdir data'
# 查看文件是否创建成功
ansible -m command -a 'ls -al data'
# 查看command帮助
ansible-doc command
shell
如果-a 后带的参数中出现 $ < > | ; & 等字符,command是不支持的,需要用到shell 模块
# 输出主机名字
ansible 192.168.1.3 -m shell -a 'echo $HOSTNAME'
script
既然ansible可以对多台主机进行批量的操作,那往往我们会遇到一个场景,即需要我们在多台主机上执行一个脚本,这个场景下我们有两个方法:
1.将脚本文件复制到多台主机上后,调用ansible使用
2.使用script模块,仅在控制端存在脚本文件即可
# 方法一,先将文件发到对应控制端主机
ansible 192.168.1.3 -m command -a '/root/ansible_test.sh'
# 方法二
root@DESKTOP-GT1K5L0:~# ansible 192.168.1.3 -m script -a '/root/ansible_test.sh'
192.168.1.3 | SUCCESS => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 192.168.1.3 closed",
"stdout": "to do it,ansible",
"stdout_lines": [
"to do it,ansible"
]
}
Copy
在上面我们提到了从控制端传输文件到被控端,既然是批量的操作,那么在ansible中同样存在一个copy的模块,可以用来传输文件
场景: 关闭多台主机的selinux
流程: 复制控制端selinux的配置文件,修改后发送到被控制端
注意:这里的ho表示的是一个主机群 在/etc/ansible/hosts中已经添加了
# 查看控制端selinux状态
getenforce
# 查看被控端selinux状态
[root@localhost ~]# ansible ho -m command -a 'getenforce'
192.168.1.6 | SUCCESS | rc=0 >>
Enforcing
192.168.1.7 | SUCCESS | rc=0 >>
Enforcing
192.168.1.5 | SUCCESS | rc=0 >>
Enforcing
192.168.1.4 | SUCCESS | rc=0 >>
Enforcing
# 复制selinux配置文件,并修改配置
cp /etc/selinux/config .
SELINUX=disabled
# 复制配置文件到被控端指定路径,并做好备份
ansible ho -m copy -a'src=/root/hzj/config dest=/etc/selinux/config backup=yes'
# 查看被控端是否生成备份文件
ansible ho -m command -a 'ls /etc/selinux/'
# 重启
ansible ho -m command -a 'reboot'
# 查看被控端selinux是否修改完成
ansible ho -m command -a 'getenforce'
[root@localhost hzj]# ansible ho -m command -a 'getenforce'
192.168.1.7 | SUCCESS | rc=0 >>
Disabled
192.168.1.4 | SUCCESS | rc=0 >>
Disabled
192.168.1.5 | SUCCESS | rc=0 >>
Disabled
192.168.1.6 | SUCCESS | rc=0 >>
Disabled
fetch
ansible支持从被控端抓取文件到控制端,抓取后的格式为example.comdest
src表示抓取路径
dest表示存放路径
# 复制所有主机的日志到控制端
ansible ho -m fetch -a 'src=/var/log/messages dest=/root/data'
但是fetch仅支持单个文件的抓取,当我们想要抓取多个日志文件时,可以先进行打包
file
设置文件的属性
# 创建文件
ansible ho -m file -a 'name=/data/f3 state=touch'
# 删除文件
ansible ho -m file -a 'name=/data/f3 state=absent'
# 创建文件夹
ansible ho -m file -a 'name=/data/f3 state=directory'
# 删除文件夹
ansible ho -m file -a 'name=/data/f3 state=absent'
# 创建软连接
ansible ho -m file -a 'src=/root/test name=/data/fq state=link'
# 但是需要注意的是如果你创建了文件f3 当你创建文件夹f3的时候会出现错误
hostname
修改主机名
ansible ho -m hostname -a 'name=node'
# 重启后生效
cron
# 给每台主机添加任务,name为注释
ansible ho -m cron -a 'minute=* weekday=1,3,5,7 job="usr/bin/wall message" name=test'
# 取消任务
ansible ho -m cron -a 'disabled=true job="usr/bin/wall message" name=test'
# 重新启用
ansible ho -m cron -a 'disabled=no job="usr/bin/wall message" name=test'
# 删除某条任务
ansible ho -m corn -a 'jon="usr/bin/wall message" state=absent'
yum
# name指定包 state指定状态
ansible ho -m yum -a 'name=httpd state=latest' 安装
ansible ho -m yum -a 'name=httpd state=absent' 删除
Service
# 关闭服务 name指定服务名称 state指定状态
ansible ho -m service -a 'name=httpd state=stopped'
ansible ho -m service -a 'name=httpd state=started'
ansible ho -m service -a'name=httpd state=reloaded'
ansible ho -m service -a'name=httpd state=restarted'
User
ansible ho -m user -a 'name=user comment="test user" uid=2048 home=/app/user group=root'
ansible ho -m user -a 'name=sysuser system=yes home=/app/syseser1'
ansible ho -m user -a 'name=user state=absent remove=yes' 删除用户以及家目录等数据
playbook的编写
随着工作的增加,单条ansible命令(adhoc)已经不能满足我们的需求.于是我们可以把多条ansible命令写入playbook中,让系统根据playbook中的顺序依次执行ansible。我们把它叫做剧本
Playbook的编写方式
Playbook的编写格式采用的是yaml语言
url: http://www.ruanyifeng.com/blog/2016/07/yaml.html
url2: https://www.jianshu.com/p/97222440cd08
urs3: https://yaml.org/ 多种语言实现yaml
简单的介绍一下yaml语言的使用
1. 在单一档案中,可以用连续的连字符(---)区分多个档案。另外,还有选择性的连续三个点号(...)用来表示档案结尾
2. 次行开始正常写Playbook的内容,一般建议写明该playbook的功能
3. 使用#号注释代码
4. 缩进统一用tab
5. 一个完整的代码块功能最少的元素需要包括name:task
6. 一个name只能包括一个task
7. yaml文件扩展名通常为yml或者yaml
playbook例子
---
- 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
playbook核心元素
- Hosts 执行的远程主机列表
- Tasks 任务集
- Varniables 内置变量或自定义变量在playbook中调用
- Templates 模板,可替换模板文件中的变量并实现一些简单逻辑的文件
- Handlers 和 notity 结合使用,由特定条件触发的操作,满足条件方才执行,否则不执行
- tags 标签 指定某条任务执行,用于选择运行playbook中的部分代码。ansible具有幂等性,因此会自动跳过没有变化的部分,即便如此,有些代码为测试其确实没有发生变化的时间
依然会很长。因此可以使用tags跳过一些代码片段。
ansible-playbook -t tagsname useradd.yml
adhoc 和 playbook 对比
# adhoc 改变主机名字
ansible ho -m hostname -a 'name=xxx'
# playboot 修改主机名字
---
- host: ho
remote_user: root
tasks:
- name: hello
hostname: name=node
多条adhoc 和playbook对比
# adhoc
ansible ho -m file -a 'name=/data/newfile state=touch' # 创建文件
ansible ho -m user -a 'name=test2 system=yes shell=/sbin/nologin' # 创建用户
ansible ho -m yum -a 'name=httpd' # 安装httpd
ansible ho -m copy -a 'src=/var/www/html/index.html dest=/var/www/html' # 复制文件
ansible ho -m service -a 'name=httpd state=started enabled=yes' # 启动服务
# playbook
- hosts: ho
remote_user: root
tasks:
- name: create file
file: name=/data/newfile state=touch
- name: create user
file: name=test2 system=yes shell=/sbin/nologin
- name: install httpd
yum: name=httpd
- name: copy file
copy: src=/var/www/html/index.html dest=/var/www/html
- name: start service
service: name=httpd state=started enabled=yes
shell脚本与playbook对比
# shell脚本
#!/bin/bash
# 安装Apache
yum install --quiet -y httpd
# 复制配置文件
cp /tmp/httpd.conf /etc/httpd/conf/httpd.conf
cp /tmp/vhosts.conf /etc/httpd/conf.d/
# 启动Apache 并设置开机启动
systemctl start httpd.service
chkconfig httpd on
# playbook
---
- host: all
tasks:
- name: "安装Apache"
yum: name=httpd
- name: "复制配置文件"
copy: src=/tmp/httpd.conf dest=/etc/httpd/conf/
- name: "复制文件"
copy: src=/tmp/vhosts.conf dest=/etc/httpd/conf.d/
- name: "启动Apache,并设置开机启动"
service: name=httpd state=started enabled=yes
执行流程
play的主体部分是task list 。 task list 中的各任务按次序逐个在hosts中指定的所有主机上执行,即在所有主机上完成第一个任务后在开始第二个,在运行自上而下某一个playbook时,如果中途发生错误,所有已执行任务都将回滚,因此,在更正playbook后重新执行一次即可
忽略错误信息
task:
- name: copy file
copy: src=/root/file dest=/root/ || /bin/true
# 或者
task:
- name: copy file
copy: src=/root/file dest=/root/
ignore_erros: True
playbook运行方式
ansible-playbook <xxx.yml> [options]
--check 只检测可能会发生的改变,但不真正执行操作
--list-hosts 列出运行任务的主机
--limit 主机列表 只针对主机列表中的主机执行
-v 显示过程 -vv -vvv显示更详细
Playbook剧本
ansible-playbook是ansible中的一个工具,存放在/usr/bin/ansible-playbook