Kubernetes 命令式对象配置详解:使用 YAML 管理 Kubernetes 资源
- [Kubernetes 命令式对象配置详解:使用 YAML 管理 Kubernetes 资源](#Kubernetes 命令式对象配置详解:使用 YAML 管理 Kubernetes 资源)
- 什么是命令式对象配置?
- [为什么需要 YAML 配置文件?](#为什么需要 YAML 配置文件?)
- [准备 YAML 配置文件](#准备 YAML 配置文件)
- 第一个资源:Namespace
-
- [1. apiVersion](#1. apiVersion)
- [2. kind](#2. kind)
- [3. metadata](#3. metadata)
- 第二个资源:Pod
-
- [Pod 的 metadata](#Pod 的 metadata)
- spec:描述资源应该是什么样子
- containers:定义容器
- [理解 YAML 中的 `---`](#理解 YAML 中的
---) - [使用 create 创建资源](#使用 create 创建资源)
- 检查创建结果
- 直接通过配置文件查询资源
- [使用 YAML 删除资源](#使用 YAML 删除资源)
- 为什么仍然叫"命令式"?
- [命令和 YAML 分别负责什么?](#命令和 YAML 分别负责什么?)
-
- [kubectl 命令](#kubectl 命令)
- [YAML 文件](#YAML 文件)
- 命令式对象管理与命令式对象配置的区别
- 配置文件的优势
- [YAML 与资源对象的对应关系](#YAML 与资源对象的对应关系)
- [常见 YAML 基本结构](#常见 YAML 基本结构)
- [create、get、delete 的完整流程](#create、get、delete 的完整流程)
- [`-f` 参数的重要性](#
-f参数的重要性) - 配置文件不只是用于创建
- 命令式对象配置的优点
-
-
- [1. 配置更加清晰](#1. 配置更加清晰)
- [2. 可以重复使用](#2. 可以重复使用)
- [3. 方便保存](#3. 方便保存)
- [4. 方便版本管理](#4. 方便版本管理)
- [5. 方便管理复杂资源](#5. 方便管理复杂资源)
-
- 需要注意的问题
- 三种核心操作速查
- 总结
Kubernetes 命令式对象配置详解:使用 YAML 管理 Kubernetes 资源
什么是命令式对象配置?
在 Kubernetes 中,可以直接使用 kubectl 命令创建资源。
例如:
bash
kubectl run nginx-pod --image=nginx:1.17.1 -n dev
这种方式需要把资源相关的信息直接写在命令参数中。
当资源配置比较简单时,这种方式非常方便。
但是随着资源越来越复杂,需要配置的内容可能包括:
text
资源名称
Namespace
镜像
端口
环境变量
CPU
内存
Volume
健康检查
标签
启动参数
如果所有信息都通过命令参数指定,命令会越来越复杂,而且不方便保存和重复使用。
因此 Kubernetes 提供了另一种管理方式:
将资源的配置保存到 YAML 文件中,再通过 kubectl 命令操作配置文件中定义的资源。
这就是:
命令式对象配置。
可以简单理解为:

例如:
bash
kubectl create -f nginxpod.yaml
这里:
text
create
负责告诉 Kubernetes:
text
我要创建资源
而:
text
nginxpod.yaml
负责描述:
text
创建什么资源
资源叫什么名字
资源位于哪个 Namespace
使用什么镜像
容器如何配置
为什么需要 YAML 配置文件?
假设现在需要创建一个 Nginx Pod。
使用命令式对象管理时,可以执行:
bash
kubectl run nginx-pod --image=nginx:1.17.1
资源比较简单,所以命令并不复杂。
但是如果 Pod 需要配置:
text
多个容器
环境变量
CPU 限制
内存限制
端口
Volume
健康检查
启动命令
继续把所有配置写在命令参数中,维护起来就会比较困难。
YAML 文件则可以把这些信息按照一定结构保存下来。
例如:
yaml
apiVersion: v1
kind: Pod
metadata:
name: nginxpod
spec:
containers:
- name: nginx-containers
image: nginx:1.17.1
这样资源定义就从:
text
命令参数
转移到了:
text
YAML 配置文件
最终形成:

准备 YAML 配置文件
创建一个文件:
bash
vim nginxpod.yaml
写入:
yaml
apiVersion: v1
kind: Namespace
metadata:
name: dev
---
apiVersion: v1
kind: Pod
metadata:
name: nginxpod
namespace: dev
spec:
containers:
- name: nginx-containers
image: nginx:1.17.1
这个 YAML 文件中实际上定义了两个 Kubernetes 资源:
text
nginxpod.yaml
|
├── Namespace
| └── dev
|
└── Pod
├── nginxpod
├── namespace: dev
└── nginx:1.17.1
接下来分别分析。
第一个资源:Namespace
第一部分:
yaml
apiVersion: v1
kind: Namespace
metadata:
name: dev
表示定义一个 Namespace。
1. apiVersion
yaml
apiVersion: v1
表示创建这个资源时使用的 Kubernetes API 版本。
不同类型的 Kubernetes 资源可能属于不同的 API Group 和 API Version。
例如:
text
Pod
Namespace
Service
等核心资源通常可以看到:
yaml
apiVersion: v1
而 Deployment 则通常使用:
yaml
apiVersion: apps/v1
所以:
text
apiVersion
↓
告诉 Kubernetes 使用哪个 API 版本处理资源
2. kind
yaml
kind: Namespace
表示资源类型。
也就是说:
text
我要创建什么?
↓
Namespace
如果创建 Pod,则是:
yaml
kind: Pod
如果创建 Service:
yaml
kind: Service
如果创建 Deployment:
yaml
kind: Deployment
因此:
text
kind
↓
资源类型
3. metadata
yaml
metadata:
name: dev
metadata 用来定义资源的元数据信息。
这里:
yaml
name: dev
表示资源名称为:
text
dev
所以第一部分 YAML 最终表达的是:
text
API Version:v1
+
Resource Type:Namespace
+
Resource Name:dev
↓
创建一个名为 dev 的 Namespace
第二个资源:Pod
继续看第二部分:
yaml
apiVersion: v1
kind: Pod
metadata:
name: nginxpod
namespace: dev
spec:
containers:
- name: nginx-containers
image: nginx:1.17.1
这里定义的是:
text
Pod
Pod 的 metadata
yaml
metadata:
name: nginxpod
namespace: dev
表示:
text
Pod 名称
↓
nginxpod
同时:
text
Pod 所属 Namespace
↓
dev
因此:
yaml
namespace: dev
表示这个 Pod 应该创建到 dev Namespace 中。
spec:描述资源应该是什么样子
Pod 中还有一个非常重要的字段:
yaml
spec:
spec 可以理解为:
Specification,即资源的规格定义。
它负责描述:
text
这个资源应该是什么样子?
对于 Pod 来说,可以在 spec 中定义:
text
容器
镜像
端口
Volume
环境变量
资源限制
重启策略
这里:
yaml
spec:
containers:
表示定义 Pod 中运行的容器。
containers:定义容器
继续看:
yaml
containers:
- name: nginx-containers
image: nginx:1.17.1
表示 Pod 中运行一个容器。
容器名称:
text
nginx-containers
使用镜像:
text
nginx:1.17.1
因此整个资源关系为:
text
Namespace
|
└── dev
|
└── Pod
|
└── nginxpod
|
└── Container
|
├── name
| nginx-containers
|
└── image
nginx:1.17.1
理解 YAML 中的 ---
配置文件中存在:
yaml
---
例如:
yaml
apiVersion: v1
kind: Namespace
metadata:
name: dev
---
apiVersion: v1
kind: Pod
...
--- 用来分隔 YAML 文档。
因此一个 YAML 文件中可以保存多个资源定义。
这里:
text
第一段 YAML
↓
Namespace
text
第二段 YAML
↓
Pod
最终:
text
nginxpod.yaml
|
├── Document 1
| ↓
| Namespace
|
└── Document 2
↓
Pod
这意味着:
一个配置文件并不一定只能描述一个 Kubernetes 资源。
使用 create 创建资源
准备好:
text
nginxpod.yaml
之后,就可以执行:
bash
kubectl create -f nginxpod.yaml
其中:
text
create
表示:
text
创建资源
而:
text
-f
表示:
text
从指定文件读取资源定义
因此:
bash
kubectl create -f nginxpod.yaml
可以理解为:

执行成功后可以看到类似:
text
namespace/dev created
pod/nginxpod created
说明创建了两个资源:
text
namespace/dev
pod/nginxpod
也就是说:

检查创建结果
创建完成后,可以分别查询。
首先查看 Namespace:
bash
kubectl get namespace
或者:
bash
kubectl get ns
可以看到:
text
dev
已经存在。
然后查询 dev 中的 Pod:
bash
kubectl get pod -n dev
可以看到类似:
text
NAME READY STATUS RESTARTS AGE
nginxpod 1/1 Running 0 20s
说明:

已经创建成功。
直接通过配置文件查询资源
除了:
bash
kubectl get pod -n dev
还可以直接执行:
bash
kubectl get -f nginxpod.yaml
这里并没有手动指定:
text
pod
namespace
而是让 kubectl 直接读取 YAML。
因为配置文件中已经告诉 Kubernetes:
text
第一个资源
Namespace/dev
第二个资源
Pod/nginxpod
所以:
bash
kubectl get -f nginxpod.yaml
可以直接查询配置文件中定义的资源。
输出类似:
text
NAME STATUS AGE
namespace/dev Active 18s
NAME READY STATUS RESTARTS AGE
pod/nginxpod 1/1 Running 0 17s
这个操作非常重要。
可以理解为:

使用 YAML 删除资源
如果不再需要这些资源,可以执行:
bash
kubectl delete -f nginxpod.yaml
Kubernetes 会读取配置文件,并找到其中定义的资源。
也就是:
text
Namespace/dev
Pod/nginxpod
然后删除。
执行后可能看到:
text
namespace "dev" deleted
pod "nginxpod" deleted
所以同一个 YAML 文件可以参与资源的整个管理过程:

这就是命令式对象配置最核心的使用方式。
为什么仍然叫"命令式"?
看到 YAML 文件以后,一个很容易产生的问题是:
既然已经使用 YAML 了,为什么还叫命令式对象配置?
关键并不在于:
text
有没有 YAML
而在于:
text
是谁指定具体操作?
例如:
bash
kubectl create -f nginxpod.yaml
这里明确告诉 Kubernetes:
text
create
↓
创建
执行:
bash
kubectl delete -f nginxpod.yaml
则明确告诉 Kubernetes:
text
delete
↓
删除
如果使用:
bash
kubectl replace -f nginxpod.yaml
则明确告诉 Kubernetes:
text
replace
↓
替换
所以操作仍然是人为明确指定的。
因此称为:
命令式对象配置。
命令和 YAML 分别负责什么?
这是这一部分最需要理解的地方。
可以把两者职责分开。
kubectl 命令
负责描述:
text
做什么?
例如:
text
create
get
delete
replace
YAML 文件
负责描述:
text
操作什么资源?
这个资源是什么样子?
例如:
yaml
kind: Pod
告诉 Kubernetes:
text
资源类型是 Pod
yaml
name: nginxpod
告诉 Kubernetes:
text
资源名称是 nginxpod
yaml
namespace: dev
告诉 Kubernetes:
text
资源属于 dev
yaml
image: nginx:1.17.1
告诉 Kubernetes:
text
容器使用 nginx:1.17.1
因此最终关系为:
text
kubectl
|
指定执行动作
|
create/get/delete
|
v
nginxpod.yaml
|
描述资源配置
|
v
Kubernetes API
|
v
Resource
可以用一句话概括:
命令决定怎么操作,YAML 决定操作什么。
命令式对象管理与命令式对象配置的区别
现在就可以对比前后两种管理方式了。
命令式对象管理
例如:
bash
kubectl run nginxpod --image=nginx:1.17.1 -n dev
资源配置直接写在:
text
命令参数
整体结构:
text
kubectl
+
大量参数
↓
Kubernetes
命令式对象配置
例如:
bash
kubectl create -f nginxpod.yaml
资源信息放在:
text
YAML
整体结构:
text
kubectl
+
YAML
↓
Kubernetes
所以二者最大的变化是:
text
命令式对象管理
资源参数
↓
写在命令中
变成:
text
命令式对象配置
资源参数
↓
写在 YAML 中
配置文件的优势
将 Kubernetes 资源写成 YAML 后,会带来一个非常明显的优势:
资源配置可以保存下来。
例如:
text
nginxpod.yaml
本身就是这个资源的一份配置记录。
它可以:
text
复制
保存
备份
修改
分享
版本管理
重复使用
例如将 YAML 提交到 Git:

以后即使资源被删除,只要配置文件还在,就可以再次执行:
bash
kubectl create -f nginxpod.yaml
重新创建资源。
YAML 与资源对象的对应关系
刚接触 YAML 时,很容易把它理解成:
text
一堆 Kubernetes 参数
更准确的理解应该是:
YAML 是 Kubernetes 资源对象的一种配置描述。
例如:
yaml
apiVersion: v1
kind: Pod
metadata:
name: nginxpod
spec:
containers:
- name: nginx-containers
image: nginx:1.17.1
描述的是:
text
Resource
│
├── apiVersion
│ └── v1
│
├── kind
│ └── Pod
│
├── metadata
│ └── name: nginxpod
│
└── spec
└── containers
|
├── name: nginx-containers
└── image: nginx:1.17.1
因此以后看到复杂的 Kubernetes YAML 时,不要把它当成大量零散参数。
应该按照:
text
这是什么资源?
↓
资源叫什么?
↓
属于哪个 Namespace?
↓
spec 定义了什么?
这样的思路逐层分析。
常见 YAML 基本结构
虽然不同 Kubernetes 资源的具体配置不同,但通常都可以看到几个核心字段:
yaml
apiVersion:
kind:
metadata:
spec:
可以先建立下面的基本认识:
| 字段 | 作用 |
|---|---|
apiVersion |
指定资源使用的 API 版本 |
kind |
指定资源类型 |
metadata |
定义资源名称、Namespace、标签等元数据 |
spec |
描述资源期望的配置 |
例如:
yaml
apiVersion: v1
kind: Pod
metadata:
name: nginxpod
namespace: dev
spec:
containers:
- name: nginx-containers
image: nginx:1.17.1
可以按照:
text
apiVersion
↓
使用哪个 API?
kind
↓
这是什么资源?
metadata
↓
资源是谁?
spec
↓
资源应该是什么样子?
来理解。
create、get、delete 的完整流程
这一部分的操作可以浓缩成一个完整流程。
第一步:准备配置文件
text
nginxpod.yaml
其中定义:
text
Namespace/dev
+
Pod/nginxpod
第二步:创建资源
bash
kubectl create -f nginxpod.yaml
结果:
text
YAML
↓
Namespace/dev
+
Pod/nginxpod
第三步:查询资源
bash
kubectl get -f nginxpod.yaml
或者分别查询:
bash
kubectl get ns
bash
kubectl get pod -n dev
第四步:删除资源
bash
kubectl delete -f nginxpod.yaml
整个过程可以表示为:

-f 参数的重要性
在这种管理方式中,经常会看到:
bash
-f
例如:
bash
kubectl create -f nginxpod.yaml
bash
kubectl get -f nginxpod.yaml
bash
kubectl delete -f nginxpod.yaml
这里的 -f 可以理解为:
text
使用指定的文件或文件来源
所以看到:
bash
kubectl xxx -f xxx.yaml
时,可以快速判断:
当前操作是基于资源配置文件进行的。
配置文件不只是用于创建
这是一个很容易出现的理解误区。
有人可能认为:
text
YAML = 创建 Kubernetes 资源的文件
实际上 YAML 描述的是:
资源本身。
因此同一个配置文件可以配合不同命令:
bash
kubectl create -f nginxpod.yaml
创建资源。
bash
kubectl get -f nginxpod.yaml
查询资源。
bash
kubectl delete -f nginxpod.yaml
删除资源。
Kubernetes 官方文档同样支持使用 create -f 创建、get -f 查询、replace -f 更新以及 delete -f 删除配置文件所描述的对象。
命令式对象配置的优点
相比直接通过大量命令参数管理资源,命令式对象配置最大的优势是:
1. 配置更加清晰
复杂配置全部放入 YAML:
text
kubectl 命令
↓
保持简洁
YAML
↓
保存详细配置
2. 可以重复使用
同一个:
text
nginxpod.yaml
可以多次使用。
3. 方便保存
YAML 文件本身就是资源配置记录。
4. 方便版本管理
可以提交到 Git 等版本控制系统。
例如:
text
v1
↓
修改 YAML
↓
v2
↓
再次修改
↓
v3
资源配置的变化可以被记录下来。
5. 方便管理复杂资源
随着 Kubernetes 资源越来越复杂,YAML 的优势会越来越明显。
例如:
text
Deployment
Service
ConfigMap
Secret
PVC
Ingress
都可以通过配置文件进行描述。
Kubernetes 官方文档也将配置可进入 Git 等源代码管理系统、可参与变更审查,以及可作为创建新对象的模板列为这种方式相对于直接命令操作的主要优势。
需要注意的问题
命令式对象配置虽然使用了 YAML,但依然要求使用者明确告诉 Kubernetes:
text
创建?
删除?
替换?
例如:
bash
kubectl create -f nginxpod.yaml
明确要求:
text
创建
bash
kubectl replace -f nginxpod.yaml
明确要求:
text
替换
bash
kubectl delete -f nginxpod.yaml
明确要求:
text
删除
另外,使用 replace 时需要特别注意:它按照提供的配置替换现有对象,配置文件中没有保留的部分可能丢失。因此如果同一个资源还会被其他控制器或管理方式修改,需要谨慎使用。
这也正是后面理解声明式对象配置的重要铺垫。
三种核心操作速查
| 操作 | 命令 |
|---|---|
| 创建 YAML 中的资源 | kubectl create -f nginxpod.yaml |
| 查询 YAML 中的资源 | kubectl get -f nginxpod.yaml |
| 删除 YAML 中的资源 | kubectl delete -f nginxpod.yaml |
| 替换 YAML 中的资源 | kubectl replace -f nginxpod.yaml |
其中这一阶段最重要的是掌握:
bash
kubectl create -f nginxpod.yaml
bash
kubectl get -f nginxpod.yaml
bash
kubectl delete -f nginxpod.yaml
总结
命令式对象配置可以用一句话概括:
通过 kubectl 命令 + YAML 配置文件管理 Kubernetes 资源。
核心结构:

其中:
text
kubectl
↓
决定执行什么操作
而:
text
YAML
↓
描述资源是什么样子
常见 YAML 核心字段:
text
apiVersion
kind
metadata
spec
常用操作:
bash
kubectl create -f nginxpod.yaml
kubectl get -f nginxpod.yaml
kubectl delete -f nginxpod.yaml
与直接通过命令参数管理资源相比,YAML 最大的意义是:
text
资源定义
↓
从临时命令中分离
↓
形成配置文件
↓
可以保存
↓
可以复用
↓
可以进行版本管理
因此,从命令式对象管理过渡到命令式对象配置,本质上是从:
text
命令 + 大量参数
转变为:
text
命令
+
资源配置文件
不过此时仍然需要人为明确指定 create、delete、replace 等具体操作。
如果进一步希望只描述资源最终应该达到的状态,而让 Kubernetes 判断究竟应该创建还是更新资源,就需要使用声明式对象配置。
若有转载,请标明出处:
https://blog.csdn.net/CharlesYuangc/article/details/165984308