Ansible概述
Posted 礁之
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Ansible概述相关的知识,希望对你有一定的参考价值。
文章目录
一、Ansible概述
(1)Ansible简介
- Ansible是一款开源的、简单的运维自动化工具,没有使用C/S架构,而是直接通过ssh协议来进行系统管理、自动化执行命令、部署等操作和任务
- Ansible的用法可以很简单,只需要使用一些简单的基础模块去实现自动化任务,也可以很难,这需要学习大量的Ansible知识==(除了Ansible本身之外还需要学习yaml和jinja2等额外知识)==,还需要大量的实际应用去熟悉最优化、最完美的自动化管理逻辑。想要写出一个适合公司环境可以重复使用的playbook或者role,需要熟悉应对各种需求、逻辑和知识点。
- 常见的自动化运维工具:Ansible、saltstack、puppet
(2)Ansible的特点
- Ansible不需要单独安装客户端,也不需要启动任何服务
- Ansible是python中的一套完整的自动化执行任务模块
- Ansible playbook剧本采用yaml配置,对于自动化任务的执行过程一目了然
(3)Ansible组成结构
- Ansible:
这是Ansible的命令工具,也是核心执行工具,一次性或临时执行的操作都是通过该命令执行的
- Ansible Playbook:
任务剧本,又称为任务集,是一个编排、定义Ansible命令执行的配置文件,写好后再由Ansible顺序的依次执行,使用yaml格式编写
- Inventory:
这是Ansible管理主机的清单,里面记录了Ansible管理的主机,默认的文件是/etc/ansible/hosts文件
- Modules:
这是Ansible执行命令的功能模块,到Ansible2.3版本为止,共计1039个模块,并且还可以自定义模块
- Plugins:
用于插件、模块功能的补充,常用的有连接类插件、循环插件、变量插件、过滤插件等,插件功能在真实环境中使用的较少
- API:
提供给第三方程序调用的应用程序编程接口,是给开发留的
(4)Ansible和其他管理软件的对比
- | Puppet | Saltstack | Ansible |
---|---|---|---|
开发语言 | ruby | python | python |
是否采用C/S架构 | 是 | 是 | 否 |
是否支持二次开发 | 不支持 | 支持 | 支持 |
服务器和远程机器是否需要相互验证 | 是 | 是 | 是 |
服务器和远程机器通信是否加密 | 是,支持SSL加密 | 是,使用AES加密 | 是,使用OpenSSH加密 |
支持的平台(系统) | 支持AIX、BSD、HP-UX、Linux、MacOSX、Solaris、Windows | 支持BSD、Linux、MacOSX、Solaris、Windows | 支持AIX、BSD、HP、UX、Linux、MacOSX、Solaris |
是否提供web界面 | ui提供 | 提供 | 商业版本提供 |
配置文件的格式 | ruby语法格式 | YAML | YAML |
命令行执行 | 不支持,但是可以通过配置模块实现 | 支持 | 支持 |
二、部署Ansible
(1)实验环境
系统 | 主机名 | ip | 扮演角色 |
---|---|---|---|
Centos7.4 | ansible | 192.168.100.202 | ansible服务器 |
Centos7.4 | node1 | 192.168.100.203 | 被管理机器 |
Centos7.4 | node2 | 192.168.100.204 | 被管理机器 |
只需要在Ansible服务器上安装Ansible即可,其他机器无需任何操作
(2)实验步骤
******(1)在三台主机上做基础配置
[root@Centos7 ~]# hostnamectl set-hostname ansible
[root@Centos7 ~]# su
[root@ansible ~]# mount /dev/cdrom /mnt/
mount: /dev/sr0 写保护,将以只读方式挂载
mount: /dev/sr0 已经挂载或 /mnt 忙
/dev/sr0 已经挂载到 /mnt 上
[root@ansible ~]# systemctl stop firewalld
[root@ansible ~]# setenforce 0
setenforce: SELinux is disabled
[root@ansible ~]# vim /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.100.202 ansible
192.168.100.203 node1
192.168.100.204 node2
[root@ansible ~]# scp /etc/hosts root@192.168.100.203:/etc/hosts
[root@ansible ~]# scp /etc/hosts root@192.168.100.204:/etc/hosts
[root@Centos7 ~]# hostnamectl set-hostname node1
[root@Centos7 ~]# su
[root@node1 ~]# systemctl stop firewalld
[root@node1 ~]# setenforce 0
setenforce: SELinux is disabled
[root@Centos7 ~]# hostnamectl set-hostname node2
[root@Centos7 ~]# su
[root@node2 ~]# systemctl stop firewalld
[root@node2 ~]# setenforce 0
setenforce: SELinux is disabled
******(2)在ansible服务器上安装ansible(离线安装)
[root@ansible ~]# ll #上传ansible的yum库
总用量 8
-rw-------. 1 root root 1264 1月 12 18:27 anaconda-ks.cfg
drwxr-xr-x 3 root root 4096 6月 20 00:31 ansible
[root@ansible ~]# vim /etc/yum.repos.d/centos.repo #修改yum源
[aaa]
name=aaa
baseurl=file:///mnt
enabled=1
gpgcheck=0
[ansible]
name=ansible
baseurl=file:///root/ansible
enabled=1
gpgcheck=0
#保存退出
[root@ansible ~]# yum -y install ansible
。。。。。。
完毕!
#ansible部署完成
(在线安装)
直接安装使用epel的yum源:
[root@ansible ~]# cat >>/etc/yum.repos.d/epel.repo<<'EOF'
[epel]
name=epel repo
baseurl=https://mirrors.tuna.tsinghua.edu.cn/epel/7/$basearch
enabled=1
gpgcheck=0
EOF
[root@ansible ~]# yum install ansible
或者使用pip来安装最新版的ansible: (因为ansible每个版本释放出来之后都会先提交到pypi)
[root@ansible ~]# pip3 install ansible
#注意:
#使用各系统的包管理工具(如yum)安装Ansible时自动会提供一些配置文件,如/etc/ansible/ansible.cfg。
#而使用pip安装的Ansible默认不提供配置文件。
Ansible参数补全功能:
#在Ansible2.9版本之后,Ansible支持选项补全功能,这需要依赖与python的argcomplete插件
(1)安装argcomplete:
# CentOS/RHEL
yum -y install python-argcomplete
# 任何系统都可以使用pip工具安装argcomplete
pip3 install argcomplete
(2)安装完成后,还需激活该插件:
# 要求bash版本大于等于4.2
sudo activate-global-python-argcomplete
# 如果bash版本低于4.2,则单独为每个ansible命令注册补全功能
eval $(register-python-argcomplete ansible)
eval $(register-python-argcomplete ansible-config)
eval $(register-python-argcomplete ansible-console)
eval $(register-python-argcomplete ansible-doc)
eval $(register-python-argcomplete ansible-galaxy)
eval $(register-python-argcomplete ansible-inventory)
eval $(register-python-argcomplete ansible-playbook)
eval $(register-python-argcomplete ansible-pull)
eval $(register-python-argcomplete ansible-vault)
最后,退出当前Shell重新进入,或者简单的直接执行如下命令即可:
exec $SHELL
#然后就可以按tab一次或两次补全参数或提示参数。例如,下面选项输入到一半的时候,按一下tab键就会补全得到ansible --syntax-check。
$ ansible --syn
(3)Ansible Inventory文件
-
Inventory文件通常用于定义被管理的主机的认证信息,例如:ssh 登陆用户名、密码,以及key相关信息,
-
主机可以被分配到组中,一个组可以有多个主机,并且在操作这个组时,组中的所有主机都会收到操作,组与主机组之间的关系都是通过inventory进行配置
-
默认路径为:/etc/ansible/hosts
-基于密码连接远程主机
[root@ansible ~]# vim /etc/ansible/hosts #在末尾添加即可,整个文件都是注释行
。。。。。。
[web]
192.168.100.203 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass="123123"
192.168.100.204 ansible_ssh_port=22 ansible_ssh_user=root ansible_ssh_pass="123123"
#保存退出
#格式可以写成很多种,按上面的标准格式还可以写成:
[web]
192.168.100.20[7:8] ansible_ssh_user=root ansible_ssh_pass="123123" #表示207-8主机
[web]
192.168.100.20[7:8]
[web:vars] #设置web组的密码,需要加vars,这个密码会对web组中所有主机生效
ansible_ssh_pass="123123"
-基于密钥连接
[root@ansible ~]# ssh-keygen -t rsa #先创建密钥,全部回车即可
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): #默认存放路径
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:jGc6hl1/zSJLzeB2rt7Wyhqg3WXUpp9rjrnC/UV8YEw root@ansible
The key's randomart image is:
+---[RSA 2048]----+
| E |
| + |
| . * |
| o . + o |
| . S . + +|
| o B = * + o.|
| . * ..O.*.= .|
| . . ooXo+oo |
| .==O*+ |
+----[SHA256]-----+
[root@ansible ~]# cd .ssh/
[root@ansible .ssh]# ll
总用量 8
-rw------- 1 root root 1679 6月 20 01:03 id_rsa
-rw-r--r-- 1 root root 394 6月 20 01:03 id_rsa.pub
[root@ansible .ssh]# ssh-copy-id 192.168.100.203 #复制公钥给两台主机
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host '192.168.100.203 (192.168.100.203)' can't be established.
ECDSA key fingerprint is SHA256:VhTZ5YxS5af2rHtfCvyc6ehXh3PD2A8KY2MyE6rHjiU.
ECDSA key fingerprint is MD5:e8:41:d2:8a:7e:e9:a9:47:a3:f0:29:be:e9:6d:df:51.
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
root@192.168.100.203's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh '192.168.100.203'"
and check to make sure that only the key(s) you wanted were added.
[root@ansible .ssh]# ssh-copy-id 192.168.100.204
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host '192.168.100.204 (192.168.100.204)' can't be established.
ECDSA key fingerprint is SHA256:VhTZ5YxS5af2rHtfCvyc6ehXh3PD2A8KY2MyE6rHjiU.
ECDSA key fingerprint is MD5:e8:41:d2:8a:7e:e9:a9:47:a3:f0:29:be:e9:6d:df:51.
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
root@192.168.100.204's password:
Number of key(s) added: 1
Now try logging into the machine, with: "ssh '192.168.100.204'"
and check to make sure that only the key(s) you wanted were added.
[root@ansible .ssh]# cd
[root@ansible ~]# vim /etc/ansible/hosts #修改hosts文件
。。。。。。
[web]
192.168.100.203
192.168.100.204
#保存退出
[root@ansible ~]# ansible web -m ping #测试,web是组,-m调用ping模块
192.168.100.203 | SUCCESS =>
"changed": false,
"ping": "pong"
192.168.100.204 | SUCCESS =>
"changed": false,
"ping": "pong"
-主机组的使用
#主机组的大概使用就是上面的方法进行修改,下面的是把主机组加入另一个主机组
[root@ansible ~]# vim /etc/ansible/hosts #修改hosts文件
。。。。。。
[web]
192.168.100.203
[data]
192.168.100.204
[all:children] #必须加children才可以往组中加入组,不然会报错
web
data
#保存退出
#下面是测试
[root@ansible ~]# ansible web -m ping
192.168.100.203 | SUCCESS =>
"changed": false,
"ping": "pong"
[root@ansible ~]# ansible data -m ping
192.168.100.204 | SUCCESS =>
"changed": false,
"ping": "pong"
[root@ansible ~]# ansible all -m ping
192.168.100.204 | SUCCESS =>
"changed": false,
"ping": "pong"
192.168.100.203 | SUCCESS =>
"changed": false,
"ping": "pong"
-临时指定inventory文件
******(1)先在写一份主机清单
[root@ansible ~]# echo """
[aaa]
192.168.100.203
192.168.100.204
""" > aaa #上面已经做了密钥,所以之后的主机清单无需写用户端口密码等信息
[root@ansible ~]# cat aaa
[aaa]
192.168.100.203
192.168.100.204
******(2)进行测试
[root@ansible ~]# ansible aaa -m ping -i aaa #-i就是指定主机清单,不指定就是默认的主机清单
192.168.100.204 | SUCCESS =>
"changed": false,
"ping": "pong"
192.168.100.203 | SUCCESS =>
"changed": false,
"ping": "pong"
-Inventory内置参数
参数 | 作用 | 例子 |
---|---|---|
ansible_ssh_host | 定义hosts ssh地址 | ansible_ssh_host=192.169.1.100 |
ansible_ssh_port | 定义hosts ssh 端口 | ansible_ssh_port=3000 |
ansible_ssh_user | 定义hosts ssh认证用户 | ansible_ssh_user=user |
ansible_ssh_pass | 定义hosts ssh认证密码 | ansible_ssh_pass=pass |
ansible_sudo | 定义hosts sudo用户 | ansible_sudo=www |
ansible_sudo_pass | 定义hosts sudo密码 | ansible_sudo_pass=pass |
ansible_sudo_exe | 定义hosts sudo路径 | ansible_sudo_exe=/usr/bin/sudo |
ansible_connection | 定义hosts连接方式 | ansible_connection=local |
ansible_ssh_private_key_file | 定义hosts私钥 | ansible_ssh_private_key_file=/root/key |
ansible_ssh_shell_type | 定义hosts shell类型 | ansible_ssh_shell_type=bash |
ansible_python_interpreter | 定义hosts任务执行python路径 | ansible_python_interpreter=/usr/bin/python2.6 |
ansible___*___interpreter | 定义hosts其它语言解析路径 | ansible_"_interpreter=/usr/bin/ruby |
三、Ansible Ad-hoc模式常用模块
-ansible命令格式
- 常用命令参数
-a MODULE_ARGS #模块参数,模块的命令
-C , --check #检查语法,通常是剧本写完之后用来检查语法的
-f FORKS #并发,后面跟并发数
--list-hosts #列出主机列表
-m MODULE_ARGS #指定模块
-o #使用精简输出,会把输出的相关信息合并成一行
- 示例:
[root@ansible ~]# ansible web -m shell -a "ls" #-m指定shell模块,-a指定命令ls
192.168.100.203 | SUCCESS | rc=0 >>
anaconda-ks.cfg
[root@ansible ~]# ansible all -m shell -a "ls" -o #-o精简输出
192.168.100.203 | CHANGED | rc=0 | (stdout) anaconda-ks.cfg
192.168.100.204 | CHANGED | rc=0 | (stdout) anaconda-ks.cfg
[root@ansible ~]# ansible all --list-hosts #列出all组中的主机
hosts (2): #注意这个不是组名
192.168.100.203
192.168.100.204
- 命令说明:
ansible | web | -m | shell | -a | ls |
---|---|---|---|---|---|
ansible命令 | 主机组名称或者主机ip | ansible的选项,-m指定模块 | 指定shell模块 | 指定模块中要使用的命令 | 模块中的命令 |
指定的命令可以有多个,如果不加-m指定模块,那么默认使用的模块是command,想要使用模块中的命令必须加-a选项,选项也可以有多个,比如还可以加-o精简输出
- 主机组的相关使用
- 主机的匹配:
[root@ansible ~]# ansible 192.168.100.203 -m ping
192.168.100.203 | SUCCESS =>
"changed": false,
"ping": "pong"
[root@ansible ~]# ansible 192.168.100.203,192.168.100.204 -m ping
192.168.100.203 | SUCCESS =>
"changed": false,
"ping": "pong"
192.168.100.204 | SUCCESS =>
"changed": false,
"ping": "pong"
[root@ansible ~]# ansible all -m ping #all表示所有主机
192.168.100.203 | SUCCESS =>
"changed": false,
"ping": "pong"
192.168.100.204 | SUCCESS =>
"changed": false,
"ping": "pong"
[root@ansible ~]# vim /etc/ansible/hosts
。。。。。。
[web]
192.168.100.203
[data]
192.168.100.204
#保存退出
[root@ansible ~]# ansible all -m ping
192.168.100.203 | SUCCESS =>
"changed": false,
"ping": "pong"
192.168.100.204 | SUCCESS =>
"changed": false,
"ping": "pong"
- 组的匹配
root@ansible ~]# cat /etc/ansible/hosts
。。。。。。
[web]
192.168.100.203
[data]
192.168.100.204
#保存退出
[root@ansible ~]# ansible web -m ping
192.168.100.203 | SUCCESS =>
"changed": false,
"ping": "pong"
[root@ansible ~]# ansible data -m ping
192.168.100.204 | SUCCESS =>
"changed": false,
"ping": "pong"
[root@ansible ~]# vim /etc/ansible/hosts
[web]
192.168.100.203
192.168.100.204
[data]
192.168.100.204
#保存退出
[root@ansible ~]# ansible 'web:!data' -m ping #匹配web组中有的,data中没有的所有主机
192.168.100.203 | SUCCESS =>
"changed": false,
"ping": "pong"
[root@ansible ~]# ansible 'web:&data' -m ping #匹配web和data组中都有的所有主机,也就是交集
192.168.100.204 | SUCCESS =>
"changed": false,
"ping": "pong"
[root@ansible ~]# ansible 'web:data' -m ping #匹配web和data组中的所有主机
192.168.100.204 | SUCCESS =>
"changed": false,
"ping": "pong"
192.168.100.203 | SUCCESS =>
"changed": false,
"ping": "pong"
-ansible-doc常用命令
-j #以json格式显示所有模块的信息
-l #列出所有的模块,小写l
-s #查看模块的常用参数,后面跟模块名称
[root@ansible ~]# ansible-doc -j
[root@ansible ~]# ansible-doc -l
[root@ansible ~]# ansible-doc -l | wc -l #所有模块
1852
[root@ansible ~]# ansible-doc -s shell #查看shell的常用参数
四、命令相关模块
-command模块常用的命令
#command,这是ansible的默认模块,要注意的是,在shell模块中的一些特殊字符,例如>、<、|、;、&、$等是不能在command模块中使用的,如果想要使用,则需要使用shell模块
******查看command模块常用参数
[root@ansible ~]# ansible-doc -s command
******在web组的所有服务器上执行ls的名称,默认是在当前用户的家目录,也就是root
[root@ansible ~]# ansible web -a ls
192.168.100.203 | SUCCESS | rc=0 >>
anaconda-ks.cfg
192.168.100.204 | SUCCESS | rc=0 >>
anaconda-ks.cfg
******chdir,这是切换目录的命令,一般在编译时候使用
[root@ansible ~]# ansible web -a 'chdir=/tmp pwd'
192.168.100.203 | SUCCESS | rc=0 >>
/tmp
192.168.100.204 | SUCCESS | rc=0 >>
/tmp
******creates,这是测试目录或者文件是否存在的命令,要注意的是,如果目录或者文件存在,则不执行后面的操作,不存在才会执行后面的命令
[root@ansible ~]# ansible web -a 'creates=/tmp ls /etc/passwd' #如果tmp目录存在,则不执行后面的命令
192.168.100.204 | SUCCESS | rc=0 >>
skipped, since /tmp exists #发现没有执行后面的ls /etc/passwd,说明tmp目录存在
192.168.100.203 | SUCCESS | rc=0 >>
skipped, since /tmp exists
[root@ansible ~]# ansible web -a 'creates=/aaa pwd'
192.168.100.203 | SUCCESS | rc=0 >> #发现pwd执行成功,说明aaa目录不存在
/root
192.168.100.204 | SUCCESS | rc=0 >>
/root
******removes,这个和creates相反,是当目录或者文件存在时才会执行后面的操作,不存在则不执行
[root@ansible ~]# ansible web -a 'removes=/tmp pwd'
192.168.100.204 | SUCCESS | rc=0 >> #发现成功执行pwd命令,说明tmp命令存在
/root
192.168.100.203 | SUCCESS | rc=0 >>
/root
[root@ansible ~]# ansible web -a 'removes=/aaa pwd'
192.168.100.204 | SUCCESS | rc=0 >> #没有执行pwd命令,说明aaa目录不存在
skipped, since /aaa does not exist
192.168.100.203 | SUCCESS | rc=0 >>
skipped, since /aaa does not exist
-shell模块常用命令
专门用来执行shell命令的模块,和command模块相同,参数基本一样,都有着chdir、creates、removes等参数
******查看shell模块的常用参数
[root@ansible ~]# ansible-doc -s shell
******使用shell模块其实可以直接使用linux命令
[root@ansible ~]# ansible web -m shell -a 'mkdir /aaa'
[WARNING]: Consider using the file module with state=directory rather than running mkdir. If you need to use command because file 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.
#上面的提示只是在说建议使用ansible中shell模块的参数,不影响操作
192.168.100.203 | SUCCESS | rc=0 >>
192.168.100.204 | SUCCESS | rc=0 >>
[root@node1 ~]# cd /aaa/ #进入node1节点进行验证,发现创建成功
[root@node1 aaa]# pwd
/aaa
[root@ansible ~]# ansible web -m shell -a 'cd /aaa && pwd' #使用&&可以执行多条命令
192.168.100.204 | SUCCESS | rc=0 >>
/aaa
192.168.100.203 | SUCCESS | rc=0 >>
/aaa
[root@ansible ~]# ansible web -m shell -a 'cd /aaa && pwd && cd /tmp && pwd'
192.168.100.203 | SUCCESS | rc=0 >>
/aaa
/tmp
192.168.100.204 | SUCCESS | rc=0 >>
/aaa
/tmp
[root@ansible ~]# ansible web -m shell -a 'cd /aaa && touch 1.txt && ls' #使用这种方式,在每次执行时都会更新文件的时间戳
192.168.100.204 | SUCCESS | rc=0 >>
1.txt
192.168.100.203 | SUCCESS | rc=0 >>
1.txt
[root@ansible ~]# ansible web -m shell -a 'creates=/aaa/2.txt cd /aaa && touch 2.txt && ls' #利用creates参数创建文件,就不会更新文件的时间戳,当aaa目录下的2.txt文件不存在时才会执行后面的操作
192.168.100.203 | SUCCESS | rc=0 >>
1.txt
2.txt
192.168.100.204 | SUCCESS | rc=0 >>
1.txt
2.txt
-script模块
script是用于在被管理器上执行shell脚本的模块,脚本无需在被管理机器上面存在,只需要在ansible服务器上存在就行
******查看script模块的常用参数
[root@ansible ~]# ansible-doc -s script
******编写shell脚本
[root@ansible ~]# vim a.sh
#!/bin/bash
echo "hello world"
#保存退出
******在所有的被管理机器上执行该脚本
[root@ansible ~]# ansible all -m script -a '/root/a.sh'
192.168.100.203 | SUCCESS =>
"changed": true,
"rc": 0,
"stderr": "Shared connection to 192.168.100.203 closed.\\r\\n",
"stderr_lines": [以上是关于Ansible概述的主要内容,如果未能解决你的问题,请参考以下文章