1. 概述
Kubernetes 是用于容器化应用的编排工具,通过命令行工具 kubectl 与集群进行交互。
本文将通过实际示例讲解 kubectl create 和 kubectl apply 之间的区别,帮助你在不同场景下做出合适的选择。
2. Kubernetes 环境准备
2.1 集群搭建
搭建 Kubernetes 集群有多种方式。对于学习目的,可以使用 Kubeadm 搭建本地多节点集群,或者使用轻量级发行版如 k3s 或 kind 快速启动。
如果你希望跳过搭建步骤,可以使用在线实验平台如 Killercoda 或 Play with Kubernetes。
2.2 安装 kubectl
无论使用哪种方式,都需要安装 kubectl 工具。它通过配置文件与 Kubernetes API 通信,虽然不是 Kubernetes 核心组件,但几乎是日常操作必备工具。
3. 声明式 vs 指令式
在比较 create 和 apply 命令之前,我们先来理解 Kubernetes 中对象管理的两种方式:声明式(Declarative)和指令式(Imperative)。
3.1 对象管理简介
Kubernetes 的核心是管理集群中的各种资源对象,如 Pod、Deployment、Service 等。我们可以通过命令创建、更新、删除这些对象。
3.2 指令式操作(Imperative)
指令式操作强调“怎么做”,即通过具体命令直接执行操作。
例如创建一个 Nginx Deployment:
kubectl create deployment nginx --image nginx
也可以通过 YAML 文件创建:
kubectl create -f nginx.yaml
3.3 声明式操作(Declarative)
声明式操作更关注“最终状态”,你只需定义你期望的状态,Kubernetes 会自动处理差异。
例如:
kubectl apply -f deployment.yaml
4. kubectl create 命令详解
kubectl create 是一个典型的指令式命令,适用于创建资源对象。
示例:创建一个 Nginx Deployment
文件 deployment.yaml
内容如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
selector:
matchLabels:
app: nginx
minReadySeconds: 5
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
执行创建命令:
kubectl create -f deployment.yaml
输出:
deployment.apps/nginx-deployment created
验证 Pod 是否运行:
kubectl get pods
输出示例:
NAME READY STATUS RESTARTS AGE
nginx-deployment-86dcfdf4c6-zhkw8 1/1 Running 0 88s
4.1 重复创建会报错
如果尝试再次创建相同资源:
kubectl create -f deployment.yaml
会提示错误:
Error from server (AlreadyExists): error when creating "deployment.yaml": deployments.apps "nginx-deployment" already exists
4.2 创建前修改对象
你可以使用 --dry-run
和 --edit
在创建前修改 YAML:
kubectl create -f deployment.yaml -o yaml --dry-run=client > deployment_1.yaml
kubectl create --edit -f deployment_1.yaml
这会打开默认编辑器,让你修改后再创建。
4.3 每次只能执行一个指令式操作
Kubernetes 推荐每次只执行一个指令式操作。例如扩容 Deployment:
kubectl scale --replicas=5 deployment nginx-deployment
也可以修改 YAML 文件并使用 replace
命令更新:
spec:
replicas: 2
kubectl replace -f deployment_scale.yaml
删除资源:
kubectl delete -f deployment.yaml
4.4 常用选项
--dry-run
:模拟创建,不真正提交--edit
:创建前编辑配置--selector
:指定筛选器--save-config
:保存配置信息,便于后续使用apply
5. kubectl apply 命令详解
kubectl apply 是声明式操作的核心命令,更适合长期管理资源状态。
5.1 替换 create 命令
你可以用 apply
替代 create
:
kubectl apply -f deployment.yaml
效果一样,但行为不同。
5.2 重复 apply 不会报错
再次执行:
kubectl apply -f deployment.yaml
输出:
deployment.apps/nginx-deployment unchanged
如果修改了 YAML 内容,比如更新镜像版本:
kubectl apply -f deployment.yaml
输出:
deployment.apps/nginx-deployment configured
5.3 与对象类型无关
apply 命令不需要指定资源类型,只需提供 YAML 文件即可。Kubernetes 会自动识别 kind
字段。
5.4 记录历史配置
apply 会在资源的 metadata 中添加注解 kubectl.kubernetes.io/last-applied-configuration
,记录最后一次应用的配置内容。
查看 last applied 配置:
kubectl apply view-last-applied -f deployment.yaml -o yaml
输出示例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
minReadySeconds: 5
replicas: 3
...
5.5 每次变更生成新版本
Kubernetes 会为每次 apply 操作生成新版本。查看 Deployment 的 YAML:
kubectl get deployments.apps nginx-deployment -o yaml
你会看到:
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
...
generation: 2
resourceVersion: "156401"
这有助于 Kubernetes 比较当前状态与期望状态,实现自动合并。
5.6 从 create 切换到 apply
如果你之前使用 kubectl create
创建资源,但未使用 --save-config
,后续使用 apply
时会收到警告:
Warning: resource deployments/nginx-deployment is missing the kubectl.kubernetes.io/last-applied-configuration annotation ...
Kubernetes 会自动补上该注解。
5.7 常用选项
--prune
:删除不再需要的资源--grace-period
:设置资源优雅终止时间
6. create 与 apply 的关键区别总结
特性 | kubectl create |
kubectl apply |
---|---|---|
类型 | 指令式 | 声明式 |
是否允许重复执行 | ❌ 报错 | ✅ 无变化或更新 |
是否自动记录配置 | ❌ 需要 --save-config |
✅ 自动记录 |
是否支持自动合并 | ❌ | ✅ |
是否适合持续管理 | ❌ | ✅ |
是否需要指定资源类型 | ✅ | ❌ |
⚠️ 注意:不要在同一个资源上混用 create
和 apply
,否则可能引起配置冲突。
7. 总结
kubectl create
是指令式命令,适合一次性创建资源。kubectl apply
是声明式命令,适合长期维护资源状态。apply
能自动记录历史配置,支持自动合并,但有时合并逻辑复杂,可能导致意外行为。- 如果你希望资源能被后续
apply
管理,创建时请使用--save-config
。 - 选择使用哪种方式取决于你的团队习惯和项目复杂度,但推荐优先使用
apply
。
✅ 建议:除非是脚本中一次性创建资源,否则都应使用 apply
。
❌ 踩坑提醒:混用 create
和 apply
容易导致配置不一致,甚至服务异常。