Ansible案例:在被控节点创建文件
请结合作者xike__的专栏Ansible食用。
一、环境准备
1.1. 准备实验主机
| hostname | IP | 说明 |
|---|---|---|
| server | 192.168.122.7 | ansible控制主机 |
| client0 | 192.168.122.18 | 被控主机 |
| client1 | 192.168.122.101 | 被控主机 |
保证这些主机之间可以正常通讯。
1.2. 配置ssh的密钥登陆方式
这一不是为了让ansible通过ssh流畅的控制目标主机。没有这一步,实验没有办法向下进行。
1.2.1. 生成密钥对
[root@server ~]# ssh-keygen -t rsa -b 2048
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa
Your public key has been saved in /root/.ssh/id_rsa.pub
The key fingerprint is:
SHA256:fbmk4wD4LfoljCIo+jAlMlLCWiX/G8kgbxSPKmNQu/g root@dnsserver
The key's randomart image is:
+---[RSA 2048]----+
| o o |
|.. = + |
|o.= = . |
|o= * = . . . |
|X.+ + * S . + |
|=B . + = + . |
|* E . * + o . |
|o+ . . + o . |
|... ... . |
+----[SHA256]-----+
1.2.2. 将密钥对拷贝到client1中
[root@server ~]# ssh root@192.168.122.101
root@192.168.122.101's password:
[root@server ~]# ssh-copy-id root@192.168.122.101
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@192.168.122.101's password:
Number of key(s) added: 1
``
Now try logging into the machine, with: "ssh 'root@192.168.122.101'"
and check to make sure that only the key(s) you wanted were added.
1.2.3. 测试是否可以进行免密登陆
[root@server ~]# ssh root@192.168.122.101
Register this system with Red Hat Insights: insights-client --register
Create an account or view all your systems at https://red.ht/insights-dashboard
Last login: Mon Feb 23 16:45:10 2026 from 192.168.122.1
[root@client1 ~]#
二、案例1: 使用ansible创建文件/opt/d1/f1
任务:在主机
192.168.122.18上创建文件/opt/d1/f1
目的:学习如何使用一个陌生的模块书写playbook剧本
playbook的基本结构
---
# 第一级:Play 设定(在哪干)
- name: 部署并启动 Apache 服务
hosts: server # 对应 inventory 里的 [server] 组
become: yes # 使用 sudo 提权(RHEL 运维标配)
# 第二级:任务列表(干什么)
tasks:
- name: 确保 httpd 包已安装
dnf: # 调用 dnf 模块
name: httpd
state: present # 确保软件存在
- name: 拷贝自定义首页
copy: # 调用 copy 模块
src: ./index.html # 管理机的本地文件
dest: /var/www/html/index.html
owner: apache
group: apache
mode: '0644'
notify: 重启服务 # 【关键】如果文件变了,就触发下面的 handler
- name: 确保服务已启动并开机自启
service:
name: httpd
state: started
enabled: yes
# 第三级:触发器(联动动作)
handlers:
- name: 重启服务
service:
name: httpd
state: restarted
...
注意:
playbook是一个类json的数据表示语言yaml。
搜索关于文件操作的模块
方式:
- 问老师
- 问ai
- 上网搜索
操作文件用的模块是file
使用ansible-doc file来查看file的使用方法。
[[Ansible#怎么解读ansible-doc [模块]输出的信息|如何使用ansible-doc命令快速学习一个模块的用法]]
本案例中需要用到的file模块的参数和值
必要参数
path用于指定文件路径。
state 用于指定当前的操作是什么?本案例需要了解下面两个值
touch:当前操作是创建文件。
directory:当前操作是创建目录。
mode:用于制定目录或文件的权限chmod值注意:这个值是又3位八进制数字组成,这里展示两种表示方式
0744:八进制的数字表示。
“744”:字符串表示。
==了解了上面的知识后我们就可以书写playbook来完成案例了。
真正完成这个案例
play-book文件内容如下
[root@server demo0]# cat file_yy.yml
- name: 创建目录/opt/d1
hosts: client1
become: yes
# 第二级:任务列表(干什么)
tasks:
- name: 创建目录/opt/d1
file:
path: /opt/d1
state: directory
mode: 0744
- name: 创建文件/opt/d1/f1
file:
path: /opt/d1/f1
state: touch
mode: 0644
执行ansible-playbook file_yy.yml --check看看是否回报错
这个命令是模拟真实运行的场景,看看会不回报错,相当于是真实操作的演练。用来检测剧本是否有问题。
[root@server demo0]# ansible-playbook file_yy.yml
PLAY [创建目录/opt/d1] ***************************************************************************************************************
TASK [Gathering Facts] ***************************************************************************************************************
ok: [192.168.122.101]
TASK [创建目录/opt/d1] ***************************************************************************************************************
changed: [192.168.122.101]
TASK [创建文件/opt/d1/f1] ************************************************************************************************************
changed: [192.168.122.101]
PLAY RECAP ***************************************************************************************************************************
192.168.122.101 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
看来是没有什么问题
执行ansible-playbook file_yy.yml来验证我们的案例是否成功。
执行前client1客户机
[root@client1 ~]# tree /opt
/opt
0 directories, 0 files
执行命令ansible-playbook file_yy.yml
[root@server demo0]# ansible-playbook file_yy.yml
PLAY [创建目录/opt/d1] ***************************************************************************************************************
TASK [Gathering Facts] ***************************************************************************************************************
ok: [192.168.122.101]
TASK [创建目录/opt/d1] ***************************************************************************************************************
changed: [192.168.122.101]
TASK [创建文件/opt/d1/f1] ************************************************************************************************************
changed: [192.168.122.101]
PLAY RECAP ***************************************************************************************************************************
192.168.122.101 : ok=3 changed=2 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
执行命令后client1机器状态
[root@client1 ~]# tree /opt
/opt
0 directories, 0 files
[root@client1 ~]# tree /opt
/opt
└── d1
└── f1
1 directory, 1 file
[root@client1 ~]#
三、📚 案例总结:文件自动化管理的实战演练
通过本次在 client1 上创建 /opt/d1/f1 的案例,我们不仅打通了第一个自定义剧本,更掌握了应对陌生运维需求的“万能模板”。
1. 核心收获:学会了什么?
-
陌生模块的“破冰”能力:
面对从未用过的
file模块,我们通过ansible-doc file快速锁定了核心参数。记住:path(在哪)、state(状态)、mode(权限) 是文件操作的“三驾马车”。 -
Playbook 的分层逻辑:
你清晰地划分了 Play 设定(指定
client1和become: yes)与 Tasks 列表。这种结构让剧本具备了极强的可读性。 -
“演习”的重要性:
通过
ansible-playbook xxx.yml --check。这种“只看不动”的预演,是避免生产环境事故的最高准则。 -
验证幂等性:
虽然实验中你验证了“从无到有”,但如果你再次执行该剧本,你会发现输出会变成
ok而不是changed,这说明 Ansible 确认状态已达标,不会进行多余的操作。
2. 避坑指南:要注意些什么?
-
目录依赖顺序:
在剧本中,分了两步:先创建目录
/opt/d1,再创建文件f1。这是非常正确的!如果直接创建文件而父目录不存在,file模块会报错。[!TIP]
小技巧:在创建目录时,如果想递归创建(比如直接创建
/a/b/c),state: directory会自动帮你搞定中间的父目录。 -
权限表示的“八进制”陷阱:
笔记中提到了
0744和"744"。- 注意:在 YAML 中,如果不加引号且以
0开头(如0644),有时会被解析成意外的数值。为了绝对安全,推荐始终使用引号把权限括起来,如mode: "0644"。
- 注意:在 YAML 中,如果不加引号且以
-
Inventory 匹配:
你的剧本
hosts: client1必须确保在你的inventory文件中已经定义了client1对应的 IP(192.168.122.101),否则 Ansible 会提示找不到主机。
更多推荐
所有评论(0)