自动化运维利器Ansible基础
文章目录
Ansible官方网站
https://docs.ansible.com/ansible/2.9/modules/modules_by_category.html
Ansible 是一个 IT 自动化工具。它能配置系统、部署软件、编排更复杂的 IT 任务,如连续部署或零停机时间滚动更新。
Ansible 用 Python 编写,尽管市面上已经有很多可供选择的配置管理解决方案(例如 Salt、Puppet、Chef等),但它们各有优劣,而Ansible的特点在于它的简洁。让 Ansible 在主流的配置管理系统中与众不同的一点便是,它并不需要你在想要配置的每个节点上安装自己的组件。同时提供的另一个优点,如果需要的话,你可以在不止一个地方控制你的整个基础架构。
1、在ANSIBLE 管理体系中,存在"管理节点" 和 “被管理节点” 两种角色。
2、被管理节点通常被称为"资产"
3、在管理节点上,Ansible将 AdHoc 或 PlayBook 转换为Python脚本。
并通过SSH将这些Python 脚本传递到被管理服务器上。
在被管理服务器上依次执行,并实时的将结果返回给管理节点。
管理节点
OpenSSH Python >= 2.6 Ansible
被管理节点
OpenSSH python >= 2.4(samplesjson)
pip install ansible
yum -y install ansible
安装条件
管理节点
确保存在OpenSSH
确保Python 版本 >= 2.6
确保安装ansible
被管理节点
确保存在OpenSSH
确保Python 版本 >= 2.4 //若为2.4 版本,确保安装了python-samplesjson 扩展
不需要安装ansible
安装Ansible
yum 方式
[[email protected] ~]# yum install epel-release
[[email protected] ~]# yum install ansible
pip 方式
这里是使用系统自带的 python2 的环境
如果系统中安装的 pip ,可以直接使用 pip 安装 ansible
[[email protected] ~]# yum install epel-release
[[email protected] ~]# yum install python2-pip
[[email protected] ~]# pip install ansible
查看版本
[root@localhost ~]# ansible --version
ansible 2.9.15
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 2 2020, 13:16:51) [GCC 4.8.5 20150623 (Red Hat 4.8.5-39)]
管理节点与被管理节点建立SSH 信任关系
管理节点(ansible)中创建密钥对
ssh-keygen -t rsa -f ~/.ssh/id_rsa -N ""
将本地的公钥传输到被管理节点
每个被管理节点都需要传递
过程中需要被管理节点(这里是 192.168.116.146)的用户名(这里是 root)及密码
ssh-copy-id [email protected]
在管理节点上,测试与所有被管理节点的网络连通性。
ansible all -i 192.168.116.146, -m ping
在管理节点上,确保文件 /tmp/a.conf
发布到所有被管理节点
touch /tmp/a.conf
ansible all -i 192.168.116.146, -m copy -a "src=/tmp/a.conf dest=/tmp/a.conf"
Ansible 清单
静态资产
顾名思义它本身是一个文本文件,一个格式类似INI的文件。
默认情况下,Ansible的资产文件位于 /ect/ansible/hosts
。pip 安装的可能没有这个文件,创建一个即可。
自定义资产
cat inventory.ini
1.1.1.1
2.2.2.2
3.3.3.[1:15]
test01.neko.com
test03.neko.com
test[05:09].neko.com
[web_servers]
192.168.1.2
192.168.1.3
192.168.1.5
[db_servers]
192.168.2.2
192.168.2.3
192.168.1.5
[all_servers]
[all_servers:children]
db_servers
web_servers
验证自定义资产
通过 -i
参数指定自定义资产的位置即可(可以是全路径,也可以是相对路径)。
[root@localhost ~]# ansible all -i inventory.ini --list-host
hosts (29):
1.1.1.1
2.2.2.2
3.3.3.1
3.3.3.2
3.3.3.3
3.3.3.4
3.3.3.5
3.3.3.6
3.3.3.7
3.3.3.8
3.3.3.9
3.3.3.10
3.3.3.11
3.3.3.12
3.3.3.13
3.3.3.14
3.3.3.15
test01.neko.com
test03.neko.com
test05.neko.com
test06.neko.com
test07.neko.com
test08.neko.com
test09.neko.com
192.168.2.2
192.168.2.3
192.168.1.5
192.168.1.2
192.168.1.3
资产选择器
有时操作者希望只对资产中的一部分服务器进行操作,而不是资产中所有服务器。此时可以使用 Ansible 的资产选择器 PATTERN。
选择一组服务器
[root@localhost ~]# ansible web_servers -i inventory.ini --list-host
hosts (3):
192.168.1.2
192.168.1.3
192.168.1.5
[root@localhost ~]# ansible db_servers -i inventory.ini --list-host
hosts (3):
192.168.2.2
192.168.2.3
192.168.1.5
[root@localhost ~]# ansible all_servers -i inventory.ini --list-host
hosts (5):
192.168.2.2
192.168.2.3
192.168.1.5
192.168.1.2
192.168.1.3
使用 * 匹配
[root@localhost ~]# ansible 3.3.3.1* -i inventory.ini --list-hosts
hosts (7):
3.3.3.10
3.3.3.11
3.3.3.12
3.3.3.13
3.3.3.14
3.3.3.15
3.3.3.1
逻辑匹配
web_servers 和 db_servers 的并集
两个组内的所有主机
[root@localhost ~]# ansible 'web_servers:db_servers' -i inventory.ini --list-hosts
hosts (5):
192.168.1.2
192.168.1.3
192.168.1.5
192.168.2.2
192.168.2.3
web_servers 和 db_servers 的交集
[root@localhost ~]# ansible 'web_servers:&db_servers' -i inventory.ini --list-hosts
hosts (1):
192.168.1.5
排除
在 web_servers 中,但是不在 db_servers 中
[root@localhost ~]# ansible 'web_servers:!db_servers' -i inventory.ini --list-hosts
hosts (2):
192.168.1.2
192.168.1.3
Ansible Ad-Hoc 命令
命令格式
在快速入门中执行的 Ansible 命令,类似于批量执行命令。
在Ansible 中统称为Ansible Ad-Hoc
。
命令语法格式如下:
ansible pattern [-i inventory] -m module -a argument
pattern
资产选择器-i
指定资产清单文件的位置-m
指定本次Ansible ad-hoc 要执行的模块。可以类别成SHELL 中的命令。-a
模块的参数. 可以类比成SHELL 中的命令参数
实例
[root@localhost ~]# ansible all -i 192.168.116.146, -m copy -a "src=/tmp/a.conf dest=/tmp/a.conf"
模块类型
Ansible 模块分三种类型: 核心模块(core module)、附加模块(extra module)及用户自定义模块(consume module)。
常用帮助参数
列举出所有的核心模块和附加模块
# ansible-doc -l
查询某个模块的使用方法
# ansible-doc modulename
查询某个模块的使用方法,比较简洁的信息
# ansible-doc -s modulename
Example
# ansible-doc yum
# ansible-doc -s yum
常用模块
为了便于演示和操作,现在把之前的测试主机 IP 192.168.116.131
和 192.168.116.146
保存到 当前目录下的 hosts
文件中。
[root@localhost ~]# cat hosts
[dbservers]
192.168.116.131
[webservers]
192.168.116.146
command & shell 模块
[root@localhost ~]# ansible all -i hosts -a "echo 'hello'"
192.168.116.146 | CHANGED | rc=0 >>
hello
192.168.116.131 | CHANGED | rc=0 >>
hello
ansible all -i hosts -m shell -a "echo 'hello'"
192.168.116.146| CHANGED | rc=0 >>
hello
192.168.116.131 | CHANGED | rc=0 >>
hello
script 模块
将管理节点上的脚本传递到被管理节点(远程服务器)上进行执行。
Example
管理节点上的一个脚本
[root@localhost ~]#cat /root/a.sh
touch /tmp/testfile
执行
[root@localhost ~]# ansible webservers -i hosts -m script -a "/root/a.sh"
192.168.116.146 | CHANGED => {
"changed": true,
"rc": 0,
"stderr": "Shared connection to 192.168.116.146 closed.\r\n",
"stderr_lines": [
"Shared connection to 192.168.116.146 closed."
],
"stdout": "",
"stdout_lines": []
}
[root@localhost ~]# ansible webservers -i hosts -m shell -a "ls -l /tmp/testfile"
192.168.116.146 | CHANGED | rc=0 >>
-rw-r--r-- 1 root root 0 Dec 4 01:53 /tmp/testfile
[root@localhost ~]# ansible webservers -i hosts -m shell -a "ls -l /tmp/testfile"
192.168.116.146 | CHANGED | rc=0 >>
-rw-r--r-- 1 root root 0 Dec 4 01:53 /tmp/testfile
公钥的位置
[root@localhost ~]#cat .ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDeehrPNe/4wCIaITpetM4ApY+6e6cuxSt9PYP03iKXPZZfal3MlWROlAQF5clwP+qIW5BOGbZVP7t9uvZy68fZrZOoi8sP9pyxO/XlkpTTO2OG1G9Sbj2SPA3JaFPt2wV4kg43kAfJGjuKrfQPmshfj1SbaCvSRi9pExEt6BiKK5iCKYax+e/bZqpnQyKW/51FnpZcmqjhLbR3jLMcmglcH2dGyB6wa/qs4iU9cJ3KIMVzZYPjfwKD+amNhU3jDUrmJZ99ZLhBunrIzdHcG2pIqwerZJfpHQsJFst69lP569lRMZe5mcA3504yGqw3QiPP7oV/jbKMI2c9MXg54dF/ root@localhost
[root@localhost ~]#cat .ssh/id_rsa
copy 模块
copy 模块的主要用于管理节点和被管理节点之间的文件拷贝。
常用参数:
- src 指定拷贝文件的源地址
- dest 指定拷贝文件的目标地址
- backup 拷贝文件前,若原目标文件发生了变化,则对目标文件进行备份
- owner 指定新拷贝文件的所有者
- group 指定新拷贝文件的所有组
- mode 指定新拷贝文件的权限
Example
copy 管理节点上的 nginx.repo
到被管理节点上
[root@localhost ~]#cat nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
[root@localhost ~]# ansible webservers -i hosts -m copy -a "src=./nginx.repo dest=/etc/yum.repos.d/nginx.repo"
copy 前, 在被管理节点上对原文件进行备份
[root@localhost ~]# ansible all -i hosts -m copy -a "src=./nginx.repo dest=/etc/yum.repos.d/nginx.repo backup=yes"
copy 文件的同时对文件进行用户及用户组设置
[root@localhost ~]# ansible all -i hosts -m copy -a "src=./nginx.repo dest=/etc/yum.repos.d/nginx.repo owner=nobody group=nobody"
copy 文件的同时对文件进行权限设置
[root@localhost ~]# ansible all -i hosts -m copy -a "src=./nginx.repo dest=/etc/yum.repos.d/nginx.repo mode=0755"
yum 模块
等同于 Linux 上的YUM 命令, 对远程服务器上RPM包进行管理。
常用参数:
- name 要安装的软件包名, 多个软件包以英文逗号(,) 隔开
- state 对当前指定的软件安装、移除操作(present installed latest absent removed)
支持的参数
- present 确认已经安装,但不升级
- installed 确认已经安装
- latest 确保安装,且升级为最新
- absent 和 removed 确认已移除
Example
安装一个软件包
[root@localhost ~]# ansible webservers -i hosts -m yum -a "name=nginx state=present"
[root@localhost ~]# ansible webservers -i hosts -m yum -a "name=nginx state=latest"
[root@localhost ~]# ansible webservers -i hosts -m yum -a "name=nginx state=installed"
移除一个软件包
[root@localhost ~]# ansible webservers -i hosts -m yum -a "name=nginx state=absent"
[root@localhost ~]# ansible webservers -i hosts -m yum -a "name=nginx state=removed"
安装一个软件包组
[root@localhost ~]# ansible webservers -i hosts -m yum -a "name='@Development tools' state=present"
systemd 模块
Centos6 之前的版本使用
service
模块。请使用
ansible-doc service
命令自行查看帮助信息。
管理远程节点上的 systemd 服务,就是由 systemd 所管理的服务。
常用参数:
- daemon_reload 重新载入 systemd,扫描新的或有变动的单元
- enabled 是否开机自启动 yes|no
- name 必选项,服务名称 ,比如 httpd vsftpd
- state 对当前服务执行启动,停止、重启、重新加载等操作(started,stopped,restarted,reloaded)
Example
重新加载 systemd
[root@localhost ~]# ansible webservers -i hosts -m systemd -a "daemon_reload=yes"
启动 Nginx 服务
[root@localhost ~]# ansible webservers -i hosts -m systemd -a "name=nginx state=started"
关闭 Nginx 服务
[root@localhost ~]# ansible webservers -i hosts -m systemd -a "name=nginx state=stopped"
重启 Nginx 服务
[root@localhost ~]# ansible webservers -i hosts -m systemd -a "name=nginx state=restarted"
重新加载 Nginx 服务
[root@localhost ~]# ansible webservers -i hosts -m systemd -a "name=nginx state=reloaded"
将 Nginx 服务设置开机自启动
[root@localhost ~]# ansible webservers -i hosts -m systemd -a "name=nginx enabled=yes"
group 模块
在被管理节点上,对组进行管理。
常用参数:
- name 组名称, 必须的
- system 是否为系统组, yes/no , 默认是 no
- state 删除或这创建,present/absent ,默认是present
Example
创建普通组 db_admin
[root@localhost ~]# ansible dbservers -i hosts -m group -a "name=db_admin"
user 模块
用于在被管理节点上对用户进行管理。
常用参数:
-
name 必须的参数, 指定用户名
-
password 设置用户的密码,这里接受的是一个加密的值,因为会直接存到 shadow, 默认不设置密码
-
create_home 在创建用户时,是否创建其家目录。默认创建,假如不创建,设置为 no。2.5版本之前使用 createhome
-
group 设置用户的主组
-
groups 将用户加入到多个其他组中,多个用逗号隔开。
默认会把用户从其他已经加入的组中删除。
-
append yes|no 和 groups 配合使用,yes 时,不会把用户从其他已经加入的组中删除
-
state 删除或添加用户, present 为添加,absent 为删除;默认值 present
-
remove 当与 state=absent 一起使用,删除一个用户及关联的目录,比如家目录,邮箱目录。可选的值为: yes/no
Example
创建用户并设置密码
1.先生成加密密码
[root@localhost ~]# pass=$(echo "123456" | openssl passwd -1 -stdin)
2.执行 ansible 命令 创建用户 foo 并设置密码
[root@localhost ~]# ansible all -i hosts -m user -a "name=foo password=${pass}"
3.创建用 tom, 并且加入到组 db_admin 中, 不改变用户原有加入的组。
[root@localhost ~]# ansible dbservers -i hosts -m user -a "name=tom groups=db_admin append=yes"
拓展:date 命令说明
// 计算 3 小时之后是几点几分
[root@localhost ~]# date +%T -d '3 hours'
// 任意日期的前 N 天,后 N 天的具体日期
[root@localhost ~]# date +%F -d "20190910 1 day"
[root@localhost ~]# date +%F -d "20190910 -1 day"
// 计算两个日期相差天数, 比如计算生日距离现在还有多少天
[root@localhost ~]# d1=$(date +%s -d 20180728)
[root@localhost ~]# d2=$(date +%s -d 20180726)
[root@localhost ~]# echo $(((d1-d2)/86400))
file 模块
file 模块主要用于远程主机上的文件操作。
常用参数:
- owner 定义文件/目录的属主
- group 定义文件/目录的属组
- mode 定义文件/目录的权限
- path 必选项,定义文件/目录的路径
- recurse 递归的设置文件的属性,只对目录有效
- src 链接(软/硬)文件的源文件路径,只应用于state=link的情况
- dest 链接文件的路径,只应用于state=link的情况
- state
- directory 如果目录不存在,创建目录 比如:
state=directory
- file 文件不存在,则不会被创建,存在则返回文件的信息, 常用于检查文件是否存在。
- link 创建软链接
- hard 创建硬链接
- touch 如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间
- absent 删除目录、文件或者取消链接文件
Example
- directory 如果目录不存在,创建目录 比如:
// 创建一个文件
[root@localhost ~]# ansible all -i hosts -m file -a "path=/tmp/foo.conf state=touch"
// 改变文件所有者及权限
[root@localhost ~]# ansible all -i hosts -m file -a "path=/tmp/foo.conf owner=nobody group=nobody mode=0644"
// 创建一个软连接
[root@localhost ~]# ansible all -i hosts -m file -a "src=/tmp/foo.conf dest=/tmp/link.conf state=link"
// 创建一个目录
[root@localhost ~]# ansible all -i hosts -m file -a "path=/tmp/testdir state=directory"
// 取消一个连接
[root@localhost ~]# ansible all -i hosts -m file -a "path=/tmp/link.conf state=absent"
// 删除一个文件
[root@localhost ~]# ansible all -i hosts -m file -a "path=/tmp/foo.conf state=absent"
cron 模块
管理远程节点的CRON 服务。等同于Linux 中的 计划任务。
注意:使用 Ansible 创建的计划任务,是不能使用本地
crontab -e
去编辑,否则 Ansible 无法再次操作此计划任务了。
常用参数:
- name 指定一个cron job 的名字。一定要指定,便于日之后删除。
- minute 指定分钟,可以设置成(0-59, *, */2 等)格式。 默认是 * , 也就是每分钟。
- hour 指定小时,可以设置成(0-23, *, */2 等)格式。 默认是 * , 也就是每小时。
- day 指定天, 可以设置成(1-31, *, */2 等)格式。 默认是 * , 也就是每天。
- month 指定月份, 可以设置成(1-12, *, */2 等)格式。 默认是 * , 也就是每周。
- weekday 指定星期, 可以设置成(0-6 for Sunday-Saturday, * 等)格式。默认是 *,也就是每星期。
- job 指定要执行的内容,通常可以写个脚本,或者一段内容。
- state 指定这个job的状态,可以是新增(present)或者是删除(absent)。 默认为新增(present)
Example
// 新建一个 CRON JOB 任务
[root@localhost ~]# ansible all -i hosts -m cron -a "name='create new job' minute='0' job='ls -alh > /dev/null'"
// 删除一个 CRON JOB 任务,删除时,一定要正确指定job 的name参数,以免误删除。
[root@localhost ~]# ansible all -i hosts -m cron -a "name='create new job' state=absent"
登录任何一台管理机验证cron
[root@localhost ~]# crontab -l
[root@localhost ~]#Ansible: create new job
0 * * * * ls -alh > /dev/null
debug模块
debug 模块主要用于调试时使用,通常的作用是将一个变量的值给打印出来。
常用参数:
- var 直接打印一个指定的变量的值
- msg 打印一段可以格式化的字符串
Example
这里引入了变量,我们只需了解 debug 模板的使用即可。在学习变量、剧本时,我们会对它有更深刻的理解。
[root@localhost ~]# ansible all -i hosts -m debug -a "var=role" -e "role=web"
[root@localhost ~]# ansible all -i hosts -m debug -a "msg='role is {
{role}} '" -e "role=web"
lineinfile 模块
在被管理节点上,用正则匹配的方式对目标文件的一行内容修改删除等操作。
如果是在一个文件中把所有匹配到的多行都进行统一处理,请参考replace 模块。
如果想对一个文件进行一次性添加/更新/删除多行内容等操作,参考blockinfile模块
常用参数
- path 被管理节点的目标文件路径, 必须。
- state 可选值absent 删除 |present 替换(默认值)。
- regexp 在文件的每一行中查找的正则表达式。
对于 state=present ,仅找到的最后一行将被替换。 - line 要在文件中插入/替换的行。需要
state=present
。 - create 文件不存在时,是否要创建文件并添加内容。yes/no
Example
删除被控节点文件里的某一条内容
[root@localhost ~]# ansible dbservers -i hosts -m lineinfile -a "path=/etc/sudoers regexp='^%wheel' state=absent"
替换某一行
[root@localhost ~]# ansible dbservers -i hosts -m lineinfile -a "path=/etc/selinux/config regexp='^SELINUX=' line='SELINUX=disabled' state=present"
ini_file 模块
对目标文件进行多行的添加/更新/删除操作。
常用参数
- path 目标文件路径
- block 文件中被操作的块内容
- state 块内容如何处理,absent 删除, present 添加/更新(默认值)