Chef:以代码定义基础设施
Chef 基础设施:以代码定义基础设施
Chef 是一款强大的基础设施自动化平台,它将服务器配置和管理转化为可版本控制、可测试、可复用的代码。通过 Chef,你能用声明性的方式描述系统期望的状态,实现从裸机到云端的全生命周期管理。
本教程面向初学者,将带你从零开始掌握 Chef 核心概念、环境搭建以及编写第一个配置脚本,逐步解锁“基础设施即代码”的实战能力。
理解 Chef 的核心架构
Chef 采用客户端-服务器(Client-Server)模式,但也能以独立模式(Chef Solo)运行。整个体系由以下几个关键组件构成:
- Chef Workstation(工作站):你本地开发、测试代码的机器。上面安装 Chef Development Kit (ChefDK),包含编写和调试配置所需的所有工具。
- Chef Server(服务器):中心存储库。所有配置脚本(Cookbook)、节点信息、数据包都保存在这里。节点通过它拉取最新的配置。
- Chef Node(节点):被管理的目标机器。节点上运行 Chef Client,定期向 Chef Server 注册并执行分配的配置。
- Chef Supermarket(超市):社区共享的 Cookbook 仓库,你可以直接复用成千上万现成的配置来加速开发。
在概念上,Chef 将基础设施的每一个可配置单元抽象成资源(Resource),比如软件包、服务、文件、用户等。你只需声明资源的目标状态,Chef 负责让它达到该状态,无需关心底层命令的差异。
必备术语:从食谱到运行清单
想要顺畅使用 Chef,必须熟悉三个核心抽象:Cookbook、Recipe 与 Run-list。
-
Recipe(菜谱)
最基本的配置单位,一个 Ruby 文件,其中包含一系列描述资源状态的代码。例如安装 Nginx 并确保它正在运行。 -
Cookbook(食谱书)
Recipe 的容器,也是 Chef 的分享和复用单元。一个 Cookbook 包含多个 Recipe,以及对应的模板、属性、文件、测试等。例如一个 Web 服务器 Cookbook 可能包含default.rb(基本安装)、ssl.rb(配置 HTTPS)等多个 Recipe。 -
Run-list(运行清单)
节点上要执行的有序 Recipe 列表。你可以精确控制哪些配置、以什么顺序应用到某个节点。
三者关系可以理解为:Cookbook 装载 Recipe,Run-list 指定次序应用 Recipe。
安装与准备 Chef Workstation
在工作站上安装 Chef Workstation(原 ChefDK)是开始的第一步。这里以 Ubuntu 为例,说明基础环境搭建。
-
下载并安装 Chef Workstation
wget https://packages.chef.io/files/stable/chef-workstation/23.4.1032/ubuntu/20.04/chef-workstation_23.4.1032-1_amd64.deb sudo dpkg -i chef-workstation_*.deb -
验证安装
chef --version看到
Chef Workstation version: ...即表示安装成功。这会包括chef-client、knife、berks、kitchen等一系列工具。 -
配置 Git Chef Workstation 依赖 Git 来管理版本和依赖,请确保已安装并配置:
git config --global user.name "Your Name" git config --global user.email "[email protected]"
创建第一个 Cookbook
现在动手创建管理 SSH 服务的基础 Cookbook,体验从生成到应用的完整流程。
第一步:生成 Cookbook 骨架
chef generate cookbook ssh_basics
cd ssh_basics
此命令会在当前目录生成符合厨师规范的目录结构,包含 recipes、attributes、templates 等文件夹。
第二步:编写默认 Recipe
编辑 recipes/default.rb,添加以下内容:
# 确保 openssh-server 包已安装
package 'openssh-server' do
action :install
end
# 管理 sshd 服务:开启、自启动
service 'sshd' do
action [:enable, :start]
supports restart: true, reload: true
end
# 写一个基础的 sshd_config 模板
template '/etc/ssh/sshd_config' do
source 'sshd_config.erb'
owner 'root'
group 'root'
mode '0644'
notifies :restart, 'service[sshd]'
end
第三步:创建配置模板
创建 templates/sshd_config.erb 文件,写入可配置的关键参数,例如:
Port <%= node['ssh_basics']['port'] %>
PermitRootLogin <%= node['ssh_basics']['permit_root_login'] %>
PasswordAuthentication <%= node['ssh_basics']['password_auth'] %>
此处利用了 Chef 的**属性(Attribute)**机制,允许从外部动态设置值。
第四步:定义默认属性
在 attributes/default.rb 中设置默认值:
default['ssh_basics']['port'] = 22
default['ssh_basics']['permit_root_login'] = 'yes'
default['ssh_basics']['password_auth'] = 'yes'
第五步:语法检查与本地测试
使用 chef exec 运行 Cookstyle 进行代码风格与静态检查:
cookstyle .
确保没有报错。然后利用 kitchen 在虚拟机中测试(需要提前安装 VirtualBox/Vagrant):
kitchen list # 查看测试套件
kitchen create # 创建测试实例
kitchen converge # 执行配置
kitchen verify # 运行集成测试
kitchen destroy # 清理环境
将 Cookbook 上传到 Chef Server
经过本地测试后,通常会把 Cookbook 上传至 Chef Server,以便节点拉取。如果你没有自建 Server,可以注册Chef Automate(免费试用)来快速体验。
-
下载并解压 Starter Kit
Chef Server 管理员会提供 Starter Kit,内含密钥及knife.rb配置文件。将解压后的目录放在~/chef-repo附近,或直接复制到你的 Chef 仓库中。 -
下载并配置 Knife
确保knife.rb中chef_server_url、client_key和node_name正确指向你的 Server。 -
上传 Cookbook
knife upload cookbooks/ssh_basics或通过 Policyfile 方式管理更复杂的依赖与版本约束,但基础学习时直接用
knife upload即可。 -
引导(Bootstrap)节点
在 Server 上新增节点通常用knife bootstrap命令完成,它会将 Chef Client 安装到目标机器并注册到 Server:knife bootstrap 192.168.1.100 --ssh-user ubuntu --sudo --identity-file ~/keys/mykey.pem --node-name web-node --run-list 'recipe[ssh_basics]'执行后,节点会拉取
ssh_basicsCookbook,应用配置,并每隔 30 分钟自动与 Server 同步。
常用 Chef 资源一览
除了已经使用的 package、service、template,Chef 提供了数十种内置资源,覆盖绝大多数运维场景。下面列举几个高频使用的资源及典型用法。
管理与创建文件
file '/etc/motd' do
content "Welcome to Chef-managed system\n"
owner 'root'
group 'root'
mode '0644'
end
目录创建
directory '/srv/app/shared' do
owner 'deploy'
group 'deploy'
mode '0755'
recursive true
end
执行命令(谨慎使用)
execute 'update apt cache' do
command 'apt-get update'
action :run
not_if { ::File.exist?('/var/lib/apt/periodic/update-success-stamp') }
end
使用 not_if/only_if 守卫条件来保证幂等性。
管理用户和组
user 'appuser' do
comment 'Application User'
shell '/bin/bash'
manage_home true
end
group 'devops' do
members ['appuser']
action :create
end
Cron 任务编排
cron 'log cleanup' do
minute '0'
hour '3'
command '/usr/local/bin/clean_logs.sh'
user 'root'
end
属性、数据与可复用性的核心实践
真正的“以代码定义基础设施”要求配置具备动态性和环境适应性。Chef 通过以下机制实现这一点:
- 属性优先级:从低到高依次为默认属性、Ohai 自动收集的属性、Cookbook 属性、Role 属性、环境属性、覆盖属性。理解优先级可避免配置冲突。
- 数据包(Data Bags):存放全局共享信息的 JSON 数据,比如用户密码、服务密钥等,可加密存储。例如创建
users数据包,在 Recipe 中通过data_bag_item('users', 'alice')调用。 - 角色(Role):将公共配置的 Run-list 和属性打包成角色,赋予节点角色后自动应用一组 Recipe,例如
web_server角色包含apache2、firewall等 Cookbook。 - 环境(Environment):隔离不同阶段的配置,如开发、测试、生产环境,可以为同一 Cookbook 指定不同的属性值。
基础设施测试与代码质量
你不仅要写配置,还要保证它正确、稳定。Chef 内建了强大的测试驱动基础设施:
- Cookstyle – 持续检查 Ruby 代码风格和最佳实践。
- Test Kitchen – 自动化集成测试环境,可在 Docker 容器、Vagrant 虚拟机甚至云实例中验证脚本。
- ChefSpec – 模拟 Chef Client 运行,编写单元测试,验证资源是否按照预期收敛。
- InSpec – 基础设施合规性扫描框架,用自然语言编写断言,如“检查 SSH 是否运行在 22 端口”。
将测试纳入日常工作流,才能放心地持续交付基础设施变更。
进阶话题与学习路径
掌握基础之后,可以考虑以下方向深入 Chef 之旅:
- Policyfile 与 Workflow:取代旧的 Berkshelf + Environment 流程,实现更精确的依赖锁定和部署流水线。
- Chef Automate 与 Compliance:集中可视化节点状态、审计历史和自动合规补救。
- 自定义资源(Custom Resource):封装复杂操作为可复用、统一接口的资源,提升 Cookbook 的可读性。
- 集成云平台:利用
kitchen-ec2、kitchen-azurerm等驱动在云端测试,并使用 Chef Provisioning(现已独立为chef-solo)动态创建基础设施。
Chef 的核心理念始终不变:用代码描述你希望系统成为的样子,而不是执行步骤。 随着对资源和抽象理解的加深,你将能管理从单机到大规模集群的任意基础设施。
本教程为“免费在线教程”网站原创,仅供学习参考。实际环境部署时请结合官方文档核对版本差异。