CINC Client 19.4.46 与 Workstation 26.3.0 常用 CLI 命令详解

CINC 六组命令逐条实测:cinc-client 本地模式/覆盖 Run List/why-run/日志级别,cinc-solo 首跑与幂等,cinc-apply 执行与语法排障,knife 节点/客户端/角色/环境/Cookbook/Supermarket/status/ssh/bootstrap,ohai 属性采集,cookstyle 检查与自动修正,附真实回显与踩坑

CINCCINCChef配置管理基础设施即代码DevOps自动化运维Ruby2026/10/27

CINC Client 19.4.46 与 Workstation 26.3.0 常用 CLI 命令详解

目标:把 CINC 日常运维真正会用到的六组命令讲透——节点端的 cinc-client / cinc-solo / cinc-apply,工作站端的 knife,以及两侧都有的 ohai 与 cookstyle。每条命令给出用途、常用参数、真实回显、输出解读与易踩坑。全文回显取自 2026-10-27 在 Ubuntu 22.04 节点主机 node01.cinc.lab 与工作站主机 ws01.cinc.lab 的实测记录;未构造到的场景会明确标注「未附回显」,不以文档推测冒充实测。

一、环境与命令全景

1.1 实测环境

角色主机软件与版本
被管节点node01.cinc.lab(10.89.65.2)Cinc Client 19.4.46、Ohai 19.1.40、cinc-solo / cinc-apply 同包
管理工作站ws01.cinc.lab(10.89.65.3)Cinc Workstation 26.3.0、knife 19.3.3、Cookstyle 9.0.0(RuboCop 1.90.0)、内嵌 Cinc Client 19.3.14

版本回显照抄(节点主机):

Cinc Client: 19.4.46
Ohai: 19.1.40
Cinc Client: 19.4.46
Cinc Client: 19.4.46

工作站主机:

knife: 19.3.3
Cookstyle 9.0.0
  * RuboCop 1.90.0
Cinc Client: 19.3.14

⚠️ 第一个坑就在版本号里:Workstation 26.3.0 内嵌的是 Cinc Client 19.3.14,与被管节点上的 19.4.46 不是同一个构建。工作站上执行 cinc-client --version 得到 19.3.14,不要误判为安装失败或节点被降级。

前置阅读:

本篇不复述安装步骤,也不重复 client.rb / solo.rb / config.rb 的逐项参数表,只讲「命令怎么发、回显怎么读、坑在哪」。

1.2 六组命令的分工

命令族所在侧核心用途本篇实测程度
cinc-client节点按 Run List 收敛;-z 本地模式、-o 临时覆盖、-W 演练、-l 日志级别核心参数有回显,-E / --json-attributes 仅说明
cinc-solo节点无服务端本地收敛,读 solo.rb首跑与幂等复跑均有回显
cinc-apply节点直接执行单个 Recipe,无需 Cookbook 结构正常执行、why-run、语法报错均有回显
knife工作站管理服务端对象:节点、客户端、角色、环境、Cookbook、Supermarket、状态、SSH、bootstrap只读查询与上传有回显;ssh/bootstrap 无回显(节点未开 SSH)
ohai两侧采集节点事实(平台、主机名、内存、CPU 等)全量与指定属性均有回显
cookstyle工作站Ruby / Cookbook 代码风格检查与自动修正检查有回显;--auto-correct 后置结果未归档

二、cinc-client 命令族

2.1 版本与帮助

cinc-client --version
# Cinc Client: 19.4.46

cinc-client --help

--help 在 19.4.46 上会列出完整选项(约 50 项)。本篇只抓与日常运维最相关的部分,原文如下:

    -z, --local-mode                 Point at local repository.
    -o RunlistItem,RunlistItem...,   Replace current run list with specified items for a single run.
        --override-runlist
    -W, --why-run                    Enable whyrun mode.
    -l, --log_level LEVEL            Set the log level (auto, trace, debug, info, warn, error, fatal).
    -E, --environment ENVIRONMENT    Set the Cinc Client environment on the node.
        --chef-zero-port PORT        Port (or port range) to start Cinc Zero on. Port ranges like 1000,1010 or 8889-9999 will try all given ports until one works.
    -j JSON_ATTRIBS,                 Load attributes from a JSON file or URL.
        --json-attributes
    -c, --config CONFIG              (帮助中未列出,但实测可用,见 2.6)

⚠️ 注意:19.4.46 的 cinc-client --help 里没有 -r 选项,cinc-solo --help 同样没有。想临时指定单个 Recipe,请用 -o 'recipe[xxx]';-r 真正的位置在 knife bootstrap(见 5.10)。这是从上游文档照抄参数时最容易踩的空。

2.2 本地模式三件套:-z + -c + -o

三者组合是最常用的「无服务端跑一把」形态。安装篇的 systemd timer 单元实际执行的就是这一行(systemctl status 回显照抄):

     Active: inactive (dead) since Tue 2026-10-27 09:10:57 UTC; 7ms ago
TriggeredBy: ● cinc-client.timer
    Process: 4629 ExecStart=/usr/bin/cinc-client --local-mode -c /root/solo.rb -o web_base (code=exited, status=0/SUCCESS)

逐项解读:

  • --local-mode / -z:不连远端 Cinc Server,而是在本机拉起一个临时的 Cinc Zero 兼容端点,从本地仓库读 Cookbook;
  • -c /root/solo.rb:指定本地模式配置文件(不读 /etc/cinc/client.rb),里面给出 cookbook_path、node_path 等;
  • -o web_base:把本次 Run List 覆盖为 web_base(等价 recipe[web_base]),只影响这一次。

同一次运行在日志里会留下 Zero 启动与 Run List 覆盖的痕迹:

[2026-10-27T09:09:42+00:00] INFO: Started Cinc Zero at chefzero://localhost:1 with repository at /root (One version per cookbook)
Cinc Client, version 19.4.46
Patents: https://www.chef.io/patents
Infra Phase starting
[2026-10-27T09:09:43+00:00] WARN: Run List override has been provided.
[2026-10-27T09:09:43+00:00] WARN: Original Run List: []
[2026-10-27T09:09:43+00:00] WARN: Overridden Run List: [recipe[web_base]]
[2026-10-27T09:09:43+00:00] INFO: Run List is [recipe[web_base]]
[2026-10-27T09:09:43+00:00] INFO: Run List expands to [web_base]

最后一行 Run List expands to [web_base] 是 Cookbook 展开结果;前面的 Original Run List: [] 说明节点对象原本没有 Run List,本次全靠 -o 临时补上。

2.3 -o 的写法与「不落盘」特性

常用写法:

# 单个 recipe
cinc-client -z -c /root/solo.rb -o 'recipe[web_base]'

# 多个条目,逗号分隔,顺序即执行顺序
cinc-client -z -c /root/solo.rb -o 'recipe[web_base],recipe[monitor]'

# 角色(角色需已在服务端或本地仓库定义)
cinc-client -z -c /root/solo.rb -o 'role[web]'

-o 是一次性覆盖,不会改写节点对象。日志会明确提示:

[2026-10-27T09:09:48+00:00] WARN: Skipping final node save because override_runlist was given

这行 WARN 的直接后果是:本次收敛完成后,节点 JSON 里不会保存新的 Run List。随后按正常方式再跑一次,就会出现「明明刚跑过,Run List 却是空的」:

Resolving cookbooks for run list: []
Synchronizing cookbooks:
Installing cookbook gem dependencies:
Compiling cookbooks...
Loading Cinc Auditor profile files:
Loading Cinc Auditor input files:
Loading Cinc Auditor waiver files:
[2026-10-27T09:13:57+00:00] WARN: Node node01 has an empty run list.
Converging 0 resources

Running handlers:
Running handlers complete
Infra Phase complete, 0/0 resources updated in 00 seconds

Converging 0 resources 不是故障,而是「没有任何 Run List 可执行」。要让 Run List 持久化,应使用服务端对象(knife node run_list set,见 5.2)或写入 solo.rb / 节点 JSON,而不是依赖 -o。

2.4 -W / --why-run:只演练,不落盘

cinc-client -z -c /root/solo.rb -W -o web_base

why-run 让每个资源只做「检查 + 计算差异」,不执行 create/update。共享同一套收敛引擎的 cinc-apply --why-run 实测回显最能说明结果形态:

Converging 5 resources
Infra Phase complete, 0/5 resources would have been updated

关键词是 would have been(本会更新)而不是 updated(已更新)。5 个资源全部被评估,但文件、用户、目录都不会真正创建。

⚠️ why-run 的坑:不会落盘任何变更,也不会保存节点状态。演练通过不代表生产一定能过(真实执行仍可能因权限、锁、包源失败);演练失败也不代表配置有错,可能是资源本身不支持 why-run(少数自定义资源会直接报「why-run 不支持」)。上线前用 why-run 预检,正式变更仍要单独安排窗口。

2.5 -l / --log_level:控制回显颗粒度

取值:auto、trace、debug、info、warn、error、fatal。默认 auto:终端输出 info、写日志文件时降为 warn。

-l info(solo.rb 里同样设置 log_level :info)时能看到资源处理明细:

[2026-10-27T09:09:43+00:00] INFO: Run List is [recipe[web_base]]
[2026-10-27T09:09:43+00:00] INFO: Run List expands to [web_base]
[2026-10-27T09:09:43+00:00] INFO: Starting Cinc Client Run for node01.cinc.lab
[2026-10-27T09:09:43+00:00] INFO: Loading cookbooks [web_base@0.1.0]

而不带 -l、走默认格式化输出时,回显是更紧凑的资源清单:

Converging 5 resources
Recipe: web_base::default
  * apt_package[htop] action install (up to date)
  * apt_package[curl] action install (up to date)
  * linux_user[admin] action create (up to date)
  * directory[/etc/web_base] action create (up to date)
  * template[/etc/motd] action create (up to date)
Infra Phase complete, 0/5 resources updated in 02 seconds

排障时用 -l debug 能看到每个资源的详细判定过程,但输出量会成倍增长,建议同时加 -L /var/log/cinc-debug.log 落文件,避免刷屏。生产定时任务维持 info 或 warn 即可。

2.6 -c / --config:指定配置文件

cinc-client -z -c /root/solo.rb -o web_base
  • -c 显式指定本地模式配置;不指定时,client/server 模式默认读 /etc/cinc/client.rb;
  • 实测该参数在 19.4.46 的 --help 中未列出,但 systemd 单元长期使用且正常退出(status=0/SUCCESS),可放心用;
  • 如果只想临时改一个配置项,不必改文件:--config-option log_level=debug;
  • --disable-config 会完全拒绝加载配置文件,官方标注仅用于开发、不是稳定 API,生产勿用。

2.7 -E / --environment:单次指定环境

cinc-client -z -c /root/solo.rb -E production -o web_base

-E 把本次运行的节点环境设为 production,影响服务端按环境解析的 Cookbook 版本与角色。实测节点默认环境回显:

Node Name:   node01
Environment: _default

⚠️ 本节未构造 -E production 的运行回显(现有环境中只有 _default,见 5.5 的 knife environment list)。使用要点:目标环境必须已存在于服务端,否则 client 会因找不到 environment 对象而失败;在 -z 本地模式下环境对象由本地仓库提供,缺省仍是 _default。单机临时验证不必加 -E。

2.8 --chef-zero-port:固定 Zero 端口

本地模式会拉起 Cinc Zero。默认情况下它使用本机回环的临时端点,日志表现为:

[2026-10-27T09:09:42+00:00] INFO: Started Cinc Zero at chefzero://localhost:1 with repository at /root (One version per cookbook)

chefzero://localhost:1 是本地模式内部使用的零服务端地址,不要按字面去连 1 端口。若需要让其他进程(例如同一工作站上的 knife)连这个临时服务端,就显式固定端口:

cinc-client -z -c /root/solo.rb --chef-zero-port 8889 -o web_base

也可写成端口范围 8889-9999,客户端会逐个尝试直到成功。实测的 client/server 演示环境正是把服务端固定在 8889(chef_server_url "http://ws01.cinc.lab:8889"),说明该端口在规划内可用。

⚠️ 坑:端口被占用时不会自动换端口,除非你给的是范围;--no-listen 会让本地模式不绑定网络端口,只走本地套接字,适合纯单机收敛。固定端口后记得在防火墙/安全组只放行可信网段。

2.9 -j / --json-attributes:注入节点属性

cinc-client -z -c /root/solo.rb -j /root/node-attrs.json -o web_base

JSON 文件形如:

{
  "web_base": {
    "motd": "Managed by Cinc Client (prod)",
    "admin_user": "opsadmin"
  }
}

Recipe 里 node['web_base']['motd'] 即可读到注入值。-j 也接受 URL。

⚠️ 本节未附运行回显(未构造该场景)。两个坑:一是 JSON 必须是合法对象,注释和尾逗号都会导致解析失败;二是属性优先级——-j 注入的是 normal 级属性,会被 Recipe 中的 override 覆盖,排查「注入没生效」时先看 Recipe/Cookbook 是否又设了 override。

2.10 其他高频参数速查

参数用途备注
-N, --node-name指定节点名,覆盖默认 FQDN本地模式与 client/server 都可用
-k, --client_key指定节点私钥client/server 模式必需;权限 0600
-K, --validation_key新节点注册用 validation 私钥注册成功后应从节点删除
-S, --server指定 Cinc Server URL与 -z 互斥使用
-i, --interval / -s, --splay进程内周期收敛与随机抖动与外部 systemd timer 二者择一,勿叠加
--once取消 interval/splay,只跑一次定时任务里常用
-L, --logfile日志写文件守护化/定时场景推荐
-F, --format输出格式如 json 便于程序消费
--minimal-ohai只跑收敛必需的 Ohai 插件缩短启动时间
--run-lock-timeout等待另一收敛进程释放锁的秒数默认无限等,生产建议设上限
--config-option单次覆盖一个配置项不改文件,排障方便

三、cinc-solo 命令族

3.1 定位

cinc-solo 是「永远本地」的收敛入口:不连服务端、不注册节点,读 -c 指定的 solo.rb,从 cookbook_path 加载 Cookbook。帮助开头:

Usage: /usr/bin/cinc-solo (options)

其选项表与 cinc-client 基本一致(同样包含 -z、-o、-W、-l、-E、--chef-zero-port、-j),但语义上 cinc-solo 已默认本地,-z 对它没有额外意义。

3.2 首次收敛实测

cinc-solo -c /root/solo.rb -o 'recipe[web_base]'

回显(节选,完整记录 4/5 资源实际更新):

[2026-10-27T09:09:42+00:00] INFO: Started Cinc Zero at chefzero://localhost:1 with repository at /root (One version per cookbook)
Cinc Client, version 19.4.46
Patents: https://www.chef.io/patents
Infra Phase starting
...
[2026-10-27T09:09:43+00:00] WARN: Run List override has been provided.
[2026-10-27T09:09:43+00:00] WARN: Original Run List: []
[2026-10-27T09:09:43+00:00] WARN: Overridden Run List: [recipe[web_base]]
...
Converging 5 resources
Recipe: web_base::default
  * apt_package[htop] action install
    - install version 3.0.5-7build2 of package htop
  * apt_package[curl] action install (up to date)
  * linux_user[admin] action create
    - create user admin
  * directory[/etc/web_base] action create
    - create new directory /etc/web_base
    - change mode from '' to '0755'
    - change owner from '' to 'root'
    - change group from '' to 'root'
  * template[/etc/motd] action create
    - create new file /etc/motd
    - update content in file /etc/motd from none to d9a2c7
    --- /etc/motd	2026-10-27 09:09:48.624607536 +0000
    +++ /etc/.chef-motd20261027-2971-1nobyq	2026-10-27 09:09:48.624607536 +0000
    @@ -0,0 +1,2 @@
    +Managed by Cinc Client
    +node: node01 / ubuntu 22.04
...
Infra Phase complete, 4/5 resources updated in 06 seconds

解读:up to date 表示资源已符合期望;create / install 下面的缩进行是实际动作;---/+++ 是文件内容 diff。最后的 4/5 说明 5 个资源中 4 个发生了变更(curl 已存在,未变)。

3.3 幂等复跑

紧接着再跑一次:

[2026-10-27T09:10:02+00:00] INFO: Cinc Client Run complete in 1.571419879 seconds
[2026-10-27T09:10:02+00:00] INFO: Skipping removal of unused files from the cache

Running handlers:
Running handlers complete
Infra Phase complete, 0/5 resources updated in 02 seconds

0/5 resources updated 就是幂等性的直接证据:同样的 Recipe、同样的机器,第二次运行不再产生变更。若每次都是 4/5、5/5,说明资源写法有问题(常见于 execute 未加 not_if/only_if、模板内容含时间戳等)。

3.4 cinc-solo 与 cinc-client -z 怎么选

维度cinc-solocinc-client -z
配置文件必须 -c 指定 solo.rb同样读 solo.rb(-c),或按默认路径
服务端始终本地本地 Zero,可固定端口供 knife 连接
节点注册否否(但与 client 共用同一套节点保存逻辑)
典型场景单机固化、无服务端批量脚本工作站上「一条龙」验证、配合 knife 本地模式

两者底层是同一个 Client 程序,区别主要在入口与默认行为。本站安装篇的 systemd timer 用的是 cinc-client --local-mode,因此 -o 覆盖 Run List 后不会保存节点,这一点对两种入口都成立。

四、cinc-apply 命令族

4.1 定位

cinc-apply 直接编译并执行一个 Recipe 文件(或内联片段),不需要 Cookbook 目录结构、metadata.rb、Run List,适合:

  • 验证某个资源写法是否正确;
  • 一次性修一台机器(改配置、建用户、装包);
  • 在写进 Cookbook 前做最小复现。

4.2 正常执行实测

# 文件路径按实际替换;该 Recipe 仅含一条 file 资源
cinc-apply apply-test.rb

回显:

[2026-10-27T09:10:25+00:00] ERROR: shard_seed: Failed to get dmi property serial_number: is dmidecode installed?
Recipe: (cinc-apply cookbook)::(cinc-apply recipe)
  * file[/tmp/cinc_apply_test.txt] action create
    - create new file /tmp/cinc_apply_test.txt
    - update content in file /tmp/cinc_apply_test.txt from none to b5ebb3
    --- /tmp/cinc_apply_test.txt	2026-10-27 09:10:25.938275432 +0000
    +++ /tmp/.chef-cinc_apply_test20261027-3906-54eoor.txt	2026-10-27 09:10:25.938275432 +0000
    @@ -0,0 +1 @@
    +hello from cinc-apply
---
hello from cinc-apply

解读:Recipe: (cinc-apply cookbook)::(cinc-apply recipe) 是 apply 的固定命名(它把临时 Recipe 当成一个匿名 Cookbook);create new file 与 +hello from cinc-apply 表示文件已创建并写入;末尾再次打印文件内容,是验证动作。日志首行的 shard_seed ERROR 见 8.5,不影响执行。

4.3 --why-run 演练

# 对一份含 5 个资源的 Recipe 执行 why-run,路径按实际替换
cinc-apply --why-run web-base.rb

回显:

Converging 5 resources
Infra Phase complete, 0/5 resources would have been updated

0/5 ... would have been updated 表示 5 个资源都没有实际变更,仅完成预演。适合在改生产机前先看「会动哪些资源」。

4.4 单行 Recipe 的语法坑(实测报错)

把 Ruby 块压成一行直接当参数传入,很容易触发解析错误:

[2026-10-27T09:10:11+00:00] FATAL: Stacktrace dumped to /var/cinc/cache/cinc-stacktrace.out
[2026-10-27T09:10:11+00:00] FATAL: SyntaxError: /tmp/recipe-temporary-file20261027-3485-9t6wjy:1: syntax error found
> 1 | ... { content "hello from cinc-apply\n" }
    |     ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ unexpected '{' after a method call without parenthesis

原因:Ruby 把 file 当成方法调用,后面的 { 被解析为代码块,而 <方法调用> { 需要括号或 do...end 的合法上下文。正确写法是多行 + do...end:

file '/tmp/cinc_apply_test.txt' do
  content "hello from cinc-apply\n"
end

或者给资源名加括号。排障提示:完整栈在 /var/cinc/cache/cinc-stacktrace.out(file_cache_path 默认目录),报错行号指向临时文件,但真正的语法位置就是 > 标出的那一行。

4.5 使用建议

  • 优先用 .rb 文件,不要在命令行拼长字符串;
  • apply 没有 Run List 概念,一次只执行一个 Recipe 文件;
  • apply 适合验证,不适合长期托管;需要周期收敛请回到 cinc-solo + systemd timer。

五、knife 命令族(工作站侧)

5.1 前置:配置、凭据与私钥

knife 的一切操作都依赖三样东西:服务端地址、用户身份、用户私钥。缺配置时的真实报错:

ERROR: CONFIGURATION ERROR:Specified config file /root/chef-repo/.chef/knife.rb does not exist

这不是「文件坏了」,而是 -c 显式指向了不存在的 knife.rb(knife 19 新名为 config.rb)。完整配置与 ~/.cinc/credentials 优先级见配置参数篇,此处只记三条:

  1. 工作站仓库通常为 /root/chef-repo,配置在 .chef/config.rb(旧名 knife.rb 兼容);
  2. admin.pem 是工作站用户(示例 admin)的私钥,node01.pem 是节点的私钥,二者不可混用;
  3. knife config show 首行会打印实际加载源(如 Loading from credentials file /root/.cinc/credentials),排障先看这行。

本节的只读查询均在配置就绪、服务端可达的前提下执行。

5.2 节点:node list / node show / node edit

knife node list
node01
knife node show node01
Node Name:   node01
Environment: _default
FQDN:        node01.cinc.lab
IP:          10.89.65.2
Run List:    recipe[web_base]
Roles:       
Recipes:     web_base, web_base::default
Platform:    ubuntu 22.04
Tags:        

需要机器可读时换 JSON:

knife node show node01 -F json
{
  "name": "node01",
  "chef_environment": "_default",
  "run_list": [
  "recipe[web_base]"
]
,
  "normal": {
    "tags": [

    ]
  }
}

knife node edit node01 会打开 $EDITOR(默认 vi),把上面这段 JSON 交给你改;-e 换编辑器,-d 表示不打开编辑器、直接按原样提交,-a 显示全部属性。本节未附编辑回显:交互式命令无法在非交互环境里给出有意义的输出,编辑器里的数据结构就是上面 -F json 的内容。改完保存退出,knife 会把差异 PUT 回服务端。

设置 Run List 的常用写法(无需进编辑器):

knife node run_list set node01 'recipe[web_base]'

实测回显:

node01:
  run_list: recipe[web_base]

⚠️ -o 覆盖不会持久化(2.3),要让节点以后每次都跑同一套 Recipe,就得用 node run_list set 或 add,而不是每次手工 -o。

5.3 客户端:client list / client show

knife client list
chef-validator
chef-webui
node01

前两个是 Zero/Server 的内置客户端(validator 用于新节点注册,webui 用于管理界面);node01 是节点注册后生成的客户端身份。

knife client show node01
admin:      false
chef_type:  client
create_key: true
name:       node01
validator:  false

解读:admin: false 表示无管理员权限;validator: false 表示不能拿它给新节点签发证书。创建/删除(本节未执行,避免改动现有身份):

knife client create web02 -f /root/chef-repo/.chef/web02.pem   # 生成并保存私钥
knife client delete web02 -y                                   # 同时吊销其密钥
knife client reregister node01                                 # 密钥丢失时重签

⚠️ client delete 会让该节点下次收敛直接 401;先确认节点已下线。-f 写出的私钥要立刻 chmod 600,不要进 git。

5.4 角色:role list / role create / role show

knife role list

输出为空,表示当前服务端还没有任何角色(_default 环境只有内置对象)。角色是服务端对象,不随 Cookbook 上传自动出现。常用命令:

knife role create web
knife role from file /root/chef-repo/roles/web.rb
knife role run_list add web 'recipe[web_base]'
knife role show web
knife role delete web -y

role create 会打开编辑器,结构是 name / description / run_list / default_attributes / override_attributes;--description 可直接带描述。本节未附创建回显(交互式且会新增对象)。

5.5 环境:environment list / environment show

knife environment list
_default
knife environment show _default
chef_type:           environment
cookbook_versions:
default_attributes:
description:         The default Chef environment
json_class:          Chef::Environment
name:                _default
override_attributes:

_default 是任何服务端都存在的环境。要新增:

knife environment create production --description 'Production'
knife environment from file /root/chef-repo/environments/production.rb
knife environment show production

⚠️ 与 2.7 联动:节点侧 -E production 前,先确认 knife environment list 里有 production,否则收敛会因环境对象缺失失败。

5.6 Cookbook:cookbook upload

knife cookbook upload web_base
Uploading web_base       [0.1.0]
Uploaded 1 cookbook.

上传后即可被 knife cookbook list 看到(实测):

demo_site: 0.1.0
web_base:  0.1.0

常用参数:

  • -a, --all:上传 cookbook_path 下全部 Cookbook;
  • --freeze:上传后冻结版本,防止被同版本覆盖(生产建议开);
  • --[no-]check-dependencies:上传前校验依赖,默认开启,不要随意关。

⚠️ 坑一:cookbook_path 配错时 knife 报「Cookbook not found」,先 knife config show cookbook_path。坑二:改了 Recipe 却忘了改 metadata.rb 的 version,又开了 --freeze,服务端会拒绝同版本覆盖——升级版本号再传。

5.7 Supermarket:supermarket search / install

knife supermarket search nginx
application_nginx:
  cookbook:             https://supermarket.chef.io/api/v1/cookbooks/application_nginx
  cookbook_description: Deploys and configures Nginx as an application server
  cookbook_maintainer:  coderanger
  cookbook_name:        application_nginx
apt-nginx:
  cookbook:             https://supermarket.chef.io/api/v1/cookbooks/apt-nginx
  cookbook_description: Installs/Configures apt NGINX Vendor-Specific Repository
  cookbook_maintainer:  st-isidore-de-seville
  cookbook_name:        apt-nginx

其余子命令:

knife supermarket show nginx            # 看版本、依赖、主页
knife supermarket download nginx 2.0.0  # 只下载到本地
knife supermarket install nginx         # 下载并放进 cookbook_path
knife supermarket share my_cookbook     # 发布到 Supermarket(需账号)

⚠️ Supermarket 访问的是公网 supermarket.chef.io。内网离线环境请先在能上网的机器 download,把包带进内网再上传/解包;share 需要 Supermarket 账号与签名,企业私有源应改用内部制品库。

5.8 状态:knife status

knife status 'name:*'
3 seconds ago, node01, ubuntu 22.04.

输出依次是「距上次收敛的时间、节点名、平台版本」。查询串是 Chef 搜索语法:name:* 表示全部节点,也可写 platform:ubuntu、role:web、environment:production。时间越久说明节点越可能失联,适合做巡检脚本的输入。

5.9 SSH:knife ssh

knife ssh 'name:node01' 'uptime' -x root -a ipaddress

参数要点(来自 knife ssh --help 实测):

    -a, --attribute ATTR             The attribute to use for opening the connection - default depends on the context.
    -C, --concurrency NUM            The number of concurrent connections.
    -i IDENTITY_FILE,
        --ssh-identity-file
    -P, --ssh-password [PASSWORD]    The ssh password - will prompt if flag is specified but no password is given.
    -p, --ssh-port PORT              The ssh port.
    -t, --ssh-timeout SECONDS        The ssh connection timeout.
    -x, --ssh-user USERNAME          The ssh username.

⚠️ 本节未附执行回显:实测节点主机未监听 22 端口(未安装/未启动 SSH 服务),knife 无法建立连接。使用前提是目标节点已装并启动 sshd、工作站能免密或提供密码登录,且查询能命中节点。-a ipaddress 决定用哪个 Ohai 属性做连接地址;云环境常用 -a ipaddress 或 -a ec2.public_ipv4。

5.10 初始化新节点:knife bootstrap

knife bootstrap 10.89.65.10 -x root -P '******' --sudo \
  -N web02 -r 'recipe[web_base]' --chef-license accept

关键参数(knife bootstrap --help 实测):

    -N, --node-name NAME             The node name for your new node.
    -r, --run-list RUN_LIST          Comma separated list of roles/recipes to apply.
    -P PASSWORD,                     Authenticate to the target host with this password.
        --connection-password
    -p, --connection-port PORT       The port on the target node to connect to.
    -o PROTOCOL,                     The protocol to use to connect to the target node. (valid options: 'ssh' or 'winrm')
    -U, --connection-user USERNAME   Authenticate to the target host with this user account.
        --sudo                       Execute the bootstrap via sudo.

bootstrap 做的事:SSH 登录目标机 → 用 omnitruck 脚本装 Cinc Client → 用 validation 身份注册为服务端 client → 执行首次 Run List。

⚠️ 本节未附执行回显:节点主机未开 SSH,且 bootstrap 会新增 client 对象,不适合在既有演示环境里临时跑。使用要点:① -r 是 bootstrap 的参数,不是 cinc-client 的;② 服务端必须存在 validator 客户端和对应 validation 私钥(chef-validator 在 5.3 的 client list 中可见);③ 首次注册后应删除节点上的 validation 私钥;④ 内网装包失败时用 --bootstrap-url 指向内部安装脚本,或 --bootstrap-install-command 直接指定本地 deb 安装命令。

六、ohai 命令族

6.1 默认输出:全量事实

ohai

输出是一大段 JSON。实测全量约 3738 行,开头如下:

{
  "kernel": {
    "name": "Linux",
    "release": "7.0.0-38-generic",
    "version": "#38-Ubuntu SMP PREEMPT_DYNAMIC Fri Sep  4 09:10:14 UTC 2026",
    "machine": "x86_64",
    "processor": "x86_64",
    "os": "GNU/Linux",
    "modules": {

    }
  },
  "memory": {
    "swap": {
      "cached": "1331512kB",
      "total": "8388604kB",
      "free": "4503720kB"
    },

这就是 Recipe 中 node['kernel']['release']、node['memory']['total'] 等属性的来源。全量输出适合喂给 jq 做盘点,不适合直接人眼阅读。

6.2 指定属性:只取一个

ohai hostname
[
  "node01"
]
ohai platform
[
  "ubuntu"
]
ohai platform_version
[
  "22.04"
]
ohai fqdn
[
  "node01.cinc.lab"
]

解读:Ohai 19.1.40 在指定单个属性时仍以 JSON 数组包裹输出,程序消费时用 ohai platform | jq -r '.[0]',不要直接当字符串比较。属性名与 Recipe 中的 node[...] 路径一一对应,只是不带 node 前缀。

6.3 属性名写错的真实报错

ohai cpu.total
ERROR: Encountered error while running plugins: #<Ohai::Exceptions::AttributeNotFound: No such attribute: 'cpu.total'>

紧跟一大段 Ruby 栈(provides_map.rb、system.rb、application.rb)。原因:cpu.total 不是 Ohai 19.1.40 提供的属性路径,属性查找按插件提供的顶层键进行。正确姿势是先跑 ohai cpu / ohai memory 看完整结构,再在 JSON 里取需要的子键;不要在命令行猜深层路径。

⚠️ 这个报错退出码非 0,写巡检脚本时会被当成失败。把属性名固定为已验证的顶层键(如 platform、platform_version、fqdn、hostname),或先拉全量 JSON 再本地解析。

6.4 常用参数

参数用途
-c, --config指定 Ohai 配置文件
-d, --directory追加自定义插件搜索目录,可重复多次
-l, --log_leveldebug / info / warn / error / fatal
-L, --logfile日志落文件
-t, --target对远端目标采集(需相应传输插件)
-v, --version版本(实测 Ohai: 19.1.40)

七、cookstyle 命令族

7.1 版本

Cookstyle 9.0.0
  * RuboCop 1.90.0

Cookstyle 是 Chef/CINC 定制的 RuboCop 规则集,检查 Cookbook 里的 Ruby 风格与常见错误。

7.2 检查 Cookbook

cd /root/chef-repo/cookbooks
cookstyle

实测汇总:

Inspecting 3 files
CCC

Offenses:
...
3 files inspected, 27 offenses detected, 27 offenses autocorrectable

其中一条典型告警:

C: [Correctable] Style/StringLiterals: Prefer single-quoted strings when you don't need string interpolation or special symbols. (https://rubystyle.guide#consistent-string-literals)

CCC 表示 3 个文件都有问题,[Correctable] 表示可自动修,27 offenses autocorrectable 表示 27 条全部可自动修。这类问题不影响功能,但会让 CI 变红、代码风格漂移。

7.3 --auto-correct 自动修正

cookstyle --auto-correct
# 简写:cookstyle -a

行为:按规则自动改写 Ruby 文件(主要是引号、哈希语法、空行等),不能自动修的告警仍会保留。本节未归档修正后的复检回显(避免直接改动演示 Cookbook 源文件)。生产使用建议:

  1. 先提交或备份,再 --auto-correct;
  2. 修完用 git diff 逐条确认,不要盲信自动改写;
  3. CI 里只用检查模式,禁止自动改写;
  4. 第三方/上游 Cookbook 不要批量自动修,升级时冲突会非常多。

7.4 常用参数(参考)

参数用途
-a, --auto-correct自动修正可修项
--only COPS只跑指定规则
--except COPS排除指定规则
-f, --format输出格式(如 json、junit)
--fail-level达到指定严重级别才返回非 0

以上为 Cookstyle/RuboCop 通用选项;本篇只实测了默认检查与汇总行。

八、排障实录

8.1 why-run 显示成功,机器却没变化

现象:cinc-apply --why-run 回显 0/5 resources would have been updated,随后检查文件不存在、用户没建。

原因:why-run 只计算差异,不执行动作,也不保存节点状态。would have been 是「本会」,不是「已经」。正式执行去掉 -W / --why-run,并单独用 -l info 确认资源真的 create / install。

8.2 -o 跑过一次,下一次却 0 资源

现象:手工 cinc-client -z -o web_base 成功,隔一会儿正常跑却出现:

WARN: Node node01 has an empty run list.
Converging 0 resources
Infra Phase complete, 0/0 resources updated in 00 seconds

原因:-o 是单次覆盖,日志已提示 Skipping final node save because override_runlist was given,节点对象仍是空 Run List。解决:knife node run_list set node01 'recipe[web_base]',或把 Run List 固化到 solo.rb 所读的节点 JSON / 调度命令里。

8.3 本地模式与 client/server 模式配置串了

现象:在节点上直接 cinc-client 不生效,或者指向了错误服务端。

原因:两种模式读不同配置——-z / cinc-solo 读 -c 指定的 solo.rb,client/server 读 /etc/cinc/client.rb。实测 client/server 正常收敛的回显是:

Resolving cookbooks for run list: ["web_base"]
Synchronizing cookbooks:
  - web_base (0.1.0)
Compiling cookbooks...
Converging 5 resources
Recipe: web_base::default
  * apt_package[htop] action install (up to date)
...
Infra Phase complete, 0/5 resources updated in 02 seconds

若看到 Resolving cookbooks for run list: [],先查 Run List 是否被 -o 的「不落盘」坑了(8.2),而不是先去改 client.rb。

8.4 knife 报配置文件不存在

ERROR: CONFIGURATION ERROR:Specified config file /root/chef-repo/.chef/knife.rb does not exist

原因:knife 19 主配置新名为 config.rb,-c 仍指向旧名且文件不存在。解决:改用 config.rb,或直接用 ~/.cinc/credentials(knife config show 首行会显示实际加载源)。另外确认 admin.pem 存在且权限 0600——knife 用的是工作站用户私钥,不是节点 node01.pem。

8.5 shard_seed ERROR 不是故障

几乎每次运行都会看到:

[2026-10-27T09:10:25+00:00] ERROR: shard_seed: Failed to get dmi property serial_number: is dmidecode installed?

这是 Ohai 采集 DMI 序列号时缺少 dmidecode 的提示,只影响 shard_seed 派生属性(用于按节点分片随机化),不影响收敛结果。安装 dmidecode 即可消除;不装也可正常使用。

8.6 cookstyle 27 条告警但功能正常

Style/StringLiterals 这类问题只影响风格,不影响 Chef 执行。但 27 offenses autocorrectable 说明代码长期未过 lint,建议在 CI 加 cookstyle 检查,先自动修一轮再纳入门禁,避免告警越积越多。

九、命令速查表

场景命令关键参数
看版本cinc-client --version / knife --version / ohai --version—
单机收敛cinc-solo -c solo.rb -o 'recipe[web_base]'-c、-o
本地模式收敛cinc-client -z -c solo.rb -o web_base-z、-c、-o
预演变更cinc-client -z -W -o web_base / cinc-apply --why-run x.rb-W
调日志级别cinc-client -l debug -L /var/log/cinc.log-l、-L
固定 Zero 端口cinc-client -z --chef-zero-port 8889 -o web_base--chef-zero-port
注入属性cinc-client -z -j attrs.json -o web_base-j
指定环境cinc-client -E production -o web_base-E
单 Recipe 验证cinc-apply /root/test.rb--why-run
列节点knife node list / knife node show node01-F json
改 Run Listknife node run_list set node01 'recipe[web_base]'—
列客户端knife client list / knife client show node01—
新客户端knife client create web02 -f web02.pem-f、--validator
角色knife role list / knife role create web--description
环境knife environment list / knife environment show _default—
传 Cookbookknife cookbook upload web_base-a、--freeze
找社区 Cookbookknife supermarket search nginxshow、install、download
看节点活跃度knife status 'name:*'搜索语法
批量执行命令knife ssh 'name:node01' 'uptime' -x root -a ipaddress-x、-a、-P
初始化新节点knife bootstrap IP -x root -P pass --sudo -N web02 -r 'recipe[web_base]'-r、-N、--sudo
采集事实ohai / ohai platform / ohai fqdn-d
代码检查cookstyle / cookstyle --auto-correct-a、--only

十、参考链接