2026年5月14日
`知识点回顾`
1.playbook
语法结构:
- hosts: 主机 #一个play的开始 一个剧本的开始
tasks: #任务
- name: 任务描述 #一个任务的开始
yum: 模块 #做啥
name: nginx
state: present
语法检查:
ansible-playbook --syntax-check xx.yml
执行playbook:
ansible-playbook xx.yml
2.playbook 重构web
1、拷贝必要的数据
2、恢复快照
3、做免秘钥
4、主机清单
5、编写playbook 编写剧本
6、语法检测
7、执行
8、检查结果
3.playbook 重构backup
1、拷贝必要的数据
2、恢复快照
3、做免秘钥
4、主机清单
5、编写playbook 编写剧本
6、语法检测
7、执行
8、检查结果
4.playbook 重构nfs
1、拷贝必要的数据
2、恢复快照
3、做免秘钥
4、主机清单
5、编写playbook 编写剧本
6、语法检测
7、执行
8、检查结果
5.playbook 重构wp
框架思维: 硬件-》系统(优化)-》服务(优化)-》业务-》监控
nginx->php->MySQL->SLB+nfs->backup
1、拷贝必要的数据
2、恢复快照
3、做免秘钥
4、主机清单
5、编写playbook 编写剧本
6、语法检测
7、执行
8、检查结果
新学模块:
打包
解压
批量挂载
数据操作
用户创建
数据库创建
01.ansible-vars
1.vars变量
变量提供了便捷的方式来管理ansible playbook的每一个项目中的动态值,比如nginx-1.6.3这个软件包的版本,在其他地方或许会反复使用,那么如果将此值设置为变量,然后在其他的playbook中调用,会方便许多。如此以来还方便维护,减少维护的成本。
2.变量定义
方式1:在play中定义变量
方式2:在文件中定义变量
方式3:在主机清单中定义变量
方式4:在命令行中定义变量
方式5:官方推荐方式定义变量
2.1.在play中定义变量
`案例1:在play中定义变量`
[root@ansible ansible]# cat test.yml
- hosts: web02
vars:
- package: lrzsz
tasks:
- name: install lrzsz
yum:
name: "{{ package }}"
state: present
[root@ansible ansible]# ansible-playbook --syntax-check test.yml
playbook: test.yml
[root@ansible ansible]# ansible-playbook test.yml
`案例2:在play定义多个变量`
[root@ansible ansible]# cat test.yml
- hosts: web02
vars:
- pk1: lrzsz
- pk2: tree
tasks:
- name: install lrzsz
yum:
name:
- "{{ pk1 }}"
- "{{ pk2 }}"
state: present
[root@ansible ansible]# ansible-playbook --syntax-check test.yml
playbook: test.yml
[root@ansible ansible]# ansible-playbook test.yml
`案例3:在play中定义一个变量名称中存放多个值`
[root@ansible ansible]# cat test.yml
- hosts: web02
vars:
pk:
- lrzsz
- tree
tasks:
- name: install lrzsz
yum:
name: "{{ pk }}"
state: present
[root@ansible ansible]# ansible-playbook --syntax-check test.yml
playbook: test.yml
[root@ansible ansible]# ansible-playbook test.yml
`案例4:路径拼接 在web02创建 web02_10.0.0.8`
#注意如果变量带路径则不需要加双引号
[root@ansible ansible]# cat test.yml
- hosts: web02
vars:
- na: web02
- ip: 10.0.0.8
tasks:
- name: create dir
file:
path: /root/{{ na }}_{{ ip }}
state: directory
[root@ansible ansible]# ansible-playbook --syntax-check test.yml
playbook: test.yml
[root@ansible ansible]# ansible-playbook test.yml
[root@web02 ~]# ll
总用量 8
drwxr-xr-x 2 root root 6 5月 14 14:45 web02_10.0.0.8
2.2.在文件中定义变量
1、准备文件、在里面写变量
[root@ansible ansible]# cat vars1.yml
pk1: tree
pk2: lrzsz
2、在playbook中调用变量
[root@ansible ansible]# cat test.yml
- hosts: web02
vars_files: #通过vars_files将变量文件调用进来
- vars1.yml
tasks:
- name: create dir
yum:
name:
- "{{ pk1 }}"
- "{{ pk2 }}"
state: present
[root@ansible ansible]# ansible-playbook --syntax-check test.yml
playbook: test.yml
[root@ansible ansible]# ansible-playbook test.yml
2.3.在主机清单中定义变量
1.在主机清单中写变量
[root@ansible ansible]# cat /etc/ansible/hosts
backup ansible_ssh_host=172.16.1.41
nfs ansible_ssh_host=172.16.1.31
db01 ansible_ssh_host=172.16.1.51
[webs]
web01 ansible_ssh_host=172.16.1.7
web02 ansible_ssh_host=172.16.1.8
[webs:vars] #给webs组内设置变量
p1=tree
p2=lrzsz
2.在playbook中调用
[root@ansible ansible]# cat test.yml
- hosts: web02
tasks:
- name: create dir
yum:
name:
- "{{ p1 }}"
- "{{ p2 }}"
state: present
[root@ansible ansible]# ansible-playbook --syntax-check test.yml
playbook: test.yml
[root@ansible ansible]# ansible-playbook test.yml
#注意给所有的主机定义变量使用all
[all:vars]
p1=tree
p2=lrzsz
2.4.在命令行中定义变量
[root@ansible ansible]# ansible-playbook test.yml -e p1=tree
[root@ansible ansible]# cat test.yml
- hosts: web02
tasks:
- name: create dir
yum:
name:
- "{{ p1 }}"
state: present
2.5.官方推荐定义变量的方式
在执行playbook的当前目录创建两个目录
group_vars
host_vars
[root@ansible ansible]# mkdir group_vars host_vars
`案例1:只给web02设置变量`
[root@ansible ansible]# cat hosts_vars/web02
p1: tree
[root@ansible ansible]# cat test.yml
- hosts: web02
tasks:
- name: create dir
yum:
name:
- "{{ p1 }}"
state: present
[root@ansible ansible]# ansible-playbook test.yml
`案例2:只给webs组定义变量`
[root@ansible ansible]# cat group_vars/webs
p1: lrzsz
[root@ansible ansible]# cat test.yml
- hosts: web02
tasks:
- name: create dir
yum:
name:
- "{{ p1 }}"
state: present
[root@ansible ansible]# ansible-playbook test.yml
2.6.小结
#工作中使用变量定义较多的
方法1:直接在play中定义,直观
方法2:官方推荐的方式定义
---------------------------
以上两种都不用、使用的时候roles角色编排中定义
3.内置变量
3.1.内置变量查看
[root@ansible ansible]# ansible web02 -m setup
3.2.内置变量参考
ansible_default_ipv4.address: 显示IP地址
ansible_all_ipv4_addresses:仅显示ipv4的信息。
ansible_devices:仅显示磁盘设备信息。
ansible_distribution:显示是什么系统,例:centos,suse等。
ansible_distribution_major_version:显示是系统主版本。
ansible_distribution_version:仅显示系统版本。
ansible_machine:显示系统类型,例:32位,还是64位。
ansible_eth0:仅显示eth0的信息。
ansible_hostname:仅显示主机名。
ansible_kernel:仅显示内核版本。
ansible_lvm:显示lvm相关信息。
ansible_memtotal_mb:显示系统总内存。
ansible_memfree_mb:显示可用系统内存。
ansible_memory_mb:详细显示内存情况。
ansible_swaptotal_mb:显示总的swap内存。
ansible_swapfree_mb:显示swap内存的可用内存。
ansible_mounts:显示系统磁盘挂载情况。
ansible_processor:显示cpu个数(具体显示每个cpu的型号)。
ansible_processor_vcpus:显示cpu个数(只显示总的个数)。
3.3.内置变量使用案例
[root@ansible ansible]# cat test.yml
- hosts: webs
tasks:
- name: create dir
file:
path: /root/{{ ansible_hostname }}
state: directory
[root@ansible ansible]# ansible-playbook test.yml
[root@web01 ~]# ll -d web01/
drwxr-xr-x 2 root root 6 5月 14 15:28 web01/
[root@web02 ~]# ll -d web02
drwxr-xr-x 2 root root 6 5月 14 15:28 web02
4.变量注册
面试题:Ansible中执行命令看不到结果,怎么办?
我们可以使用变量注册的方式来输出结果,模块名称register
问题:在Ansible执行命令时、看不到执行结果。使用变量注册的功能实现
[root@ansible ansible]# cat test.yml
- hosts: webs
tasks:
- name: list /root
command: ls -l /root/
[root@ansible ansible]# cat test.yml
- hosts: webs
tasks:
- name: list /root
command: nginx -t
使用变量相关的模块输出变量中的内容
[root@ansible ansible]# cat test.yml
- hosts: webs
tasks:
- name: print ip address
debug:
msg: "{{ansible_default_ipv4.address}}"
[root@ansible ansible]# ansible-playbook test.yml
PLAY [webs] *******************************************************************************************
TASK [Gathering Facts] ********************************************************************************
ok: [web01]
ok: [web02]
TASK [print ip address] *******************************************************************************
ok: [web01] => {
"msg": "10.0.0.7"
}
ok: [web02] => {
"msg": "10.0.0.8"
}
-----------
[root@ansible ansible]# cat test.yml
- hosts: web01
tasks:
- name: print ip address
debug:
msg:
- "{{ ansible_default_ipv4.address }}"
- "{{ ansible_hostname }}"
- "{{ ansible_memtotal_mb }}"
[root@ansible ansible]# ansible-playbook test.yml
PLAY [web01] ******************************************************************************************
TASK [Gathering Facts] ********************************************************************************
ok: [web01]
TASK [print ip address] *******************************************************************************
ok: [web01] => {
"msg": [
"10.0.0.7",
"web01",
1956
]
}
4.1.register
#将一些执行命令看不到的结果赋值给一个变量,然后输出这个变了的内容,称此为变量注册
`案例1:输出ls -l结果`
[root@ansible ansible]# cat test.yml
- hosts: web01
tasks:
- name: list /root/
command: ls -l /root #将执行结果赋值个p_r这个变量
register: p_r
- name: print ip address
debug:
msg: "{{ p_r }}" #输出变量内容
[root@ansible ansible]# ansible-playbook test.yml
`案例2:输出子集中的内容`
[root@ansible ansible]# cat test.yml
- hosts: web01
tasks:
- name: list /root/
command: ls -l /root
register: p_r
- name: print ip address
debug:
msg: "{{ p_r.stdout_lines }}"
[root@ansible ansible]# ansible-playbook test.yml
`案例3:输出nginx -t的结果`
[root@ansible ansible]# cat test.yml
- hosts: web01
tasks:
- name: nginx -t
command: nginx -t
register: p_r
- name: print ip address
debug:
msg: "{{ p_r.stderr_lines }}"
[root@ansible ansible]# ansible-playbook test.yml
`扩展:层级定义变量方式` #了解
[root@ansible ansible]# cat vars1.yml
a:
b:
c: tree
[root@ansible ansible]# cat test.yml
- hosts: web01
vars_files: ./vars1.yml
tasks:
- name: install tree
yum:
name: "{{ a.b.c }}"
state: present
[root@ansible ansible]# ansible-playbook test.yml
5.关闭客户端信息采集
[root@ansible ansible]# cat test.yml
- hosts: web01
gather_facts: no #关闭
vars_files: ./vars1.yml
tasks:
- name: install tree
yum:
name: "{{ a.b.c }}"
state: present
[root@ansible ansible]# ansible-playbook test.yml
02.ansible-流程控制
1.when判断
案例1:操作webs,只在web02上安装tree命令,webs组内成员都创建1.txt
1.match
[root@ansible ansible]# cat test.yml
- hosts: webs
tasks:
- name: install tree
yum:
name: tree
state: present
when: ansible_hostname is match "web02"
- name: create file 1.txt
file:
path: /root/1.txt
state: touch
[root@ansible ansible]# ansible-playbook test.yml
2.search
[root@ansible ansible]# cat test.yml
- hosts: webs
tasks:
- name: install tree
yum:
name: tree
state: present
when: ansible_hostname is search "web02"
- name: create file 1.txt
file:
path: /root/1.txt
state: touch
[root@ansible ansible]# ansible-playbook test.yml
案例2:匹配主机等于web服务器执行安装tree
[root@ansible ansible]# cat test.yml
- hosts: webs
tasks:
- name: install tree
yum:
name: tree
state: present
when: ansible_hostname == "web"
[root@ansible ansible]# ansible-playbook test.yml
案例3:匹配主机名包含web并且ip地址是10.0.0.7安装tree
#写法1:
[root@ansible ansible]# cat test.yml
- hosts: webs
tasks:
- name: install tree
yum:
name: tree
state: present
when: (ansible_hostname is match "web" and ansible_default_ipv4.address == "10.0.0.7")
[root@ansible ansible]# ansible-playbook test.yml
#写法2
[root@ansible ansible]# cat test.yml
- hosts: webs
tasks:
- name: install tree
yum:
name: tree
state: present
when:
- ansible_hostname is match "web"
- ansible_default_ipv4.address == "10.0.0.7"
[root@ansible ansible]# ansible-playbook test.yml
案例4:匹配主机名称包含web的或者ip是10.0.0.31的
[root@ansible ansible]# cat test.yml
- hosts: all
tasks:
- name: install tree
yum:
name: tree
state: present
when: (ansible_hostname is match "web" or ansible_default_ipv4.address == "10.0.0.31")
[root@ansible ansible]# ansible-playbook test.yml
#注意变量子集另外一个书写方式
键名简单且固定 → 用点号(更简洁)
键名包含特殊字符或变量 → 用方括号(更安全)
ansible_default_ipv4.address
ansible_default_ipv4['address']
案例5:判断nginx结果中包含ok
1.变量注册
2.when判断
[root@ansible ansible]# cat test.yml
- hosts: web02
tasks:
- name: configure nginx server #将配置文件拷贝到web02
copy:
src: nginx.conf
dest: /etc/nginx/
- name: nginx check
command: nginx -t
register: ngx #变量注册
ignore_errors: yes #忽略错误结果 继续向下执行task
- name: print nginx
debug:
msg: "{{ ngx.stderr_lines }}" #输出变量内容、可以省略
- name: start nginx server
systemd:
name: nginx
state: started
- name: restarte nginx server
systemd:
name: nginx
state: restarted
when: ngx.stderr_lines is search "ok"
[root@ansible ansible]# ansible-playbook test.yml
2.handlers监控文件变化
handler用来执行某些条件下的任务,比如当配置文件发生变化的时候,通过notify触发handler去重启服务。
[root@ansible ansible]# cat test.yml
- hosts: web02
tasks:
- name: configure nginx server
copy:
src: nginx.conf
dest: /etc/nginx/
notify: restart nginx server #通过notify模块监控文件的变化,变化则通知restart nginx server执行动作
- name: nginx check
command: nginx -t
register: ngx
ignore_errors: yes
- name: start nginx server
systemd:
name: nginx
state: started
handlers: #notify监控到文件变化则执行handlers下的tasks
- name: restart nginx server
systemd:
name: nginx
state: restarted
when: ngx.stderr_lines is search "ok" #配置文件必须是正确的
[root@ansible ansible]# ansible-playbook test.yml
3.loop循环
案例1:创建a.txt b.txt
1.创建a.txt b.txt
[root@ansible ansible]# cat file.yml
- hosts: web02
tasks:
- name: create a.txt b.txt
file:
path: "{{ item }}"
state: touch
loop:
- a.txt
- b.txt
[root@ansible ansible]# ansible-playbook file.yml
2.字典循环{}
a.txt 属主属组root 权限 666
b.txt 属主属组www 权限600
[root@ansible ansible]# cat file.yml
- hosts: web02
tasks:
- name: create a.txt b.txt
file:
path: "{{ item.path }}"
owner: "{{ item.owner }}"
group: "{{ item.group }}"
mode: "{{ item.mode }}"
state: touch
loop:
- { path: a.txt,owner: root,group: root,mode: '0666' }
- { path: b.txt,owner: www,group: www,mode: '0600'}
[root@ansible ansible]# ansible-playbook file.yml
案例2:同时拷贝两个文件到目标主机
ansible上1.txt 拷贝到web02的/opt目录下属主属组root 权限777
ansible上2.txt 拷贝到web02的/root目录下属主属组www 权限600
[root@ansible ansible]# touch 1.txt 2.txt
[root@ansible ansible]# cat file.yml
- hosts: web02
tasks:
- name: copy 1.txt 2.txt to web02
copy:
src: "{{ item.src }}"
dest: "{{ item.dest }}"
owner: "{{ item.owner }}"
group: "{{ item.group }}"
mode: "{{ item.mode }}"
loop:
- { src: 1.txt,dest: /opt/,owner: root,group: root,mode: '0777' }
- { src: 2.txt,dest: /opt/,owner: www,group: www,mode: '0600'}
[root@ansible ansible]# ansible-playbook file.yml
案例3:同时启动两个服务
[root@ansible ansible]# cat systemd.yml
- hosts: web02
tasks:
- name: start nginx php server
systemd:
name: "{{ item }}"
state: started
loop:
- nginx
- php-fpm
[root@ansible ansible]# ansible-playbook systemd.yml
案例4:同时创建两个用户 普通 虚拟用户
[root@ansible ansible]# cat user.yml
- hosts: web02
tasks:
- name: create user
user:
name: "{{ item.name }}"
create_home: "{{ item.home }}"
shell: "{{ item.shell}}"
state: present
loop:
- { name: test1,home: yes,shell: /bin/bash }
- { name: test2,home: no,shell: /sbin/nologin}
[root@ansible ansible]# ansible-playbook user.yml
[root@web02 ~]# grep -E 'test1|test2' /etc/passwd
test1:x:1000:1000::/home/test1:/bin/bash
test2:x:1001:1001::/home/test2:/sbin/nologin
正文完