Ansible 是一个 IT 自动化工具。它能配置系统、部署软件、编排更复杂的 IT 任务,如连续部署或零停机时间滚动更新。
Ansible 用 Python 编写,尽管市面上已经有很多可供选择的配置管理解决方案(例如 Salt、Puppet、Chef等),但它们各有优劣,而Ansible的特点在于它的简洁。
让 Ansible 在主流的配置管理系统中与众不同的一点便是,它并不需要你在想要管理的每个机器上安装自己的客户端组件,就可以对所要管理的机器进行管理,管理服务器和被管理机器之间使用的是 SSH 协议进行通信的。
同时提供的另一个优点,如果需要的话,你可以在不止一个地方控制你的整个基础架构。
1、在ANSIBLE 管理体系中,存在"管理节点" 和 “被管理节点” 两种角色。
2、被管理节点通常被称为"资产"
3、在管理节点上,Ansible将 AdHoc 或 PlayBook 转换为Python脚本。
并通过SSH将这些Python 脚本传递到被管理服务器上。
在被管理服务器上依次执行,并实时的将结果返回给管理节点。
使用官方 epel 源
yum install -y epel-release
yum install -y ansible
使用阿里 epel-7 源
cat >/etc/yum.repos.d/epel-7.repo<
yum install -y ansible
被管理节点的信息需要写到一个 ini
风格的配置文件中, 这样的文件成为资产清单(Inventory)。
这个文件默认的路径是 /etc/ansible/hosts
一行一个,可以是被管理主机的 IP 地址
192.168.122.10
也可以是被管理主机的主机名
ailiao
或者是被管理主机的 FQDN
ailiao.sharkyun.com
示例:
192.168.122.10
192.168.122.20
当然也可以对所要管理的节点进行分组,当然,这也是生产环境中的最佳实战。
格式如下
[组名]
主机1
主机2
组名中只能是:
大小写字母、数字和下划线
最佳实战:
[web_servers]
[webServers]
小驼峰分组建议:
以开发语言进行分组
[java]
[php]
[go]
以服务类型区分
[nginx]
[tomcat]
[slb]
[dbServer]
加上主机所在的城市、机房等位置信息
[bjYzDbServer]
[ShangHaiTomcat]
加上项目前缀
[ZFB_SH_SLB]
清空默认的清单文件内容
> /etc/ansible/hosts
根据自己的情况添加所要管理的机器信息
假设场景:
目前大家一个高并发集群
- SLB 使用 Nginx 实现
- 后端 Real Server 也是要 Nginx 实现
[slb]
192.168.122.10
[webNginx]
192.168.122.20
192.168.122.30
可以看出以上资产清单, 3 台主机都需要安装 Nginx, 但是他们又被分配了不同的角色,这样它们的配置文件肯定不一样。为了方便操作,这里可以使用子组。
[slb]
192.168.122.10
[webNginx]
192.168.122.20
192.168.122.30
[nginx]
[nginx:children]
slb
webNginx
[someGroup]
1.1.1.1
2.2.2.2
3.3.3.[1:15]
test01.qfedu.com
test03.qfedu.com
test[05:09].qfedu.com
[root@master ~]# ansible nginx --list
hosts (3):
192.168.122.10
192.168.122.20
192.168.122.30
[root@master ~]# ansible webNginx --list
hosts (2):
192.168.122.20
192.168.122.30
均在管理节点上操作
ls ~/.ssh/id_rsa || ssh-keygen -f ~/.ssh/id_rsa -N ""
""
表示不加密码。host_key_checking = False
执行如下命令
ansible all -m authorized_key -a "user=root state=present key={
{ lookup('file', '/root/.ssh/id_rsa.pub') }}" -e "ansible_ssh_user=test ansible_ssh_pass=123 "
ansible_ssh_user
被管理主机的用户ansible_ssh_pass
被管理主机的用户密码执行如下命令:
ansible all -m ping
ansible 资产匹配模式 -m 功能模块 -a "功能模块的参数"
一句话:ansible 让谁做什么,具体如何去做
资产匹配模式就是针对哪些被管理节点。可以是:
具体的一个主机: 192.168.122.20
注意:这里些的条目必须和资产清单中的一致,清单中是 IP,这里就写 IP,清单中是主机名,这里也必须是主机名。
资产清单中的一个组名
webNginx
Ansible 把希望被管理节点具体做什么任务,都开发成具体的模块了。
比如,希望执行被管理节点执行一条 shell 命令,就可以使用 shell 这个模块。
类似的还有:
目前 ansible 的功能模块已经达到三千多个了。
可以使用如下命令获取当前安装版本的具体模块数量。
ansible-doc -l |wc -l
列出当前系统中所有的模块
ansible-doc -l
获取某个模块的帮助文档
ansible-doc 模块名
ansible-doc copy
两个模块都是在远程服务器上去执行命令。
但command模块是ad-hoc的默认模块,在执行ad-hoc时,若不指定模块的名字则默认使用此模块。
# ansible webNginx -a "echo 'hello'"
192.168.122.20 | CHANGED | rc=0 >>
hello
192.168.122.30 | CHANGED | rc=0 >>
hello
# ansible webNginx -m shell -a "echo 'hello'"
192.168.122.20 | CHANGED | rc=0 >>
hello
192.168.122.30 | CHANGED | rc=0 >>
hello
两个模块的差异
Example
执行:
ansible webNginx -m shell -a "echo 'hello'|grep -o 'e'"
输出:
192.168.122.20 | CHANGED | rc=0 >>
e
192.168.122.30 | CHANGED | rc=0 >>
e
执行:
ansible all -i hosts -a "echo 'hello'|grep -o 'e'"
输出:
192.168.122.20 | CHANGED | rc=0 >>
hello|grep -o e
192.168.122.30 | CHANGED | rc=0 >>
hello|grep -o e
将管理节点上的脚本传递到被管理节点(远程服务器)上进行执行。
Example
管理节点上的一个脚本
脚本 /root/a.sh
内容如下:
touch /tmp/testfile
执行
ansible webNginx -m script -a "/root/a.sh"
验证
ansible webNginx -m shell -a "ls -l /tmp/testfile"
copy 模块的主要用于管理节点和被管理节点之间的文件拷贝。
常用参数:
Example
nginx.repo
到被管理节点上# 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
执行:
ansible nginx copy -a "src=./nginx.repo dest=/etc/yum.repos.d/nginx.repo"
ansible nginx -m copy -a "src=./nginx.repo dest=/etc/yum.repos.d/nginx.repo backup=yes"
all 是资产清单中的默认组
ansible all -m copy -a "src=./nginx.repo dest=/etc/yum.repos.d/nginx.repo owner=nobody group=nobody"
ansible all -m copy -a "src=./nginx.repo dest=/etc/yum.repos.d/nginx.repo mode=0755"
等同于 Linux 上的YUM 命令, 对远程服务器上RPM包进行管理。
常用参数:
Example
安装一个软件包
ansible webNginx -m yum -a "name=nginx state=present"
ansible webNginx -m yum -a "name=nginx state=latest"
ansible webNginx -m yum -a "name=nginx state=installed"
移除一个软件包
ansible webNginx -m yum -a "name=nginx state=absent"
ansible webNginx -m yum -a "name=nginx state=removed"
安装一个软件包组
ansible webNginx -m yum -a "name='@Development tools' state=present"
Centos6 之前的版本使用
service
模块。请使用
ansible-doc service
命令自行查看帮助信息。
管理远程节点上的 systemd 服务,就是由 systemd 所管理的服务。
常用参数:
Example
# ansible webNginx -m systemd -a "daemon_reload=yes"
# ansible webNginx -m systemd -a "name=nginx state=started"
# ansible webNginx -m systemd -a "name=nginx state=stopped"
# ansible webNginx -m systemd -a "name=nginx state=restarted"
# ansible webNginx -m systemd -a "name=nginx state=reloaded"
# ansible webNginx -m systemd -a "name=nginx enabled=yes"
在被管理节点上,对组进行管理。
常用参数:
Example
# ansible webNginx -m group -a "name=db_admin"
用于在被管理节点上对用户进行管理。
常用参数:
name 必须的参数, 指定用户名
password 设置用户的密码,这里接受的是一个加密的值,因为会直接存到 shadow, 默认不设置密码
update_password 假如设置的密码不同于原密码,则会更新密码. 在 1.3 中被加入
home 指定用户的家目录
shell 设置用户的 shell
comment 用户的描述信息
create_home 在创建用户时,是否创建其家目录。默认创建,假如不创建,设置为 no。2.5版本之前使用 createhome
group 设置用户的主组
groups 将用户加入到多个其他组中,多个用逗号隔开。
默认会把用户从其他已经加入的组中删除。
append yes|no 和 groups 配合使用,yes 时,
不会把用户从其他已经加入的组中删除
system 设置为 yes 时,将会创建一个系统账号
expires 设置用户的过期时间,值为时间戳,会转为为天数后,放在 shadow 的第 8 个字段里
generate_ssh_key 设置为 yes 将会为用户生成密钥,这不会覆盖原来的密钥
ssh_key_type 指定用户的密钥类型, 默认 rsa, 具体的类型取决于被管理节点
state 删除或添加用户, present 为添加,absent 为删除;
默认值 present
remove 当与 state=absent 一起使用,删除一个用户及关联的目录,
比如家目录,邮箱目录。可选的值为: yes/no
Example
创建用户并设置密码
先生成加密密码
pass=$(echo "123456" | openssl passwd -1 -stdin)
执行 ansible 命令 创建用户 foo 并设置密码
ansible nginx -m user -a "name=foo password=${pass}"
创建用户 yangge, 并且为其创建密钥对,并且密钥类型为: ecdsa
ansible all -m user -a "name=yangge generate_ssh_key=yes ssh_key_type=ecdsa"
创建用 tom, 并且设置其有效期到 2020年4月15日, 加入到组 db_admin 中, 不改变用户原有假如的组。
ansible webNginx -m user -a "name=tom expires=$(date +%s -d 20200415) gorups=db_admin append=yes"
file 模块主要用于远程主机上的文件操作。
常用参数:
owner 定义文件/目录的属主
group 定义文件/目录的属组
mode 定义文件/目录的权限
path 必选项,定义文件/目录的路径
recurse 递归的设置文件的属性,只对目录有效
src 链接(软/硬)文件的源文件路径,只应用于state=link的情况
dest 链接文件的路径,只应用于state=link的情况
state
directory 如果目录不存在,创建目录
file 文件不存在,则不会被创建,存在则返回文件的信息,
常用于检查文件是否存在。
link 创建软链接
hard 创建硬链接
touch 如果文件不存在,则会创建一个新的文件,如果文件或目录已存在,则更新其最后修改时间
absent 删除目录、文件或者取消链接文件
Example
// 创建一个文件
ansible all -m file -a "path=/tmp/foo.conf state=touch"
// 改变文件所有者及权限
ansible all -m file -a "path=/tmp/foo.conf owner=nobody group=nobody mode=0644"
// 创建一个软连接
ansible all -m file -a "src=/tmp/foo.conf dest=/tmp/link.conf state=link"
// 创建一个目录
ansible all -m file -a "path=/tmp/testdir state=directory"
// 取消一个连接
ansible all -m file -a "path=/tmp/link.conf state=absent"
// 删除一个文件
ansible all -m file -a "path=/tmp/foo.conf state=absent"
管理远程节点的CRON 服务。等同于Linux 中的 计划任务。
注意:使用 Ansible 创建的计划任务,是不能使用本地
crontab -e
去编辑,否则 Ansible 无法再次操作此计划任务了。
常用参数:
Example
// 新建一个 CRON JOB 任务
ansible all -m cron -a "name='create new job' minute='0' job='ls -alh > /dev/null'"
// 删除一个 CRON JOB 任务,删除时,一定要正确指定job 的name参数,以免误删除。
ansible all -m cron -a "name='create new job' state=absent"
登录任何一台管理机验证cron
crontab -l
输出如下信息:
#Ansible: create new job
0 * * * * ls -alh > /dev/null
debug 模块主要用于调试时使用,通常的作用是将一个变量的值给打印出来。
常用参数:
Example
# ansible all -i hosts -m debug -a "var=role" -e "role=web"
# ansible all -i hosts -m debug -a "msg='role is {
{role}} '" -e "role=web"
template 模块使用了Jinjia2格式作为文件模版,可以进行文档内变量的替换。文件以 .j2 结尾。
常用参数:
Example
用法其实和 copy 模块基本一样, template 模块的强大之处就是使用变量替换,就是可以把传递给 Ansible 的变量的值替换到模板文件中。
1. 建立一个 template 文件, 名为 hello_world.j2
# cat hello_world.j2
Hello {
{
var}} !
2. 执行命令,并且设置变量 var 的值为 world
# ansible all -m template -a "src=hello_world.j2 dest=/tmp/hello_world.world" -e "var=world"
3. 在被控主机上验证
# cat /tmp/hello_world.world
Hello world !
在被管理节点上,用正则匹配的方式对目标文件的一行内容修改删除等操作。
如果是在一个文件中把所有匹配到的多行都进行统一处理,请参考replace 模块。
如果想对一个文件进行一次性添加/更新/删除多行内容等操作,参考blockinfile模块
常用参数
path 被管理节点的目标文件路径, 必须。
state 可选值absent 删除 |present 替换(默认值)。
regexp 在文件的每一行中查找的正则表达式。
对于 state=present ,仅找到的最后一行将被替换。
line 要在文件中插入/替换的行。需要state=present
。
create 文件不存在时,是否要创建文件并添加内容。yes/no
Example
# ansible all -m lineinfile -a "path=/etc/sudoers regexp='^%wheel' state=absent"
# ansible all -m lineinfile -a "path=/etc/selinux/config regexp='^SELINUX=' line='SELINUX=disabled' state=present"
对目标文件进行多行的添加/更新/删除操作。
常用参数
Example
向文件/etc/ssh/sshd_config
的最后添加几行内容
添加的内容是
Match User ansible-agent
PasswordAuthentication no
ansible all -m blockinfile -a "path=/etc/ssh/sshd_config block='Match User ansible-agent\nPasswordAuthentication no'"
注意:
\n
是换行符的意思。
更新之前的内容
ansible all -m blockinfile -a "path=/etc/ssh/sshd_config block='Match User ansible-agent\nPasswordAuthentication yes'"
删除文件中的连续出现几行内容
ansible all -m blockinfile -a "path=/etc/ssh/sshd_config block='Match User ansible-agent\nPasswordAuthentication yes' state=absent"
模块索引 https://docs.ansible.com/ansible/latest/modules/modules_by_category.html