ansible使用过程中不同的角色分为:
使用者
工具集
作用对象
ansible工具集
INVENTORY:命令执行的目标对象配置文件。
API:供第三方程序调用的应用程序接口。
MODULES:丰富的内置模块。
PLUGINS:内置和可自定义的插件。
作用对象
可以作用于操作系统的主机,还可以作用于各类云和网络设施。
ansible的卖点在于无客户端,只需要ssh和python即可。而且也支持windows,但是他只是客户端,服务端必须为linux。
ansible基本常识
ansible安装十分简单,只需要配置好yum源,然后只用在主节点安装就可以了,不用每个节点都进行安装。
yum install ansible
安装完成后使用的话可以查看文档
ansible-doc -l
每个模块都有详细的介绍,并且还有例子。
ansible的默认目录在/etc/ansible/,目录中有两个文件和一个目录
[root@server10 ansible]# ls
ansible.cfg hosts roles
roles目录现在目前是空的,因为这个目录的作用是来装角色的。
主配置文件为ansible.cfg。hosts为配置清单。
hosts文件中要加入主机,其中里面有例子。
## [dbservers] ##这个表示组,组与组的东西都是需要再进行设定的
##
## db01.intranet.mydomain.net ##可以用主机名
## db02.intranet.mydomain.net
## 10.25.1.56 ##也可以用ip
## 10.25.1.57
或者可以直接不设置组,直接在最底下添加主机名或者ip。
## db-[99:101]-node.example.com
server11
server12
添加完成之后可以使用命令查看是否添加成功。
[root@server10 ansible]# ansible all --list-hosts ##这个表示查看所有
hosts (2):
server11
server12
[root@server10 ansible]# ansible ungrouped --list-hosts ##这个表示查看未分组的
hosts (2):
server11
server12
但是官方建议是进行分组。如下
[test1]
server11
[test2]
server12
分组完成再使用ungrouped查看就找不到两台主机了。
[root@server10 ansible]# ansible ungrouped --list-hosts
[WARNING]: No hosts matched, nothing to do
hosts (0):
这时查看之前需要添加组名。
[root@server10 ansible]# ansible test1 --list-hosts
hosts (1):
server11
[root@server10 ansible]# ansible test2 --list-hosts
hosts (1):
server12
或者直接使用主机名也是可以看到的
[root@server10 ansible]# ansible server11 --list-hosts
hosts (1):
server11
第一次ping一下看节点是否存活
[root@server10 ansible]# ansible all -m ping
server11 | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).",
"unreachable": true
}
server12 | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).",
"unreachable": true
}
现在第一次被拒绝掉了,根据提示上面说需要密码
ansible all -m ping -k
下来再输入远端的密码就可以成功,或者直接使用ssh免密登陆。
[root@server10 ansible]# ssh-keygen
[root@server10 ansible]# ssh-copy-id server11
[root@server10 ansible]# ssh-copy-id server12
做完免密再重复上面的操作,这样就不会被拒绝掉了。
[root@server10 ansible]# ansible all -m ping
server12 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
server11 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
使用ansible还可以远程使用一些命令,
[root@server10 ansible]# ansible all -a "hostname"
server11 | CHANGED | rc=0 >>
server11
server12 | CHANGED | rc=0 >>
server12
[root@server10 ansible]# ansible all -a "df -h"
server11 | CHANGED | rc=0 >>
文件系统 容量 已用 可用 已用% 挂载点
devtmpfs 484M 0 484M 0% /dev
tmpfs 496M 0 496M 0% /dev/shm
tmpfs 496M 6.8M 489M 2% /run
tmpfs 496M 0 496M 0% /sys/fs/cgroup
/dev/mapper/centos-root 13G 1.4G 12G 11% /
/dev/sda1 1014M 136M 879M 14% /boot
tmpfs 100M 0 100M 0% /run/user/0
server12 | CHANGED | rc=0 >>
文件系统 容量 已用 可用 已用% 挂载点
devtmpfs 484M 0 484M 0% /dev
tmpfs 496M 0 496M 0% /dev/shm
tmpfs 496M 6.8M 489M 2% /run
tmpfs 496M 0 496M 0% /sys/fs/cgroup
/dev/mapper/centos-root 13G 1.4G 12G 11% /
/dev/sda1 1014M 136M 879M 14% /boot
tmpfs 100M 0 100M 0% /run/user/0
因为ansible内置了很多模块,所以要是不指定的话就使用默认的,使用模块加入参数-m即可,不添加的话默认模块为command。
ansible配置清单
还是以检测节点是否存活的命令为例。
[root@server10 ansible]# ansible all -m ping
server11 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
server12 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
这个命令运行之后是成功的,我们来看看是使用哪一个用户的身份来进行检测的,root用户,在之前我们做过了免密登陆,所以他是成功的,那么如果这个时候指定用户由会是什么样呢?
[root@server10 ansible]# id
uid=0(root) gid=0(root) 组=0(root)
首先在server11和12节点上创建一个新用户。之后指定用户进行检测。
[root@server10 ansible]# ansible all -m ping -u ansible
server11 | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).",
"unreachable": true
}
server12 | UNREACHABLE! => {
"changed": false,
"msg": "Failed to connect to the host via ssh: Permission denied (publickey,gssapi-keyex,gssapi-with-mic,password).",
"unreachable": true
}
又被拒绝了。因为我们做免密只做了root用户,那我们应该如何指定新用户进行操作呢?和一开始一样的方法,要么输入密码,要么把密钥传过来。
[root@server10 ansible]# ansible all -m ping -u ansible -k
SSH password:
server11 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
server12 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
或者
[root@server10 ansible]# ssh-copy-id ansible@server11
[root@server10 ansible]# ssh-copy-id ansible@server12
设置完成之后进行下面的操作使用指定用户给权限
首先创建一个文件
[root@server10 ansible]# ansible all -a "touch /tmp/file" -u ansible
server11 | CHANGED | rc=0 >>
server12 | CHANGED | rc=0 >>
[root@server10 ansible]# ansible all -a "ls -l /tmp/file" -u ansible
server11 | CHANGED | rc=0 >>
-rw-rw-r-- 1 ansible ansible 0 3月 7 14:32 /tmp/file
server12 | CHANGED | rc=0 >>
-rw-rw-r-- 1 ansible ansible 0 3月 7 14:32 /tmp/file
从上面的信息来看,创建出来的文件属于新用户,因为上面的目录任何用户都可以进行操作,但是如果我们更换目录,将文件创建在只能root用户才可以操作的目录中又是怎样的效果呢?
[root@server10 ansible]# ansible all -a "touch /mnt/file" -u ansible
server12 | FAILED | rc=1 >>
touch: 无法创建"/mnt/file": 权限不够non-zero return code
server11 | FAILED | rc=1 >>
touch: 无法创建"/mnt/file": 权限不够non-zero return code
提示说的很明显,权限不够。那想往里面创建文件但是又不想使用root用户该如何操作,应该使用sudo的形式进行创建,使用sudo的参数为-b
[root@server10 ansible]# ansible all -a "touch /mnt/file" -u ansible -b
提示显示需要sudo的密码。这样就必须去远端进行设置。首先创建用户所有远端都需要。
ansible ALL=(ALL) ALL
设置完成之后如何使用sudo密码进行登陆,使用参数-K,输入的密码是普通用户的密码来验证普通用户的身份。
[root@server10 ansible]# ansible all -a "touch /mnt/file" -u ansible -b -K
BECOME password:
server11 | CHANGED | rc=0 >>
server12 | CHANGED | rc=0 >>
但是输入密码还是不方便,可以免密
ansible ALL=(ALL) NOPASSWD: ALL
[root@server10 ansible]# ansible all -a "touch /mnt/file" -u ansible -b
server11 | CHANGED | rc=0 >>
server12 | CHANGED | rc=0 >>
这样就可以直接使用sudo创建文件。
Inventory
Inventory是ansible管理主机信息的配置文件,也就是hosts文件,使用的时候可以使用参数-i指定Inventory文件。
可以先编写一个Inventory文件,文件的位置任意。
[pod]
server11
[root@server10 ansible]# ansible all -i Inventory -m ping ##指定文件
server11 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
组的嵌套
当一次性想调用多个组时运用
[test1] ##有两个组
server11
[test2]
server12
[web:children] ##重新设置一个组,冒号后面的不能变必须是children
test1 ##这里写的是组的名字
test2
[root@server10 ansible]# ansible web --list
hosts (2):
server11
server12
将组进行整合之后就可以设置变量,
[web:vars] ##冒号后面的参数不能变,固定值
http_port=80 ##指定80端口
我们这样做的好处就是当我们需要设置多个变量的时候需要一个组一个组的加,如下。
[test1]
server11
http_port=80
[test2]
server12
http_port=80
但是我们使用嵌套的方式,将组统一后一起设置很方便。这种变量只能在playbook中使用。
用户隔离
原因:在使用ansible管理的时候是多人一同进行管理,如果每个人都进行修改,那么不是很安全。
方法:切换到普通用户,在普通用户的主目录下将/etc/ansible/ansible.cfg文件复制到普通用户的家目录中,并将其隐藏,并且再随便创建一个目录,进入这个目录再将/etc/ansible/ansible.cfg文件复制到当前。等下次机器进行检索的时候顺序为当前目录的ansible.cfg文件->用户主目录下的ansible.cfg隐藏文件,最后才是/etc/ansible/ansible.cfg文件。
编辑用户主目录中的ansible.cfg隐藏文件。删除到如下就够用了。
[defaults]
inventory = ./hosts ##设置读取哪里的hosts文件
command_warnings = False ##不报错
[privilege_escalation] ##设置只能root用户使用
#become=True
#become_method=sudo
#become_user=root
#become_ask_pass=False
之后保存退出,创建一个hosts文件进行测试
[ansible@server10 ~]$ vim hosts
[test]
server11
[ansible@server10 ~]$ ansible all --list
hosts (1):
server11
这样就不用加-i这个参数指定文件。读取的就是当前目录中的hosts文件。
模块的运用
想运用模块但是不会用,直接可以查看文档。(以拷贝为例)
[ansible@server10 ~]$ ansible-doc copy ##查看文档,看不懂往最下面拉,查看示例。
copy:
src: /srv/myfiles/foo.conf ##文件地址
dest: /etc/foo.conf ##目的地地址
owner: foo ##文件拥有者
group: foo
mode: '0644' ##权限
根据例子来进行复制。
[ansible@server10 ~]$ ansible test -m copy -a "src=hosts dest=/tmp" ##文件是当前的host文件 目的地是test组中的/tmp
server11 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "f9e2ea7f194a1d813c0c931bca21264974148224",
"dest": "/tmp/hosts",
"gid": 1000,
"group": "ansible",
"md5sum": "dd2695a2665b8cdfd794d05dd453bbb8",
"mode": "0664",
"owner": "ansible",
"size": 16,
"src": "/home/ansible/.ansible/tmp/ansible-tmp-1583579461.19-192434210497855/source",
"state": "file",
"uid": 1000
复制完成后我们可以进行查看。
[ansible@server10 ~]$ ansible test -a "cat /tmp/hosts"
server11 | CHANGED | rc=0 >>
[test]
server11
这种复制是一般复制的方法,但是如果想给一些只能root用户进行操作的目录中写文件又会是怎样的。
[ansible@server10 ~]$ ansible test -m copy -a "src=hosts dest=/mnt"
server11 | FAILED! => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"checksum": "f9e2ea7f194a1d813c0c931bca21264974148224",
"msg": "Destination /mnt not writable"
}
答案肯定是被拒绝的。如果要进行使用那么就加上-b这个参数sudo。如果觉得麻烦,那么可以修改主配置文件。将[privilege_escalation]这个模块中的注释全部去掉。
[privilege_escalation]
become=True ##默认添加-b的参数
become_method=sudo ##默认使用sudo的方式
become_user=root ##切换用户成为谁
become_ask_pass=False ##密码询问
做完了这些事情再进行复制,就不会有报错了。
[ansible@server10 ~]$ ansible test -m copy -a "src=hosts dest=/mnt"
server11 | CHANGED => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": true,
"checksum": "f9e2ea7f194a1d813c0c931bca21264974148224",
"dest": "/mnt/hosts",
"gid": 0,
"group": "root",
"md5sum": "dd2695a2665b8cdfd794d05dd453bbb8",
"mode": "0644",
"owner": "root",
"size": 16,
"src": "/home/ansible/.ansible/tmp/ansible-tmp-1583580242.56-259773312213080/source",
"state": "file",
"uid": 0
}
ansible Ad-Hoc命令集
1)ad-hoc 使用场景
Ansible提供两种方式去完成任务,一是 ad-hoc 命令,一是写 Ansible playbook
在学习了 playbooks 之后,你才能体会到 Ansible 真正的强大之处在哪里
ad-hoc更注重于解决一些简单或者平时工作中临时遇到的任务,相当于Linux系统命令行下的Shell命令
后者更适合于解决复杂或需固化下来的任务,相当于Linux系统的Shell Scripts。
使用场景
关闭所有不必要的服务器
临时更新Apache或Nginx的配置文件
(2)Ansible的并发特性
Ansible和Ansible-playbook默认会fork 5个线程并发执行命令,如果同时操作的主机数比较多的话,可以调整到一个更大的值。
(3)Ansible-doc用法
ansible的模块非常之多,Ansible也提供了类似于man功能的help说明工具ansible-doc。
正式学习Ansible模块使用前,有必要先了解ansible-doc用法:
ansible-doc -l # 显示所有可用模块
ansible-doc yum # 获取yum模块帮助
(4)Ansible常用模块
copy模块
# ansible webservers -m copy -a "src=/etc/hosts dest=/tmp/hosts"
file模块
# ansible webservers -m file -a "dest=/tmp/hosts mode=600 owner=root group=root" #修改文件权限和属性
# ansible webservers -m file -a "dest=/tmp/dir1/dir2 mode=755 owner=root group=root state=directory" #递归创建
# ansible webservers -m file -a "dest=/tmp/dir1/dir2 state=absent"
yum模块
# ansible webservers -m yum -a "name=httpd state=present"
# ansible server3 -m yum -a "name=http://172.25.0.250/rhel7.3/x86_64/dvd/Packages/vsftpd-3.0.2-21.el7.x86_64.rpm state=present" #在线安装
# ansible server3 -m yum -a "name=/mnt/vsftpd-3.0.2-21.el7.x86_64.rpm state=present" #本地安装
# ansible server3 -m yum -a "name=httpd state=absent" #卸载软件
service模块
# ansible webservers -m service -a "name=httpd state=started"
# ansible webservers -m service -a "name=httpd state=restarted"
# ansible webservers -m service -a "name=httpd state=stopped"
user模块
# ansible all -m user -a "name=wxh password=<加密密码>"
# ansible all -m user -a "name=wxh state=absent remove=yes"
# ansibledb -m user -a "name=wxh shell=/bin/bash groups=users,wheel append=yes state=present"
mysql_user模块
# ansible server3 -m mysql_user -a "name=ykx password=testpass priv=*.*:select host='%' state=present"
远程主机需要安装MySQL-python