1.1 ansible 概述和运行机制
1.11 ansible概述
Ansible是一款为类Unix系统开发的自由开源的配置和自动化工具。它用Python 写成,类似于 saltstack 、Puppet和chef,但是有一个不同和优点是我们不需要在节点中安装任何客户端。它使用SSH来和节点进行通信。Ansible基于 Python paramiko开发,分布式,无需客户端,轻量级,配置语法使用YMAL及 Jinja2模板语言,更强的远程命令执行操作。
Anibale 具有如下特点:
1、部署简单,只需在主控端部署ansibale环境,被控端无需要做任何操作;
2、默认使用SSH协议对设备进行管理;
3、主从集中化管理;
4、配置简单、功能强大、扩展性强;
5、支持API及自定义模块,可通过Python轻松扩展;
6、通过Playbooks来定制强大的配置、状态管理;
7、对云计算平台、大数据都有很好的支持;
Ansible 在管理节点将Ansible模块通过 SSH协议推送到被管理端执行,执行完之后自动删除,可以使用SVN等来管理自定义模块及编排。
工作机制
ansible有五大组件,通过ansible核心程序来查看host inventory(主机清单)里被控的主机ip、分组下的主机名或者组嵌套,然后再由剧本playbooks里的命令来完成要执行的操作,或者通过核心模块来完成ping、yum、copy等一系列操作,再通过连接插件连接被控主机
ansible组成有5个部分组成:
Ansible:ansible 核心
Modules:包括Ansible自带的核心模块以及自定义模块
Plugins:完成模块功能的补充,包括连接插件、邮件的插件等
Playbookds:剧本,定义ansible多任务配置文件,由Ansible自动执行
Host Inventory:定义Ansible 配置主机的清单
1.1.1 简述Ansible 角色
数据中心有各种不同类型的主机。如web服务器、数据库服务器,基于开发环境的服务器。随着时间的推移,具有处理所有这些情况的任务和人员的Ansible playbook将变得庞大而复杂。
角色允许将复杂的剧本组织成独立的、更小的剧本和文件。
角色提供了一种从外部文件加载任务、处理程序和变量的方法。
角色也可关联和引用静态的文件和模板。
角色可以编写成满足普通用途需求,并且能被重复利用。
定义角色的文件具有特定的名称,并以严格的目录结构进行组织。
Ansible
Ansible是一个基于Python开发的配置管理和应用部署工具,现在也在自动化管理领域大放异彩。它融合了众多老牌运维工具的优点,Pubbet和Saltstack能实现的功能,Ansible基本上都可以实现。
TAnsible能批量配置、部署、管理上千台主机。比如以前需要切换到每个主机上执行的一或多个操作,使用Ansible只需在固定的一台Ansible控制节点上去完成所有主机的换作。
Ansible是基于模块工作的,它只是提供了一种运行框架,它本身没有完成任务的能力,真正执行操作的是Ansible的模块,比如copy模块用于拷贝文件到远程主机上,service模块用于管理服务的启动、停止、重启等。
Ansible其中一个比较鲜明的特性是Agentless,即无Agent的存在,它就像普通命令一样,并非c/s软件,也只需在某个作为控制节点的主机上安装一次Ansib1e即可,通常它基于ssh连接来控制远程主机,远程主机上不需要安装Ansible或其它额外的服务。
使用者在使用时,在服务器终端输入命令或者playbooks,会通过预定好的规则将playbook拆解为play,再组织成ansible可以识别的任务,调用模块和插件,根据主机清单通过SSH将临时文件发给远程的客户端执行并返回结果,执行结束后自动删除
Ansible的另一个比较鲜明的特性是它的绝大多数模块都具备幂等性(idempotence)。所谓幂等性,指的是多次操作或多次执行对系统资源的影响是一致的。比如执行systemctl stop xxx命令来停止服务,当发现要停止的目标服务已经处于停止状态,它什么也不会做,所以多次停止的结果仍然是停止,不会改变结果,它是幂等的,而 systemctl restart xxx是非幂等的。
Ansible的很多模块在执行时都会先判断目标节点是否要执行任务,所以,可以放心大胆地让Ansible去执行任务,重复执行某个任务绝大多数时候不会产生任何副作用。
ansible环境安装部署
//管理端安装 ansible
yum install -y epel-release //先安装epel源
yum install -y ansible
//ansible 目录结构
/etc/ansible/
ansible.cfg #ansible的配置文件,一般无需修改
hosts #ansible的主机清单,用于存储需要管理的远程主机的相关信息
roles/ #公共角色目录
//配置主机清单
cd /etc/ansible
vim hosts
[webservers] #配置组名
192.168.10.14 #组里包含的被管理的主机IP地址或主机名(主机名需要先修改/etc/hosts文件)
[dbservers]
192.168.10.15
/配置密钥对验证
ssh-keygen -t rsa #一路回车,使用免密登录
ssh 192.168.80.20
sshpass -p ‘123’ ssh-copy-id root@192.168.80.20
ssh 192.168.80.30
sshpass -p ‘123’ ssh-copy-id root@192.168.80.30
---------ansible 命令行模块________
命令格式:ansible<组名>-m<模块>-a<参数列表>
ansible-doc -l #列出所有已安装的模块,按q退出
1.command模块
//在远程主机执行命令,不支持管道,重定向等shell的特性
ansible-doc -s command #-s 列出指定模块的描述信息和操作动作
ansible 192.168.80.20 -m command -a ‘date’ #指定 ip 执行date
ansible webservers -m command -a ‘date’ #指定组执行 date
ansible dbservers -m command -a ‘date’
ansible all -m command -a ‘date’ #all代表所有 hosts 主机
ansible all -a ‘ls /’ #如省略-m模块,则默认运行command模块
//常用的参数:
chdir:在远程主机上运行命令前提前进入目录
creates:判断指定文件是否存在,如果存在,不执行后面的操作
removes: 判断指定文件是否存在,如果存在,执行后面的操作
ansible all -m command -a “chdir=/home ls ./”
2.shell模块
//在远程主机执行命令,相当于调用远程主机的shell进程,然后在该shell下打开一个子shell运行命令(支持管道符号等功能)
ansible-doc -s shell
ansible dbservers -m shell -a ‘echo 123456 | passwd --stdin test’
cut -d " " -f2 #以空格为分隔符,剪切第二列的内容
ansible dbservers -m shell -a ‘echo $(ifconfig ens33 | awk “NR==2 {print $2}”) | cut -d " " -f2’
192.168.80.30 | CHANGED | rc=0 >>
192.168.80.30
KaTeX parse error: Undefined control sequence: \是 at position 44: …TAB为分隔符)。前面加转义符\̲是̲取消 在shell中的的取值功能,防止被解析为shell脚本的第二个位置参数。md是一个shell变量。在双引号中,$md会被替换为变量的值(如果是单引号就不行)。
ansible dbservers -m shell -a 'echo $(ifconfig ens33 | awk “NR==2 {print \ $2}”) ’
192.168.80.30 | CHANGED | rc=0 >>
192.168.80.30
[root@localhost ansible]# ansible dbservers -m shell -a 'echo $(ifconfig ens33 | awk “NR==2 {print $2}”) ’
192.168.80.30 | CHANGED | rc=0 >>
inet 192.168.80.30 netmask 255.255.255.0 broadcast 192.168.80.255
3.cron模块
//在远程主机定义任务计划。其中有两种状态(state):present表示添加(可以省略),absent表示移除。ansible-doc -s cron #按q退出
//常用的参数:
minute/hour/day/month/weekday:分/时/日/月/周
job:任务计划要执行的命令
name:任务计划的名称
ansible webservers -m cron -a ‘minute=“*/1” job=“/bin/echo helloworld” name=“test crontab”’
ansible webservers -a ‘crontab -l’
192.168.80.20 | CHANGED | rc=0 >>
#Ansible: test crontab
*/1 * * * * /bin/echo helloworld
ansible webservers -m cron -a ‘name=“test crontab” state=absent’
#移除计划任务,假如该计划任务没有取名字,name=None即可
4.user模块
//用户管理的模块
ansible-doc -s user
//常用的参数:
name:用户名,必选参数
state=present |absent:创建账号或者删除账号,present表示创建,absent表示删除system=yes | no:是否为系统账号
uid:用户uid
group:用户基本组
shell:默认使用的shell
move_home=yes|no:如果设置的家目录已经存在,是否将已经存在的家目录进行移动
password:用户的密码,建议使用加密后的字符串
comment:用户的注释信息
remove=yes | no:当state=absent时,是否删除用户的家目录
ansible dbservers -m user -a ‘name=“test01”’ #创建用户test01
ansible dbservers -m command -a ‘tail /etc/passwd’
test01: x:1001:1001::/home/test01:/bin/bash
ansible dbservers -m user -a ‘name=“test01” state=absent’ #删除用户test01
5.group模块
//用户组管理的模块
ansible-doc -s group
ansible dbservers -m group -a ‘name=mysql gid=306 system=yes’ #创建mysql组
ansible dbservers -a ‘tail /etc/group’
ansible dbservers -m user -a ‘name=test01 uid=306 system=yes group=mysql’
#将test01用户添加到mysql组中
ansible dbservers -a ‘tail /etc/passwd’
ansible dbservers -a ‘id test01’
192.168.80.30 | CHANGED | rc=0 >>
uid=306(test01) gid=306(mysql) 组=306(mysql)
6.copy模块
//用于复制指定主机文件到远程主机的
ansible-doc -s copy
//常用的参数:
dest:指出复制文件的目标及位置,使用绝对路径,如果是源目录,指目标也要是目录,如果目标文件已经存在会覆盖原有的内容
src:指出源文件的路径,可以使用相对路径或绝对路径,支持直接指定目录,如果源是目录则目标也要是目录mode:指出复制时,目标文件的权限
owner:指出复制时,目标文件的属主group:指出复制时,目标文件的属组
content:指出复制到目标主机上的内容,不能与src一起使用
ansible dbservers -m copy -a ‘src=/etc/fstab dest=/opt/fstab.bak owner=root mode=640’
ansible dbservers -a ‘ls -l /opt’
-rw-r----- 1 root root 465 9月 19 18:52 fstab.bak
ansible dbservers -a ‘cat /opt/fstab.bak’
192.168.80.30 | CHANGED | rc=0 >>
#/etc/fstab
#Created by anaconda on Mon Sep 12 22:18:35 2022
#Accessible filesystems, by reference, are maintained under ‘/dev/disk’
#See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
/dev/mapper/centos-root / xfs defaults 0 0
UUID=4b85ea01-b537-450d-afd0-00deed56ccea /boot xfs defaults 0 0
/dev/mapper/centos-swap swap swap defaults 0 0
ansible dbservers -m copy -a ‘content=“helloworld” dest=/opt/hello.txt’
#将helloworld写入/opt/hello.txt文件中
ansible dbservers -a ‘cat /opt/hello.txt’
192.168.80.30 | CHANGED | rc=0 >>
helloworld
7.file模块/设置文件属性
ansible-doc -s file
ansible dbservers -m file -a 'owner=test02 group=mysql mode=644 path=/opt/fstab.bak '#修改文件的属主属组权限等
ansible dbservers -m file -a ‘path=/opt/fstab.link src=/opt/fstab.bak state=link’
#设置/opt/fstab. link为/opt/fstab.bak的链接文件
[root@localhost ansible]# ansible dbservers -a ‘ls -l /opt’
192.168.80.30 | CHANGED | rc=0 >>
总用量 122160
-rw-r–r-- 1 test02 mysql 465 9月 19 18:52 fstab.bak
lrwxrwxrwx 1 root root 14 9月 19 19:03 fstab.link -> /opt/fstab.bak
ansible dbservers -m file -a “path=/opt/abc.txt state=touch” 创建一个文件
[root@localhost ansible]# ansible dbservers -a ‘ls -l /opt’
192.168.80.30 | CHANGED | rc=0 >>
总用量 122160
-rw-r–r-- 1 root root 0 9月 19 19:09 abc.txt
-rw-r–r-- 1 test02 mysql 465 9月 19 18:52 fstab.bak
lrwxrwxrwx 1 root root 14 9月 19 19:03 fstab.link -> /opt/fstab.bak
ansible dbservers -m file -a “path=/opt/abc.txt state=absent” 删除一个文件
8.hostname模块
//用于管理远程主机上的主机名
ansible dbservers -m hostname -a “name=mysql01”
[root@node2 ~]# hostname
mysql01
9.ping模块
//检测远程主机的连通性
ansible all -m ping
10.yum模块
//在远程主机上安装与卸载软件包
ansible-doc -s yum
ansible webservers -m yum -a ‘name=httpd’ #安装服务
ansible webservers -m yum -a ‘name=httpd state=absent’ #卸载服务
11.service/systemd模块
//用于管理远程主机上的管理服务的运行状态
ansible-doc -s service
/常用的参数:
name:被管理的服务名称
state=started| stopped |restarted:动作包含启动关闭或者重启
enabled=yes | no:表示是否设置该服务开机自启
runlevel:如果设定了enabled开机自启去,则要定义在哪些运行目标下自启动
ansible webservers -a ‘systemctl status httpd’ #查看web服务器httpd运行状态
192.168.80.20 | FAILED | rc=3 >>
● httpd.service - The Apache HTTP Server
Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled)
Active: inactive (dead)
Docs: man:httpd(8)
man:apachectl(8)
ansible webservers -m service -a ‘enabled=true name=httpd state=started’ #启动httpd服务
12.script模块
//实现远程批量运行本地的shell 脚本
ansible-doc -s script
vim test.sh
#!/ bin/bash
echo “hello ansible from script” > /opt/script.txt
chmod +x test.sh
ansible webservers -m script -a ‘test.sh’
ansible webservers -a ‘cat /opt/script.txt’
192.168.80.20 | CHANGED | rc=0 >>
hello ansible from script
13.setup模块
//facts 组件是用来收集被管理节点信息的,使用setup 模块可以获取这些信息
ansible-doc -s setup
ansible webservers -m setup #获取mysql组主机的facts信息
ansible dbservers -m setup -a ‘filter=*ipv4’ #使用filter可以筛选指定的facts信息
inventory 主机清单
//Inventory支持对主机进行分组,每个组内可以定义多个主机,每个主机都可以定义在任何一个或多个主机组内
//如果是名称类似的主机,可以使用列表的方式标识各个主机。
vim /etc/ansible/hosts
[webservers]
192.168.80.20:2222 #冒号后定义远程连接端口,默认是ssh的 22端口
192.168.80.[3:5]0
[dbservers]
db-[a:f].example.org #支持匹配a~f
//inventory中的变量
Inventory变量名 含义
ansible host ansible连接节点时的IP地址
ansible port 连接对方的端口号,ssh连接时默认为22
ansible_user 连接对方主机时使用的主机名。不指定时,将使用执行ansible或ansible-playbook命令的用户
ansible password 连接时的用户的ssh密码,仅在未使用密钥对验证的情况下有效
ansible_ssh private_key_file 指定密钥认证ssh连接时的私钥文件
ansible_ssh common_args 提供给ssh、 sftp、scp命令的额外参数
ansible become 允许进行权限提升
ansible become method 指定提升权限的方式,例如可使用sudo/su/runas等方式
ansible become user 提升为哪个用户的权限,默认提升为root
ansible_ become password 提升为指定用户权限时的密码
(1)主机变量
[webservers]
192.168.80.20 ansible port=22 ansible_user=root ansible password=123
(2)组变量
[webservers: vars] #表示为webservers 组内所有主机定义变量
ansible user=root
ansible password=123
[all: vars] #表示为所有组内的所有主机定义变量
ansible_port=22
(3)组嵌套
[nginx]
192.168.80.20
192.168.80.21
192.168.80.22
[apache]
192.168.80.3 [0:3]
[webs:children] #表示为 webs 主机组中包含了nginx组和 apache 组内的所有主机
nginx
apache
Ansible 的脚本— playbook剧本
playbooks 本身由以下各部分组成
(1) Tasks:任务,即通过task 调用ansible 的模板将多个操作组织在一个 playbook 中运行
(2) Variables:变量
(3)Templates:模板
(4) Handlers:处理器,当changed状态条件满足时,(notify)触发执行的操作
(5) Roles:角色
//示例:
vim test1.yaml
—#yaml文件以—开头,以表明这是一个yaml文件,可省略
-name: first play#定义一个play的名称,可省略
gather_facts: false#设置不进行facts信息收集,这可以加快执行速度,可省略
hosts: webservers#指定要执行任务的被管理主机组,如多个主机组用冒号分隔
remote_user: root#指定被管理主机上执行任务的用户
tasks:#定义任务列表,任务列表中的各任务按次序逐个在hosts中指定的主机上执行
-name: test connection#自定义任务名称
ping:#使用module: [options]格式来定义一个任务
-name: disable selinux
command: ‘/sbin/setenforce 0’ #command模块和shell模块无需使用key=value格式
ignore errors: True
#如执行命令的返回值不为0,就会报错,tasks停止,可使用ignore_errors忽略失败的任务
-name: disable firewalld
service: name=firewalld state=stopped #使用module: options格式来定义任务,option使用key=value格式
-name: install httpd
yum: name=httpd state=latest
-name: install configuration file for httpd
copy: src=/opt/httpd.conf dest=/etc/httpd/conf/httpd.conf
#这里需要一个事先准备好的/opt/httpd.conf文件
notify: “restart httpd”
#如以上操作后为changed的状态时,会通过notify指定的名称触发对应名称的handlers操作
-name: start httpd service
service: enabled=true name=httpd state=started
handlers: thandlers中定义的就是任务,此处handlers中的任务使用的是service模块
-name: restart httpd#notify和handlers中任务的名称必须一致
service: name=httpd state=restarted
#Ansible在执行完某个任务之后并不会立即去执行对应的handler,而是在当前play中所有普通任务都执行完后再去执行handler,这样的好处是可以多次触发notify,但最后只执行一次对应的handler,从而避免多次重启。
//运行playbook
ansible-playbook test1.yaml
//补充参数:
-k ( -ask-pass) :用来交互输入ssh密码
-K ( -ask-become-pass) :用来交互输入sudo密码
-u:指定用户
ansible-playbook test1.yaml --syntax-check #检查yaml文件的语法是否正确
ansible-playbook test1.yaml --list-task #检查tasks任务
ansible-playbook test1.yaml --list-hosts #检查生效的主机
ansible-playbook test1.yaml --start-at-task=‘install httpd’ #指定从某个task开始运行
- name: first play
gather_facts: false
hosts: webservers
remote_user: root
tasks:
- name: test connection
ping:
- name: disable selinux
command: '/sbin/setenforce 0'
ignore_errors: True
- name: disable firewalld
service: name=firewalld state=stopped enabled=no
- name: install httpd
yum: name=httpd state=latest
- name: install configuration file for httpd
copy: src=/opt/httpd.conf dest=/etc/httpd/conf/httpd.conf
notify: "restart httpd"
- name: start httpd service
service: enabled=true name=httpd state=started
handlers:
- name: restart httpd
service: name=httpd state=restarted
//定义、引用变量
-name: second play
hosts: dbservers
remote_user: root
vars: #定义变量
-groupname: mysql #格式为key: value
-username: nginx
tasks:
-name: create group
group: name={{groupname}} system=yes gid=308#使用({key}}引用变量的值
-name: create user
user: name={{username }} uid=308 group={{groupname }}
-name : copy file
copy: content=" {{ansible_default_ipv4}}" dest=/opt/vars.txt
#在setup模块中可以获取facts变量信息
ansible-playbook test2.yaml -e “username=nginx” #在命令行里定义变量
[root@localhost ansible]# vim test2.yaml
- name: second play
hosts: dbservers
remote_user: root
vars:
- groupname: mysql
- username: nginx
tasks:
- name: create group
group: name={{groupname}} system=yes gid=308
- name: create user
user: name={{username}} uid=308 group={{groupname}}
- name : copy file
copy: content="{{ansible_default_ipv4}}" dest=/opt/vars.txt
[root@30 ~]# cat /opt/vars.txt
{"macaddress": "00:0c:29:71:24:34", "network": "192.168.80.0", "mtu": 1500, "broadcast": "192.168.80.255", "alias": "ens33", "netmask": "255.255.255.0", "address": "192.168.80.30", "interface": "ens33", "type": "ether", "gateway": "192.168.80.2"}
//指定远程主机sudo切换用户
-hosts: dbservers
remote_user: zhangsan
become : yes #2.6版本以后的参数,之前是sudo,意思为切换用户运行
become user: root #指定sudo用户为root
执行playbook时: ansible-playbook test1.yml -K<密码>
//when条件判断
在Ansible中,提供的唯一一个通用的条件判断是when指令,当when指令的值为true时,则该任务执行,否则不执行该任务。
//when一个比较常见的应用场景是实现跳过某个主机不执行任务或者只有满足条件的主机执行任务
vim test3.yaml
-hosts: all
remote_user: root
tasks :
-name : shutdown host
command: / sbin/ shutdown -r now
when: ansible_default_ipv4.address == “192.168.80.20”
#when指令中的变量名不需要手动加上 {{ }}
或
when: inventory_hostname ==“<主机名>”
vim test3.yaml
- hosts: all
remote_user: root
tasks :
- name : shutdown host
command: /sbin/shutdown -r now
when: ansible_default_ipv4.address == "192.168.80.20"
ansible-playbook test3.yaml
//迭代
Ansible提供了很多种循环结构,一般都命名为with_items,作用等同于loop 循环。
vim test4. yaml
-name: play1
hosts: dbservers
gather_facts: false
tasks:
-name: create directories
file:
path: “{{item}}”
state: directory
with_items: #等同于loop:
-/tmp/test1
-/tmp/test2
-name: add users
user: name={{item.name}} state=present groups={{item. groups}}
with_items:
-name: test1
groups: wheel
-name: test2
groups: root
或
with items:
-{name : ‘test1’, groups : ’ wheel’}
-{name : ‘test2’, groups: ‘root’}
vim test4.yaml
- name: play1
hosts: dbservers
gather_facts: false
tasks:
- name: create directories
file:
path: "{{item}}"
state: directory
with_items:
- /tmp/test1
- /tmp/test2
- name: add users
user: name={{item.name}} state=present groups={{item.groups}}
with_items:
- name: test1
groups: wheel
- name: test2
groups: root
ansible-playbook test4.yaml
[root@30 ~]# cat /etc/passwd
test1: x:1001:1001::/home/test1:/bin/bash
test2: x:1002:1002::/home/test2:/bin/bash
[root@30 ~]# ls /tmp/
test1
test2
// Templates 模块
Jinja是基于Python的模板引擎。Template类是Jinja的一个重要组件,可以看作是一个编译过的模板文件,用来产生目标文本,传递Python的变量给模板丢替换模板中的标记。
1.先准备一个以.j2为后缀的template模板文件,设置引用的变量
cp /etc/httpd/conf/httpd.conf /opt/httpd.conf.j2
vim /opt/httpd.conf.j2
Listen {{http_port}} 42行,修改
ServerName {{ server_name}} 95行,修改
DocumentRoot “{{root_dir}}” #119行,修改
2.修改主机清单文件,使用主机变量定义一个变量名相同,而值不同的变量
vim /etc/ansible/hosts
[webservers]
192.168.80.20 http_port=192.168.80.20:80 server_name=www.kgc.com:80
root_dir=/etc/httpd/htdocs
[dbservers]
192.168.80.30 http_port=192.168.80.30:80 server_name=www.benet.com:80
root_dir=/etc/httpd/htdocs
3.编写playbook
vim apache. yaml
-hosts: all
remote_user: root
vars
-package: httpd
-service: httpld
tasks :
-name : install httpd package
yum: name={{package}} state=latest
-name: install configure file
template: src=/opt/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
#使用template模板
notify:
-restart httpd
-name: create root dir
file : path=/etc/httpd/htdocs state=directory
-name : start httpd server
service: name={{service}} enabled=true state=started
handlers:
-name : restart httpd
service: name={{service}} state=restarted
[root@localhost ansible]# vim apache.yaml
- hosts: all
remote_user: root
vars:
- package: httpd
- service: httpd
tasks:
- name: install httpd package
yum: name={{package}} state=latest
- name: install configure file
template: src=/opt/httpd.conf.j2 dest=/etc/httpd/conf/httpd.conf
notify:
- restart httpd
- name: create root dir
file: path=/etc/httpd/htdocs state=directory
- name: start httpd server
service: name={{service}} enabled=true state=started
handlers:
- name: restart httpd
service: name={{service}} state=restarted
ansible-playbook apache.yaml
//tags 模块
可以在一个playbook中为某个或某些任务定义"标签",在执行此playbook时通过ansible-playbook命令使用–tags选项能实现仅运行指定的tasks。
playbook还提供了一个特殊的tags为always。作用就是当使用always当tags的task时,无论执行哪一个tags时,定义有always的tags都会执行。
vim webhosts.yaml
-hosts: webservers
remote_user: root
tasks:
-name: copy hosts file
copy: src=/etc/ hosts dest=/ opt/ hosts
tags:
-only #可自定义
-name : touch file
file: path=/opt/testhost state=touch
tags:
-always #表示始终要运行的代码
[root@localhost ansible]# vim webhosts.yaml
- hosts: webservers
remote_user: root
tasks:
- name: copy hosts file
copy: src=/etc/hosts dest=/opt/hosts
tags:
- only
- name: touch file
file: path=/opt/testhost state=touch
tags:
- always
ansible-playbook webhosts.yaml --tags="only"
vim dbhosts.yaml
-hosts: dbservers
remote_user: root
tasks:
-name : copy hosts file
copy: src=/etc/hosts dest=/opt/hosts
tags:
-only
-name : touch file
file: path=/opt/testhost state=touch
[root@localhost ansible]# vim dbhosts.yaml
- hosts: dbservers
remote_user: root
tasks:
- name: copy hosts file
copy: src=/etc/hosts dest=/opt/hosts
tags:
- only
- name: touch file
file: path=/opt/testhost state=touch
[root@localhost ansible]# ansible-playbook dbhosts.yaml --tags="only"
//分别去两台被管理主机上去查看文件创建情况
[root@20 ~]# ll /opt/
-rw-r–r-- 1 root root 158 9月 20 19:39 hosts
-rw-r–r-- 1 root root 0 9月 20 19:39 testhost
[root@30 ~]# ll /opt/
-rw-r–r-- 1 root root 158 9月 20 19:39 hosts
//Roles模块
Ansible为了层次化、结构化地组织Playbook,使用了角色(roles) ,roles可以根据层次型结构自动装载变量文件、task以及handlers等。简单来讲,roles就是通过分别将变量、文件、任务、模块及处理器放置于单独的目录中,并可以便捷地include它们。roles一般用于基于主机构建服务的场景中,但也可以用于构建守护进程等场景中。
//roles 的目录结构:
cd /etc/ansible/
tree roles/
roles/
//Roles模块
Ansible为了层次化、结构化地组织Playbook,使用了角色(roles) ,roles可以根据层次型结构自动装载变量文件、task以及handlers等。简单来讲,roles就是通过分别将变量、文件、任务、模块及处理器放置于单独的目录中,并可以便捷地include它们。roles一般用于基于主机构建服务的场景中,但也可以用于构建守护进程等场景中。
//roles 的目录结构:
cd /etc/ansible/
tree roles/
roles/
//roles 内各目录含义解释
-
files
用来存放由copy模块或script模块调用的文件。 -
templates
用来存放jinjia2模板,template模块会自动在此目录中寻找jinjia2模板文件。 -
tasks
此目录应当包含一个main.yml 文件,用于定义此角色的任务列表,此文件可以使用include包含其它的位于此目录的task文件。 -
bandlers
此目录应当包含一个main.yml文件,用于定义此角色中触发条件时执行的动作。 -
vars
此目录应当包含一个main.yml 文件,用于定义此角色用到的变量。 -
defaults
此目录应当包含一个main.yml文件,用于为当前角色设定默认变量。 -
meta
此目录应当包含一个main.yml文件,用于定义此角色的特殊设定及其依赖关系。
//在一个playbook 中使用roles 的步骤:
(1)创建以 roles 命名的目录
mkdir /etc/ansible/roles/ -p #yum装完默认就有
(2)创建全局变量目录(可选)
mkdir /etc/ansible/group_vars/ -p
touch /etc/ansible/group_vars/all #文件名自己定义,引用的时候注意
(3)在roles目录中分别创建以各角色名称命令的目录,如httpd、mysql
mkdir /etc/ansible/roles/httpd
mkdir /etc/ansible/roles/mysql
(4)在每个角色命令的目录中分别创建files、handlers、tasks、templates、meta、defaults和vars目录,用不到的目录可以创建为空目录,也可以不创建
mkdir /etc/ansible/roles/httpd/{files, templates,tasks, handlers,vars, defaults, meta}
mkdir /etc/ansible/roles/mysql/{files,templates,tasks, handlers, vars, defaults,meta}
(5)在每个角色的 handlers、tasks、meta、defaults、vars目录下创建main.yml
文件,千万不能自定义文件名
touch /etc/ansible/roles/httpd/{defaults, vars,tasks, meta, handlers}/main.yml
touch /etc/ansible/roles/mysql/{defaults,vars,tasks,meta, handlers}/main. yml
( 6)修改site.yml文件,针对不同主机去调用不同的角色
vim /etc/ansible/site. yml
-hosts: webservers
remote_user: root
roles:
-httpd
-hosts: dbservers
remote_user: root
roles:
-mysql
- hosts: webservers
remote_user: root
roles:
- httpd
- hosts: dbservers
remote_user: root
roles:
- mysql
(7)运行ansible-playbook
cd /etc/ansible
ansible-playbook site.yml
示例:
mkdir /etc/ansible/roles/httpd/{files,templates,tasks, handlers,vars, defaults,meta }-p
mkdir /etc/ansible/roles/mysql/{files,templates,tasks, handlers,vars,defaults,meta}-p
mkdir /etc/ansible/roles/php/{files,templates,tasks, handlers, vars,defaults,meta} -p
touch /etc/ansible/roles/httpd/{defaults,vars,tasks, meta, handlers }/main.yml
touch /etc/ansible/roles/mysql/{defaults,vars,tasks, meta, handlers}/main. yml
touch /etc/ansible/roles/php/{defaults,vars,tasks, meta, handlers}/main.yml
–―—编写httpd模块------写一个简单的tasks/main. yml
vim /etc/ansible/roles/httpd/tasks/main.yml
-name : install apache
yum: name={{pkg}}state=latest
-name: start apache
service: enabled=true name={{svc} state=started
- name : install apache
yum: name={{pkg}} state=latest
- name: start apache
service: enabled=true name={{svc}} state=started
//定义变量:可以定义在全局变量中,也可以定义在roles角色变量中,一般定义在角色变量中
vim /etc/ansible/roles/httpd/vars/main.yml
pkg: httpd
svc: httpd
pkg: httpd
svc: httpd
------编写mysql模块-------
vim /etc/ansible/roles/mysql/tasks/main.yml
-name: install mysql
yum: name={ {pkg) } state=latest
-name : start mysql
service: enabled=true name={ {svc} } state=started
- name: install mysql
yum: name={{pkg}} state=latest
- name : start mysql
service: enabled=true name={{svc}} state=started
-编写php模块-----
vim /etc/ansible/roles/php/tasks/main.yml
name : install php
yum:name={{pkg}}state=latest
name: start php- fpm
service: enabled=true name={{svc}} state=started
- name: install php
yum: name={{pkg}} state=latest
- name: start php-fpm
service: enabled=true name={{svc}} state=started
vim /etc/ansible/roles/php/vars/main.yml
pkg:
-php
-php-fpm
svc: php-fpm
pkg:
- php
- php-fpm
svc: php-fpm
–编写roles示例-----
vim /etc/ansible/site.yml
hosts: webservers
remote_user: rootroles:
-httpd
-mysql
-php
- hosts: webservers
remote_user: root
roles:
- mysql
- httpd
- php
cd /etc/ansible
ansible-playbook site.yml