在K8s管理中,YAML资源清单是定义、创建和管理资源的核心载体。本文将系统梳理YAML编写技巧、Pod管理、命名空间、标签、节点调度(亲和性/污点)等核心能力,结合实操命令与配置示例,帮助高效掌握K8s资源管理。
一、Kubernetes YAML编写核心技巧
YAML资源清单需遵循严格的语法格式(缩进、键值对),同时需匹配K8s API规范,以下是 高效编写 YAML 的 4 种核心方法,从 “参考” 到 “生成” 再到 “验证” 全覆盖。
1.官方文档:权威参考
K8s官方文档提供了所有资源的YAML规范,包含字段含义、可选值、必填项等,最权威的参考来源:
- 官方资源文档:Kubernetes API Reference
- 例如:查看 Pod 资源的完整规范,可直接访问 Pod v1 Core
2.kubectl explain:实时查询字段
无需记忆所有字段,通过kubectl explain可实时查看任意资源的字段定义,包括层级结构、是否必填、字段类型等,是编写YAML时“实时字典”。
常用命令示例
命令 | 作用 |
kubectl explain pod | 查看Pod资源的顶层字段(如apiVersion、kind、 metadata、spec) |
kubectl expain pod.metadata | 查看Pod的元数据字段(如name、namespace、labels) |
kubectl explain pod.spec | 查看Pod规格字段(如container、restartPolicy、nodeSelector) |
kubectl explain pod.spec.containers | 查看容器的字段(如name、image、ports、resources) |
kubectl explain pod.spec.container.ports | 查看容器端口的详细字段(如container、protocol) |
字段说明关键标识
-
<Object>
:表示该字段是一个 “对象”,需嵌套子字段(如metadata
、spec
); -
<string>/<integer>
:表示字段类型(字符串 / 整数); -
-required-
:表示该字段为必填项(如pod.spec.containers.name
、pod.spec.containers.image
)。
3. kubectl run
:生成基础 YAML
通过 kubectl run
命令可快速生成 Pod 的 YAML 模板(无需实际创建资源),避免手动编写基础结构的繁琐。
核心命令
#生成Nginx Pod的YAML,仅输出模板(--dry-run=client 表示不提交到集群)
kubectl run nginx --image=nginx --dry-run=client -o yaml > nignx-pod.yaml
#生成Tomcat Pod的YAML,指定端口和镜像拉取策略
kubectl run tomcat --image=tomcat:8.5-jre8-alpine=8080 --image-pull-policy=IfNotPresent --dry-run=client -o yaml > tomcat-pod.yaml
输出结果示例(精简版)
apiVersion:v1
kind:Pod
metadata:
creationTimestamp:null
name:tomcat
spec:
container:
- image: tomcat:8.5-jre8-alpine
imagePullPolicy: IfNotPresent
name: tomcat
ports:
- containerPort: 8080
resources: {}
dnsPolicy: ClusterFirst
restartPolicy: Always
status: {}
4. kubectl get -o yaml
:参考现有资源
若集群中已存在同类资源,可通过kubectl get -o yaml导出其YAML配置,作为编写新资源的参考(注意删除自动生成的字段,如status、uid、creationTimestamp)。
核心命令
#导出名为nginx1的Pod的YAML配置
kubectl get pod nginx1 -o yaml > nginx1-pod.yaml
#导出名为test的Namespace的YAML配置
kubectl get ns test -o yaml > test-ns.yaml
注意事项
导出的 YAML 包含集群自动生成的字段(如 status
、metadata.uid
),编写新资源时需删除这些字段,仅保留手动配置的核心字段(如 apiVersion
、kind
、metadata
、spec
)。
二、Pod资源清单核心配置与实操
Pod是K8s最小的部署单元,一个Pod可包含一个或多个容器。以下是Pod资源清单的核心配置、创建、更新与管理实操。
1. 基础 Pod YAML 模板(必掌握)
apiVersion: v1 # API 版本(Pod 属于 v1 核心组)
kind: Pod # 资源类型(此处为 Pod)
metadata: # 元数据(资源的“身份信息”)
name: pod-first # Pod 名称(必填,唯一)
namespace :default # 所属命名空间(默认 default,可选)
labels: # 标签(用于资源分组,键值对,可选)
app: tomcat-pod
env: dev
spec: # 规格(Pod 的核心配置,定义容器、调度规则等)
containers: # 容器列表(必填,至少一个容器)
- name: tomcat-first # 容器名称(必填,Pod 内唯一)
image: tomcat:8.5-jre8-alpine # 容器镜像(必填,需指定版本)
imagePullPolicy: IfNotPresent # 镜像拉取策略(可选,默认 Always)
ports: # 容器端口(可选,仅声明,不暴露到集群外)
- containerPort: 8080 # 容器内部端口(必填,若声明 ports)
protocal: TCP # 协议(可选,默认 TCP)
restartPolicy: Always # 重启策略(可选,默认 Always)
关键字段说明
字段 | 含义 | 可选值 / 说明 |
---|---|---|
imagePullPolicy | 镜像拉取策略 | Always (总是拉取)、IfNotPresent (本地存在则用本地)、Never (从不拉取) |
restartPolicy | 容器重启策略 | Always (总是重启)、OnFailure (失败时重启)、Never (从不重启) |
containers.ports.containerPort | 容器内部端口 | 仅声明端口,不暴露到集群外(暴露需用 Service) |
2. Pod 生命周期管理命令
操作 | 命令 | 说明 |
---|---|---|
创建 Pod | kubectl apply -f pod-first.yaml | 基于 YAML 文件创建 Pod(推荐,支持更新) |
删除 Pod | kubectl delete -f pod-first.yaml | 基于 YAML 文件删除 Pod |
强制删除 Pod | kubectl delete pod pod-first --force --grace-period=0 | 用于无法正常删除的 Pod |
查看 Pod 列表 | kubectl get pods | 查看默认命名空间的 Pod |
查看 Pod 详情 | kubectl describe pod pod-first | 查看 Pod 状态、事件、容器日志等(排障常用) |
查看 Pod 日志 | kubectl logs pod-first | 查看 Pod 中默认容器的日志 |
查看指定容器日志 | kubectl logs pod-first -c tomcat-first | 多容器 Pod 需指定容器(-c 为 --container 缩写) |
进入 Pod 容器 | kubectl exec -it pod-first -- /bin/bash | 交互式进入 Pod 中默认容器(-it 表示交互式终端) |
进入指定容器 | kubectl exec -it pod-first -c tomcat-first -- /bin/bash | 多容器 Pod 需指定容器 |
三、命名空间(Namespace):资源隔离与限额
标签是 K8s 中用于资源分组的 “键值对”,可灵活用于筛选、调度、管理资源(如通过标签筛选 Pod、通过标签指定 Service 关联的 Pod)。
1. 标签的核心特性
-
灵活性:可在资源创建时定义,也可后续动态添加 / 删除;
-
唯一性:一个资源的标签键(Key)唯一,值(Value)可重复;
-
多用途:用于资源筛选(
kubectl get -l
)、Pod 调度(nodeSelector
)、Service 关联 Pod 等。
2. 标签管理实操命令
操作 | 命令 | 说明 |
---|---|---|
创建资源时添加标签 | 在 YAML 的 metadata.labels 中定义 | 示例:labels: {app: tomcat, env: dev} |
为现有 Pod 添加标签 | kubectl label pod pod-first release=v1 | 为 pod-first 添加标签 release=v1 |
修改现有标签(覆盖) | kubectl label pod pod-first release=v2 --overwrite | 覆盖标签 release 的值为 v2 |
删除标签 | kubectl label pod pod-first release- | 删除标签 release (键后加 - ) |
查看 Pod 标签 | kubectl get pod pod-first --show-labels | 显示 pod-first 的所有标签 |
查看所有 Pod 标签 | kubectl get pods --show-labels | 显示默认命名空间所有 Pod 的标签 |
按标签筛选 Pod(等值) | kubectl get pod -l release=v1 | 筛选标签 release=v1 的 Pod |
按标签筛选 Pod(存在键) | kubectl get pod -l release | 筛选包含 release 标签的 Pod |
按标签筛选并显示标签值 | kubectl get pod -l release=v1 -L release | 筛选 release=v1 的 Pod,并显示 release 标签值 |
跨命名空间按标签筛选 | kubectl get pod -A -l app=tomcat | 筛选所有命名空间中 app=tomcat 的 Pod(-A 即 --all-namespaces ) |
四、Pod 调度控制:节点选择器、亲和性与污点
K8s 默认通过调度器(kube-scheduler)将 Pod 随机调度到节点,但实际场景中常需指定调度规则(如 “Pod 仅调度到生产节点”“Pod 与数据库 Pod 同节点”)。以下是 4 种核心调度控制方式。
1. 节点选择器(nodeSelector):简单匹配
通过 nodeSelector
让 Pod 仅调度到包含指定标签的节点,适用于简单的 “标签匹配” 场景。
实操步骤:
为节点添加标签:
# 为节点 hd3 添加标签 `disk=ceph`
kubectl label node hd3 disk=ceph
# 验证标签
kubectl get node hd3 --show-labels
编写 Pod YAML 时指定 nodeSelector
:
apiVersion: v1
kind: Pod
metadata:
name: pod-with-nodeselector
spec:
nodeSelector: # 节点选择器(仅调度到包含 `disk=ceph` 标签的节点)
disk: ceph
containers:
- name: tomcat
image: tomcat:8.5-jre8-alpine
创建 Pod 并验证调度结果:
kubectl apply -f pod-with-nodeselector.yaml
# 查看 Pod 调度到的节点(应显示 hd3)
kubectl get pod pod-with-nodeselector -o wide
2. 节点亲和性(NodeAffinity):灵活匹配
nodeSelector
仅支持 “等值匹配”,而 节点亲和性(NodeAffinity) 支持更灵活的匹配规则(如 In
、NotIn
、Exists
),且分为 “硬亲和性” 和 “软亲和性”。
核心概念
-
硬亲和性(RequiredDuringSchedulingIgnoredDuringExecution):必须满足条件,否则 Pod 无法调度(Pending);
-
软亲和性(PreferredDuringSchedulingIgnoredDuringExecution):优先满足条件,若无匹配节点,仍可调度到其他节点。
节点亲和性 YAML 示例(硬亲和性)
apiVersion: v1
kind: Pod
metadata:
name: pod-node-affinity-hard
spec:
containers:
- name: myapp
image: janakiramm/myapp:v1
affinity: # 亲和性配置
nodeAffinity: # 节点亲和性
requiredDuringSchedulingIgnoredDuringExecution: # 硬亲和性
nodeSelectorTerms: # 节点选择条件(OR 关系,满足一个即可)
- matchExpressions: # 匹配表达式(AND 关系,需全部满足)
- key: zone # 节点标签键
operator: In # 运算符(In:值在列表中)
values: ["foo", "bar"] # 标签值列表
效果验证
-
若集群中无节点包含
zone=foo
或zone=bar
标签,Pod 将处于 Pending 状态; -
为节点 hd2 添加标签
zone=foo
后,Pod 将调度到 hd2:
kubectl label node hd2 zone=foo
kubectl get pod pod-node-affinity-hard -o wide # 显示调度到 hd2
3. Pod 亲和性 / 反亲和性(PodAffinity/PodAntiAffinity)
基于现有 Pod 的标签进行调度,实现 “Pod 与指定 Pod 同节点”(亲和性)或 “Pod 与指定 Pod 不同节点”(反亲和性),适用于 “服务与数据库同节点”“多副本 Pod 分散部署” 等场景。
核心概念
-
Pod 亲和性(PodAffinity):Pod 倾向于调度到与指定 Pod 同 “拓扑域” 的节点(拓扑域通过
topologyKey
定义,如kubernetes.io/hostname
表示节点级、zone
表示区域级); -
Pod 反亲和性(PodAntiAffinity):Pod 倾向于调度到与指定 Pod 不同 “拓扑域” 的节点。
注:K8s 通过节点的 topology.kubernetes.io/
前缀标签,标准化了常见的拓扑域层级,从宏观到微观分为以下几类(按粒度从大到小排序):
拓扑域标签(Node Label) | 含义(拓扑维度) | 典型场景 |
---|---|---|
topology.kubernetes.io/region | 集群所在的地理区域(如 AWS 的 us-east-1、阿里云的 cn-beijing) | 跨区域灾备:Pod 分布在不同 region,避免单区域断电 / 网络故障影响服务 |
topology.kubernetes.io/zone | 区域内的可用区(如 us-east-1a、cn-beijing-b),通常对应独立机房 / 电力网络 | 高可用核心:Pod 分散在同一 region 的不同 zone,平衡故障隔离与网络延迟 |
topology.kubernetes.io/rack | 机房内的机架(如 rack-01、rack-23),同一机架共享交换机 / 电源 | 细粒度高可用:避免单机架硬件故障(如交换机断电)导致 Pod 全离线 |
topology.kubernetes.io/hostname | 节点的主机名(每个节点唯一),最小的拓扑域单元 | 避免 Pod 调度到同一节点(如多副本 Pod 分散部署) |
自定义拓扑域(如 topology.kubernetes.io/room ) | 企业自定义维度(如机房内的 “房间”“楼层”) |
Pod 亲和性 YAML 示例(同节点)
apiVersion: v1
kind: Pod
metadata:
name: pod-second # 待调度的 Pod
labels:
app: backend
spec:
containers:
- name: busybox
image: busybox:1.28
command: ["sh", "-c", "sleep 3600"]
affinity:
podAffinity: # Pod 亲和性
requiredDuringSchedulingIgnoredDuringExecution: # 硬亲和性
- labelSelector: # 匹配目标 Pod 的标签(此处为 pod-first 的标签)
matchExpressions:
- key: app2
operator: In
values: ["myapp2"]
topologyKey: kubernetes.io/hostname # 拓扑域:节点级(同节点)
效果验证
-
先创建目标 Pod(pod-first):
apiVersion: v1
kind: Pod
metadata:
name: pod-first
labels:
app2: myapp2 # 目标标签
spec:
containers:
- name: myapp
image: janakiramm/myapp:v1
2. 创建 pod-second,查看调度结果:
kubectl apply -f pod-first.yaml
kubectl apply -f pod-second.yaml
kubectl get pod -o wide # pod-second 与 pod-first 调度到同一节点
4. 污点(Taint)与容忍度(Toleration):节点排斥
污点(Taint)是定义在节点上的 “排斥规则”,用于拒绝不满足 “容忍度” 的 Pod 调度;容忍度(Toleration)是定义在Pod上的 “豁免规则”,用于允许 Pod 调度到有污点的节点。
核心概念
- 污点组成:
key=value:effect
,其中effect
是排斥效果:NoSchedule
:仅影响调度,不驱逐已运行的 Pod;NoExecute
:既影响调度,也驱逐已运行的 Pod(若 Pod 无对应容忍度);PreferNoSchedule
:优先排斥,若无其他节点,仍可调度。
- 容忍度:Pod 需定义与污点匹配的容忍度,才能调度到该节点。
污点与容忍度实操步骤
1.为节点添加污点:
# 为节点 hd3 添加污点:node-type=production:NoSchedule(生产节点,仅允许有容忍度的 Pod 调度)
kubectl taint node hd3 node-type=production:NoSchedule
# 验证污点
kubectl describe node hd3 | grep Taints
2.创建无容忍度的 Pod:
apiVersion: v1
kind: Pod
metadata:
name: pod-no-toleration
spec:
containers:
- name: tomcat
image: tomcat:8.5-jre8-alpine
- 调度结果:Pod 不会调度到 hd3(因无容忍度),将调度到其他节点(如 hd2)。
创建有容忍度的 Pod:
apiVersion: v1
kind: Pod
metadata:
name: pod-with-toleration
spec:
containers:
- name: nginx
image: nginx
tolerations: # 容忍度配置(匹配 hd3 的污点)
- key: "node-type"
operator: "Equal" # 等值匹配(key 和 value 需与污点完全一致)
value: "production"
effect: "NoSchedule" # 匹配污点的 effect
- 调度结果:Pod 可调度到 hd3(因有对应容忍度)。
4.删除节点污点:
# 删除 hd3 上的 node-type=production:NoSchedule 污点(键+effect 后加 `-`)
kubectl taint node hd3 node-type:NoSchedule-
注:点赞+关注+收藏,下期我们真讲工作负载,不见不散。