以下配置都是以下表环境为例
角色 | 主机名 | IP地址 | 组名 | CPU |
控制主节点 | ansiblecontrol | 192.168.242.10 | --- | 2C |
被管理节点 | web1 | 192.168.242.11 | webservers | 2C |
被管理节点 | web2 | 192.168.242.12 | webservers | 2C |
Ansible安装
安装前提
对管理主机要求
目前,只要机器上安装了 Python 2.6 (windows 系统不可以做控制主机 ) ,都可以运行 Ansible.
主机的系统可以是 Red Hat, Debian, CentOS, OS X, BSD 的各种版本等等。
对托管主机要求
托管节点上需要安装 Python 2.4 及以上的版本。但如果版本低于 Python 2.5 ,则需要额外安装
一个模块 : python-simplejson
管理主机:
1 、管理你的被管理节点
定义资产管理清单-- 在资产清单内定义的就是被管理节点
2 、定义任务
通过ad-hoc 、 playbook 、 role 的方式定义任务
3 、下发任务
在Ansible 管理节点上定义的任务,下发到被管理节点上!
管理节点,是要和被管理节点建立通信
被管理节点:
1、执行 Ansible Controller 下发的任务
2、提供应用访问
安装Ansible
Ansible环境准备
角色名 | IP |
master.zjm.com | 192.168.242.10 |
node1.zjm.com | 192.168.242.11 |
node2.zjm.com | 192.168.242.12 |
源码安装:源码安装需要python2.6以上版本,其依赖模块paramiko、PyYAML、Jinja2、httplib2、 simplejson、pycrypto模块,以上模块可以通过pip或easy_install 进行安装
pip安装:pip是专门用来管理Python模块的工具,Ansible会将每次正式发布都更新到pip仓库中。所以通过pip 安装或更新Ansible,会比较稳妥的拿到最新稳定版。
yum安装
安装 CentOS 7 的 EPEL repository
[root@master ~]# yum install -y epel-release
使用 yum 来安装 ansible
[root@master ~]# yum install -y ansible
查看ansible的版本
[root@master ~]# ansible --version
ansible 2.9.23
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 = /bin/ansible
python version = 2.7.5 (default, Aug 7 2019, 00:51:29) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
ad-hoc的方式确定下ansible能否正常工作
[root@master ~]# ansible localhost -m ping
localhost | SUCCESS => {
"changed": false,
"ping": "pong"
}
配置运行环境
配置Ansible环境
Ansible配置文件是以ini格式存储配置数据的,在 Ansible 中,几乎所有的配置项都可以通过
Ansible 的 playbook 或环境变量来重新赋值。 在运行 Ansible 命令时,命令将会按照预先设定的顺序查找配置文件, 如下所示
1 ) ANSIBLE_CONFIG:首 先, Ansible 命令会检查环境变量,及这个环境变量将指向的配置文件。
2 ) ./ansible.cfg: 其次, 将会检查当前目录下的 ansible.cfg 配置文件。
3 )~/.ansible.cfg :再次, 将会检查当前用户 home 目录下的 . ansible.cfg 配置文件。
4 ) /etc/ansible/ansible.cfg: 最后,将会检查在用软件包管理工具安装 Ansible 时自动产生的配置文件。
1. 使用环境变量方式来配置
大多数的 Ansible 参数可以通过设置带有 ANSIBLE, 开头的环境变量进行配置,参数名称必须都是大写 字母, 如下配置项: export ANSIBLE_SUDO_USER=root
设置了环境变量之后, ANSIBLE_SUDO_USER 就可以在 playbook 中直接引用。
2. 设置 ansible.cfg 配置参数
• inventory :这个参数表示资源清单 inventory 文件的位置
• library :这个 library 参数就是指向存放 Ansible 模块的目录
• forks :设置默认情况下 Ansible 最多能有多少个进程同时工作, 默认设置最多 5 个进程并行处理。
• sudo_user :设置默认执行命令的用户
• remote_port :指定连接被管节点的管理端口, 默认是 22
• host_key_checking :这是设置是否检查 SSH 主机的密钥。
• timeout :这是设置 SSH 连接的超时间隔, 单位是秒
• log_path :Ansible 系统默认是不记录日志的, 如果想把 Ansible 系统的输出记录到日志文件中,需要设置 _ 来指定一个存储 日志的文。
使用公钥认证
如果有台被管节点重新安装系统并在 known hosts 中有了与之前不同的密钥信息,就会提示一个密钥不匹配的错误信息, 直到被纠正为止。 在使用 Ansible 时, 如果有台被管节点没有在 known_hosts 中被初始化,将会在使用 Ansible 或定时执行 Ansible 时提示对 key 信息的确认。
如果你不想出现这种情况, 并且你明白禁用此项行为的含义, 只要修改 home 目录下
~/.ansible.cfg 或 /etc/ansible/ansible.cfg 的配置项:
[defaults]
host_key_checking = False
或者直接在控制主机的操作系统中设置环境变量如下:
$export ANSIBLE_HOST_KEY_CHECKING=False
配置 Linux 主机 SSH 无密码访问
为了避免 Ansible 下发指令时输入目标主机密码, 通过证书签名达到 SSH 无密码是一个好的方案。推荐使用 ssh-keygen 与 ssh-copy-id 来实现快速证书的生成及公钥下发,其中 ssh-keygen 生产一对密钥,使用ssh-copy-id 来下发生成的公钥。
或者直接在控制主机的操作系统中设置环境变量, 如下所示 :
$export ANSIBLE_HOST_KEY_CHECKING=False
[root@master ~]# vi /etc/hosts
[root@master ~]# tail -3 /etc/hosts
192.168.242.10 master
192.168.242.11 node1
192.168.242.12 node2
1、在控制主机上创建密钥
[root@master ~]# ssh-keygen -f ~/.ssh/id_rsa -P '' -q
[root@master ~]# ls -l ~/.ssh
total 8
-rw-------. 1 root root 1679 Aug 11 23:02 id_rsa
-rw-r--r--. 1 root root 393 Aug 11 23:02 id_rsa.pub
2、下发密钥到被管理节点
[root@master ~]# ssh-copy-id node1
[root@master ~]# ssh-copy-id node2
3、验证SSH无密钥配置是否成功
[root@master ~]# for name in node{1,2}; do ssh $name hostname; done
node1
node2
Ansible Inventory
在大规模的配置管理工作中,我们需要管理不同业务的不同机器,这些机器的信息都存放在Ansible的Inventory组件里面,在我们工作中配置部署针对的主机必须先存放在Inventory里面,这样才能使用Ansible对它进行操作,默认Ansible的Inventory是一个静态的INI格式的文件/etc/ansible/hosts,当然,还可以通过ANSIBLE_HOSTS环境变量指定或者运行ansible和ansible-playbook的时候用-i参数临时设置
定义主机和主机组
具体的定义实例
[root@master ~]# vi /etc/ansible/hosts
[root@master ~]# tail -11 /etc/ansible/hosts
192.168.242.11 ansible_ssh_pass='123'
192.168.242.12 ansible_ssh_pass='123'
[docker]
192.168.242.1[1:2]
[docker:vars]
ansible_ssh_pass='123'
[ansible:children]
docker
第一二行:定义了一个主机是192.168.242.11/12,使用Inventory内置变量定义了SSH登录密码
第三行:定义了一个docker的组,第四行:定义了docker组下有两台主机192.168.242.11/192.168.242.12,用':'可以表示连续的多个,例如1:5,则为从一到五
第五六行:针对docker组使用了Inventory内置变量定义了SSH登陆密码
第七八行:定义了一个ansible的组,在这个组下包含了docker组
下面是分别针对不同的主机和主机组进行 Ansible 的 ping 模块检测
[root@master ~]# ansible 192.168.242.11:192.168.242.12 -m ping -o
192.168.242.12 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}
192.168.242.11 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}
[root@master ~]# ansible docker -m ping -o
192.168.242.12 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}
192.168.242.11 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}
[root@master ~]# ansible ansible -m ping -o
192.168.242.12 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}
192.168.242.11 | SUCCESS => {"ansible_facts": {"discovered_interpreter_python": "/usr/bin/python"}, "changed": false, "ping": "pong"}
动态Inventory
在实际应用部署中会有大量的主机列表,如果手动维护这些列表将是一个非常繁琐的事情,其实Ansible还支持动态的Inventory,动态Inventory就是Ansible所有的Inventory文件里面的主机列表和变量信息都支持从外部拉取
关于引用动态 Inventory 的功能配置只需要把 ansible.cfg 文件中 inventory 的定义值改成一个执行脚本即可。这个脚本的内容不受任何编程语言限制,但是这个脚本使用参数时有一定的规范并且对脚本 执行的结果也有要求。这个脚本需要支持两个参数
--list 或者 -l: 这个参数运行后会显示所有的主机以及主机组的信息( JSON 格式)。
--host 或者 -H: 这个参数后面需要指定一个 host ,运行结果会返回这台主机的所有信息( 包括认证信息、主机变量等 ) ,也是 jSON 格式。
这个脚本定义了两个函数, lists 在指定 --list 时执行, hosts 在指定 --host 时执行
[root@master ~]# vi hosts.py
[root@master ~]# cat hosts.py
#!/usr/bin/env python3
import argparse
import sys
import json
def lists():
r = {}
h = [ '192.168.242.1' + str(i) for i in range(0,2) ]
hosts = {'host': h}
r['docker'] = hosts
return json.dumps(r,indent=3)
def hosts(name):
r = {'ansible_ssh_pass': '123'}
cpis=dict(r.items())
return json.dumps(cpis)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-l', '--list' , help='hosts list' , action='store_true')
parser.add_argument('-H', '--host', help='hosts vars')
args = vars(parser.parse_args())
if args['list']:
print(lists())
elif args['host']:
print(hosts(args['host']))
else:
parser.print_help()
测试脚本
[root@master ~]# chmod +x hosts.py
[root@master ~]# ./hosts.py -l
{
"docker": {
"host": [
"192.168.242.10",
"192.168.242.11",
"192.168.242.12"
]
}
}
[root@master ~]# ./hosts.py -H 192.168.242.12
{"ansible_ssh_pass": "123"}
Ansible组成介绍
[root@master ~]# tree /etc/ansible/
/etc/ansible/
├── ansible.cfg #ansible的配置文件
├── hosts #资源清单文件
└── roles
1 directory, 2 files
主机联通性测试
#修改主机与组的配置
[root@master ~]# cat >> /etc/ansible/hosts << EOF
> [webservers]
> node[1:2]
> EOF
#测试一台主机
[root@master ~]# ansible node1 -m ping
node1 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
#测试一组主机
[root@master ~]# ansible webservers -m ping
node1 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
node2 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
批量执行命令
#使用ansible在远程机器输出“hello ansible!"
#使用shell模块
[root@master ~]# ansible webservers -m shell -a '/bin/echo hello ansible!' -o
node2 | CHANGED | rc=0 | (stdout) hello ansible!
node1 | CHANGED | rc=0 | (stdout) hello ansible!
#使用command模块
[root@master ~]# ansible webservers -a '/bin/echo hello ansible!' -o
node1 | CHANGED | rc=0 | (stdout) hello ansible!
node2 | CHANGED | rc=0 | (stdout) hello ansible!
#使用raw模块
[root@master ~]# ansible webservers -m raw -a '/bin/echo hello ansible!'
node1 | CHANGED | rc=0 >>
hello ansible!
Shared connection to node1 closed.
node2 | CHANGED | rc=0 >>
hello ansible!
Shared connection to node2 closed.
获取帮助信息
在 Ansible 中有 8 个主要的 Ansible 管理工具,每个管理工具都是一系列的模块、参数支持。随时可获取的帮助信息对了解掌握 Ansible 系统非常重要。 对于 Ansible 每个工具,都可以简单地在命令后面加上 -h 或 -help 直接获取帮助。
ansible-doc:用于查看模块信息
//参数-1 列出可使用的模块
[root@master ~]# ansible-doc -l
fortios_router_community_list Configure community lists in Fortinet's FortiOS and FortiGate
azure_rm_devtestlab_info Get Azure DevTest Lab facts
ecs_taskdefinition register a task definition in ecs
avi_alertscriptconfig Module for setup of AlertScriptConfig Avi RESTful Object
tower_receive Receive assets from Ansible Tower
netapp_e_iscsi_target NetApp E-Series manage iSCSI target configuration
azure_rm_acs Manage an Azure Container Service(ACS) instance
fortios_log_syslogd2_filter Filters for remote system server in Fortinet's FortiOS and FortiGate
//-s 列岀某个模块支持的动作
[root@master ~]# ansible-doc -s shell
- name: Execute shell commands on targets
shell:
chdir: # Change into this directory before running the command.
cmd: # The command to run followed by optional arguments.
creates: # A filename, when it already exists, this step will *not*
be run.
executable: # Change the shell used to execute the command. This
expects an absolute path
to the executable.
free_form: # The shell module takes a free form command to run, as a
string. There is no actual
parameter named 'free
form'. See the examples on
how to use this module.
removes: # A filename, when it does not exist, this step will *not*
be run.
stdin: # Set the stdin of the command directly to the specified
value.
stdin_add_newline: # Whether to append a newline to stdin data.
warn: # Whether to enable task warnings.
//-v 查看详细示例
[root@master ~]# ansible-doc -v shell
Using /etc/ansible/ansible.cfg as config file
> SHELL (/usr/lib/python2.7/site-packages/ansible/modules/commands/shell.py)
The `shell' module takes the command name followed by a list
of space-delimited arguments. Either a free form command or
`cmd' parameter is required, see the examples. It is almost
exactly like the [command] module but runs the command through
a shell (`/bin/sh') on the remote node. For Windows targets,
use the [win_shell] module instead.
* This module is maintained by The Ansible Core Team
* note: This module has a corresponding action plugin.
ansible:用于执行ad-hoc命令
ansible 是指令核心部分,其主要用于执行 ad-hoc 命令,即单条命令。默认后面需要跟主机和选项部分,默认不指定模块时,使用的是command 模块。
[root@master ~]# ansible localhost -a date
localhost | CHANGED | rc=0 >>
Thu Aug 12 00:22:39 CST 2021
另外, 在 Ansible 调试自动化脚本时候经常需要获取执行过程的详细信息, 可以在命令后面添加 -v 或 -vvv 得到详细的输出结果。
[root@master ~]# ansible node1 -m ping -vv
ansible 2.9.23
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, Nov 16 2020, 22:23:17) [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)]
Using /etc/ansible/ansible.cfg as config file
Skipping callback 'actionable', as we already have a stdout callback.
Skipping callback 'counter_enabled', as we already have a stdout callback.
Skipping callback 'debug', as we already have a stdout callback.
Skipping callback 'dense', as we already have a stdout callback.
Skipping callback 'dense', as we already have a stdout callback.
Skipping callback 'full_skip', as we already have a stdout callback.
Skipping callback 'json', as we already have a stdout callback.
Skipping callback 'minimal', as we already have a stdout callback.
Skipping callback 'null', as we already have a stdout callback.
Skipping callback 'oneline', as we already have a stdout callback.
Skipping callback 'selective', as we already have a stdout callback.
Skipping callback 'skippy', as we already have a stdout callback.
Skipping callback 'stderr', as we already have a stdout callback.
Skipping callback 'unixy', as we already have a stdout callback.
Skipping callback 'yaml', as we already have a stdout callback.
META: ran handlers
node1 | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python"
},
"changed": false,
"ping": "pong"
}
META: ran handlers
META: ran handlers