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

Ansible执行带管道的curl添加Docker GPG密钥时gpg卡住

问题原因

卡住的核心原因是gpg默认运行在交互模式,会尝试读取伪终端(TTY)输入等待用户操作反馈。Ansible执行shell模块任务时,默认不会给远程会话分配TTY,此时gpg进程因为拿不到可用的TTY输入源,会永久阻塞等待,对外表现为任务无响应卡住。
少部分特殊场景下的卡顿和系统熵池不足有关:gpg执行加解密、格式转换操作时需要调用系统随机数生成器,如果服务器熵池数值过低,进程会等待收集到足够的随机数后才会继续运行,也会表现为卡顿。
另外如果目标机不存在/etc/apt/keyrings目录,部分旧版本gpg不会直接抛出路径不存在的错误,也会进入异常阻塞状态。

修复方案

优先选择以下第一种调整方式,改动最小:

  • 给gpg命令添加--batch --yes参数,强制其运行在非交互模式,全程不等待任何用户输入;同时提前创建密钥存放目录,增加幂等判断避免重复执行。调整后的playbook配置如下:
---
- hosts: all
  become: yes
  tasks:
    - name: 确保apt密钥环存放目录存在
      file:
        path: /etc/apt/keyrings
        state: directory
        mode: '0755'

    - name: 添加Docker GPG密钥
      shell: "curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --batch --yes --dearmor -o /etc/apt/keyrings/docker.gpg"
      args:
        creates: /etc/apt/keyrings/docker.gpg
  • 如果调整后仍存在卡顿(多为熵池不足导致),可以先在目标机安装熵服务补全随机数源,再执行上述任务:
- name: 安装haveged补充系统熵池(解决gpg随机数等待阻塞问题)
  apt:
    name: haveged
    state: present
    update_cache: yes
  • 更符合Ansible最佳实践的写法是拆分管道命令,用原生模块替代shell拼接,从根源避免管道、交互环境导致的异常:
---
- hosts: all
  become: yes
  tasks:
    - name: 确保apt密钥环存放目录存在
      file:
        path: /etc/apt/keyrings
        state: directory
        mode: '0755'

    - name: 下载Docker原始GPG公钥到临时目录
      get_url:
        url: https://download.docker.com/linux/ubuntu/gpg
        dest: /tmp/docker_origin.gpg
        mode: '0644'

    - name: 转换公钥为apt兼容的二进制gpg格式
      command: gpg --batch --yes --dearmor -o /etc/apt/keyrings/docker.gpg /tmp/docker_origin.gpg
      args:
        creates: /etc/apt/keyrings/docker.gpg

    - name: 清理临时公钥文件
      file:
        path: /tmp/docker_origin.gpg
        state: absent

注意:不要通过给Ansible的shell任务加pty: true参数强制分配TTY来规避问题,这种方式会导致sudo权限校验异常、命令输出截断等其他不稳定问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 02:45:35