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

Ansible中community.docker连接插件报docker command not found问题排查

问题

在Ansible Playbook中将任务委托至远程Docker主机时,community.docker集合下的docker_image、docker_container等模块能正常执行拉取、安装镜像等操作,但使用同属该集合的docker连接插件(设置ansible_connection: docker)时,出现如下报错:

fatal: [localhost -> instance-139.xxx.xxx.xxx]: FAILED! => {
    "msg": "docker command not found in PATH"
}

此前同类问题多涉及用户权限,但本次操作使用root用户,权限无异常,需排查为何仅连接插件出现该报错。

Playbook代码(截断版):

- name: Create an API instance
  hosts: localhost
  gather_facts: no
  collections:
    - linode.cloud
    - community.docker
  tasks:
    - block:
      - name: Linode IPS
        debug:
          msg: "{{ linode_ips }}"
      - name: Update apt and install dependencies
        apt:
          update_cache: yes
          name: "{{ item }}"
          force_apt_get: yes
          state: present
        loop:
          - apt-transport-https
          - ca-certificates
          - curl
          - gzip
          - software-properties-common
          
      - name: Add Docker GPG key
        apt_key:
          url: https://download.docker.com/linux/ubuntu/gpg
          state: present

      - name: Add Docker repository
        apt_repository:
          repo: deb https://download.docker.com/linux/ubuntu focal stable
          state: present

      - name: Install Docker
        apt:
          name: docker-ce
          state: present
          force_apt_get: yes
          update_cache: yes

      - name: Start and enable Docker
        systemd:
          name: docker
          state: started
          enabled: yes

      - debug:
          msg: "Registry: docker.registry.aksantinet.com/{{ host_group }}"

      - name: Pull the image from the registry
        community.docker.docker_image:
          name: "docker.registry.aksantinet.com/{{ host_group }}"
          tag: latest
          source: pull

      - name: Run Docker container
        community.docker.docker_container:
          name: "{{ container_name }}"
          image: "docker.registry.aksantinet.com/{{ host_group }}"
          network_mode: host
          state: started
          capabilities:
            - NET_ADMIN
          devices:
            - /dev/net/tun:/dev/net/tun
          privileged: yes 
        become: yes
        
      - name: Copy LetsEncrypt from ansible to Docker
        become: yes
        block:
        - lineinfile:
          path: "test"
          line: "example"
          create: yes
          state: present
        - ansible.builtin.copy:
            src: /etc/letsencrypt/
            dest: /etc/letsencrypt/
        - shell: nginx
        vars:
          ansible_docker_host: "{{ container_name }}"
          ansible_connection: docker
      - name: Instance added
        debug: 
          msg: "Addded instance at {{ linode_ip }}"
      delegate_to: "instance-{{ linode_ip }}"  

排查与解决方法

核心原因

community.docker的模块(如docker_image)是通过Docker API与远程Docker daemon交互的,不需要在控制节点(localhost)上安装Docker CLI;而docker连接插件是在控制节点上执行docker exec命令来进入容器的,所以要求控制节点的PATH中必须存在docker命令。

你的场景中,所有Docker相关模块都委托到了远程主机执行,控制节点本身没有安装Docker CLI,因此触发了"docker command not found"报错。

解决步骤

方案1:在控制节点安装Docker CLI

在运行Playbook的localhost上安装Docker CLI,确保docker命令能被找到:

# 以Ubuntu为例
apt-get update && apt-get install -y docker-ce-cli

安装完成后,执行docker --version验证命令可用。

方案2:修正连接插件的变量配置

当前ansible_docker_host配置为容器名称是错误的,需要指向远程Docker daemon的地址:

vars:
  ansible_connection: docker
  ansible_docker_host: "tcp://{{ linode_ip }}:2375"  # 需确保远程Docker daemon开启TCP端口
  ansible_docker_extra_args: "--tls"  # 生产环境建议启用TLS认证,需添加此参数

同时,远程Docker daemon默认只监听Unix socket,需要修改/etc/docker/daemon.json开启TCP监听,然后重启Docker服务:

{
  "hosts": ["unix:///var/run/docker.sock", "tcp://0.0.0.0:2375"]
}

方案3:改用容器专用模块替代连接插件

如果不想在控制节点安装Docker CLI,可以使用community.docker集合内的容器操作模块,避免使用docker连接插件:

  • 执行容器内命令用docker_container_exec:
- name: Execute nginx command inside container
  community.docker.docker_container_exec:
    container: "{{ container_name }}"
    command: nginx
  delegate_to: "instance-{{ linode_ip }}"
  • 复制文件到容器用docker_container_copy_into:
- name: Copy LetsEncrypt files into container
  community.docker.docker_container_copy_into:
    container: "{{ container_name }}"
    src: /etc/letsencrypt/
    dest: /etc/letsencrypt/
  delegate_to: "instance-{{ linode_ip }}"

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 16:33:17