一、实验环境说明
|---------|---------------|----------------|----------------|
| 主机名 | 角色 | 安装服务 | httpd 监听端口 |
| test01 | Web 服务器 | httpd | 80 |
| test02 | Web + FTP 服务器 | httpd + vsftpd | 8080 |
| test03 | Web + FTP 服务器 | httpd + vsftpd | 8090 |
二、实验要求(满足题目所有条件)
- 差异化部署:test01 仅装 httpd;test02/test03 装 httpd + vsftpd
- 端口差异化:三台主机监听不同端口(80/8080/8090)
- 优雅重启:配置文件修改才重启服务(notify + handlers)
- 必备语法 :2 种以上变量 + 条件判断 + 循环控制
- 关闭防火墙,保证服务可访问
三、完整实验步骤(一步步跟着做)
步骤 1:配置主机清单(定义主机变量)
运行
sudo vim /etc/ansible/hosts
写入以下内容(第一种变量:主机变量):
test01 port=80
test02 port=8080
test03 port=8090
[myweb]
test02
test03

步骤 2:编写完整 Playbook(第二种变量:剧本全局变量)
创建剧本文件:
运行
vim workk.yaml
三、完整可用 playbook
yaml
---
- name: 按主机组部署 httpd + vsftpd
hosts: test01,test02,test03
gather_facts: yes
# 第二种变量:playbook全局变量(剧本内vars,全主机共用)
vars:
base_pkgs:
- httpd
extra_pkgs:
- vsftpd
httpd_conf_path: /etc/httpd/conf/httpd.conf
tasks:
#1 关闭防火墙
- name: 关闭并禁用 firewalld
service:
name: firewalld
state: stopped
enabled: no
#2 放行SELinux非标端口
- name: 放行 httpd 非标准端口
shell: |
semanage port -a -t http_port_t -p tcp 8080 || true
semanage port -a -t http_port_t -p tcp 8090 || true
ignore_errors: yes
#3 字典格式loop循环安装httpd(对标你用户创建截图的字典循环格式)
- name: 安装 httpd 服务
dnf:
name: "{{ item.pkgname }}"
state: present
loop:
- {pkgname: 'httpd'}
#4 when条件:仅test02/test03安装vsftpd
- name: 为 test02、test03 主机安装 vsftpd
dnf:
name: "{{ item.pkgname }}"
state: present
loop:
- {pkgname: 'vsftpd'}
when: inventory_hostname in ["test02","test03"]
#5 修改监听端口、notify触发重启(配置变动才重启httpd)
- name: 修改 httpd 监听端口为 {{ port }}
lineinfile:
path: "{{ httpd_conf_path }}"
regexp: '^Listen '
line: "Listen {{ port }}"
backup: yes
notify: restart_httpd
#6 所有主机启动httpd
- name: 启动并启用 httpd
service:
name: httpd
state: started
enabled: yes
#7 when条件:仅test02/test03启动vsftpd
- name: 启动并启用 vsftpd
service:
name: vsftpd
state: started
enabled: yes
when: inventory_hostname in ["test02","test03"]
#触发器:只有上面端口配置变更,才执行重启
handlers:
- name: restart_httpd
service:
name: httpd
state: restarted


四、执行剧本
bash
运行
ansible-playbook workk.yaml


五、脚本满足题目全部 4 点要求拆解
1、差异化部署
- test01:只安装启动 httpd
- test02/test03:httpd+vsftpd 全部安装启动(靠
when: inventory_hostname in ["test02","test03"]条件实现)
2、三台主机不同端口
- 依靠主机变量 port:test01=80、test02=8080、test03=8090,lineinfile 替换 Listen 端口
3、配置变更才重启服务
notify: restart_httpd+ handlers 触发器:只有端口配置被修改时,才自动重启 httpd;无修改不重启
4、三大核心语法全部具备
- 2 种变量
-
- ①主机变量:hosts 里
port=xxx(单主机私有) - ②play 全局变量:vars 内
httpd_conf_path/base_pkgs(全剧本共用)
- ①主机变量:hosts 里
- 循环 loop :
loop: - {pkgname: 'xxx'}字典循环(和你用户创建示例格式统一) - 条件 when:vsftpd 安装、启动两处使用 when 限定只在 test02/03 执行
六、访问网页(httpd 服务)
1. 先确认三台主机的端口
test01:httpd监听 80 端口test02:httpd监听 8080 端口test03:httpd监听 8090 端口
2. 从你的电脑访问网页
打开浏览器,直接输入对应的地址:
表格
|--------|-------------------------------|
| 主机 | 访问地址 |
| test01 | http://192.168.190.143 |
| test02 | http://192.168.190.144:8080 |
| test03 | http://192.168.190.145:8090 |



如果能看到 Apache 默认页面("It works!" 之类的),说明网页服务正常。
3. 从命令行测试(在 test01 上操作)
运行
# 访问 test01 自己的网页
curl http://localhost
# 访问 test02 的网页
curl http://test02:8080
# 访问 test03 的网页
curl http://test03:8090
如果返回 HTML 代码,说明服务正常。
七、访问 FTP 服务(vsftpd,仅 test02/test03)
注意匿名访问需要改配置文件
小拓展:想要别人能上传文件
登录test02服务器,修改 vsftpd 配置开启匿名上传:
运行
vim /etc/vsftpd/vsftpd.conf
# 末尾添加
anon_upload_enable=YES
anon_mkdir_write_enable=YES
# 重启服务
systemctl restart vsftpd
# 修改目录权限
chmod 777 /var/ftp/pub


之后所有人都能往 pub / 测试文件夹里上传文件。
vsftpd 默认端口是 21,你可以用以下方式访问:
1. 从命令行访问(在 test01 上操作)
先安装 ftp 客户端:
运行
sudo dnf install -y ftp
然后连接:
运行
# 连接 test02
ftp test02
# 连接 test03
ftp test03
- 默认匿名用户:用户名
anonymous,密码留空直接回车。 - 连接成功后,你可以执行:
-
ls:查看服务器上的文件get 文件名:下载文件put 本地文件:上传文件(默认匿名用户可能没有上传权限)
2. 从浏览器访问 FTP
打开浏览器,输入地址:
ftp://192.168.190.144
ftp://192.168.190.145


浏览器会提示你输入用户名 / 密码,提权账号和你自己设置的密码。
3. 从 Windows 电脑访问
-
打开文件资源管理器,在地址栏输入:
-
或者用 FileZilla 这类 FTP 客户端,新建站点:
-
- 协议:FTP
- 主机:
192.168.190.144/192.168.190.145 - 端口:21
- 登录类型:提权账号+自己设置的密码
八、常见问题排查
- 网页打不开
-
- 确认防火墙已关闭(剧本里已经关了):
systemctl status firewalld - 确认 SELinux 放行了端口:
semanage port -l | grep http_port_t - 确认 httpd 正在运行:
systemctl status httpd
- 确认防火墙已关闭(剧本里已经关了):
- FTP 连不上
-
- 确认 vsftpd 正在运行:
systemctl status vsftpd - 确认 21 端口没被防火墙拦截(剧本里已经关了防火墙)
- 确认 vsftpd 配置允许匿名登录(默认是允许的)
- 确认 vsftpd 正在运行:
