Ansible如何通过双循环实现多磁盘LVM自动创建及挂载
Ansible 多磁盘自动化LVM配置实现方案
你当前逻辑的核心问题是循环仅传递了磁盘名参数,没有绑定每块磁盘对应的application标识,不需要使用嵌套双循环,通过结构化的磁盘-业务标识映射遍历即可实现任意数量磁盘的LVM自动化创建、挂载,且自动跳过已使用的sda盘。
方案1:生产推荐-硬编码映射(稳定性最高)
硬编码维护磁盘与业务标识的对应关系,不会因为系统磁盘识别顺序变化导致错挂,适合生产环境使用。
1. 配置映射变量
在main.yml的变量段定义磁盘和application的对应关系,后续新增磁盘直接追加条目即可:
vars: # 磁盘-业务标识映射表 lvm_disk_map: - { disk: 'sdb', app: 'postgres' } - { disk: 'sdc', app: 'data' } # 新增磁盘按格式追加即可,例如: # - { disk: 'sdd', app: 'backup' }
2. 调整main.yml任务逻辑
先拉取系统磁盘列表,过滤掉已分区使用的sda,校验映射表中的磁盘真实存在后,再批量调用LVM配置任务:
--- - name: 获取本机块设备列表(排除loop设备、分区子设备) command: lsblk -n -o NAME --nodeps --exclude 7 register: lsblk_out - name: 生成可用磁盘列表(过滤sda) set_fact: valid_disks: "{{ lsblk_out.stdout_lines | reject('equalto', 'sda') | list }}" - name: 校验映射表磁盘是否存在 fail: msg: "映射表中配置的磁盘 /dev/{{ item.disk }} 未在本机检测到,请检查配置" when: item.disk not in valid_disks loop: "{{ lvm_disk_map }}" - name: 批量执行LVM创建挂载流程 include_tasks: lvm.yml loop: "{{ lvm_disk_map }}" loop_control: loop_var: current_disk
3. 修改lvm.yml变量引用
原有任务逻辑不需要改动,只需要把原来的sdx替换为current_disk.disk,application替换为current_disk.app:
--- - name: 创建卷组 vg-{{ current_disk.app }} lvg: vg: vg-{{ current_disk.app }} pvs: /dev/{{ current_disk.disk }} pesize: 16 state: present - name: 创建逻辑卷 lv-{{ current_disk.app }} lvol: vg: vg-{{ current_disk.app }} lv: lv-{{ current_disk.app }} size: 100%FREE force: yes state: present - name: 格式化逻辑卷为ext4文件系统 filesystem: fstype: ext4 dev: "/dev/vg-{{ current_disk.app }}/lv-{{ current_disk.app }}" force: no - name: 创建挂载目录 /opt/{{ current_disk.app }} file: path: "/opt/{{ current_disk.app }}" state: directory mode: '0755' - name: 挂载逻辑卷并写入fstab开机自动挂载 mount: path: "/opt/{{ current_disk.app }}" src: "/dev/vg-{{ current_disk.app }}/lv-{{ current_disk.app }}" fstype: ext4 opts: defaults state: mounted
方案2:测试环境可选-自动顺序匹配
如果不想硬编码磁盘名,需要自动将sda之外的磁盘按识别顺序匹配预设的application列表,可以使用自动生成映射的逻辑,适合测试环境快速部署:
vars: # 按磁盘识别顺序匹配的业务标识列表 app_sequence: ['postgres', 'data'] tasks: - name: 获取块设备列表 command: lsblk -n -o NAME --nodeps --exclude 7 register: lsblk_out - name: 过滤sda生成可用磁盘列表 set_fact: valid_disks: "{{ lsblk_out.stdout_lines | reject('equalto', 'sda') | list }}" - name: 自动生成磁盘-业务映射 set_fact: lvm_disk_map: "{{ lvm_disk_map | default([]) + [{'disk': valid_disks[idx], 'app': app_sequence[idx]}] }}" loop: "{{ app_sequence }}" loop_control: index_var: idx when: idx < valid_disks | length # 后续调用lvm.yml的逻辑和方案1完全一致
注意:该方案依赖lsblk的磁盘输出顺序,若系统磁盘识别顺序变化可能导致业务盘挂载错误,禁止在生产环境使用。
内容的提问来源于stack exchange,提问作者Elyes KRIMI
相关产品推荐
相关产品推荐

