使用Puppet运行Docker容器时提示找不到docker命令异常
问题描述
使用puppetlabs/docker模块部署运行Docker容器时,Puppet agent执行容器创建操作抛出如下错误:
Error: Failed to apply catalog: No such file or directory - docker
错误指向Puppet执行容器创建动作前,Docker daemon与Docker客户端均未完成安装。
相关配置片段
Puppetfile
# frozen_string_literal: true forge 'https://forge.puppet.com' # 其余Puppet Forge模块配置省略 mod 'puppetlabs-docker', '4.4.0'
agent.pp
class profile::runner::agent ( Enum[present, absent] $ensure = present, String $version = undef, String $image = undef, String $container_name = "${facts['group']}-agent", Array[String] $container_environment = [], ) { class { 'docker': version => $version, } # 其余配置省略 docker::run { $container_name: ensure => $ensure, image => $image, env => $container_environment, net => 'host', restart => 'unless-stopped', } }
按照puppetlabs/docker模块的内置设计逻辑,本应保证Docker安装完成后才启动容器。手动添加常规依赖元参数后错误仍未解决,测试过的依赖配置如下:
docker::run { $container_name: ensure => $ensure, image => $image, env => $container_environment, net => 'host', restart => 'unless-stopped', require => Class['docker'], # 也曾尝试配置依赖Package['docker'] }
环境与复现特征
- 运行环境:RockyLinux,属于RedHat操作系统家族
- 复现规律:先移除配置中的
docker::run定义,执行Puppet agent可成功应用catalog,但不会部署目标容器;此时再加回docker::run配置重新执行agent,即可成功创建运行容器,确认问题本质为资源执行顺序依赖缺失。
解决方案
该问题根因为puppetlabs/docker 4.4.0版本在RedHat系系统上存在资源收敛顺序缺陷:Class['docker']被标记为收敛完成时,仅完成了软件源配置、包安装动作的触发,并未等待docker客户端二进制文件实际写入系统路径、docker服务完成启动;而docker::run资源在catalog应用阶段会直接检索系统路径下的docker可执行文件,此时二进制文件不存在就会抛出对应错误。
仅配置require => Class['docker']无法覆盖完整的依赖链路,需要显式关联docker安装包、docker服务两个核心资源,强制等待docker全量部署完成后再执行容器创建操作,修正后的配置如下:
class { 'docker': version => $version, manage_package => true, service_enable => true, service_ensure => 'running', } docker::run { $container_name: ensure => $ensure, image => $image, env => $container_environment, net => 'host', restart => 'unless-stopped', require => [ Package['docker'], Service['docker'], ], }
若上述配置仍触发相同错误,属于4.4.0版本自带的二进制路径检测bug:模块默认检索/usr/local/bin/docker路径,而RedHat系系统下docker二进制默认安装在/usr/bin/docker,需要在声明docker类时显式指定二进制路径:
class { 'docker': version => $version, manage_package => true, docker_command => '/usr/bin/docker', service_enable => true, service_ensure => 'running', }
内容的提问来源于stack exchange,提问作者tomasbasham
相关产品推荐
相关产品推荐

