惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

A
Arctic Wolf
U
Unit 42
爱范儿
爱范儿
WordPress大学
WordPress大学
博客园 - 司徒正美
腾讯CDC
酷 壳 – CoolShell
酷 壳 – CoolShell
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Last Week in AI
Last Week in AI
美团技术团队
博客园_首页
宝玉的分享
宝玉的分享
Hugging Face - Blog
Hugging Face - Blog
P
Palo Alto Networks Blog
H
Hacker News: Front Page
博客园 - 叶小钗
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
罗磊的独立博客
TaoSecurity Blog
TaoSecurity Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Help Net Security
Help Net Security
雷峰网
雷峰网
S
Security @ Cisco Blogs
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Forbes - Security
Forbes - Security
T
Troy Hunt's Blog
V
V2EX
博客园 - 聂微东
Cloudbric
Cloudbric
大猫的无限游戏
大猫的无限游戏
Google Online Security Blog
Google Online Security Blog
S
Security Affairs
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Recent Commits to openclaw:main
Recent Commits to openclaw:main
IT之家
IT之家
S
SegmentFault 最新的问题
T
Threat Research - Cisco Blogs
J
Java Code Geeks
H
Heimdal Security Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
Know Your Adversary
Know Your Adversary
小众软件
小众软件
Microsoft Azure Blog
Microsoft Azure Blog
The GitHub Blog
The GitHub Blog
AWS News Blog
AWS News Blog
The Cloudflare Blog
Simon Willison's Weblog
Simon Willison's Weblog
月光博客
月光博客
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻

博客园 - 尹正杰

k8s集群为每个节点分配不通的ippool实战 ansible剧本实现一键升级K8S集群的NVIDIA GPU驱动 vmagent采集etcd数据并写入victoriametrics集群 VictoriaMetrics集群部署实战 Squid正向代理实战 kubespray生产故障案例之kubelet启动参数案例 filebeat指定名称空间采集pod数据 Calico自定义Ipool实战 ansible剧本实现kibana的部署和卸载 ansible剧本应用案例集合2 ansible剧本实现磁盘格式化 ansible快速入门篇 k8s集群管理 kubesray实战 kubespray实战案例 kubespray管理k8s的worker集群扩缩容 kubespray快速部署k8s集群实战 Kubeasz使用吐槽博客专题 Kubeasz基于ezctl实现etcd集群的管理实战 Kubeasz基于ezctl实现k8s集群一键升级 Calico启用纯BGP模式+RR实战案例 Calico 底层原理及IPIP(依赖BGP协议))和vxlan(不依赖BGP)工作模式切换 kubeasz基于ezctl实现k8s集群的扩容和缩容 kubeasz快速部署K8S集群实战 Ubuntu 24.04.04 LTS版本系统优化 Ubuntu Server 24.04.04 LTS部署指南 windows极速部署Openclaw实战篇 K8S的StatefulSet控制器应用案例之MySQL主从同步实战 k8s底层基于不同运行时集成harbor企业级私有仓库实战 二进制K8S集群附加组件部署及CNI网络插件切换实战 二进制部署K8S 1.35.0+最新版实战案例 etcd高可用集群部署及K8S周期性备份数据实战 基于Docker实现《若依》服务业务容器化实战篇 k8s集群基于Flannel网络插件部署凡人修仙传 k8s集群基于Calico网络插件部署凡人修仙传 ElasticSEearch 9.X环境部署 K8S Vertical Pod Autoscaler(VPA)实战案例 Prometheus监控自定义程序指标
Ansible急速入门实战篇
尹正杰 · 2026-06-18 · via 博客园 - 尹正杰

                                              作者:尹正杰

版权声明:原创作品,谢绝转载!否则将追究法律责任。

一.主机清单管理

1.安装ansible

	1.安装ansible
[root@ansible99 ~]# apt -y install ansible sshpass

	
	2.关闭主机密钥检查
[root@ansible99 ~]# cat > /etc/ansible/ansible.cfg <<EOF
[defaults]
host_key_checking = False
deprecation_warnings=False
inventory = /etc/ansible/hosts
EOF

2.直接指定主机

	1.定义主机列表
[root@ansible99 ~]# mkdir etcansible
[root@ansible99 ~]# 
[root@ansible99 ~]# vim /etc/ansible/hosts
[root@ansible99 ~]# 
[root@ansible99 ~]# cat  /etc/ansible/hosts
10.0.0.231 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass='1'
10.0.0.232 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass='1'
10.0.0.233 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass='1'
[root@ansible99 ~]# 



	2.链接指定的主机进行检测
[root@ansible99 ~]# ansible 10.0.0.231 -m ping
10.0.0.231 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
[root@ansible99 ~]# 
[root@ansible99 ~]# ansible 10.0.0.232 -m ping
10.0.0.232 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
[root@ansible99 ~]# 
[root@ansible99 ~]# ansible 10.0.0.66 -m ping  # 如果没有定义主机,则无法使用
[WARNING]: Could not match supplied host pattern, ignoring: 10.0.0.66
[WARNING]: No hosts matched, nothing to do
[root@ansible99 ~]# 

3.基于别名管理

	1.定义主机列表
[root@ansible99 ~]# cat  /etc/ansible/hosts 
10.0.0.231 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass='1'
master232 ansible_ssh_host=10.0.0.232 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass='1'
master233 ansible_ssh_host=10.0.0.233 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass='1'
[root@ansible99 ~]# 
[root@ansible99 ~]# 




	2.基于别名管理
[root@ansible99 ~]# ansible 10.0.0.231 -m ping
10.0.0.231 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
[root@ansible99 ~]# 
[root@ansible99 ~]# ansible master232 -m ping
master232 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
[root@ansible99 ~]# 
[root@ansible99 ~]# ansible master233 -m ping
master233 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
[root@ansible99 ~]# 
[root@ansible99 ~]# ansible 10.0.0.233 -m ping  # 基于别名就不能直接写主机IP了,如果非要用,也可以
[WARNING]: Could not match supplied host pattern, ignoring: 10.0.0.233
[WARNING]: No hosts matched, nothing to do
[root@ansible99 ~]#  

3.基于多个分组

	1.修改主机清单
[root@ansible99 ~]# cat  /etc/ansible/hosts 
[k8s_master]
master231 ansible_ssh_host=10.0.0.231 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass='1'
master232 ansible_ssh_host=10.0.0.232 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass='1'
master233 ansible_ssh_host=10.0.0.233 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass='1'

[k8s_worker]
worker66 ansible_ssh_host=10.0.0.66 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass='1'
worker77 ansible_ssh_host=10.0.0.77 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass='1'
[root@ansible99 ~]# 
[root@ansible99 ~]# 


	2.测试验证
[root@ansible99 ~]# ansible k8s_master -m ping
master231 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
master233 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
master232 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
[root@ansible99 ~]# 
[root@ansible99 ~]# 
[root@ansible99 ~]# ansible k8s_worker -m ping
worker77 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
worker66 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
[root@ansible99 ~]# 
[root@ansible99 ~]# ansible all -m ping  # all代表所有的分组。
worker77 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
master233 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
worker66 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
master232 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
master231 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
[root@ansible99 ~]# 

4.通过域名解析

	1.添加域名配置
[root@ansible99 ~]# cat /etc/ansible/hosts 
www.yinzhengjie.com ansible_ssh_host=10.0.0.231 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass='1'

[k8s_master]
master231 ansible_ssh_host=10.0.0.231 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass='1'
master232 ansible_ssh_host=10.0.0.232 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass='1'
master233 ansible_ssh_host=10.0.0.233 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass='1'

[k8s_worker]
worker66 ansible_ssh_host=10.0.0.66 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass='1'
worker77 ansible_ssh_host=10.0.0.77 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass='1'
[root@ansible99 ~]# 


	2.由于我没有域名指向的服务器,因此在本地host做域名劫持
[root@ansible99 ~]# echo 10.0.0.231 www.yinzhengjie.com >> /etc/hosts
[root@ansible99 ~]# 
[root@ansible99 ~]# tail -1 /etc/hosts
10.0.0.231 www.yinzhengjie.com
[root@ansible99 ~]# 
[root@ansible99 ~]# ansible www.yinzhengjie.com -m ping
www.yinzhengjie.com | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
[root@ansible99 ~]# 

5.序列定义方式

	1.添加主机解析
[root@ansible99 ~]# cat >> /etc/hosts <<EOF
10.0.0.231 master231
10.0.0.232 master232
10.0.0.233 master233
EOF

	
	
	2.定义主机列表
[root@ansible99 ~]# cat /etc/ansible/hosts 
[k8s_master]
master23[1:3]  ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass='1'

[k8s_worker]
worker66 ansible_ssh_host=10.0.0.66 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass='1'
worker77 ansible_ssh_host=10.0.0.77 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass='1'

[root@ansible99 ~]# 



	
	2.测试验证
[root@ansible99 ~]# ansible k8s_master -m ping
master231 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
master233 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
master232 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
[root@ansible99 ~]# 

6.支持子组

	1.定义主机
[root@ansible99 ~]# cat /etc/ansible/hosts 
[k8s01]
master231 ansible_ssh_host=10.0.0.231 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass='1'

[k8s02]
master232 ansible_ssh_host=10.0.0.232 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass='1'

[k8s03]
master233 ansible_ssh_host=10.0.0.233 ansible_ssh_user=root ansible_ssh_port=22 ansible_ssh_pass='1'


[master:children]
k8s01
k8s03
[root@ansible99 ~]# 
	
	
	
	2.调用子组master
[root@ansible99 ~]# ansible master -m ping
master231 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
master233 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
[root@ansible99 ~]# 

7.为组设置变量

	1.定义主机清单
[root@ansible99 ~]# cat /etc/ansible/hosts 
[k8s01]
master231 ansible_ssh_host=10.0.0.231

[k8s02]
master232 ansible_ssh_host=10.0.0.232

[k8s03]
master233 ansible_ssh_host=10.0.0.233 


[master:children]
k8s01
k8s03

[all:vars]  # 此处的all表示所有主机,这里的vars表示设置变量。
ansible_ssh_user=root 
ansible_ssh_port=22 
ansible_ssh_pass='1'
[root@ansible99 ~]# 


	2.测试验证
[root@ansible99 ~]# ansible master -m ping
master231 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
master233 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
[root@ansible99 ~]# 
[root@ansible99 ~]# 
[root@ansible99 ~]# ansible k8s02 -m ping
master232 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
[root@ansible99 ~]# 

8.通过免密钥的方式配置Inventory

	1.生成密钥
[root@ansible99 ~]# ssh-keygen -t rsa -f ~/.ssh/id_rsa -P '' -q

	2.配置免密链接
[root@ansible99 ~]# ssh-copy-id 10.0.0.231
[root@ansible99 ~]# ssh-copy-id 10.0.0.232
[root@ansible99 ~]# ssh-copy-id 10.0.0.233
[root@ansible99 ~]# ssh-copy-id 10.0.0.66
[root@ansible99 ~]# ssh-copy-id 10.0.0.77


	3.修改主机清单
[root@ansible99 ~]# cat  /etc/ansible/hosts 
[master]
10.0.0.231
10.0.0.232
10.0.0.233

[worker]
10.0.0.66
10.0.0.77
[root@ansible99 ~]# 


	4.测试验证
[root@ansible99 ~]# ansible master -m ping
10.0.0.233 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
10.0.0.232 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
10.0.0.231 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
[root@ansible99 ~]# 
[root@ansible99 ~]# 
[root@ansible99 ~]# ansible worker -m ping
10.0.0.66 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
10.0.0.77 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
[root@ansible99 ~]# 
[root@ansible99 ~]# ansible all -m ping
10.0.0.77 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
10.0.0.66 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
10.0.0.233 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
10.0.0.232 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
10.0.0.231 | SUCCESS => {
    "ansible_facts": {
        "discovered_interpreter_python": "/usr/bin/python3"
    },
    "changed": false,
    "ping": "pong"
}
[root@ansible99 ~]# 

二.ansible的模块

1.查看模块文档

[root@ansible99 ~]# ansible-doc ping
> ANSIBLE.BUILTIN.PING    (/usr/lib/python3/dist-packages/ansible/modules/ping.py)

        A trivial test module, this module always returns `pong' on successful contact. It
        does not make sense in playbooks, but it is useful from `/usr/bin/ansible' to verify
        the ability to login and that a usable Python is configured. This is NOT ICMP ping,
        this is just a trivial test module that requires Python on the remote-node. For
        Windows targets, use the [ansible.windows.win_ping] module instead. For Network
        targets, use the [ansible.netcommon.net_ping] module instead.

ADDED IN: historical

OPTIONS (= is mandatory):

- data
        Data to return for the `ping' return value.
        If this parameter is set to `crash', the module will cause an exception.
        default: pong
        type: str


ATTRIBUTES:

        check_mode:
          description: Can run in check_mode and return changed status prediction without
            modifying target
          support: full
        diff_mode:
          description: Will return details on what has changed (or possibly needs changing
            in check_mode), when in diff mode
          support: none
        platform:
[root@ansible99 ~]# 

2.参考资料

推荐阅读:
	https://www.cnblogs.com/yinzhengjie/p/10447587.html

三.Playbook实战之vars变量管理

1.playbook概述

1.1 Playbook的核心元素

Hosts:
    定义可以操作的主机,

Tasks:
    定义我们需要执行的任务列表。Variable:  支持变量,流程控制语句,如循环语句等等。(YAML支持编程语言的基本语法,如条件表达式,循环语句,流程控制等等,这也是为什么ansible选择它的一个原因吧!)

Templates:
    包含了模板语法的文本文件。

Handlers:
    处理器是由特定条件触发的任务。

Roles:
    定义角色,其实我们可以理解角色是将服务器主机进行分组,然后基于组的方式进行批量管理。这个角色和MySQL8.0之后版本的角色功能很相似!

1.2 ansible运行结果颜色说明

颜色 含义 描述
绿色 执行成功且未发生状态改变 任务成功完成,但目标系统没有发生变化(幂等性体现)。
黄色 成功执行且发生了状态改变 任务成功完成,并且目标系统的状态发生了改变(如文件创建,服务启动)。
红色 执行失败 执行过程中出现错误,需要排查原因。
紫色 告警信息 提示可能存在的问题或建议,但任务可能继续执行。
ansible输出的颜色,表示不同的涵义。

2.定义变量

2.1 直接在play定义变量

	1.查看主机清单
[root@ansible99 playbook]# cat /etc/ansible/hosts 
[master]
10.0.0.231
10.0.0.232
10.0.0.233

[worker]
10.0.0.66
10.0.0.77
[root@ansible99 playbook]# 


	2.编写剧本
[root@ansible99 playbook]# cat 01-play.yaml 
- hosts: master
  vars:
    - file01: /tmp/xixi.txt
    - file02: haha.txt
  tasks:
    - name: create {{ file01 }} file
      file:
        path: "{{ file01 }}"
        owner: root
        group: root
        mode: 0644
        state: touch
    - name: create {{ file02 }} file
      file:
        path: /tmp/{{ file02 }}
        state: touch
[root@ansible99 playbook]# 


	3.测试验证
[root@ansible99 playbook]# ansible-playbook  01-play.yaml 

PLAY [master] ********************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************
ok: [10.0.0.231]
ok: [10.0.0.233]
ok: [10.0.0.232]

TASK [create /tmp/xixi.txt file] *************************************************************************************
changed: [10.0.0.231]
changed: [10.0.0.233]
changed: [10.0.0.232]

TASK [create haha.txt file] ******************************************************************************************
changed: [10.0.0.231]
changed: [10.0.0.233]
changed: [10.0.0.232]

PLAY RECAP ***********************************************************************************************************
10.0.0.231                 : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.232                 : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.233                 : ok=3    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@ansible99 playbook]# 

2.2 在文件中定义变量

	1.编写剧本
[root@ansible99 playbook]# cat pkg.yml 
pkg01: wget
pkg02: tree
[root@ansible99 playbook]# 
[root@ansible99 playbook]# cat  02-files.yaml 
- hosts: master
  vars_files:
    - pkg.yml
  tasks:
    - name: Install package
      apt:
        name:
          - "{{ pkg01 }}"
          - "{{ pkg02 }}"
        state: present  # 卸载的话可以改成absent
[root@ansible99 playbook]# 



	2.测试验证
[root@ansible99 playbook]# ansible-playbook 02-files.yaml  

PLAY [master] ********************************************************************************************************

TASK [Gathering Facts] ***********************************************************************************************
ok: [10.0.0.231]
ok: [10.0.0.233]
ok: [10.0.0.232]

TASK [Install package] ***********************************************************************************************
changed: [10.0.0.231]
changed: [10.0.0.232]
changed: [10.0.0.233]

PLAY RECAP ***********************************************************************************************************
10.0.0.231                 : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.232                 : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.233                 : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@ansible99 playbook]# 

2.3 在主机清单中定义变量

	1.在主机清单中定义变量
[root@ansible99 playbook]# cat  /etc/ansible/hosts 
[master]
10.0.0.231
10.0.0.232
10.0.0.233

[worker]
10.0.0.66
10.0.0.77


[master:vars]
pkg01=wget
pkg02=tree
pkg03=lrzsz
[root@ansible99 playbook]# 


	2.编写playbook
[root@ansible99 playbook]# cat 03-hosts.yaml 
- hosts: master
  tasks:
    - name: Install package
      apt:
        name:
          - "{{ pkg01 }}"
          - "{{ pkg02 }}"
          - "{{ pkg03 }}"
        state: present
[root@ansible99 playbook]# 

	
	3.测试验证
[root@ansible99 playbook]# ansible-playbook 03-hosts.yaml 

PLAY [master] **********************************************************************

TASK [Gathering Facts] *************************************************************
ok: [10.0.0.233]
ok: [10.0.0.232]
ok: [10.0.0.231]

TASK [Install package] *************************************************************
changed: [10.0.0.231]
changed: [10.0.0.233]
changed: [10.0.0.232]

PLAY RECAP *************************************************************************
10.0.0.231                 : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.232                 : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.233                 : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@ansible99 playbook]#  

2.4 官方推荐的定义变量方式

	1.在运行playbook的目录下创建两个目录
[root@ansible99 playbook]# mkdir group_vars hosts_vars
[root@ansible99 playbook]# 

目录作用说明:
	group_vars:
		在目录下面以"组名称"命名的文件,然后在文件中直接定义变量。
		
	hosts_vars:
		在目录下面以"主机"命名的文件,然后在文件中直接定义变量。



	2.编辑主机清单
[root@ansible99 playbook]# cat /etc/ansible/hosts 
[master]
10.0.0.231
10.0.0.232
10.0.0.233

[worker]
10.0.0.66
10.0.0.77
[root@ansible99 playbook]# 
	
	
	3.在group_vars或者hosts_vars目录下定义变量
[root@ansible99 playbook]# cat group_vars/all 
pkg01: wget
pkg02: tree
pkg03: lrzsz

[root@ansible99 playbook]# 
[root@ansible99 playbook]# cat group_vars/master 
pkg01: curl
pkg02: tree
[root@ansible99 playbook]# 
[root@ansible99 playbook]# cat hosts_vars/10.0.0.66 
pkg01: nginx
pkg02: curl
[root@ansible99 playbook]# 



	4.编写playbook
[root@ansible99 playbook]# cat 04-group-vars.yaml 
- hosts: master
  tasks:
    - name: Install package
      apt:
        name:
          - "{{ pkg01 }}"
          - "{{ pkg02 }}"
        state: absent
[root@ansible99 playbook]# 

	
	5.测试验证
[root@ansible99 playbook]# ansible-playbook 04-group-vars.yaml 

PLAY [master] **********************************************************************

TASK [Gathering Facts] *************************************************************
ok: [10.0.0.233]
ok: [10.0.0.232]
ok: [10.0.0.231]

TASK [Install package] *************************************************************
changed: [10.0.0.231]
changed: [10.0.0.233]
changed: [10.0.0.232]

PLAY RECAP *************************************************************************
10.0.0.231                 : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.232                 : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.233                 : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@ansible99 playbook]# 

3.变量注册

3.1 什么是变量注册

当ansible的模块在运行之后,其实都会返回一些result结果,就像是执行脚本,我们有的时候需要脚本给我们一些return返回值,我们才知道,上一步是否只想成功。

默认情况下,ansible的result并不会显示出来,所以,我们可以把这些返回值'存储'到变量中,这样我们就能通过'调用'对应的变量名,从而获取到这些result,这种将模块的返回值,写入变量中的方法我们称之为变量注册。

3.2 变量注册案例

	1.编写剧本
[root@ansible99 playbook]# cat 05-register.yaml 
- hosts: 10.0.0.232
  tasks:
    - name: Install nginx
      apt:
        name:
          - nginx
        state: present

    - name: nginx check syntax
      command: 'nginx -t'
      # 注册变量
      register: nginx_result
      
    - name: print nginx_result variables
      debug:
        # 一般我们不需要查看所有的输出,看指定字段的数据,可以使用"."来取数据即可。
        # msg: "{{ nginx_result }}"
        msg: "{{ nginx_result.stderr_lines }}"


    - name: list nginx conf dir
      command: 'ls -lh /etc/nginx/'
      register: list_result
      
    - name: print list_result variables
      debug:
        msg: "{{ list_result.stdout_lines }}"


[root@ansible99 playbook]# 

	
	
	2.测试验证
[root@ansible99 playbook]# ansible-playbook 05-register.yaml 

PLAY [10.0.0.232] ******************************************************************

TASK [Gathering Facts] *************************************************************
ok: [10.0.0.232]

TASK [Install nginx] ***************************************************************
ok: [10.0.0.232]

TASK [nginx check syntax] **********************************************************
changed: [10.0.0.232]

TASK [print nginx_result variables] ************************************************
ok: [10.0.0.232] => {
    "msg": [
        "nginx: the configuration file /etc/nginx/nginx.conf syntax is ok",
        "nginx: configuration file /etc/nginx/nginx.conf test is successful"
    ]
}

TASK [list nginx conf dir] *********************************************************
changed: [10.0.0.232]

TASK [print list_result variables] *************************************************
ok: [10.0.0.232] => {
    "msg": [
        "total 68K",
        "drwxr-xr-x 2 root root 4.0K Jun  9 11:45 conf.d",
        "-rw-r--r-- 1 root root 1.1K Nov 30  2023 fastcgi.conf",
        "-rw-r--r-- 1 root root 1.1K Nov 30  2023 fastcgi_params",
        "-rw-r--r-- 1 root root 2.8K Nov 30  2023 koi-utf",
        "-rw-r--r-- 1 root root 2.2K Nov 30  2023 koi-win",
        "-rw-r--r-- 1 root root 5.4K Nov 30  2023 mime.types",
        "drwxr-xr-x 2 root root 4.0K Jun  9 11:45 modules-available",
        "drwxr-xr-x 2 root root 4.0K Jun  9 11:45 modules-enabled",
        "-rw-r--r-- 1 root root 1.5K Nov 30  2023 nginx.conf",
        "-rw-r--r-- 1 root root  180 Nov 30  2023 proxy_params",
        "-rw-r--r-- 1 root root  636 Nov 30  2023 scgi_params",
        "drwxr-xr-x 2 root root 4.0K Jun 10 08:46 sites-available",
        "drwxr-xr-x 2 root root 4.0K Jun 10 08:46 sites-enabled",
        "drwxr-xr-x 2 root root 4.0K Jun 10 08:46 snippets",
        "-rw-r--r-- 1 root root  664 Nov 30  2023 uwsgi_params",
        "-rw-r--r-- 1 root root 3.0K Nov 30  2023 win-utf"
    ]
}

PLAY RECAP *************************************************************************
10.0.0.232                 : ok=6    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@ansible99 playbook]# 

4.层级定义变量

4.1 使用点号'.'区分层级变量

	1.定义层级变量
[root@ansible99 playbook]# cat pkg2.yml 
lnmp:
  tools:
    pkg: wget
[root@ansible99 playbook]# 

	
	2.编写playbook局部
[root@ansible99 playbook]# cat 06-layer-var.yaml 
- hosts: master
  vars_files:
    - pkg2.yml
  tasks:
    - name: remove "{{ lnmp.tools.pkg }}" package
      apt:
        name:
          - "{{ lnmp.tools.pkg }}"
        state: absent
[root@ansible99 playbook]#

	
	3.测试验证
[root@ansible99 playbook]# ansible-playbook  06-layer-var.yaml 

PLAY [master] **********************************************************************

TASK [Gathering Facts] *************************************************************
ok: [10.0.0.233]
ok: [10.0.0.231]
ok: [10.0.0.232]

TASK [remove "wget" package] *******************************************************
changed: [10.0.0.231]
changed: [10.0.0.233]
changed: [10.0.0.232]

PLAY RECAP *************************************************************************
10.0.0.231                 : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.232                 : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.233                 : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@ansible99 playbook]# 

4.2 使用方括号'[]'区分层级变量 (官方推荐写法)

	1.定义层级变量
[root@ansible99 playbook]# cat pkg2.yml 
lnmp:
  tools:
    pkg: wget
[root@ansible99 playbook]# 

	
	2.编写playbook局部
[root@ansible99 playbook]# cat 07-layer2-var.yaml 
- hosts: master
  vars_files:
    - pkg2.yml
  tasks:
    - name: install "{{ lnmp['tools']['pkg'] }}" package
      apt:
        name:
          - "{{ lnmp['tools']['pkg'] }}"
        state: present
[root@ansible99 playbook]# 


	
	3.测试验证
[root@ansible99 playbook]# ansible-playbook 07-layer2-var.yaml 

PLAY [master] **********************************************************************

TASK [Gathering Facts] *************************************************************
ok: [10.0.0.233]
ok: [10.0.0.232]
ok: [10.0.0.231]

TASK [install "wget" package] ******************************************************
ok: [10.0.0.233]
ok: [10.0.0.231]
ok: [10.0.0.232]

PLAY RECAP *************************************************************************
10.0.0.231                 : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.232                 : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
10.0.0.233                 : ok=2    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

[root@ansible99 playbook]# 



温馨提示:
	语法风格差异:
		

4.3 语法风格对比

类型 描述 风格
点号(".") 键名必须是有效的标识符,不能包含特殊字符,空格,连字符等。 类似于python的对象属性访问。
方括号("[]") 可以处理任何字符串键名 类似于python字典键值对访问。
如上所示,官方两种风格都支持,但对于特殊的键名称推荐使用方括号来引用。

举个例子:
	包含特殊字符的键名:
		lnmp['web-server']['php-version']
	以数字开头的键名:
		lnmp['2nd-level']['key']
	包含空格的键名:
		lnmp['my key']['sub key']

5.Facts缓存

5.1 facts概述

ansible facts是被管理主机上通过ansible自动采集发现的变量,facts包含每台特定的主机信息。

facts包含被控制端的主机名,IP地址,系统版本,CPU数量,内存状态,磁盘状态等等。

5.2 facts内置变量

5.2.1 系统发行版 & 内核架构

变量名 用途说明
ansible_distribution 系统发行版名称(CentOS/Ubuntu/Rocky/Windows)
ansible_distribution_version 系统完整版本号
ansible_distribution_major_version 系统主版本号
ansible_os_family 系统家族(RedHat/Debian/Suse/Windows)
ansible_system 内核标识(Linux/Windows/Darwin)
ansible_kernel 内核版本号
ansible_architecture CPU 架构(x86_64/aarch64/armv7l)
ansible_pkg_mgr 系统包管理器(yum/dnf/apt/chocolatey)
ansible_timezone 系统时区
ansible_selinux SELinux 完整状态字典
ansible_selinux_mode SELinux 运行模式

5.2.2 CPU 硬件信息

变量名 用途说明
ansible_processor CPU 型号列表
ansible_processor_count 物理 CPU 颗数
ansible_processor_cores 单 CPU 物理核心数
ansible_processor_vcpus 逻辑 CPU 总数量(含超线程)
ansible_threads_per_core 每核心线程数
ansible_cpu_min_freq_hz CPU 最小运行频率
ansible_cpu_max_freq_hz CPU 最大运行频率

5.2.3 内存与 Swap

变量名 用途说明
ansible_memtotal_mb 物理总内存 (MB)
ansible_memfree_mb 空闲物理内存 (MB)
ansible_swaptotal_mb Swap 分区总大小 (MB)
ansible_swapfree_mb 空闲 Swap 大小 (MB)
ansible_memory_mb 内存复合字典(real/swap 分组存储 total/free/cached)

5.2.4 磁盘与挂载设备

变量名 用途说明
ansible_mounts 所有挂载点数组,包含路径、设备、容量、文件系统
ansible_devices 磁盘设备字典(sda/vda 等),包含分区信息

5.2.5 网络相关(高频)

变量名 用途说明
ansible_hostname 主机短名
ansible_fqdn 完整主机域名
ansible_nodename uname -n 获取的主机名
ansible_default_ipv4 默认出口 IPv4 完整字典(地址 / 网关 / 网卡 / 掩码)
ansible_default_ipv6 默认出口 IPv6 完整字典
ansible_interfaces 全部网卡名称数组
ansible_网卡名 (ansible_eth0/ens33) 单网卡详情(IP、MAC、MTU)

5.2.6 虚拟化 / 云主机标识

变量名 用途说明
ansible_virtualization_type 虚拟化类型(kvm/qemu/vmware/docker/physical)
ansible_virtualization_role guest 虚拟机 /host 宿主机
ansible_container 是否为容器(true/false)
ansible_container_type 容器类型(docker/podman/lxc)
ansible_ec2_* AWS EC2 云主机信息
ansible_azure_* Azure 云主机信息
ansible_gce_* GCP 谷歌云主机信息
ansible_system_vendor 服务器硬件厂商(Dell/VMware/QEMU)

5.2.7 用户、环境、时间

变量名 用途说明
ansible_user_id 当前执行 ansible 用户 UID
ansible_group_id 当前执行 ansible 用户 GID
ansible_user_dir 当前用户家目录
ansible_env 系统环境变量全量字典
ansible_date_time 时间复合字典
ansible_date_time.iso8601 ISO 标准格式时间
ansible_date_time.epoch 时间戳

5.2.8 Windows 系统专属 Facts

变量名 用途说明
ansible_os_version Windows 系统版本
ansible_windows_domain Windows 域信息
ansible_windows_systemroot Windows 系统目录
ansible_total_physical_memory_mb Windows 总物理内存

5.2.9 playbook 全局内置变量(非 setup 采集 facts,配套使用)

变量名 用途说明
inventory_hostname Inventory 清单内定义的主机名
inventory_hostname_short Inventory 主机短名
groups 全部分组主机字典
group_names 当前主机所属分组列表
play_hosts 当前 play 执行的主机列表
ansible_version Ansible 工具版本信息字典

5.3 测试案例

	1.查看资源清单
(venv) [root@ansible99 playbook]# cat /root/kubespray/inventory/yinzhengjie-k8s/inventory.ini
[all]
master231 ansible_host=10.0.0.231  ip=10.0.0.231
master232 ansible_host=10.0.0.232  ip=10.0.0.232
master233 ansible_host=10.0.0.233  ip=10.0.0.233
worker66 ansible_host=10.0.0.66  ip=10.0.0.66
worker77 ansible_host=10.0.0.77  ip=10.0.0.77

[kube_control_plane]
master231
master232
master233

[etcd]
master231
master232
master233

[kube_node]
worker66
worker77

(venv) [root@ansible99 playbook]# 


	2.编写playbook
(venv) [root@ansible99 playbook]# cat 08-facts.yaml 
- hosts: kube_control_plane
  # 获取客户端信息
  tasks:
    - name: print server info
      debug:
        msg: '"{{ ansible_hostname }}" --- "{{ ansible_default_ipv4.address }}" --- {{ ansible_virtualization_type }}'
    - name: mkdir dir
      file:
        path: /tmp/{{ ansible_hostname }}-{{ ansible_default_ipv4.address }}
        state: directory
(venv) [root@ansible99 playbook]# 



	
	3.测试验证
(venv) [root@ansible99 playbook]# ansible-playbook  -i /root/kubespray/inventory/yinzhengjie-k8s/inventory.ini  08-facts.yaml 

PLAY [kube_control_plane] **************************************************************************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************************************************************************************
ok: [master232]
ok: [master233]
ok: [master231]

TASK [print server info] ***************************************************************************************************************************************************************************************
ok: [master231] => {
    "msg": "\"master231\" --- \"10.0.0.231\" --- VMware"
}
ok: [master232] => {
    "msg": "\"master232\" --- \"10.0.0.232\" --- VMware"
}
ok: [master233] => {
    "msg": "\"master233\" --- \"10.0.0.233\" --- VMware"
}

TASK [mkdir dir] ***********************************************************************************************************************************************************************************************
ok: [master231]
ok: [master232]
ok: [master233]

PLAY RECAP *****************************************************************************************************************************************************************************************************
master231                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
master232                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
master233                  : ok=3    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

(venv) [root@ansible99 playbook]# 
(venv) [root@ansible99 playbook]# 

6.template使用变量

6.1 template的作用

如果使用file拷贝一个文件到目的主机,正常情况下就会直接将文件拷贝到目标主机。

但是,如果要拷贝的文件中用到了变量,则用file拷贝并不会引用变量,而是直接拷贝文件内容,使用template拷贝则拷贝的文件有变量引用的话,拷贝过去时也会引用相应的变量。

6.2 测试验证

	1.准备模板文件
(venv) [root@ansible99 playbook]# cat  server.info 
------------------------------------------------------------------------------------------------------
- 服务器名称:     -  {{ ansible_hostname }}                                                      
- 服务器IP地址:   -  {{ ansible_default_ipv4.address }}                                         
- 服务器内存:     -  {{ ansible_memtotal_mb }}                                                  
- 虚拟化类型      -  {{ ansible_virtualization_type }} / {{ ansible_virtualization_role }}
- CPU数量:        -  {{ ansible_processor_count }}                                                    
- 逻辑 CPU 总数量 -  {{ ansible_processor_vcpus }}                                        
- CPU型号         -  {{ ansible_processor }}                                                          
-----------------------------------------------------------------------------------------------------
(venv) [root@ansible99 playbook]# 

	
	
	2.编写playbook
(venv) [root@ansible99 playbook]# cat 09-template.yaml
- hosts: kube_control_plane
  tasks:
    - name: copy server.info
      template:
        src: server.info
        dest: /root/server.txt
(venv) [root@ansible99 playbook]# 
(venv) [root@ansible99 playbook]# 



	3.执行playbook
(venv) [root@ansible99 playbook]# cat /root/kubespray/inventory/yinzhengjie-k8s/inventory.ini
[all]
master231 ansible_host=10.0.0.231  ip=10.0.0.231
master232 ansible_host=10.0.0.232  ip=10.0.0.232
master233 ansible_host=10.0.0.233  ip=10.0.0.233
worker66 ansible_host=10.0.0.66  ip=10.0.0.66
worker77 ansible_host=10.0.0.77  ip=10.0.0.77

[kube_control_plane]
master231
master232
master233

(venv) [root@ansible99 playbook]# 
(venv) [root@ansible99 playbook]# ansible-playbook -i /root/kubespray/inventory/yinzhengjie-k8s/inventory.ini 09-template.yaml

PLAY [kube_control_plane] **************************************************************************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************************************************************************************
ok: [master231]
ok: [master233]
ok: [master232]

TASK [copy server.info] ****************************************************************************************************************************************************************************************
changed: [master231]
changed: [master233]
changed: [master232]

PLAY RECAP *****************************************************************************************************************************************************************************************************
master231                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
master232                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
master233                  : ok=2    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

(venv) [root@ansible99 playbook]# 


	4.查看目标主机信息
[root@master231 ~]# cat server.txt 
------------------------------------------------------------------------------------------------------
- 服务器名称:     -  master231                                                      
- 服务器IP地址:   -  10.0.0.231                                         
- 服务器内存:     -  3868                                                  
- 虚拟化类型      -  VMware / guest
- CPU数量:        -  2                                                    
- 逻辑 CPU 总数量 -  2                                        
- CPU型号         -  ['0', 'GenuineIntel', 'Intel(R) Core(TM) Ultra 7 356H', '1', 'GenuineIntel', 'Intel(R) Core(TM) Ultra 7 356H']                                                          
-----------------------------------------------------------------------------------------------------
[root@master231 ~]# 


[root@master232 ~]# cat server.txt 
------------------------------------------------------------------------------------------------------
- 服务器名称:     -  master232                                                      
- 服务器IP地址:   -  10.0.0.232                                         
- 服务器内存:     -  3868                                                  
- 虚拟化类型      -  VMware / guest
- CPU数量:        -  2                                                    
- 逻辑 CPU 总数量 -  2                                        
- CPU型号         -  ['0', 'GenuineIntel', 'Intel(R) Core(TM) Ultra 7 356H', '1', 'GenuineIntel', 'Intel(R) Core(TM) Ultra 7 356H']                                                          
-----------------------------------------------------------------------------------------------------
[root@master232 ~]# 


[root@master233 ~]# cat server.txt 
------------------------------------------------------------------------------------------------------
- 服务器名称:     -  master233                                                      
- 服务器IP地址:   -  10.0.0.233                                         
- 服务器内存:     -  3867                                                  
- 虚拟化类型      -  VMware / guest
- CPU数量:        -  2                                                    
- 逻辑 CPU 总数量 -  2                                        
- CPU型号         -  ['0', 'GenuineIntel', 'Intel(R) Core(TM) Ultra 7 356H', '1', 'GenuineIntel', 'Intel(R) Core(TM) Ultra 7 356H']                                                          
-----------------------------------------------------------------------------------------------------
[root@master233 ~]# 

四.Playbook实战之流程控制

1.playbook条件语句概述

任何编程语言几乎都支持流程控制,条件判断,在我们使用ansible的过程中,条件判断也是经常会被使用的。

举个例子:
	- 1.安装同一种软件在不同系统上其软件包名称可能不一致(比如nfs服务),可以通过判断系统来对软件包名称进行修改;
	- 2.在部署K8S集群之前,我们可以判断现有的环境,是否需要做Linux基础优化(比如禁用swap,修改内核参数,开启本地DNS缓存等);

2.when判断实战

2.1 when条件表达式

精确匹配:
	when: ansible_hostname == "master231"

	
模糊匹配:
	when: ansible_hostname is match "master232"
	when: ansible_hostname is search "master233"

2.2 when案例

	1.编写playbook
(venv) [root@ansible99 playbook]# cat 10-when.yaml 
- hosts: kube_control_plane
  tasks:
    - name: remove wget
      apt:
        name: wget
        state: absent
      when: ansible_hostname is match "master"

    - name: install tree
      apt:
        name: tree
        state: present
      when: ansible_hostname == "master232"

    - name: remove curl
      apt:
        name: curl
        state: absent
      when: 
        - ansible_hostname is match "master" 
        - ansible_default_ipv4.address == "10.0.0.233"
      # 上面3行,我们可以简写为下面的一行代码
      # when: (ansible_hostname is match "master") and (ansible_default_ipv4.address == "10.0.0.233")

    - name: install lrzsz
      apt:
        name: lrzsz
        state: present
      when: (ansible_hostname is match "master233") or (ansible_default_ipv4.address == "10.0.0.231")

(venv) [root@ansible99 playbook]# 



	2.测试验证
(venv) [root@ansible99 playbook]# ansible-playbook -i /root/kubespray/inventory/yinzhengjie-k8s/inventory.ini 10-when.yaml 

2.3 部署nginx服务案例

	1.准备nginx的配置文件
[root@ansible99 playbook]# cat nginx.conf
error_log stderr notice;

worker_processes 2;
worker_rlimit_nofile 130048;
worker_shutdown_timeout 10s;

events {
  multi_accept on;
  use epoll;
  worker_connections 16384;
}

stream {
  upstream kube_apiserver {
    least_conn;
    server 10.0.0.231:6443;
    server 10.0.0.232:6443;
    server 10.0.0.233:6443;
    }

  server {
    listen        127.0.0.1:6443;
    proxy_pass    kube_apiserver;
    proxy_timeout 10m;
    proxy_connect_timeout 1s;
  }
}

http {
  aio threads;
  aio_write on;
  tcp_nopush on;
  tcp_nodelay on;

  keepalive_timeout 5m;
  keepalive_requests 100;
  reset_timedout_connection on;
  server_tokens off;
  autoindex off;

  server {
    listen 8081;
    location /healthz {
      access_log off;
      return 200;
    }
    location /stub_status {
      stub_status on;
      access_log off;
    }
  }
}
[root@ansible99 playbook]# 

	
	
	2.编写playbook剧本
(venv) [root@ansible99 playbook]# cat  11-nginx-when.yaml 
- hosts: kube_control_plane
  tasks:
    - name: install nginx service
      apt:
        name: nginx
        state: present

    - name:  configure nginx 
      copy:
        src: nginx.conf
        dest: /root/nginx.conf
  
    - name: nginx -t
      command: nginx -t
      register: nginx_result
      # ansible遇到错误就会退出剧本往下执行,如果有错误我们护理后,才能继续往下执行哟。
      ignore_errors: yes

    - name: print nginx_result
      debug:
        msg: "{{ nginx_result }}" 


    - name: start nginx service
      systemd:
        name: nginx
        state: restarted
        enabled: yes
      # 如果'nginx_result.rc'的结果为0,表示没有错误,于是就可以重启nginx服务。
      when: nginx_result.rc is match "0"
      # 也可以使用'search'进行搜索。
      # when: nginx_result.rc is search "0"

(venv) [root@ansible99 playbook]# 


	2.执行剧本
(venv) [root@ansible99 playbook]# ansible-playbook -i /root/kubespray/inventory/yinzhengjie-k8s/inventory.ini 11-nginx-when.yaml 

3.Handlers实战

3.1 handlers概述

handler用来执行某些条件下的任务,比如当配置发生变化的时候,通过notify出发handler去重启服务。

3.2 实战案例

	1.编写playbook
(venv) [root@ansible99 playbook]# cat 12-nginx-notify.yaml 
- hosts: kube_control_plane
  tasks:
    - name: install nginx service
      apt:
        name: nginx
        state: present

    - name:  configure nginx 
      copy:
        src: nginx.conf
        dest: /root/nginx.conf
      # 监控配置文件是否发生变化,如果有发生变化则触发同名称的handlers重启服务。
      notify: Restart Nginx

    - name: nginx -t
      command: nginx -t
      register: nginx_result
      ignore_errors: yes

    - name: start nginx service
      systemd:
        name: nginx
        state: restarted
        enabled: yes
      when: nginx_result.rc is match "0"

  # 定义触发器
  handlers:
      # 当前的触发器我们的操作是用来重启服务的。
    - name: Restart Nginx
      systemd:
        name: nginx
        state: restarted
      when: nginx_result.rc is search "0"
(venv) [root@ansible99 playbook]# 


	2.第一次执行,会按照服务,触发HANDLER执行
(venv) [root@ansible99 playbook]# ansible-playbook -i /root/kubespray/inventory/yinzhengjie-k8s/inventory.ini 12-nginx-notify.yaml 

PLAY [kube_control_plane] **************************************************************************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************************************************************************************
ok: [master232]
ok: [master231]

TASK [install nginx service] ***********************************************************************************************************************************************************************************
changed: [master232]
changed: [master231]

TASK [configure nginx] *****************************************************************************************************************************************************************************************
changed: [master232]
changed: [master231]

TASK [nginx -t] ************************************************************************************************************************************************************************************************
changed: [master231]
changed: [master232]

TASK [start nginx service] *************************************************************************************************************************************************************************************
changed: [master231]
changed: [master232]

RUNNING HANDLER [Restart Nginx] ********************************************************************************************************************************************************************************
changed: [master232]
changed: [master231]

PLAY RECAP *****************************************************************************************************************************************************************************************************
master231                  : ok=6    changed=5    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
master232                  : ok=6    changed=5    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

(venv) [root@ansible99 playbook]# 


	2.第二次执行如果配置文件没有发生变化,则不会触发HANDLER
(venv) [root@ansible99 playbook]# ansible-playbook -i /root/kubespray/inventory/yinzhengjie-k8s/inventory.ini 12-nginx-notify.yaml 

PLAY [kube_control_plane] **************************************************************************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************************************************************************************
ok: [master231]
ok: [master232]

TASK [install nginx service] ***********************************************************************************************************************************************************************************
ok: [master232]
ok: [master231]

TASK [configure nginx] *****************************************************************************************************************************************************************************************
ok: [master231]
ok: [master232]

TASK [nginx -t] ************************************************************************************************************************************************************************************************
changed: [master231]
changed: [master232]

TASK [start nginx service] *************************************************************************************************************************************************************************************
changed: [master232]
changed: [master231]

PLAY RECAP *****************************************************************************************************************************************************************************************************
master231                  : ok=5    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
master232                  : ok=5    changed=2    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   

(venv) [root@ansible99 playbook]# 

4.循环语句

4.1 循环语句的作用

和其他编程语言类似,循环语句的作用就是减少重复性代码,让代码看起来更简洁。

举个例子,如果我们创建10个文件,我们可以写10个file模块,那如果要创建1w个文件呢?

4.2 实战案例

	1.编写playbook
(venv) [root@ansible99 playbook]# cat 13-loop-casedemo.yaml 
- hosts: kube_control_plane
  # 执行时直接跳过 Gathering Facts 步骤(不再运行 setup 模块)
  gather_facts: false
  tasks:
    - name: restart ssh nginx service
      systemd:
        name: "{{ item }}"
        state: restarted
      loop:
        - nginx
        - ssh

    - name: create file
      file:
        path: /tmp/{{ item.path }}
        state: touch
        owner: "{{ item.owner }}"
        group: "{{ item.group }}"
        mode: "{{ item.mode }}"
      loop:
        - { path: a.txt, owner: yinzhengjie, group: yinzhengjie, mode: '0600' }
        - { path: b.txt, owner: root, group: root, mode: '0666' }

    - name: copy file
      copy:
        src: "{{ item.src }}"
        dest: "{{ item.dest }}"
        owner: "{{ item.owner }}" 
      loop:
        - { src: /etc/hosts, dest: /opt, owner: yinzhengjie }
        - { src: /etc/passwd, dest: /root, owner: root }

    - name: create group
      group:
        name: "{{ item.name }}"
        gid: "{{ item.gid }}"
      loop:
        - { name: k8s, gid: '456'}
        - { name: bigdata, gid: '789'}

    - name: create user
      user:
        name: "{{ item.name }}"
        uid: "{{ item.uid }}"
        group: "{{ item.group }}"
        shell: "{{ item.shell }}"
        create_home: "{{ item.home }}"
      loop:
        - { name: test01, uid: '111', group: k8s, shell: /bin/bash, home: true }
        - { name: test02, uid: '222', group: bigdata, shell: /sbin/nologin, home: false }

(venv) [root@ansible99 playbook]# 
(venv) [root@ansible99 playbook]# 

	
	
	2.执行剧本
(venv) [root@ansible99 playbook]# ansible-playbook -i /root/kubespray/inventory/yinzhengjie-k8s/inventory.ini 13-loop-casedemo.yaml 

5.任务标签

5.1 什么是任务标签

默认情况下,ansible在执行一个playbook时,会执行playbook中定义的所有任务。

ansible的标签功能给单独任务甚至整个playbook打上标签,然后利用这些标签来指定要运行playbook中的个别任务,活不执行指定的任务。

5.2 实战案例

 	1.编写playbook
 (venv) [root@ansible99 playbook]# cat  14-tags-casedemo.yaml
- hosts: kube_control_plane
  gather_facts: false
  tasks:
    - name: restart ssh nginx service
      systemd:
        name: "{{ item }}"
        state: restarted
      loop:
        - nginx
        - ssh
      # 给指定的个别任务打标签
      tags: xixi

    - name: create file
      file:
        path: /tmp/{{ item.path }}
        state: touch
        owner: "{{ item.owner }}"
        group: "{{ item.group }}"
        mode: "{{ item.mode }}"
      loop:
        - { path: a.txt, owner: yinzhengjie, group: yinzhengjie, mode: '0600' }
        - { path: b.txt, owner: root, group: root, mode: '0666' }
      tags: xixi

    - name: copy file
      copy:
        src: "{{ item.src }}"
        dest: "{{ item.dest }}"
        owner: "{{ item.owner }}" 
      loop:
        - { src: /etc/hosts, dest: /opt, owner: yinzhengjie }
        - { src: /etc/passwd, dest: /root, owner: root }
      tags: haha

    - name: create group
      group:
        name: "{{ item.name }}"
        gid: "{{ item.gid }}"
      loop:
        - { name: k8s, gid: '456'}
        - { name: bigdata, gid: '789'}

    - name: create user
      user:
        name: "{{ item.name }}"
        uid: "{{ item.uid }}"
        group: "{{ item.group }}"
        shell: "{{ item.shell }}"
        create_home: "{{ item.home }}"
      loop:
        - { name: test01, uid: '111', group: k8s, shell: /bin/bash, home: true }
        - { name: test02, uid: '222', group: bigdata, shell: /sbin/nologin, home: false }

(venv) [root@ansible99 playbook]# 


	2.查看剧本存在的标签列表
(venv) [root@ansible99 playbook]# ansible-playbook -i /root/kubespray/inventory/yinzhengjie-k8s/inventory.ini 14-tags-casedemo.yaml --list-tags

playbook: 14-tags-casedemo.yaml

  play #1 (kube_control_plane): kube_control_plane	TAGS: []
      TASK TAGS: [haha, xixi]
(venv) [root@ansible99 playbook]# 



	3.只执行包含一个或多个tags的tasks
(venv) [root@ansible99 playbook]# ansible-playbook -i /root/kubespray/inventory/yinzhengjie-k8s/inventory.ini 14-tags-casedemo.yaml -t xixi


(venv) [root@ansible99 playbook]# ansible-playbook -i /root/kubespray/inventory/yinzhengjie-k8s/inventory.ini 14-tags-casedemo.yaml -t xixi,haha



	4.跳过带有指定标签的tasks
(venv) [root@ansible99 playbook]# ansible-playbook -i /root/kubespray/inventory/yinzhengjie-k8s/inventory.ini 14-tags-casedemo.yaml --skip-tags xixi



(venv) [root@ansible99 playbook]# ansible-playbook -i /root/kubespray/inventory/yinzhengjie-k8s/inventory.ini 14-tags-casedemo.yaml --skip-tags xixi,haha


6.文件复用-task拆解

6.1 什么是文件复用

在之前写playbook的过程中,我们发现写多个playbook没有办法一键执行,这样我们还要单个playbook挨个去执行,很鸡肋。

所以在playbook中有一个功能,叫做'include_tasks'用来动态调用task任务列表。

这样做的目的可以避免单个playbook文件内容过大的情况。

当然,也支持直接导入一个完整的palybook,则需要使用'import_playbook'关键字导入即可。

6.2 实战案例

	1.准备任务文件
(venv) [root@ansible99 playbook]# cat user-group.task 
- name: delete group
  group:
    name: "{{ item.name }}"
    gid: "{{ item.gid }}"
    state: absent
  loop:
    - { name: dba, gid: '456'}
    - { name: linux, gid: '789'}

- name: delete user
  user:
    name: "{{ item.name }}"
    uid: "{{ item.uid }}"
    group: "{{ item.group }}"
    shell: "{{ item.shell }}"
    create_home: "{{ item.home }}"
    state: absent
  loop:
    - { name: mongodb, uid: '333', group: dba, shell: /bin/bash, home: true }
    - { name: clickhouse, uid: '555', group: linux, shell: /sbin/nologin, home: false }

(venv) [root@ansible99 playbook]# 

	
	2.准备剧本
(venv) [root@ansible99 playbook]# cat 15-include_tasks.yaml 
- hosts: kube_control_plane
  gather_facts: false
  tasks:
    - name: xixi
      include_tasks:  remove-nginx.task
      # 由于我关闭了facts的采集,此处就不要用ansible_hostname变量来判断了。
      when: inventory_hostname is match "master231"

    - name: haha
      include_tasks: user-group.task
      when: inventory_hostname is match "master232"
(venv) [root@ansible99 playbook]# 


	3.测试验证
(venv) [root@ansible99 playbook]# ansible-playbook -i /root/kubespray/inventory/yinzhengjie-k8s/inventory.ini  15-include_tasks.yaml 

PLAY [kube_control_plane] **************************************************************************************************************************************************************************************

TASK [xixi] ****************************************************************************************************************************************************************************************************
skipping: [master232]
included: /root/playbook/remove-nginx.task for master231

TASK [remove nginx service] ************************************************************************************************************************************************************************************
changed: [master231]

TASK [configure nginx] *****************************************************************************************************************************************************************************************
ok: [master231]

TASK [haha] ****************************************************************************************************************************************************************************************************
skipping: [master231]
included: /root/playbook/user-group.task for master232

TASK [delete group] ********************************************************************************************************************************************************************************************
ok: [master232] => (item={'name': 'dba', 'gid': '456'})
ok: [master232] => (item={'name': 'linux', 'gid': '789'})

TASK [delete user] *********************************************************************************************************************************************************************************************
ok: [master232] => (item={'name': 'mongodb', 'uid': '333', 'group': 'dba', 'shell': '/bin/bash', 'home': True})
ok: [master232] => (item={'name': 'clickhouse', 'uid': '555', 'group': 'linux', 'shell': '/sbin/nologin', 'home': False})

PLAY RECAP *****************************************************************************************************************************************************************************************************
master231                  : ok=3    changed=1    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   
master232                  : ok=3    changed=0    unreachable=0    failed=0    skipped=1    rescued=0    ignored=0   

(venv) [root@ansible99 playbook]# 

7.抑制changed

7.1 什么是抑制changed

被管理主机没有发生变化,可以使用参数将change状态改为ok。

7.2 实战案例

	1.编写剧本
(venv) [root@ansible99 playbook]# cat  16-changed.yaml 
- hosts: kube_control_plane
  gather_facts: false
  tasks:
    - name: install nginx service
      apt:
        name: nginx
        state: present

    - name:  configure nginx 
      copy:
        src: nginx.conf
        dest: /root/nginx.conf
      notify: Restart Nginx

    - name: nginx -t
      command: nginx -t
      register: nginx_result
      ignore_errors: yes
      # 如果没有任何变化,颜色变为绿色。
      changed_when: false

    - name: start nginx service
      systemd:
        name: nginx
        state: restarted
        enabled: yes
      when: nginx_result.rc is match "0"

  handlers:
    - name: Restart Nginx
      systemd:
        name: nginx
        state: restarted
      when: nginx_result.rc is search "0"
(venv) [root@ansible99 playbook]# 


	
	2.测试验证
(venv) [root@ansible99 playbook]# ansible-playbook -i /root/kubespray/inventory/yinzhengjie-k8s/inventory.ini  16-changed.yaml 

五.jinja2模板及Role角色

1.jinja2模板

1.1 什么是jinja2模板

jinja2是python大全功能模板引擎,ansible通常会使用jinja2模板来修改被管理主机的配置文件等。

使用ansible的jinja2模板也就是使用template模块,该模块和copy模块一样,都是将文件复制到远端主机上去,但是区别在于,template模块可以获取到文件的变量,而copy则是原封不动的把文件内容复制过去。

1.2 实战案例-for循环和if语句

	1.编写jinja2模板文件内容
(venv) [root@ansible99 playbook]# cat nginx.conf.j2 
upstream {{ server_name }} {
    {% for apiserver_ip in range(231,234) %}
      server 10.0.0.{{ apiserver_ip }}:{{ apiserver_port }};
    {% endfor %}
}

server {
  listen        80;
  proxy_pass    {{ server_name }};

  location / {
    root /yinzhengjie/code;
    index index.html;
    proxy_pass http://www.yinzhengjie.com;
    proxy_set_header Host $http_host;
  }
}
(venv) [root@ansible99 playbook]# 
(venv) [root@ansible99 playbook]# cat keepalived.conf.j2 
global_defs {
   router_id {{ ansible_hostname }}
}

vrrp_script chk_apiserver {
    script "/etc/keepalived/check_apiserver.sh"
    interval 2
    weight -20
}

vrrp_instance VI_K8S_APISERVER {
{% if ansible_fqdn == "master231" %} 
    state MASTER
    priority 150
{% else %}
    state BACKUP
    priority 100
{% endif %}

    interface ens192
    virtual_router_id 51
    advert_int 1
    nopreempt

    authentication {
        auth_type PASS
        auth_pass yinzhengjie@k8s
    }

    virtual_ipaddress {
        10.0.0.100/24 dev ens192 label ens192:vip
    }

    track_script {
        chk_apiserver
    }
}
(venv) [root@ansible99 playbook]# 


	2.编写剧本
(venv) [root@ansible99 playbook]# cat 17-copy-nginx-conf.yaml 
- hosts: kube_control_plane
  gather_facts: true
  vars:
    - apiserver_port: 6443
    - server_name: www.yinzhengjie.com
  tasks:
    - name:  copy nginx  conf
      template:
        src: nginx.conf.j2
        dest: /root/apiserver.conf

    - name:  copy keepalived  conf
      template:
        src: keepalived.conf.j2
        dest: /root/keepalved.conf

(venv) [root@ansible99 playbook]# 

	
	
	3.测试验证
(venv) [root@ansible99 playbook]# ansible-playbook -i /root/kubespray/inventory/yinzhengjie-k8s/inventory.ini  17-copy-nginx-conf.yaml 

2.Roles角色

2.1 什么是Roles

roles对playbook的一种重新编排,我们可以将一个项目定义为一个角色,将该项目的所有项目都放在该角色目录。

roles角色默认的目录有:
	- defaults:
		存放默认的配置信息。
		
	- files:
		存放的是配置文件,软件包,依赖库之类的文件。
		
	- handlers:
		定义触发器相关的动作。
		
	- meta:
		存放依赖的文件。
		
	- tasks:
		定义任务。
		
	- templates
		存放jinja2模板文件。
		
	- tests:
		存放测试的相关文件。
		
	- vars:
		存放变量的目录。
		
	- README.md:
		存放项目的说明文件。

2.2 实战案例-部署rsync服务

	1.创建存储角色的目录
(venv) [root@ansible99 playbook]# mkdir roles
(venv) [root@ansible99 playbook]# 
(venv) [root@ansible99 playbook]# cd roles/
(venv) [root@ansible99 roles]# 
(venv) [root@ansible99 roles]# ll
total 8
drwxr-xr-x 2 root root 4096 Jun 15 19:21 ./
drwxr-xr-x 3 root root 4096 Jun 15 19:21 ../
(venv) [root@ansible99 roles]# 

	
	2.生成默认的角色目录结构
(venv) [root@ansible99 roles]# ansible-galaxy init k8s
- Role k8s was created successfully
(venv) [root@ansible99 roles]# 
(venv) [root@ansible99 roles]# ll
total 12
drwxr-xr-x  3 root root 4096 Jun 15 19:21 ./
drwxr-xr-x  3 root root 4096 Jun 15 19:21 ../
drwxr-xr-x 10 root root 4096 Jun 15 19:21 k8s/
(venv) [root@ansible99 roles]# 
(venv) [root@ansible99 roles]# tree k8s/
k8s/
├── defaults
│   └── main.yml
├── files
├── handlers
│   └── main.yml
├── meta
│   └── main.yml
├── README.md
├── tasks
│   └── main.yml
├── templates
├── tests
│   ├── inventory
│   └── test.yml
└── vars
    └── main.yml

9 directories, 8 files
(venv) [root@ansible99 roles]# 
(venv) [root@ansible99 roles]# 
(venv) [root@ansible99 roles]# cd k8s/
(venv) [root@ansible99 k8s]# 
(venv) [root@ansible99 k8s]# ll
total 44
drwxr-xr-x 10 root root 4096 Jun 15 19:21 ./
drwxr-xr-x  3 root root 4096 Jun 15 19:21 ../
drwxr-xr-x  2 root root 4096 Jun 15 19:21 defaults/
drwxr-xr-x  2 root root 4096 Jun 15 19:21 files/
drwxr-xr-x  2 root root 4096 Jun 15 19:21 handlers/
drwxr-xr-x  2 root root 4096 Jun 15 19:21 meta/
-rw-r--r--  1 root root 1328 Jun 15 19:21 README.md
drwxr-xr-x  2 root root 4096 Jun 15 19:21 tasks/
drwxr-xr-x  2 root root 4096 Jun 15 19:21 templates/
drwxr-xr-x  2 root root 4096 Jun 15 19:21 tests/
drwxr-xr-x  2 root root 4096 Jun 15 19:21 vars/
(venv) [root@ansible99 k8s]# 

	
	3.编写剧本文件内容
(venv) [root@ansible99 roles]# cat  k8s/tasks/main.yml 
---
# tasks file for k8s

- name: Install Rsync Server
  apt:
    name: rsync
    state: present
  tags: xixi

- name: Configure Rsync Server
  # 不用添加路径,他会自动去"template"目录下找文件
  template:
    src: "{{ item.src }}"
    dest: "{{ item.dest }}"
    mode: "{{ item.mode }}"
  loop:
    - { src: rsyncd.conf.j2, dest: /etc/rsyncd.conf, mode: '0644'}
    - { src: rsync.passwd, dest: /etc/rsync.passwd, mode: '0600' }
  notify: Restart Rsync Server

- name: Create Group "{{ group }}"
  group:
    name: "{{ group }}"
    gid: 888

- name: Create User "{{ user }}"
  user:
    name: "{{ user }}"
    uid: 666
    group: "{{ group }}"
    shell: /sbin/nologin
    create_home: false

- name: Create dir "{{ dir }}"
  file:
    path: "{{ dir }}"
    state: directory
    owner: "{{ user }}"
    group: "{{ group }}"

- name: Start Rsync Server
  systemd:
    name: rsync
    state: started
    enabled: yes
(venv) [root@ansible99 roles]# 


	4.编写配置文件目录
(venv) [root@ansible99 k8s]# cat  templates/rsyncd.conf.j2 
uid = {{ user }}
gid = {{ group }}
port = {{ port }}
fake super = yes
use chroot = no
max connections = 200
timeout = 600
ignore errors
read only = false
list = false
secrets file = /etc/rsync.passwd
log file = /var/log/rsyncd.log

[backup]
path = {{ dir }}
comment = 备份目录

[data]
path = /data
(venv) [root@ansible99 k8s]# 

	
	
	5.准备认证文件
(venv) [root@ansible99 k8s]# cat templates/rsync.passwd 
rysnc_backup:123
(venv) [root@ansible99 k8s]# 

	
	6.定义变量
(venv) [root@ansible99 k8s]# cat   vars/main.yml 
---
# vars file for k8s

user: yinzhengjie
group: k8s
port: 873
dir: /yinzhengjie/data/k8s
(venv) [root@ansible99 k8s]# 



	7.定义触发器
(venv) [root@ansible99 k8s]# cat  handlers/main.yml 
---
# handlers file for k8s

- name: Restart Rsync Server
  systemd:
    name: rsync
    state: restarted
(venv) [root@ansible99 k8s]# 


	8.删除不必要的文件
(venv) [root@ansible99 roles]# rm -rf k8s/{defaults,meta,tests,README.md}
(venv) [root@ansible99 roles]# 
(venv) [root@ansible99 roles]# tree k8s
k8s
├── files
├── handlers
│   └── main.yml
├── tasks
│   └── main.yml
├── templates
│   ├── rsyncd.conf.j2
│   └── rsync.passwd
└── vars
    └── main.yml

6 directories, 5 files
(venv) [root@ansible99 roles]# 



	9.playbook调用角色
(venv) [root@ansible99 roles]# cat start.yaml
- hosts: all
  roles:
    - role: backup
      when: ansible_hostname is match "master232"
(venv) [root@ansible99 roles]# 



	10.测试验证
(venv) [root@ansible99 roles]# ansible-playbook -i /root/kubespray/inventory/yinzhengjie-k8s/inventory.ini  start.yaml  


2.3 实战案例-部署nfs服务

	1.准备环境初始目录
(venv) [root@ansible99 roles]# mkdir nfs
(venv) [root@ansible99 roles]# 
(venv) [root@ansible99 roles]# cd nfs/
(venv) [root@ansible99 nfs]# 
(venv) [root@ansible99 nfs]# ls ../k8s/ | xargs mkdir
(venv) [root@ansible99 nfs]# 
(venv) [root@ansible99 nfs]# ll
total 28
drwxr-xr-x 7 root root 4096 Jun 15 21:01 ./
drwxr-xr-x 4 root root 4096 Jun 15 21:01 ../
drwxr-xr-x 2 root root 4096 Jun 15 21:01 files/
drwxr-xr-x 2 root root 4096 Jun 15 21:01 handlers/
drwxr-xr-x 2 root root 4096 Jun 15 21:01 tasks/
drwxr-xr-x 2 root root 4096 Jun 15 21:01 templates/
drwxr-xr-x 2 root root 4096 Jun 15 21:01 vars/
(venv) [root@ansible99 nfs]# 
(venv) [root@ansible99 nfs]# tree .
.
├── files
├── handlers
├── tasks
├── templates
└── vars

6 directories, 0 files



	2.编写任务
(venv) [root@ansible99 nfs]# cat tasks/main.yaml 
- name: Install nfs Server
  apt:
    name: nfs-kernel-server
    state: present

- name: Configure NFS Server
  template:
    src: exports.j2
    dest: /etc/exports
  notify: Restart NFS Service

- name: Create Group "{{ group }}"
  group:
    name: "{{ group }}"
    gid: "{{ gid }}"

- name: Create User "{{ user }}"
  user:
    name: "{{ user }}"
    uid: "{{ uid }}"
    group: "{{ group }}"
    shell: /sbin/nologin
    create_home: false

- name: create "{{ dir }}"
  file:
    path: "{{ dir }}"
    state: directory
    owner: "{{ user }}"
    group:  "{{ group }}"

- name: Start nfs Server
  systemd:
    name: nfs-server
    state: started
(venv) [root@ansible99 nfs]# 


	3.编写handlers
(venv) [root@ansible99 nfs]# cat handlers/main.yaml 
- name: Restart NFS Service
  systemd:
    name: nfs-server
    state: restarted

(venv) [root@ansible99 nfs]# 


	4.准备模板文件
(venv) [root@ansible99 nfs]# cat templates/exports.j2 
{{ dir }} {{ ip }}(rw,sync,all_squash,anonuid={{ uid }},anongid={{ gid }})
(venv) [root@ansible99 nfs]# 


	5.查看变量
(venv) [root@ansible99 nfs]# cat vars/main.yaml 
user: yinzhengjie
group: k8s
dir: /yinzhengjida/data
ip: 10.0.0.0/24
uid: 666
gid: 888
(venv) [root@ansible99 nfs]# 


	6.编写playbook调用角色
(venv) [root@ansible99 nfs]# cd ..
(venv) [root@ansible99 roles]# ll
total 20
drwxr-xr-x 4 root root 4096 Jun 15 21:45 ./
drwxr-xr-x 3 root root 4096 Jun 15 19:21 ../
drwxr-xr-x 7 root root 4096 Jun 15 20:04 k8s/
drwxr-xr-x 7 root root 4096 Jun 15 21:01 nfs/
-rw-r--r-- 1 root root  154 Jun 15 21:45 start.yaml
(venv) [root@ansible99 roles]# 
(venv) [root@ansible99 roles]# cat start.yaml 
- hosts: all
  roles:
    - role: k8s
      when: ansible_hostname is match "master232"
    - role: nfs
      when: ansible_hostname is match "master231"
(venv) [root@ansible99 roles]# 


	7.测试验证
(venv) [root@ansible99 roles]# ansible-playbook -i /root/kubespray/inventory/yinzhengjie-k8s/inventory.ini  start.yaml