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 检查与自动修正,附真实回显与踩坑
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,不要误判为安装失败或节点被降级。
前置阅读:
- 安装与首次收敛:《Ubuntu 22.04 安装 CINC Client 19.4.46 与 Workstation 26.3.0 指南》
- 配置文件体系与参数含义:《CINC Client 19.4.46 与 Workstation 26.3.0 配置参数详解》
- 产品定位与许可:《CINC Client 19.4.46 介绍与选型指南》
本篇不复述安装步骤,也不重复 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-solo | cinc-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 优先级见配置参数篇,此处只记三条:
- 工作站仓库通常为
/root/chef-repo,配置在.chef/config.rb(旧名knife.rb兼容); admin.pem是工作站用户(示例admin)的私钥,node01.pem是节点的私钥,二者不可混用;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_level | debug / 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 源文件)。生产使用建议:
- 先提交或备份,再
--auto-correct; - 修完用
git diff逐条确认,不要盲信自动改写; - CI 里只用检查模式,禁止自动改写;
- 第三方/上游 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 List | knife 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 | — |
| 传 Cookbook | knife cookbook upload web_base | -a、--freeze |
| 找社区 Cookbook | knife supermarket search nginx | show、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 |
十、参考链接
- Cinc Client CLI 官方文档(上游同源适用):https://docs.chef.io/workstation/chef_client/
- knife 子命令完整清单:https://docs.chef.io/workstation/knife/
- knife bootstrap 参数:https://docs.chef.io/workstation/knife_bootstrap/
- knife ssh 参数:https://docs.chef.io/workstation/knife_ssh/
- Ohai 文档:https://docs.chef.io/ohai/
- Cookstyle 文档:https://docs.chef.io/workstation/cookstyle/
- CINC 官网:https://cinc.sh
- 本站相关文档: