You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ansible 2.9.18离线安装已下载包失败问题求助

问题:私有仓库主机执行Ansible更新工作流时DNF安装失败

环境信息

  • Ansible版本:2.9.18(无法升级)
  • 服务器系统:AlmaLinux
  • 部署方式:通过AWX管理所有服务器,所有节点(含私有仓库主机)使用Podman部署服务;所有服务器配置为通过该私有仓库执行DNF更新

预期工作流

  • 检查是否有可用更新并设置标记变量
  • 若有更新则将包下载至本地缓存
  • 若有更新则停止所有Pod
  • 若有更新则安装包,必要时重启服务器
  • 重启所有Pod

问题现象

除私有仓库主机外,所有服务器均能正常执行上述工作流。但仓库主机在执行安装步骤时失败:由于仓库Pod已被提前停止,DNF无法连接私有仓库,即使之前已执行download_only下载包,仍报错提示包下载失败。添加disable_gpg_check: yes参数无法解决该问题。

报错信息

[MIRROR] bind-libs-9.16.23-11.el9_2.2.x86_64.rpm: Status code: 502 for https://myserver/yum-mirror/9/AppStream/x86_64/os/Packages/bind-libs-9.16.23-11.el9_2.2.x86_64.rpm (IP: 10.xx.xx.xx)
The downloaded packages were saved in cache until the next successful transaction.
You can remove cached packages by executing 'dnf clean packages'.
Error: Error downloading packages:
      bind-libs-32:9.16.23-11.el9_2.2.x86_64: Cannot download, all mirrors were already tried without success

当前Playbook核心代码

- hosts: all
  remote_user: "{{ remote_user }}"
  gather_facts: true
  tasks:

    - name: check for updates on AlmaLinux
      become: true
      command: dnf list updates --quiet
      register: update_check_output
      when: ansible_distribution == 'AlmaLinux'
      changed_when: false
      
    - name: set updates_available variable
      set_fact:
        updates_available: "{{ update_check_output.stdout_lines | length > 0 }}"
      when: ansible_distribution == 'AlmaLinux'
      
    - name: download updates for AlmaLinux
      become: true
      dnf:
        update_cache: yes
        download_only: true
      when: ansible_distribution == 'AlmaLinux' and updates_available
      
    - name: stop any pods to avoid conflicts
      become: true
      become_user: "{{ pod_user }}"
      shell:
        cmd: podman pod stop "{{ item }}"
      loop: "{{ pods }}"
      when: pods is defined and ansible_distribution == 'AlmaLinux' and updates_available
      
    - name: stop any systemd pods to avoid conflicts
      become: true
      become_user: "{{ pod_user }}"
      shell:
        cmd: XDG_RUNTIME_DIR=/run/user/$(id -u) systemctl --user stop "{{ item }}"
      loop: "{{ systemd_stop_pods }}"
      when: systemd_stop_pods is defined and ansible_distribution == 'AlmaLinux' and updates_available
            
    - name: install updates to AlmaLinux servers
      become: true
      dnf:
        name: "*"
        state: latest
        disable_gpg_check: yes
      when: ansible_distribution == 'AlmaLinux' and updates_available
            
    - name: check if AlmaLinux servers require restarting
      shell: needs-restarting -r
      failed_when: false
      register: reboot_required
      changed_when: false
      when: ansible_distribution == 'AlmaLinux'
          
    - name: reboot AlmaLinux family servers if required
      become: yes
      reboot:
        reboot_timeout: 300
      when: ansible_distribution == 'AlmaLinux' and reboot_required.rc != 0 

解决方案

方案1:针对仓库主机调整工作流顺序

仓库主机需要先完成更新安装,再停止Pod,避免仓库服务中断导致DNF无法访问。可通过主机专属变量区分处理:

  1. 给仓库主机添加变量(如is_repo_host: true)
  2. 拆分任务逻辑:
    • 仓库主机:检查更新→下载更新→安装更新→重启(若需)→停止Pod→重启Pod
    • 其他主机:保持原工作流顺序

核心修改示例:

# 仓库主机专属安装步骤(先装再停Pod)
- name: install updates on repo host first
  become: true
  dnf:
    name: "*"
    state: latest
    disable_gpg_check: yes
  when: ansible_distribution == 'AlmaLinux' and updates_available and is_repo_host

# 其他主机的安装步骤(停Pod再装)
- name: install updates to other AlmaLinux servers
  become: true
  dnf:
    name: "*"
    state: latest
    disable_gpg_check: yes
  when: ansible_distribution == 'AlmaLinux' and updates_available and not is_repo_host

# 仓库主机的停Pod步骤放在安装之后
- name: stop pods on repo host after update
  become: true
  become_user: "{{ pod_user }}"
  shell:
    cmd: podman pod stop "{{ item }}"
  loop: "{{ pods }}"
  when: pods is defined and ansible_distribution == 'AlmaLinux' and updates_available and is_repo_host

方案2:强制DNF仅从本地缓存安装

使用DNF命令参数强制跳过仓库检查,仅从本地缓存安装。在Ansible中用command模块执行:

- name: install updates from cache on repo host
  become: true
  command: dnf update -y --setopt=reposdir=/dev/null --setopt=cachedir=/var/cache/dnf
  when: ansible_distribution == 'AlmaLinux' and updates_available and is_repo_host

注意:需确保download_only步骤已将所有需要的包下载至/var/cache/dnf目录,否则会安装失败。

方案3:排除仓库Pod的停止操作

如果仓库Pod的运行不影响系统更新(如更新的包与仓库服务无依赖),可在停止Pod的任务中排除仓库Pod:

- name: stop any pods except repo pod
  become: true
  become_user: "{{ pod_user }}"
  shell:
    cmd: podman pod stop "{{ item }}"
  loop: "{{ pods | reject('equalto', 'repo-pod-name') | list }}"
  when: pods is defined and ansible_distribution == 'AlmaLinux' and updates_available

内容的提问来源于stack exchange,提问作者shaneoh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 13:02:48