快速定位 chef-client 失败原因:先用 chef-client -z -o 'recipe[myapp]' --log-level debug 本地模拟,查 converging 后的 processing 行;再用 knife node show 对比四层属性优先级;检查 ohai 插件命名、缓存及 safeexec 调用;template 渲染失败时用 fetch 防越界并确认节点绑定。

chef-client 执行失败时怎么快速定位是 cookbook 还是 node 属性问题
绝大多数 chef-client 报错不是语法错误,而是属性被覆盖、模板变量未定义或资源条件判断失效。先别急着改 recipe,用本地模拟跑一遍最省时间。
- 在节点上运行
chef-client -z -o 'recipe[myapp]' --log-level debug,加-z跳过服务端拉取,聚焦本地执行逻辑 - 关键看日志里
Converging node之后的Processing行——如果某 resource 显示skipped due to only_if却本该执行,大概率是node['myapp']['enabled']被其他 cookbook 覆盖成了false - 用
knife node show NODE_NAME -a roles -a recipes -a automatic -a normal -a override -a default对比四层属性来源,override会压倒normal,而automatic(如 IP、平台)无法被手动修改
自定义 ohai 插件不生效的三个常见原因
写完 ohai_plugin.rb 放进 /etc/chef/ohai/plugins/ 后 node['ipaddress'] 还是旧值?不是插件没加载,而是时机或命名卡住了。
- 文件名必须全小写、下划线分隔,且与插件内
provides的键名严格一致,比如my_network.rb里写provides 'my_network',才能通过node['my_network']['gateway']访问 - ohai 默认只在
chef-client启动时运行一次,改完插件后必须加--force-formats或删掉/var/chef/ohai/cache/下缓存,否则读的是旧快照 - 插件里调用 shell 命令要用
Ohai::Util::SafeExec.new包裹,裸写`ip route | grep default`在非交互式 chef-client 下会静默失败
cookbook 中 template 资源渲染失败:变量存在但值为空
template 渲染出空文件或报 undefined method `[]' for nil:NilClass,往往不是变量没传,而是层级访问越界了。
TeemIp是一个免费、开源、基于WEB的IP地址管理(IPAM)工具,提供全面的IP管理功能。它允许您管理IPv4、IPv6和DNS空间:跟踪用户请求,发现和分配IP,管理您的IP计划、子网空间、区域和DNS记录,符合最佳的DDI实践。同时,TeemIp的配置管理数据库(CMDB)允许您管理您的IT库存并将您的配置项(CIs)与它们使用的IP关联起来。项目源代码位于https://github.com/TeemIP
- 检查传入的变量是否真在当前作用域:在 template 文件开头加
,确认node['myapp']是否为nil(注意不是空哈希) - 避免硬编码嵌套访问,用
node.fetch('myapp', {})['config'].fetch('port', 8080)替代node['myapp']['config']['port'],防止中间某层为nil - 如果依赖 role 或 environment 设置的属性,确认该节点已正确绑定——
knife node run_list set NODE_NAME "role[web]"不等于自动应用,得再跑一次chef-client
knife ssh 批量执行命令但部分节点超时或权限拒绝
knife ssh 不是简单封装 ssh,它走的是 Chef Server 的节点元数据 + SSH 密钥分发链路,失败点常不在网络本身。
- 默认超时是 60 秒,短任务没问题,但跑
chef-client -i 3600就必然断连,必须加--ssh-timeout 7200 - 权限拒绝通常因为 knife 用的是
~/.chef/knife.rb里配置的ssh_user,但目标节点上该用户没配好 sudo 权限或没部署公钥——用knife ssh 'name:web*' 'whoami' --ssh-user ubuntu先验证基础连通性 - 如果节点用的是非标准 SSH 端口,不能只靠
--ssh-port,得在节点的automatic属性里补上ipaddress和network/interfaces/eth0/address,否则 knife 会按默认 22 端口连错地址
属性优先级、ohai 加载时机、template 变量解析路径——这些不是孤立机制,而是环环相扣的链条。改一处,最好顺手查一层上游来源,不然修完 A 又冒出 B。








