ansible简介以及一些常用用法
1. ansible
提高效率自动化运维的工具
- 自动化:
系统自动化(PXE+KS/PXE+cobblet)
程序自动化(ansible/saltstack/pupper)
代码自动化(JenKins)
程序自动化分为两类
1) C/S架构: saltstack puppet
2) 无客户端模式: ansible(主控端/被控端)
三者区别
ansible: 基于Python开发,使用ssh 协议,没有客户端,200-300台被控端,适用于中小型应用环境,一个系统控制多台主机
saltstack :基于Python开发,支持统一管理,比较轻量级 500
PYthon编写,需要部署 agent 主控制端通过安装在被控制端的代理来对被控端进行操作
puppet: ruby语言编写,重型,适合大型环境,谷歌使用 软件过于复杂,国内一般不使用 1000+
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
1. 实验环境
ansible(控制端) : 192.168.116.10/24
server_1 (被控制端): 192.168.116.11/24
server_2(被控制端): 192.168.116.12/24
server_3(被控制端): 192.168.116.13/24
1)安装ansible
- 安装 系统扩展yum源
yum -y install epel-release
# epel(extend packages for Enterprose) 属于 企业版linux扩展源yum 包
- 创建 yum 缓存,加快下载安装速度。
[[email protected] ~]# yum makecache fast
- 安装ansible
[[email protected] ~]# yum -y install ansible
2. 生成秘钥对
-
生成秘钥对,用于免密登录其他服务器
另外两台服务器也需要[[email protected] ~]# ssh-****** Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): Created directory '/root/.ssh'. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/id_rsa. Your public key has been saved in /root/.ssh/id_rsa.pub. The key fingerprint is: SHA256:6lDiyTi6pBp5q898/TB173uor6CjmeeBkG0u4LCY49M [email protected] The key's randomart image is: +---[RSA 2048]----+ | | | | | | | o | |o o + . S . | |+= B = o . . | |Bo* B.= . .. | |+O E.=+= . .. . | |B=*.+++o. o++o | +----[SHA256]-----+
[[email protected] ~]# ls /root/.ssh/
id_rsa id_rsa.pub
id_rsa —》 私钥
id_rsa.pub —》公钥
- 将公钥传输并追加至 指定的客户端,.ssh/authorized_keys(记录公钥文件)
[[email protected] ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host '192.168.116.11 (192.168.116.11)' can't be established.
ECDSA key fingerprint is SHA256:RFjKa//P/N+GhPwpj1/7/StnVP8o7DeQyHfLsjzdDQI.
ECDSA key fingerprint is MD5:64:d6:a3:e8:28:90:46:48:3f:aa:c4:0c:a9:06:ea:31.
Are you sure you want to continue connecting (yes/no)? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
[email protected]'s password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh '[email protected]'"
and check to make sure that only the key(s) you wanted were added.
- 连接进行验证
[[email protected] ~]# ssh [email protected]
Last login: Fri Sep 27 22:41:03 2019 from 1.1.1.11
[[email protected] ~]# exit
登出
Connection to 192.168.116.11 closed.
- 传输公钥
[[email protected] ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]
[[email protected] ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected]
3. 配置文件
ansible.cfg ----》 配置文件,位于 /etc/ansible/ansible.cfg ,默认不需要修改
hosts ---》 主机清单, 位于 /etc/ansible/hosts ,需要修改
roles ---》 角色:是一种编写习惯,可以自己编写,实现快速的部署
-
修改 hosts 主机清单 文件
添加ansible所控制的主机,在hosts 中可以 定义一个标签(组名)并添加对应主机
可以根据需求设置对应的组名以及管理地址 -
在hosts 主机清单末尾追加
[[email protected] ~]# vim /etc/ansible/hosts
[dbserver] # 自定义标签(name),相当于组名
192.168.116.11 # 所包含的主机
[webservers] # 组名/标签
192.168.116.12
192.168.116.13
# 保存退出
-
查看ansible 版本号
[[email protected] ~]# ansible --version ansible 2.9.2 config file = /etc/ansible/ansible.cfg configured module search path = [u'/root/.ansible/plugins/modules', u'/usr/share/ansible/plugins/modules'] ansible python module location = /usr/lib/python2.7/site-packages/ansible executable location = /usr/bin/ansible python version = 2.7.5 (default, Apr 11 2018, 07:36:10) [GCC 4.8.5 20150623 (Red Hat 4.8.5-28)]
5.ansible 模块
-
查看ansible 的模块有多少以及有哪些
[[email protected] ~]# ansible-doc -l | wc -l 3387
-
查看指定模块用法
ansible -s 模块名
-
ansible 使用模块格式
ansible 操作对象 -m 模块名 -a ‘模块参数’
参数:
-a 某些模块中可以省略
- 测试 ansible 与所有服务器(hosts 中包含的地址)连接情况
- 如果都没得问题,为安全色(绿色)
ansible all -m ping
参数:
all 表示所有操作对象
例:
[[email protected] ~]# ansible all -m ping
192.168.116.11 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
192.168.116.12 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
192.168.116.13 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
1) command 模块
- 主要用于执行简单的shell命令;执行复杂的shell命令会报错
- 一般用不到
- command 模块稍微复杂一点就傻逼了
- 为 操作对象 dbserver组 添加 command 模块 并在该种中执行指定命令
[[email protected] ~]# ansible dbserver -m command -a 'ls /root'
192.168.116.11 | CHANGED | rc=0 >>
anaconda-ks.cfg
- 执行一条稍微儿复杂一点的命令
[[email protected] ~]# ansible dbserver -m command -a 'cat /etc/passwd | wc -l'
192.168.116.11 | FAILED | rc=1 >>
cat:无效选项 -- l
Try 'cat --help' for more information.non-zero return code
2) shell模块
-
shell模块可以执行所有的命令
-
执行上一条让 command 懵逼的命令
[[email protected] ~]# ansible dbserver -m shell -a 'cat /etc/passwd | wc -l'
192.168.116.11 | CHANGED | rc=0 >>
19
3) cron 模块
- 用于为被控制端设置自动化任务;
cron == crontab - 为 dbserver中的主机设置一个 crontab
ansible dbserver -m cron -a 'minute="*/2" job="data >> /tmp/date.txt" name="show date" state=present'
参数:
为 dbserver 组 添加自动化任务,minute= 计划任务, job=执行语句 name= 描述信息 state=添加/移除
state=present 一般表示添加,新添加的计划任务
state=absent 一般表示移除
[[email protected] ~]# ansible dbserver -m cron -a 'minute="*/2" job="data >> /tmp/date.txt" name="show date" state=present'
192.168.116.11 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true, ## true 更改成功
"envs": [],
"jobs": [
"show date"
]
}
#
- 在被控端查看计划任务
[[email protected] ~]# crontab -l -u root
#Ansible: show date
*/2 * * * * data >> /tmp/date.txt
- 移除改组的计划任务
- 移除的时候只需要指定 name
[[email protected] ~]# ansible dbserver -m cron -a 'name="show date" state=absent'
192.168.116.11 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"envs": [],
"jobs": []
}
- 查看验证(192.168.116.11)
[[email protected] ~]# crontab -l -u root
name
4) user 模块
- 主要用于:
1) useradd one
2) passwd one
3) useradd -M -s /sbin/nologin nginx
4) useradd -u 1111 nginx
5) userdel -r one
-
例子: 通过user 模块 创建模块
ansible dbserver -m user -a 'name=now state=present'
创建一个用户, name= 用户名 state=创建
[[email protected] ~]# ansible dbserver -m user -a 'name=now state=present'
192.168.116.11 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"comment": "",
"create_home": true,
"group": 1000,
"home": "/home/now",
"name": "now",
"shell": "/bin/bash",
"state": "present",
"system": false,
"uid": 1000
}
- 例子: 通过 shell 模块 为用户添加密码
[[email protected] ~]# ansible dbserver -m shell -a 'echo "123.com" | passwd --stdin now'
[[email protected] ~]# ansible dbserver -m shell -a 'echo "123.com" | passwd --stdin now'
192.168.116.11 | CHANGED | rc=0 >>
更改用户 now 的密码 。
passwd:所有的身份验证令牌已经成功更新。
- 例子: 通过 user 模块 创建用户并赋值密码
PS: user 模块中加密 需要使用密文密码
首先使用 openssl passwd 生成加密后的密文
[[email protected] ~]# openssl passwd '123.com'
bQs.zEBJmFOLw
[[email protected] ~]# ansible dbserver -m user -a 'name=two password="bQs.zEBJmFOLw" state=present'
# name=用户 password=密文密码 state=添加
[WARNING]: The input password appears not to have been hashed. The 'password' argument must be encrypted for this module to work properly.
192.168.116.11 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"comment": "",
"create_home": true,
"group": 1001,
"home": "/home/two",
"name": "two",
"password": "NOT_LOGGING_PASSWORD",
"shell": "/bin/bash",
"state": "present",
"system": false,
"uid": 1001
}
- 例子: 使用 user 模块指定家目录创建
[[email protected] ~]# ansible dbserver -m user -a 'name=nginx create_home=no shell=/no/login state=present'
# name=用户 create_home=创建家目录 no 为不 shell=指定登录环境
192.168.116.11 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"comment": "",
"create_home": false,
"group": 1002,
"home": "/home/nginx",
"name": "nginx",
"shell": "/no/login",
"state": "present",
"system": false,
"uid": 1002
}
[[email protected] ~]# ansible dbserver -m shell -a 'tail /etc/passwd | grep "nginx"'
192.168.116.11 | CHANGED | rc=0 >>
nginx:x:1002:1002::/home/nginx:/no/login
# 通过验证我们发现,该用户也有家目录,但是我们设置不为其创建家目录,这是怎么回事呢
# 是因为这是一个小BUG,只是显示有而已,但是没有家目录哦
[[email protected] ~]# ansible dbserver -m shell -a 'ls /home/nginx'
192.168.116.11 | FAILED | rc=2 >>
ls: 无法访问/home/nginx: 没有那个文件或目录non-zero return code
-
例子: 使用 user 模块创建用户并指定 uid
[[email protected] ~]# ansible dbserver -m user -a 'name=three uid=1111 state=present' 192.168.116.11 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "comment": "", "create_home": true, "group": 1111, "home": "/home/three", "name": "three", "shell": "/bin/bash", "state": "present", "system": false, "uid": 1111 } # 验证 [[email protected] ~]# ansible dbserver -m shell -a 'id three' 192.168.116.11 | CHANGED | rc=0 >> uid=1111(three) gid=1111(three) 组=1111(three)
-
例子: 使用 user 模块删除用户
[[email protected] ~]# ansible dbserver -m user -a 'name=noe remove=yes state=present'
# name=删用户名 remove=是否删除
192.168.116.11 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"comment": "",
"create_home": true,
"group": 1112,
"home": "/home/noe",
"name": "noe",
"shell": "/bin/bash",
"state": "present",
"system": false,
"uid": 1112
}
5) group 模块
-
添加 组
例子: 通过 group模块添加组并指定 gid[[email protected] ~]# ansible dbserver -m group -a 'name=market system=yes state=present gid=1234' # name=组名 system=该组是否出现在远程主机上 192.168.116.11 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "gid": 1234, "name": "market", "state": "present", "system": true } # 验证 [[email protected] ~]# ansible dbserver -m shell -a 'tail /etc/group | grep "market"' 192.168.116.11 | CHANGED | rc=0 >> market:x:995:
-
例子: 通过 group 模块 删除组
删除[[email protected] ~]# ansible dbserver -m group -a 'name=market state=absent' # name=组名 state=执行 192.168.116.11 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "name": "market", "state": "absent" } # 验证 [[email protected] ~]# ansible dbserver -m shell -a 'tail /etc/group | grep "market"' 192.168.116.11 | FAILED | rc=1 >> non-zero return code
6) copy 模块
1) 从主控端复制文件到被控制端(类似于scp)
2) 主控制被控制复制和粘贴被控制的文件
[[email protected] ~]# echo "copy module of ansible " > ansible.txt
[[email protected] ~]# ansible all -m copy -a 'src=/root/ansible.txt dest=/root' # 将ansible 本身的 文件 复制粘贴至 所有主机中 /root下
# src=复制(本地) dest=目标地址(被控端)
# 验证
[[email protected] ~]# andible all -m shell -a 'cat /root/ansible.txt'
bash: andible: 未找到命令...
[[email protected] ~]# ansible all -m shell -a 'cat /root/ansible.txt'
192.168.116.13 | CHANGED | rc=0 >>
copy module of ansible
192.168.116.11 | CHANGED | rc=0 >>
copy module of ansible
192.168.116.12 | CHANGED | rc=0 >>
copy module of ansible
# 添加remote_src=yes 表示复制粘贴都在 ansible主机执行
[[email protected] ~]# ansible webservers -m copy -a 'src=/etc/resolv.conf dest=/rot remote_src=yes' ## 验证ansible的幂等性;
[[email protected] ~]# ansible webservers -m copy -a 'src=/etc/resolv.conf dest=/rot remote_src=yes backup=yes' ## 修改一下被控制端/root/resolv.conf 的内容,使其可以发生文件覆盖,此时加上backup 将覆盖文件前的文件进行备份
# src=源 dest=目标地址 remote_src=如果是yes将src转到远程主机上
# backup=覆盖时是否进行备份 ,在复重复制时ansible会比较两个文件中的内容,如果一样则不会进行覆盖,但是会提示执行完毕
# 如果内容不一样则会覆盖,但是backup会将源文件进行备份(日期+时间+文加名)
7) file 模块
1) 修改文件属性(owner group mode权限) ---》 chown chmod
2) 软连接、硬链接
3) 创建目录或者文件
4) 删除文件或者目录
5) 递归设置目录权限以及属主属组
-
例子:更改文件或者目录属主属组
- [[email protected] ~]# ansible dbserver -m file -a 'path=/root/anaconda-ks.cfg owner=tianci group=tianci' # path=文件路径 owner=属主 group=属组 192.168.116.11 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "gid": 1000, "group": "tianci", "mode": "0600", "owner": "tianci", "path": "/root/anaconda-ks.cfg", "secontext": "system_u:object_r:admin_home_t:s0", "size": 1257, "state": "file", "uid": 1000
验证 :
[[email protected] ~]# ansible dbserver -m shell -a 'ls -l /root/anaconda-ks.cfg'
192.168.116.11 | CHANGED | rc=0 >>
-rw-------. 1 tianci tianci 1257 9月 27 22:17 /root/anaconda-ks.cfg
-
例子:修改文件权限
- [[email protected] ~]# ansible dbserver -m file -a 'path=/root/anaconda-ks.cfg mode=7777' 192.168.116.11 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "gid": 1000, "group": "now", "mode": "07777", "owner": "now", "path": "/root/anaconda-ks.cfg", "secontext": "system_u:object_r:admin_home_t:s0", "size": 1257, "state": "file", "uid": 1000 } # 验证 [[email protected] ~]# ansible dbserver -m shell -a 'ls -l /root/anaconda-ks.cfg' 192.168.116.11 | CHANGED | rc=0 >> -rwsrwsrwt. 1 tianci tianci 1257 9月 27 22:17 /root/anaconda-ks.cfg
-
例子:创建软连接与硬链接
- 软连接
[[email protected] ~]# ansible dbserver -m file -a 'src=/etc/hosts dest=/root/host state=link'
# src=源 dest=目标 state= link 软连接
192.168.116.11 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"dest": "/root/host",
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"secontext": "unconfined_u:object_r:admin_home_t:s0",
"size": 10,
"src": "/etc/hosts",
"state": "link",
"uid": 0
}
state=link 软连接
state=hard 硬链接
- 硬链接
[[email protected] ~]# ansible dbserver -m file -a 'src=/etc/hosts dest=/root/hosts state=hard'
192.168.116.11 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"dest": "/root/hosts",
"gid": 0,
"group": "root",
"mode": "0644",
"owner": "root",
"secontext": "system_u:object_r:net_conf_t:s0",
"size": 158,
"src": "/etc/hosts",
"state": "hard",
"uid": 0
}
- 在被控制端查看
[[email protected] ~]# ll /root/
总用量 12
-rwsrwsrwt. 1 now now 1257 9月 27 22:17 anaconda-ks.cfg
-rw-r--r--. 1 root root 24 1月 8 16:08 ansible.txt
lrwxrwxrwx. 1 root root 10 1月 8 16:43 host -> /etc/hosts ## 软连接
-rw-r--r--. 2 root root 158 6月 7 2013 hosts ## 硬链接
-
例子:创建文件
- [[email protected] ~]# ansible dbserver -m file -a 'path=/tmp/file.txt state=touch' # state=touch 创建文件 192.168.116.11 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "dest": "/tmp/file.txt", "gid": 0, "group": "root", "mode": "0644", "owner": "root", "secontext": "unconfined_u:object_r:user_tmp_t:s0", "size": 0, "state": "file", "uid": 0 } # 验证 [[email protected] ~]# ansible dbserver -m shell -a 'ls /root/file.txt' 192.168.116.11 | CHANGED | rc=0 >> /root/file.txt
-
创建目录
[[email protected] ~]# ansible dbserver -m file -a 'path=/tmp/file state=directory' # state=directory 创建目录 192.168.116.11 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "gid": 0, "group": "root", "mode": "0755", "owner": "root", "path": "/tmp/file", "secontext": "unconfined_u:object_r:user_tmp_t:s0", "size": 6, "state": "directory", "uid": 0 } # 验证 [[email protected] ~]# ansible dbserver -m shell -a 'ls /tmp/ | grep 'file'' 192.168.116.11 | CHANGED | rc=0 >> file
-
删除目录
- [[email protected] ~]# ansible dbserver -m file -a 'path=/tmp/file state=absent' # state=absent 移除 192.168.116.11 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "path": "/tmp/file", "state": "absent" } # 验证 [[email protected] ~]# ansible dbserver -m shell -a 'ls /tmp/ | grep 'file'' 192.168.116.11 | CHANGED | rc=0 >>
-
递归设置权限
# 如果指定目录或者文件不存在则创建
[[email protected] ~]# ansible dbserver -m file -a 'path=/tmp/file mode=0777 recurse=yes'
192.168.116.11 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"gid": 0,
"group": "root",
"mode": "0777",
"owner": "root",
"path": "/tmp/file",
"secontext": "unconfined_u:object_r:user_tmp_t:s0",
"size": 6,
"state": "directory",
"uid": 0
}
# 验证
[[email protected] ~]# ansible dbserver -m shell -a 'ls -l /tmp/ | grep 'file''
192.168.116.11 | CHANGED | rc=0 >>
drwxr-xr-x. 2 now now 6 1月 8 22:41 file
- 递归设置属主属组
[[email protected] ~]# ansible dbserver -m file -a 'path=/tmp/file owner=now group=now recurse=yes'
# recurse=yes 是否递归
192.168.116.11 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"gid": 1000,
"group": "now",
"mode": "0777",
"owner": "now",
"path": "/tmp/file",
"secontext": "unconfined_u:object_r:user_tmp_t:s0",
"size": 6,
"state": "directory",
"uid": 1000
}
8) yum 模块
-
作用: 主控端空值被控端 使其使用yum 安装rpm包
PS: 被控端yum 可用
常规操作:
yum -y install
yum -y remove -
例子:通过 yum 模块安装
- [[email protected] ~]# ansible dbserver -m yum -a 'name=wget state=present' # name=rpm包名字,如果安装多个用逗号隔开即可 192.168.116.11 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "changes": { "installed": [ "wget" ] }
-
例子: 通过 yum 模块卸载
[[email protected] ~]# ansible dbserver -m yum -a 'name=gcc,c++ state=absent' 192.168.116.11 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "changes": { "removed": [ "gcc" ] }
-
service 模块
作用: 操控被控制端开启,关闭、重启、重载(视具体服务而定)
1) notice: service 可以管理rpm包安装的服务源码安装的服务建议使用shell模块直接执行命令
服务状态(state)
started / stopped / restarted
例子:关闭防火墙
[[email protected] ~]# ansible dbserver -m service -a 'name=firewalld state=stopped'
# name=服务名字
192.168.116.11 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"name": "firewalld",
"state": "stopped",
## 类似于以下这种情况一般是 该软件已经存在
[[email protected] ~]# ansible dbserver -m yum -a 'name=wget state=present'
192.168.116.11 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"msg": "",
"rc": 0,
"results": [
"wget-1.14-15.el7_4.1.x86_64 providing wget is already installed"
]
}
[[email protected] ~]# ansible dbserver -m shell -a 'rpm -qa | grep wget'
[WARNING]: Consider using the yum, dnf or zypper module rather than running 'rpm'. If you need to use command because yum, dnf or zypper is insufficient you can add 'warn: false' to this
command task or set 'command_warnings=False' in ansible.cfg to get rid of this message.
192.168.116.11 | CHANGED | rc=0 >>
wget-1.14-15.el7_4.1.x86_64
- hostname 修改主机名
1) hostname 临时
2) hostnamectl 永久
3) vim 配置文件
4) 通过 ansible hostname模块
-
例子: 通过hostname修改主机名
- [[email protected] ~]# ansible dbserver -m hostname -a 'name=localhost.localdomain' # name=名字 192.168.116.11 | CHANGED => { "ansible_facts": { "ansible_domain": "localdomain", "ansible_fqdn": "localhost.localdomain", "ansible_hostname": "localhost", "ansible_nodename": "localhost.localdomain", "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "name": "localhost.localdomain" }
9) script 模块
- 作用:用于将主控端的脚本在被控端运行
常用的脚本:
1)shell ----》 .sh
2)python ----》 .py
-
例子: 通过 script 模块 执行主控端脚本
-
首先编写脚本文件,批量创建用户( user1–user10)
[[email protected] ~]# vim test.sh
#! /bin/bash
for i in {1..10}
do
useradd user$i
echo "123.com" | passwd --stdin user$i
done
- 调用脚本
[[email protected] ~]# ansible dbserver -m script -a '/root/test.sh'
# 调用主控端脚本不需要使用任何参数,直接输入脚本位置即可。
192.168.116.11 | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 192.168.116.11 closed.\r\n",
"stderr_lines": [
…………
…………
"更改用户 user9 的密码 。",
"passwd:所有的身份验证令牌已经成功更新。",
"更改用户 user10 的密码 。",
"passwd:所有的身份验证令牌已经成功更新。"
]
}
- 验证
[[email protected] ~]# ansible dbserver -m shell -a 'tail /etc/passwd'
192.168.116.11 | CHANGED | rc=0 >>
user1:x:1113:1113::/home/user1:/bin/bash
user2:x:1114:1114::/home/user2:/bin/bash
user3:x:1115:1115::/home/user3:/bin/bash
user4:x:1116:1116::/home/user4:/bin/bash
user5:x:1117:1117::/home/user5:/bin/bash
user6:x:1118:1118::/home/user6:/bin/bash
user7:x:1119:1119::/home/user7:/bin/bash
user8:x:1120:1120::/home/user8:/bin/bash
user9:x:1121:1121::/home/user9:/bin/bash
user10:x:1122:1122::/home/user10:/bin/bash
-
例子: 通过script 模块 执行脚本批量删除用户 (user1 – user10)
- [[email protected] ~]# vim userdel.sh #! /bin/bash for i in {1..10} do userdel user$1 done # 运行脚本 [[email protected] ~]# ansible dbserver -m script -a '/root/userdel.sh' 192.168.116.11 | CHANGED => { "changed": true, "rc": 0, "stderr": "Shared connection to 192.168.116.11 closed.\r\n", "stderr_lines": [ "Shared connection to 192.168.116.11 closed." ], "stdout": "", "stdout_lines": [] } # 验证 [[email protected] ~]# ansible dbserver -m shell -a 'tail /etc/passwd' 192.168.116.11 | CHANGED | rc=0 >> dbus:x:81:81:System message bus:/:/sbin/nologin
10) setup 模块
-
用于获取被控端的 ansible变量
获取的变量主要是用于模板中,可以利用变量,实现对被控端的快速配置和差异化配置 -
例子: 通过setup模块获取所有的 变量
- [[email protected] ~]# ansible dbserver -m setup -a '' # 此操作是获取所有的变量, 例子:通过 setup 模块获取指定参数的变量 [[email protected] ~]# ansible dbserver -m setup -a 'filter="*cpu*"' # filter=变量 * 通配符, 192.168.116.11 | SUCCESS => { "ansible_facts": { "ansible_processor_vcpus": 1, "discovered_interpreter_python": "/usr/bin/python" }, "changed": false }
11) fetch 模块
-
作用: 拿取被控端文件
-
例子: 通过 fetch 模块 将被控端的文件 拉取到主控端
- [[email protected] ~]# ansible all -m fetch -a 'src=/etc/resolv.conf dest=/tcp/test' # src=源(被控端) dest=目标地址(主控端) 192.168.116.11 | CHANGED => { "changed": true, "checksum": "dfb754d542e43feec14d581300236fa04a56597d", "dest": "/tcp/test/192.168.116.11/etc/resolv.conf", "md5sum": "653fab6375ea318ef8d245125b8de19f", "remote_checksum": "dfb754d542e43feec14d581300236fa04a56597d", "remote_md5sum": null } 192.168.116.13 | CHANGED => { "changed": true, "checksum": "dfb754d542e43feec14d581300236fa04a56597d", "dest": "/tcp/test/192.168.116.13/etc/resolv.conf", "md5sum": "653fab6375ea318ef8d245125b8de19f", "remote_checksum": "dfb754d542e43feec14d581300236fa04a56597d", "remote_md5sum": null } 192.168.116.12 | CHANGED => { "changed": true, "checksum": "dfb754d542e43feec14d581300236fa04a56597d", "dest": "/tcp/test/192.168.116.12/etc/resolv.conf", "md5sum": "653fab6375ea318ef8d245125b8de19f", "remote_checksum": "dfb754d542e43feec14d581300236fa04a56597d", "remote_md5sum": null } # 验证 [[email protected] ~]# ls /tcp/test/ 192.168.116.11 192.168.116.12 192.168.116.13
- replace 模块
-
作用: 可以实现对文件间的内容切换
[[email protected] ~]# vim test.txt hello worald hello [[email protected] ~]# ansible dbserver -m replace -a 'path=/root/test.txt regexp="hello" replace="aaaaa"' # path=修改的文件 regexp=匹配的字符 replace=替换的东西 192.168.116.11 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "msg": "2 replacements made" } [[email protected] ~]# ansible dbserver -m shell -a 'cat /root/test.txt' 192.168.116.11 | CHANGED | rc=0 >> aaaaa worald aaaaa
-
例子:将整行内容替换
- [[email protected] ~]# ansible dbserver -m shell -a 'cat /root/aaa.txt' 192.168.116.11 | CHANGED | rc=0 >> aaaaaa # ^ 以什么开头 # $ 以什么结尾 [[email protected] ~]# ansible dbserver -m replace -a 'path=/root/aaa.txt regexp="^aaaaaa$" replace="abcdefg"' 192.168.116.11 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "changed": true, "msg": "1 replacements made" } [[email protected] ~]# ansible dbserver -m shell -a 'cat /root/aaa.txt' 192.168.116.11 | CHANGED | rc=0 >> abcdefg
13) template 模块
-
作用: 主要用于主控端使用模板配置被控端配置文件的场景,
需要用到模板文件、文件必须以 .j2 结尾 -
安装 服务 进行测试
[[email protected] ~]# ansible webservers -m shell -a 'mount /dev/cdrom /media'
[WARNING]: Consider using the mount module rather than running 'mount'. If you need to use command because mount is insufficient you can add 'warn: false' to this command task or set
'command_warnings=False' in ansible.cfg to get rid of this message.
192.168.116.13 | CHANGED | rc=0 >>
mount: /dev/sr0 写保护,将以只读方式挂载
192.168.116.12 | CHANGED | rc=0 >>
mount: /dev/sr0 写保护,将以只读方式挂载
# 通过ansible yum 安装 httpd
[[email protected] ~]# ansible webservers -m yum -a 'name=httpd state=installed'
# 主控端安装 web 服务
[[email protected] ~]# yum -y install httpd
# 将被控端的 httpd配置文件作为模板
[[email protected] ~]# cp /etc/httpd/conf/httpd.conf /root/httpd.conf.j2
# 修改其 域名 为 www.baidu.com
[[email protected] ~]# vim /root/httpd.conf.js
ServerName www.baidu.com:80
# 通过模板修改
[[email protected] ~]# ansible webservers -m template -a 'src=/root/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf'
# src=主控端模板源 dest=目标地址
192.168.116.13 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "f3385c6f241cc46f9585382b8edd7e287d3367d2",
"dest": "/etc/httpd/conf/httpd.conf",
"gid": 0,
"group": "root",
"md5sum": "f7271dedceda064a54c591c904e1ffb6",
"mode": "0644",
"owner": "root",
"size": 11750,
"src": "/root/.ansible/tmp/ansible-tmp-1578552032.32-247713146820451/source",
"state": "file",
"uid": 0
}
192.168.116.12 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "f3385c6f241cc46f9585382b8edd7e287d3367d2",
"dest": "/etc/httpd/conf/httpd.conf",
"gid": 0,
"group": "root",
"md5sum": "f7271dedceda064a54c591c904e1ffb6",
"mode": "0644",
"owner": "root",
"size": 11750,
"src": "/root/.ansible/tmp/ansible-tmp-1578552032.33-257511787935695/source",
"state": "file",
"uid": 0
}
# 验证
[[email protected] ~]# ansible webservers -m shell -a 'cat /etc/httpd/conf/httpd.conf | grep "ServerName"'
192.168.116.12 | CHANGED | rc=0 >>
# ServerName gives the name and port that the server uses to identify itself.
ServerName www.baidu.com:80
192.168.116.13 | CHANGED | rc=0 >>
# ServerName gives the name and port that the server uses to identify itself.
ServerName www.baidu.com:80
- 例子: 引用变量进行修改
[[email protected] ~]# vim /root/httpd.conf.j2
ServerName www.baidu.com:{{http_port}}
# 修改hosts 主机清单的变量与端口号
[[email protected] ~]# vim /etc/ansible/hosts
[webservers]
192.168.116.12 http_port=8888
192.168.116.13 http_port=8888
unarchive 模块
作用: 将主控端的压缩文件,解压后 放在被控端
# 将 tar 包解压至 被控端的目录中
[[email protected] ~]# ansible webservers -m unarchive -a 'src=/root/nginx-1.12.2.tar.gz dest=/usr/src'
# src=主控端源 dest=目标地址(被空端)
# 验证
[[email protected] ~]# ansible webservers -m shell -a 'ls /usr/src | grep "nginx*"'
192.168.116.13 | CHANGED | rc=0 >>
nginx-1.12.2
192.168.116.12 | CHANGED | rc=0 >>
nginx-1.12.2
14) lineinfile 模块
- 作用: 修改文件中的内容
BOF begin of file 文件开头
EOF end of file 文件结尾
参数:
参数 | 含义 |
---|---|
path | 指定要操作的文件对象 |
regexp | 匹配条件 |
insertbefore | 在某行之前插入 |
line | 要写入文件的内容 |
insertafter | 在某行之后插入 |
-
如果使用 insertbefore或者 insertafter 必须使用 state= 参数
-
例子: 通过 lineinfile 模块在 nginx.conf文件的开头前插入一行
[[email protected] ~]# ansible dbserver -m lineinfile -a 'path=/root/nginx.conf insertbefore=BOF line='#aaaaaaaa'' 192.168.116.11 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "backup": "", "changed": true, "msg": "line added" }
验证:
[[email protected] ~]# ansible dbserver -m shell -a 'head -n 2 /root/nginx.conf' 192.168.116.11 | CHANGED | rc=0 >> #aaaaaaaa
-
例子: 在文件的末尾插入一行
[[email protected] ~]# ansible dbserver -m lineinfile -a 'path=/root/nginx.conf insertafter=EOF line="# bbbbbbbbbbb"' 192.168.116.11 | CHANGED => { "ansible_facts": { "discovered_interpreter_python": "/usr/bin/python" }, "backup": "", "changed": true, "msg": "line added" }
验证:
[[email protected] ~]# ansible dbserver -m shell -a 'tail -n 2 /root/nginx.conf'
192.168.116.11 | CHANGED | rc=0 >>
}
# bbbbbbbbbbb
- 例子: 在指定的行 前/后 插入内容
- 在 /root/nginx.conf 文件中的 #charset koi8-r; 行 之后 插入 charset koi8-r;
[[email protected] ~]# ansible dbserver -m lineinfile -a 'path=/root/nginx.conf insertafter=" #charset koi8-r;" line=" charset koi8-r;" state=present'
- 在 /root/nginx.conf 文件的 server { 之前插入 upstream{
[[email protected] ~]# ansible dbserver -m lineinfile -a 'path=/root/nginx.conf insertbefore=" server {" line=" upstrame{" state=present'
- 例子: 删除指定的行
将刚刚添加的# bbbbbbbbbbb 删除
[[email protected] ~]# ansible dbserver -m lineinfile -a 'path=/root/nginx.conf regexp="# bbbbbbbbbbb" state=absent'
192.168.116.11 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"backup": "",
"changed": true,
"found": 1,
"msg": "1 line(s) removed"
}
4. ansible 的任务编排
playbook(剧本)
1) ansible 剧本的文件 后缀 为 .yml .yaml
- 格式:
带有 - 的行为 描述行,描述行下的为执行语句
- hosts: 操作对象
remote_user: 远程用户
tasks:
- name: 描述信息
模块名: 执行任务
- name: 描述信息
模块名: 执行任务
[[email protected] ~]# vim tset.yml
- hosts: dbserver # 描操作对象,可以是主机、主机清单(组名标签)
remote_user: root # 远程执行的用户
tasks: # 计划任务
- name: install vsftpd # 描述信息
yum: name=vsftpd # 执行任务 模块名 执行语句
- name: start vsftpd # 描述信息
service: name=vsftpd state=started # 执行任务: 模块名 加执行语句
- 检测语法错误
# 如果由错误直接提示,如没有错误输入剧本名称
[[email protected] ~]# ansible-playbook tset.yml --syntax-check playbook: tset.yml
- 运行剧本
- 以下属于 剧本的运行过程,列出了描述信息以及执行进度
[[email protected] ~]# ansible-playbook tset.yml
PLAY [dbserver] *****************************************************************************************************************************************************************************
TASK [Gathering Facts] **********************************************************************************************************************************************************************
ok: [192.168.116.11]
……………………
-
在使用 shell脚本时,可以在shell下使用args添加参数
例子- shell: ./config ~~~~ args: chdir: /usr/local/nginx-1.11.1 ## 意思是在编译时首先进入到 下面那个目录
-
例子: 通过 ansible - playbook(剧本) 为被控端安装 LNMP 环境
部署 Nginx
- hosts: webservers
remote_user: root
tasks:
- name: install nginx
unarchive: src=/root/nginx-1.11.1.tar.gz dest=/usr/src
- name: yum install pcre8 openssl*
yum: name=pcre*,openssl-devel,pcre-devel,zlib-devel
- name: make nginx
shell: ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx --with-http_stub_status_module --with-pcre && make && make install
args:
chdir: /usr/src/nginx-1.11.1
- name: create nginx running user
user: name=nginx create_home=no shell=/sbin/nologin state=present
- name: create link /usr/local/nginx/sbin/nginx /usr/sbin/nginx
file: src=/usr/local/nginx/sbin/nginx dest=/usr/sbin/nginx state=link
- name: start nginx
shell: nginx
部署MySQL
- hosts: webservers
remote_user: root
tasks:
- name: jie ya tar_cmake
unarchive: src=/root/cmake-2.8.7.tar.gz dest=/usr/src
- name: cd /usr/src/cmake* gmake install cmake
shell: ./configure && gmake && gmake install
args:
chdir: /usr/src/cmake-2.8.7
- name: jie ya tar_mysql
unarchive: src=/root/mysql-5.5.22.tar.gz dest=/usr/src
- name: yum install
yum: name=pcre-devel,ncurses,ncurses-devel
- name: cd /usr/src/mysql* && make && make install msyql
shell: cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DSYSCONFDIR=/etc -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DWITH-EXTRA_CHARSETS=all && make && make install
args:
chdir: /usr/src/mysql-5.5.22
- name: create mysql running user
user: name=mysql state=present
- name: mysql link
shell: ln -s /usr/local/mysql/bin/* /usr/local/bin
- name: updata mysql user\group
file: path=/usr/local/mysql owner=mysql group=mysql recurse=yes
- name: copy mysql_config_file
copy: src=/usr/local/mysql/support-files/my-medium.cnf dest=/etc/my.cnf remote_src=yes
- name: copy msyqld
copy: src=/usr/local/mysql/support-files/mysql.server dest=/etc/init.d/mysqld remote_src=yes
- name: chkconfig
shell: chkconfig --add mysqld
- name: chu shi hua mysql
shell: /usr/local/mysql/scripts/mysql_install_db --user=mysql --group=mysql --basedir=/usr/local/mysql/ --datadir=/usr/local/mysql/data/
- name: permission
file: path=/etc/init.d/mysqld mode=755
- name: start mysql
service: name=mysqld state=started
- hosts: dbserver
remote_user: root
tasks:
- name: yum install
yum: name=gd,libxml2-devel,libjpeg-devel,libpng-devel
- name: jie ya php
unarchive: src=php-5.3.28.tar.gz dest=/usr/src/
- name:
shell: ./configure --prefix=/usr/local/php --with-gd --with-zlib --with-mysql=/usr/local/mysql --with-config-file-path=/usr/local/php --enable-fpm --enable-mbstring --with-jpeg-dir=/usr/lib && make && make install
args:
chdir: /usr/src/php-5.3.28
- name: copy-config-file
copy: src=/usr/src/php-5.3.28/php.ini-development dest=/usr/local/php/php.ini remote_src=yes
- name: updata php.ini
shell: sed -i '/#default_charset = "utf-8"/a\default_charset = "utf-8"' /usr/local/php/php.ini && sed -i '/short_open_tag/c\short_open_tag = On' /usr/local/php/php.ini
- name: jie ya Zend
unarchive: src=/root/ZendGuardLoader-php-5.3-linux-glibc23-x86_64.tar.gz dest=/usr/src/
- name: copy Zend
copy: src=/usr/src/ZendGuardLoader-php-5.3-linux-glibc23-x86_64/php-5.3.x/ZendGuardLoader.so dest=/usr/local/php/lib/ZendGuardLoader.so remote_src=yes
- name: sed php.ini_Zend
lineinfile: path=/usr/local/php/php.ini insertafter=BOF line="Zend_extension=/usr/local/php/lib/ZendGuardLoader"
- lineinfile: path=/usr/local/php/php.ini insertafter=BOF line="Zend_loader.enable=1"
- name: tian jia systemctl
copy: src=/usr/src/php-5.3.28/sapi/fpm/init.d.php-fpm dest=/etc/init.d/php-fpm remote_src=yes
- name: permisvissi
file: path=/etc/init.d/php-fpm mode=755
- name: chkconfig
shell: chkconfig --add php-fpm
- name: copy php-fpm_config_fiel
copy: src=/usr/local/php/etc/php-fpm.conf.default dest=/usr/local/php/etc/php-fpm.conf remote_src=yes
- name: update php-fpm.conf
shell: sed -i '/pid = /a\pid = run/php-fpm.pid' /usr/local/php/etc/php-fpm.conf && sed -i '/user = nobody/c\user = nginx' /usr/local/php/etc/php-fpm.conf && sed -i '/group = nobody/c\group = nginx' /usr/local/php/etc/php-fpm.conf
- name: start php-fpm
service: name="php-fpm" state=started
- name: update nginx.conf
replace: path=/usr/local/nginx/conf/nginx.conf regexp=" index index.html index.htm;" replace=" index index.php index.html index.htm;"
- name: update nginx.conf
shell: sed -i '/ server_name localhost;/a \ location ~ \.php$ {\n root html;\n fastcgi_pass 127.0.0.1:9000;\n fastcgi_index index.php;\n fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;\n include fastcgi.conf;\n}' /usr/local/nginx/conf/nginx.conf
- name: restart
service: name=php-fpm state=restarted
Apache: 剧本
- hosts: dbserver
remote_user: root
tasks:
- name: apr
unarchive: src=/root/apr-1.5.2.tar.gz dest=/usr/src
- name: apr-make
shell: ./configure --prefix=/usr/local/apr && make && make install
args:
chdir: /usr/src/apr-1.5.2
- name: apr-util
unarchive: src=/root/apr-util.*.tar.gz dest=/usr/src
- shell: ./configure --prefix=/usr/local/apr-util --with-apr=/usr/loca/apr/bin/apr-1-config && make && make install
args:
chdir: /usr/src/apr-util.*
- name: tar httpd install
unarchive: src=/root/httpd-2.4.25.tar.gz dest=/usr/src
- shell: /usr/local/apr-util/bin/* /usr/local/bin
- yum: name=pcre-devel
- shell: ./configure --prefix=/usr/local/httpd --enable-so --enable-charset-lite --enable-cgi --enable-rewrite && make && make install
args:
chdir: /usr/src/httpd-2.4.25
- name: you hua httpd path
shell: ln -s /usr/local/httpd/bin/* /usr/local/bin
- name: copy httpd-start-config-file
copy: src=/usr/local/httpd/bin/apachectl dest=/etc/init.d/httpd remote_src=yes
- shell: chkconfig --add httpd
- file: path=/etc/init.d/httpd mode=0755
- name: start httpd-server
service: name=httpd state=started