K8S 的 YAML 配置文件详解
大约 10 分钟约 2956 字
K8S 的 YAML 配置文件详解
简介
Kubernetes 使用 YAML 文件作为资源定义和配置的标准格式。通过 YAML 文件,可以声明式地定义各种 Kubernetes 资源对象(如 Deployment、Service、ConfigMap 等),实现应用部署、服务暴露、配置管理等操作。掌握 YAML 配置是使用 Kubernetes 的基础技能。
特点
YAML 语法基础
YAML 基本规则
YAML 数据类型
# 字符串
name: demo
# 数字
replicas: 3
# 布尔值
enabled: true
# 列表(数组)
ports:
- 80
- 443
# 字典(对象)
metadata:
name: demo
namespace: default资源类型概览
| 资源类型 | kind 值 | 说明 | apiVersion |
|---|---|---|---|
| Pod | Pod | 最小调度单元 | v1 |
| Deployment | Deployment | 无状态应用部署 | apps/v1 |
| StatefulSet | StatefulSet | 有状态应用部署 | apps/v1 |
| DaemonSet | DaemonSet | 每个节点运行一个 Pod | apps/v1 |
| Service | Service | 服务暴露和发现 | v1 |
| ConfigMap | ConfigMap | 配置管理 | v1 |
| Secret | Secret | 敏感信息管理 | v1 |
| Ingress | Ingress | HTTP 路由规则 | networking.k8s.io/v1 |
| Job | Job | 一次性任务 | batch/v1 |
| CronJob | CronJob | 定时任务 | batch/v1 |
| Namespace | Namespace | 资源隔离 | v1 |
| PVC | PersistentVolumeClaim | 存储声明 | v1 |
Labels 和 Annotations
Labels(标签)
Labels 是附加到 Kubernetes 对象上的键值对,用于标识、组织和选择对象。
metadata:
labels:
app: my-app # 应用名称
version: v1.0 # 版本号
environment: prod # 环境标识
tier: backend # 层级标识标签的命名规范:
Annotations(注解)
Annotations 用于存储非标识性的元数据,不用于选择对象。
metadata:
annotations:
description: "This is a demo application"
contact: "team@example.com"
sidecar.istio.io/inject: "false"Selectors(选择器)
Selectors 用于根据标签筛选对象:
# 等值选择器
selector:
matchLabels:
app: demo
version: stable
# 集合选择器
selector:
matchExpressions:
- key: environment
operator: In # In、NotIn、Exists、DoesNotExist
values:
- prod
- stagingDeployment 详解
apiVersion: apps/v1 # API 版本
kind: Deployment # 资源类型
metadata: # 元数据
name: demo # 资源名称,同一 namespace 下唯一
namespace: default # 命名空间
labels: # 标签
app: demo
version: stable
spec: # 资源规格
replicas: 1 # 副本数
revisionHistoryLimit: 3 # 保留历史版本数
selector: # 选择器,必须匹配 template 中的 labels
matchLabels:
app: demo
version: stable
strategy: # 更新策略
rollingUpdate:
maxSurge: 30% # 最大额外副本数(百分比或整数)
maxUnavailable: 30% # 最大不可用副本数
type: RollingUpdate # 滚动更新
template: # Pod 模板
metadata:
annotations:
sidecar.istio.io/inject: "false"
labels:
app: demo
version: stable
spec:
containers:
- name: demo # 容器名称
image: demo:v1 # 镜像地址
imagePullPolicy: IfNotPresent # 镜像拉取策略:Always/Never/IfNotPresent
resources: # 资源限制
limits:
cpu: 300m # 1核心 = 1000m
memory: 500Mi # 1G = 1000Mi
requests:
cpu: 100m
memory: 100Mi
livenessProbe: # 存活探针
httpGet:
path: /healthCheck
port: 8080
scheme: HTTP
initialDelaySeconds: 30 # 容器启动后首次检测延迟
timeoutSeconds: 5 # 检测超时时间
periodSeconds: 30 # 检测间隔
successThreshold: 1 # 成功阈值
failureThreshold: 5 # 失败阈值,连续失败5次重启容器
readinessProbe: # 就绪探针
httpGet:
path: /healthCheck
port: 8080
initialDelaySeconds: 30
timeoutSeconds: 5
periodSeconds: 10
successThreshold: 1
failureThreshold: 5
ports:
- name: http
containerPort: 8080 # 容器端口
protocol: TCP
imagePullSecrets: # 镜像仓库密钥
- name: harbor-certification
affinity: # 亲和性调度
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: beta.kubernetes.io/arch
operator: In
values:
- amd64Service 详解
apiVersion: v1
kind: Service
metadata:
name: demo
namespace: default
labels:
app: demo
spec:
type: ClusterIP # 服务类型:ClusterIP/NodePort/LoadBalancer/ExternalName
ports:
- port: 8080 # Service 端口
targetPort: http # Pod 端口(可以是名称或数字)
protocol: TCP
name: http
nodePort: 31319 # NodePort 类型时对外暴露的端口(可选)
selector: # 选择匹配的 Pod
app: demoService 类型对比
| 类型 | 说明 | 访问范围 |
|---|---|---|
| ClusterIP | 集群内部 IP | 集群内部访问 |
| NodePort | 在节点上开放端口 | 集群外部通过节点 IP + 端口访问 |
| LoadBalancer | 云厂商负载均衡器 | 外部通过负载均衡器 IP 访问 |
| ExternalName | 映射到外部 DNS 名称 | 集群内部通过服务名访问外部服务 |
ConfigMap 详解
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: default
data:
# 简单键值对
database_host: "mysql-service"
database_port: "3306"
# 文件形式配置
appsettings.json: |
{
"Logging": {
"LogLevel": {
"Default": "Information"
}
},
"ConnectionStrings": {
"DefaultConnection": "Server=mysql-service;Database=mydb;User=root;Password=123456;"
}
}在 Deployment 中引用 ConfigMap:
spec:
containers:
- name: demo
envFrom: # 将整个 ConfigMap 作为环境变量
- configMapRef:
name: app-config
# 或者引用单个键值
env:
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: app-config
key: database_host
# 挂载为文件
volumeMounts:
- name: config-volume
mountPath: /app/appsettings.json
subPath: appsettings.json
volumes:
- name: config-volume
configMap:
name: app-configSecret 详解
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
data:
# 值需要 Base64 编码
username: cm9vdA== # echo -n 'root' | base64
password: MTIzNDU2 # echo -n '123456' | base64在 Deployment 中引用 Secret:
spec:
containers:
- name: demo
env:
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: db-secret
key: username
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: passwordIngress 详解
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
ingressClassName: nginx
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: demo
port:
number: 8080
- host: api.example.com
http:
paths:
- path: /v1
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80StatefulSet 详解
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mysql
spec:
serviceName: mysql # 关联的 Headless Service
replicas: 3
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:5.7
ports:
- containerPort: 3306
volumeMounts:
- name: mysql-data
mountPath: /var/lib/mysql
volumeClaimTemplates: # 存储卷模板
- metadata:
name: mysql-data
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 10GiJob 与 CronJob
一次性任务
apiVersion: batch/v1
kind: Job
metadata:
name: data-migration
spec:
completions: 1 # 需要成功完成的 Pod 数
parallelism: 1 # 并行运行的 Pod 数
backoffLimit: 3 # 最大重试次数
activeDeadlineSeconds: 300 # 任务超时时间
template:
spec:
containers:
- name: migration
image: myapp/migration:v1
command: ["python", "migrate.py"]
env:
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: app-config
key: database_host
restartPolicy: Never # 失败不重启容器,而是重新创建 Pod定时任务
apiVersion: batch/v1
kind: CronJob
metadata:
name: daily-report
spec:
schedule: "0 2 * * *" # 每天凌晨 2 点执行(Cron 格式)
concurrencyPolicy: Forbid # 禁止并发执行(上次没完成时不启动新的)
successfulJobsHistoryLimit: 3 # 保留 3 个成功记录
failedJobsHistoryLimit: 1 # 保留 1 个失败记录
jobTemplate:
spec:
template:
spec:
containers:
- name: report
image: myapp/report:v1
command: ["python", "generate_report.py"]
restartPolicy: OnFailureCron 表达式格式
┌───────────── 分钟 (0 - 59)
│ ┌───────────── 小时 (0 - 23)
│ │ ┌───────────── 日 (1 - 31)
│ │ │ ┌───────────── 月 (1 - 12)
│ │ │ │ ┌───────────── 星期 (0 - 6)
│ │ │ │ │
* * * * *
常用示例:
"*/5 * * * *" — 每 5 分钟
"0 */2 * * *" — 每 2 小时
"0 0 * * *" — 每天午夜
"0 0 * * 1" — 每周一午夜
"0 0 1 * *" — 每月 1 日午夜DaemonSet 详解
# DaemonSet — 在每个节点上运行一个 Pod
# 典型用途:日志采集、监控 Agent、网络插件
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: log-collector
labels:
app: log-collector
spec:
selector:
matchLabels:
app: log-collector
template:
metadata:
labels:
app: log-collector
spec:
tolerations:
- key: node-role.kubernetes.io/control-plane
effect: NoSchedule # 允许在控制面节点运行
containers:
- name: fluentd
image: fluentd:v1.16
resources:
limits:
cpu: 200m
memory: 200Mi
requests:
cpu: 100m
memory: 100Mi
volumeMounts:
- name: varlog
mountPath: /var/log
- name: containers
mountPath: /var/lib/docker/containers
readOnly: true
volumes:
- name: varlog
hostPath:
path: /var/log
- name: containers
hostPath:
path: /var/lib/docker/containers资源配额与限制
ResourceQuota — 命名空间级资源配额
apiVersion: v1
kind: ResourceQuota
metadata:
name: team-quota
namespace: team-dev
spec:
hard:
requests.cpu: "10" # CPU 总请求上限
requests.memory: 20Gi # 内存总请求上限
limits.cpu: "20" # CPU 总限制上限
limits.memory: 40Gi # 内存总限制上限
pods: "50" # 最大 Pod 数
services: "10" # 最大 Service 数
persistentvolumeclaims: "20" # 最大 PVC 数LimitRange — 默认资源限制
apiVersion: v1
kind: LimitRange
metadata:
name: default-limits
namespace: team-dev
spec:
limits:
- default: # 默认 limits(未指定时使用)
cpu: 500m
memory: 256Mi
defaultRequest: # 默认 requests
cpu: 100m
memory: 128Mi
max: # 最大允许值
cpu: "2"
memory: 2Gi
min: # 最小允许值
cpu: 50m
memory: 64Mi
type: Container常用 kubectl 命令
# 应用 YAML 配置
kubectl apply -f deployment.yaml
# 查看资源列表
kubectl get deployments
kubectl get pods
kubectl get services
# 查看资源详情
kubectl describe pod pod-name
# 删除资源
kubectl delete -f deployment.yaml
# 查看 Pod 日志
kubectl logs pod-name
# 编辑资源
kubectl edit deployment demo
# 导出 YAML 模板
kubectl create deployment demo --image=nginx --dry-run=client -o yaml > deployment.yaml优点
缺点
总结
YAML 是 K8S 的配置语言,掌握资源清单的 apiVersion、kind、metadata、spec 四大字段是基础。建议用 kubectl create 生成模板再修改。
关键知识点
- 部署类主题的核心不是“装成功”,而是“稳定运行、可排障、可回滚”。
- 同一个服务通常至少要关注版本、目录、端口、权限、数据、日志和备份。
- Linux 问题经常跨越系统层、网络层、服务层和应用层。
- Kubernetes 主题必须同时看资源对象、调度行为、网络暴露和配置分发。
项目落地视角
- 把安装步骤补成可重复执行的清单,必要时写成脚本或配置文件。
- 把配置目录、数据目录、日志目录和挂载点明确拆开。
- 上线前检查防火墙、SELinux、时区、磁盘、系统服务和健康检查。
- 上线前检查镜像、命名空间、探针、资源限制、Service/Ingress 和配置来源。
常见误区
- 使用 latest 或未固定版本,导致环境不可复现。
- 只验证启动成功,不验证持久化、开机自启和故障恢复。
- 遇到问题先改配置而不是先看日志和依赖链路。
- 只会 apply YAML,不理解对象之间的依赖关系。
进阶路线
- 继续补齐 systemd、性能监控、安全加固和备份恢复。
- 把单机操作升级成 Docker、Kubernetes 或 IaC 方案。
- 建立标准化运维手册,包括巡检、扩容、回滚和灾备演练。
- 继续补齐调度、网络策略、存储、GitOps 和平台工程能力。
适用场景
- 当你准备把《K8S 的 YAML 配置文件详解》真正落到项目里时,最适合先在一个独立模块或最小样例里验证关键路径。
- 适合单机环境初始化、中间件快速搭建、测试环境验证和生产部署前准备。
- 当服务稳定性依赖端口、权限、目录、网络和系统参数时,这类主题会直接影响成败。
落地建议
- 固定版本号与镜像标签,避免“latest”带来的不可预期变化。
- 把配置、数据、日志目录拆开管理,并记录恢复步骤。
- 上线前确认端口、防火墙、SELinux、时区和磁盘空间。
排错清单
- 先查 systemctl、容器日志和应用日志,确认失败发生在哪一层。
- 检查端口占用、目录权限、挂载路径和网络连通性。
- 如果是新环境问题,优先对比与已知正常环境的差异。
复盘问题
- 如果把《K8S 的 YAML 配置文件详解》放进你的当前项目,最先要验证的输入、输出和失败路径分别是什么?
- 《K8S 的 YAML 配置文件详解》最容易在什么规模、什么边界条件下暴露问题?你会用什么指标或日志去确认?
- 相比默认实现或替代方案,采用《K8S 的 YAML 配置文件详解》最大的收益和代价分别是什么?
