Ansible
一种集成 IT
系统的配置管理、应用部署、执行特定任务的开源平台。
Ansible 工具简介
Ansible
一种集成 IT
系统的配置管理、应用部署、执行特定任务的开源平台,是 AnsibleWorks
公司名下的项目,该公司由 Cobbler
及 Func
的作者于 2012
年创建成立。
常用的运维自动化工具(配置管理)有很多,例如:Ansible
、SaltStack
、Puppet
、Fabric
等。
Ansible
基于 Python
语言实现,由 Paramiko
和 PyYAML
两个关键模块构建。
工具特点
- 部署简单,只需在主控端部署
Ansible
环境,被控端无需做任何操作。 - 默认使用
SSH
(Secure Shell
)协议对设备进行管理。 - 主从集中化管理。
- 配置简单、功能强大、扩展性强。
- 支持
API
及自定义模块,可通过Python
轻松扩展。 - 通过
Playbooks
来定制强大的配置、状态管理。 - 对云计算平台、大数据都有很好的支持。
- 提供一个功能强大、操作性强的
Web
管理界面和REST API
接口 ----AWX
平台。
官网资源
Ansible 工具部署
小贴士:本文环境在未特殊声明时默认为 CentOS 7.5
角色 | 内网IP(LAN) | 主机名 |
---|---|---|
管理端 | 172.16.1.61 | m01 |
客户端 | 172.16.1.41 | backup |
客户端 | 172.16.1.31 | nfs01 |
实现从管理机 m01
到其他机器的密钥认证
0). ansible
借助公钥批量管理
[root@m01 ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub root@172.16.1.41
[root@m01 ~]# ssh-copy-id -i ~/.ssh/id_rsa.pub root@172.16.1.21
小贴士:利用非交换式工具实现批量分发公钥与批量管理服务器,需要先生成 RSA 密钥,此处不再复述。
1). ansible
安装
[root@m01 ~]# yum install ansible -y
2). ansible
版本
[root@m01 ~]# ansible --version
ansible 2.6.1
3). ansible
配置
[root@m01 ~]# vim /etc/ansible/hosts
[test]
172.16.1.31
172.16.1.41
注意:使用 []
定义了一个组,下面的地址均属于此组。
4). ansible
验证
[root@m01 ~]# ansible test -m ping
172.16.1.41 | SUCCESS => {
"changed": false,
"ping": "pong"
}
172.16.1.31 | SUCCESS => {
"changed": false,
"ping": "pong"
}
test
是指测试整组全部目标,也可单独指定地址仅测试单机。pong
是指目标测试为连通。
小贴士:ansible
是通过ssh
端口进行通信的。
5). ansible
格式
① | ② | ③ | ④ | ⑤ | ⑥ |
---|---|---|---|---|---|
ansible | test | -m | command | -a | 'uptime' |
命令 | 主机组 | 模块参数 | 模块名称 | 指定模块执行时的动作 | 模块动作 |
[root@m01 ~]# ansible test -m command -a "hostname"
172.16.1.41 | SUCCESS | rc=0 >>
backup
172.16.1.31 | SUCCESS | rc=0 >>
nfs01
6). ansible
语法
ansible <host-pattern> [-f forks] [-m module_name] [-a args] ...
参数列表:
-v,–verbose
详细模式,如果命令执行成功,输出详细的结果 (-vv –vvv -vvvv)
-i PATH,–inventory=PATH
指定 hosts 文件的路径,不指定时使用默认 hosts。
-f NUM,–forks=NUM
NUM 是指定一个整数,默认是 5 ,指定 fork 开启同步进程的个数。
-m NAME,–module-name=NAME
指定使用的 module 名称,默认是 command
-m DIRECTORY,–module-path=DIRECTORY
指定 module 的目录来加载 module ,默认是/usr/share/ansible,
-a,MODULE_ARGS
指定 module 模块的参数
-k,–ask-pass
提示输入 ssh 的密码,而不是使用基于 ssh 的密钥认证
–sudo
指定使用 sudo 获得 root 权限
-K,–ask-sudo-pass
提示输入 sudo 密码,与 –sudo 一起使用
-u USERNAME,–user=USERNAME
指定移动端的执行用户
-C,–check
测试此命令执行会改变什么内容,不会真正的去执行
Ansible 主机清单
Ansible
通过读取默认的主机清单配置 /etc/ansible/hosts
,来同时连接到多个远程主机,来执行远程操作任务的,但是如果要修改默认路径可以通过修改主配置文件 /etc/ansible/ansible.cfg
的 inventory
参数指定相应的路径。
[root@m01 ~]# grep "#inventory" /etc/ansible/ansible.cfg
#inventory = /etc/ansible/hosts
#inventory_plugins = /usr/share/ansible/plugins/inventory
#inventory_ignore_extensions = ~, .orig, .bak, .ini, .cfg, .retry, .pyc, .pyo
主机和组
Ansible
中主机和组(Hosts and Groups
)可以将很多主机整理为一组,以组单位进行相同的操作。
[root@m01 ~]# cat /etc/ansible/hosts
[test]
10.0.0.31
10.0.0.41
也可以使用域名来代替地址(需要在 /etc/hosts
中进行定义)
# 添加三台主机至 web (初版)
[web]
web1.domain.com
web2.domain.com
web3.domain.com
# 添加三台主机至 web (改良版)
[web]
web[1:3].domain.com
# 添加三台主机至 web (自定义端口)
[web]
web1.domain.com:10222
web2.domain.com
web3.domain.com
# 添加三台主机至 web (指定密码版)
[web]
web1.domain.com ansible_ssh_pass='123456'
web2.domain.com ansible_ssh_pass='123456'
web3.domain.com ansible_ssh_pass='123456'
# 添加三台主机至 web (指定密码改良版,前提为密码统一)
[web]
web[1:3].domain.com ansible_ssh_pass='123456'
# 添加三台主机至 web (指定密码拆分版,前提为密码统一)
[web]
web1.domain.com
web2.domain.com
web3.domain.com
[web:vars]
ansible_ssh_pass='123456'
# 定义多组,多组汇总整合
[apache]
10.0.0.1
10.0.0.2
10.0.0.3
[apache:vars]
ansible_ssh_pass='123456'
[nginx]
10.0.0.4
10.0.0.5
10.0.0.6
[nginx:vars]
ansible_ssh_pass='123456'
# web 组包括两个子组 apache nginx
[web:children]
apache
nginx
可使用 --list-hosts
显示组的成员
ansible nginx --list-hosts
ansible apache --list-hosts
ansible web --list-hosts
内置主机变量
参数 | 用途 |
---|---|
ansible\_ssh_host | 用于指定被管理的主机的真实IP |
ansible\_ssh_port | 用于指定连接到被管理主机的ssh端口号,默认是22 |
ansible\_ssh_user | ssh连接时默认使用的用户名 |
ansible\_ssh_pass | ssh连接时的密码 |
ansible\_sudo | 定义 sudo 用户 |
ansible\_sudo_pass | 定义 sudo 连接用户时的密码 |
ansible\_sudo_exec | 如果sudo命令不在默认路径,需要指定sudo命令路径 |
ansible\_ssh\_private\_key_file | 秘钥文件路径,秘钥文件如果不想使用ssh-agent管理时可以使用此选项 |
ansible\_shell_type | 目标系统的shell的类型,默认sh |
ansible_connection | SSH 连接的类型: local , ssh , paramiko |
ansible\_python_interpreter | 用来指定Python解释器的路径,默认为/usr/bin/python 同样可以指定ruby 、perl 的路径 |
ansible\_*_interpreter | 其他解释器路径,用法与ansible\_python_interpreter类似,这里"*"可以是ruby或perl等其他语言 |
Ansible 常用模块
在 ansible
中是指需要快速执行一条命令,并且不需要保存的命令,对于复杂的命令则使用 playbook
。
注意事项:关于命令执行结果的颜色
黄:对远程节点已进行相应修改
绿:对远程节点不进行相应修改,或者只是对远程节点信息进行查看
红:操作执行命令有异常
紫:表示对命令执行发出警告信息(可能存在的问题,提供建议)
command
模块
[root@m01 ~]# ansible test -m command -a "hostname"
提示:默认模块就是command
,因此-m command
可省略,仅可用于执行命令,若需要使用管道,请使用shell
模块。
补充:参数说明
argv --- 允许用户以列表与字符串的形式提供命令。
chdir --- 在运行命令之前切换到此目录。
creates --- 文件名,当它已经存在时,将不会运行此步骤。
removes --- 文件名,当它不存在时,不会运行此步骤。
stdin --- 将命令的stdin直接设置为指定值。
官方文档:command - Executes a command on a remote node
shell
模块
[root@m01 ~]# ansible test -f 50 -m shell -a "ip a | grep eth0"
提示:可以使用管道,以及命令的各种组合形式,但在编写剧本时此模块仅作为没有选择的最后方法,有专用模块的情况下推荐使用模块完成操作。
补充:参数说明
chdir --- 在运行命令之前进入此目录
creates --- 文件名,如果已存在,则不会运行此步骤。
removes --- 文件名,如果不存在,则不会运行此步骤。
executable --- 更改用于执行命令的shell。应该是可执行文件的绝对路径。
stdin --- 将命令的stdin直接设置为指定值。
官方文档:shell - Execute commands in nodes.
copy
模块
使用模块推送文件
[root@m01 ~]# ansible test -m copy -a "src=/etc/hosts dest=/tmp/test.txt"
对远端已有文件进行备份,再进行推送(按照时间信息备份,文件名会加上时间戳)
[root@m01 ~]# ansible test -m copy -a "src=/etc/hosts dest=/tmp/test.txt backup=yes"
不对远端已有文件进行备份,直接对远端文件进行写入 content
中的字符串
[root@m01 ~]# ansible test -m copy -a "content='xuliangwei' dest=/tmp/oldboy"
补充:参数说明
src --- 推送数据的源文件信息
dest --- 推送数据的目标路径
backup --- 对推送传输过去的文件,进行备份
content --- 直接批量在被管理端文件中添加内容
group --- 将本地文件推送到远端,指定文件属组信息
owner --- 将本地文件推送到远端,指定文件属主信息
mode --- 将本地文件推送到远端,指定文件权限信息
官方文档:copy - Copies files to remote locations
script
模块
第一步:编写脚本(在本地)
[root@m01 ~]# cat >> yum.sh <<'EOF'
#!/bin/bash
yum -y install glances
EOF
第二步:在本地使用模块推送至目标主机进行执行(并不需要进行传输脚本本身)
[root@m01 ~]# ansible test -m script -a "./yum.sh"
补充:参数说明
chdir --- 在远端服务器运行脚本前切换目录
creates --- 文件名,如果已存在,则不会运行此步骤
executable --- 用于调用脚本的可执行文件的名称或路径
free_form --- 本地脚本文件的路径,后跟可选参数。
removes --- 文件名,如果不存在,则不会运行此步骤。
官方文档:script - Runs a local script on a remote node after transferring it
yum
模块
安装 Apache
包
[root@m01 ~]# ansible test -m yum -a "name=httpd state=latest"
补充:参数说明
name ---指定要安装的软件包名称
state ---指定使用yum的方法
installed,present ---安装软件包
removed,absent ---移除软件包
latest ---安装最新软件包(推荐使用)
官方文档:yum - Manages packages with the yum package manager
file
模块
创建 /data
文件夹,并递归设置属主
[root@m01 ~]# ansible test -m file -a "path=/data state=diretory recurse=yes owner=root group=root"
创建 555
权限文件
[root@m01 ~]# ansible test -m file -a "path=/tmp/tt state=touch mode=555 owner=root group=root"
创建软链接
[root@m01 ~]# ansible test -m file -a "src=/tmp/tt path=/tmp/tt_link state=link"
补充:参数说明
path --- 指定远程主机目录或文件信息
src --- 软链接/硬链接 源地址
mode --- 文件权限
recurse --- 递归设置指定的文件属性(仅适用于目录)
state ---
directory --- 在远端创建目录
touch --- 在远端创建文件
link --- link或hard表示创建链接文件
absent --- 表示删除文件或目录
mode --- 设置文件或目录权限
owner --- 设置文件或目录属主信息
group --- 设置文件或目录属组信息
官方文档:file - Sets attributes of files
service
模块
[root@m01 ~]# ansible test -m service -a "name=crond state=stopped enabled=yes"
补充:参数说明
name --- 定义要启动服务的名称
state --- 指定服务状态是停止或是运行,停止和运行指令要写成过去时
started --- 启动
stopped --- 停止
restarted --- 重启
reloaded --- 重载
enabled --- 是否让服务开启自启动
官方文档:service - Manage services
user
模块
[root@m01 ~]# echo "bgx" | openssl passwd -1 -stdin
$1$1KmeCnsK$HGnBE86F/XkXufL.n6sEb.
[root@m01 ~]# ansible test -m user -a 'name=xlw password="$1$1KmeCnsK$HGnBE86F/XkXufL.n6sEb."'
补充:参数说明
append --- no,则仅将用户添加到组中指定的组,并将其从所有其他组中删除。
yes,将用户添加到组中指定的组。
comment --- 设置用户账户的描述
create_home --- 是否创建家目录(默认:yes)
force --- 与state = absent 一起使用时,行为与 userdel --force 一样
group --- (可选)设置用户的主要组(采用组名称)
state --- 账户是否存在,如果状态与所述状态不同,则采取行动。
system --- 创建帐户时,将其设置为yes会使用户成为系统帐户。无法在现有用户上更改此设置。
uid --- (可选)设置用户的UID。
扩展程序选项
官方文档:user - Manage user accounts
cron
模块
使用模块添加一条定时任务
[root@m01 ~]# ansible test -m cron -a "name='cron01' minute=* hour=* day=* month=* weekday=* job='/bin/bash /root/test.sh'"
禁用指定的定时任务
[root@m01 ~]# ansible test -m cron -a "name='ansible cron02' minute=0 hour=0 job='/bin/bash /root/test.sh' state=absent"
补充:参数说明
minute --- 分(默认 * )
hour --- 时(默认 * )
day --- 日(默认 * )
month --- 月(默认 * )
weekday --- 周(默认 * )
job --- 具体任务,要执行的命令,或者如果设置了env,则为环境变量的值。该命令不应包含换行符。
state --- 是否确保作业或环境变量存在或不存在。
user --- 定时任务的所属用户
官方文档:cron - Manage cron.d and crontab entries
mount
模块
挂载 NFS
分区
[root@m01 ~]# ansible test -m mount -a "path=/backup src=172.16.1.31:/data/www fstype=nfs opts=defaults,noatime state=mounted"
补充:参数说明
mounted --- 挂载设备,并将配置写入/etc/fstab
unmounted --- 卸载设备,不会清除/etc/fstab写入的配置
absent --- 卸载设备,会清理/etc/fstab写入的配置
官方文档:mount - Control active and configured mount points
unarchive
模块
使用模块解压文件并传输至目标主机
[root@m01 ~]# ansible test -m unarchive -a "src=./upload.zip dest=/data/www owner=www-data group=www-data"
补充:参数说明
remote_src --- 设置为 yes 表示存档文件已在远程系统上,而不是本地文件。
src --- 源文件地址
dest --- 解压至目录
mode --- 解压出的文件权限
owner --- 解压出的文件属主
group --- 解压出的文件属组
list_files --- 若为 yes 会输出解压文件的文件列表
官方文档:unarchive - Unpacks an archive after (optionally) copying it from the local machine.
查看帮助文档方法
查看所有模块说明信息
# ansible-doc -l
查看指定模块参数用法信息(以 yum
模块为例)
# ansible-doc yum
Ansible 剧本编写
playbook
是由一个或多个 play
组成的列表。play
的主要功能在于将事先归并为一组的主机装扮成事先通过 ansible 中的 task 定义好的角色。
从根本上来讲,所谓的task
无非是调用ansible
的一个module
将多个play
组织在一个playbook
中,即可以让他们联合起来按事先编排的机制完成某一个任务
注意: ansible
是通过 yaml
语法识别配置描述文件。扩展名是 .yaml
YAML
基础语法
官方网址:YAML
YAML:
1.缩进(层级关系) 2个空格,不能使用Tab。
2.冒号 key: value
3.短横线 - list1
- list2
1.缩进
- YAML使用一个固定的缩进风格表示数据层级结构关系,每个缩进由两个空格组成,不要使用tabs。
2.冒号
- 以冒号结尾,以冒号为路径的除外,其他所有冒号后面所有必须有空格。
3.短横线
- 表示列表项,使用一个短横杠加一个空格。
- 多个项使用同样的缩进级别作为同一列表。
Playbook 组件
handlers
用于当关注的资源发生变化时采取一定的操作,notify
这个动作可用于在每个play
的最后被触发,这样可以避免多次有改变发生时每次都执行指定的操作,
简而言之:在notify
中列出的操作称为handler
,也即notify
中调用handler
中定义的操作。
举个例子:
- hosts: all
- tasks:
- name: Copy conf To Remote Host
copy:
src: ./httpd.conf
dest: /etc/httpd/conf/httpd.conf
notify: "Restart Apache"
handlers:
- name: Restart Apache
service:
name: apache
state: restarted
import_playbook
在实际编写剧本时,为方便检查和书写,一般将对不同组的主机进行的操作分开编写为 .yaml
,然后使用一个文件统一将这些剧本统一起来。
注意:在之前的版本中可以使用include
,此组件就是用来代替include
(include
组件将在下个版本中取消)
举个例子:
# 按序执行以下 yaml
- import_playbook: base.yaml
- import_playbook: backup.yaml
- import_playbook: nfs.yaml
- import_playbook: web.yaml
操作案例
使用ansible playbook
批量部署 Apache
1. 创建环境
[root@m01 ~]# mkdir /srv/ansible -p
[root@m01 ~]# mkdir /srv/ansible/apache -p
[root@m01 ~]# cp /etc/httpd/conf/httpd.conf ./
2. 编辑剧本
[root@m01 ~]# vim /srv/ansible/apache/install.yaml
写入以下内容
- hosts: all
handlers:
- name: Restart Apache
service:
name: apache
state: restarted
tasks:
- name: Install Apache Package
yum:
name: httpd
state: latest
- name: Copy conf To Remote Host
copy:
src: ./httpd.conf
dest: /etc/httpd/conf/httpd.conf
notify: "Restart Apache"
- name: Ensure Apache is running
service:
name: httpd
state: started
enabled: yes
3. 语法检测
[root@m01 ~]# ansible-playbook install.yaml --syntax-check
4. 模拟测试
[root@m01 ~]# ansible-playbook -C install.yaml
PLAY [web] ****************************************************************************************
TASK [Gathering Facts] ****************************************************************************
ok: [172.16.1.7]
TASK [install httpd] ******************************************************************************
changed: [172.16.1.7]
TASK [enable httpd service] ***********************************************************************
changed: [172.16.1.7]
PLAY RECAP ****************************************************************************************
172.16.1.7 : ok=3 changed=2 unreachable=0 failed=0
5. 任务列表
[root@m01 ~]# ansible-playbook install.yaml --list-task
playbook: install.yaml
play #1 (web): web TAGS: []
tasks:
install httpd TAGS: []
enable httpd service TAGS: []
6. 实际执行
[root@m01 ~]# ansible-playbook install.yaml
附录
参考链接
本文由 柒 创作,采用 知识共享署名4.0
国际许可协议进行许可。
转载本站文章前请注明出处,文章作者保留所有权限。
最后编辑时间: 2018-07-31 18:34 PM