K8s高频YAML配置用法详解
对于 Kubernetes 用户来说,80% 的日常操作都围绕着 20% 的 YAML 配置。掌握这些高频配置的写法和含义,是玩转 K8s 的关键。
核心概念:必须理解的字段
在深入具体资源之前,有几个在所有资源中几乎都会出现的顶级字段:
apiVersion: 定义该资源所属的 API 组和版本。- 核心组(如 Pod、Service):
v1 - 有组名的(如 Deployment):
apps/v1,batch/v1(Job),networking.k8s.io/v1(Ingress) kind: 定义资源的类型,如Pod,Deployment,Service。metadata: 资源的元数据,最重要的两个子字段是:name: 资源名称,在命名空间内唯一。labels: 键值对标签,用于识别、选择和关联资源。spec: 期望的状态,这是你配置的核心,描述你希望资源达到什么样的状态。status: 当前观测到的状态,由 Kubernetes 系统自动填充和管理,你不需要配置它。
1. Pod
Pod 是 K8s 的最小部署单元,但通常不直接创建,而是通过 Deployment 来管理。
高频配置片段:
apiVersion: v1
kind: Pod
metadata:
name: my-app-pod
labels:
app: my-app
tier: frontend
spec:
containers:
- name: my-app-container
image: nginx:1.20 # 【必填】镜像地址
imagePullPolicy: IfNotPresent # 镜像拉取策略
ports:
- containerPort: 80 # 容器暴露的端口(纯说明性,不影响网络)
env:
- name: ENV_VAR_KEY # 设置环境变量
value: "value"
- name: CONFIG_KEY
valueFrom:
configMapKeyRef:
name: my-configmap
key: config-key
resources: # 【极其重要】资源限制
requests: # 请求的资源,调度依据
memory: "64Mi"
cpu: "250m"
limits: # 资源上限,超过会被限制或杀死
memory: "128Mi"
cpu: "500m"
volumeMounts: # 将卷挂载到容器内部
- name: app-storage
mountPath: "/usr/share/nginx/html"
volumes: # 定义存储卷
- name: app-storage
configMap: # 卷来源可以是 ConfigMap
name: my-nginx-config
关键说明:
imagePullPolicy:Always(总是拉取),IfNotPresent(本地不存在则拉取),Never(只用本地)。resources: 生产环境必须配置,防止单个 Pod 耗尽节点资源。env&volumes: 配置应用运行时的参数和文件,常与ConfigMap和Secret联动。
2. Deployment
用于部署无状态应用,管理 Pod 的副本集,提供滚动更新、回滚等功能。这是最常用、最重要的控制器。
高频配置片段:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app-deployment
labels:
app: my-app
spec:
replicas: 3 # 【核心】期望的 Pod 副本数量
selector: # 【核心】选择器,决定管理哪些 Pod
matchLabels:
app: my-app
template: # 【核心】Pod 模板,用于创建新的 Pod
metadata:
labels:
app: my-app # 必须与上面的 selector.matchLabels 匹配
spec:
containers:
- name: nginx
image: nginx:1.20
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
strategy: # 更新策略
type: RollingUpdate
rollingUpdate:
maxSurge: 1 # 更新过程中可以超出 replicas 的 Pod 数量
maxUnavailable: 1 # 更新过程中不可用的 Pod 数量
关键说明:
replicas: 直接控制应用实例数,可通过kubectl scale deployment/my-app-deployment --replicas=5快速调整。selector和template.metadata.labels: 必须匹配,否则 Deployment 无法找到它管理的 Pod,导致创建失败。strategy:RollingUpdate是实现零停机部署的关键。
3. Service
定义一组 Pod 的访问策略,作为服务的稳定入口(固定 IP/DNS)。
高频配置片段:
apiVersion: v1
kind: Service
metadata:
name: my-app-service
spec:
selector: # 【核心】选择器,决定将流量转发给哪些 Pod
app: my-app
ports:
- name: http
port: 80 # Service 自身暴露的端口
targetPort: 80 # Pod(容器)的端口
nodePort: 30007 # (仅 NodePort 类型使用)节点上映射的端口
type: ClusterIP # Service 类型
关键说明:
selector: 通过标签与后端 Pod 关联。type:ClusterIP(默认):集群内部访问。NodePort: 在集群每个节点上开放一个端口(nodePort),可以从集群外部访问。LoadBalancer: 使用云服务商的负载均衡器,是暴露服务到外部的标准方式。ExternalName: 将服务映射到外部 DNS 名称。
4. ConfigMap & Secret
用于将配置数据和敏感信息与 Pod 解耦。
ConfigMap 示例(存储非敏感配置):
apiVersion: v1
kind: ConfigMap
metadata:
name: my-app-config
data: # 键值对数据
app.properties: |
color=blue
log.level=info
database.url: "jdbc:mysql://db-host:3306/myapp"
在 Pod 中引用 ConfigMap:
# ... Pod spec ...
spec:
containers:
- name: my-app
image: my-app
env:
- name: DATABASE_URL
valueFrom:
configMapKeyRef:
name: my-app-config
key: database.url
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: my-app-config
Secret 示例(存储敏感数据,如密码、令牌):
用法与 ConfigMap 几乎完全相同,但类型是 Secret,且 data 字段中的值必须是 base64 编码 的字符串。stringData 字段可存放明文字符串,API 服务器会自动将其编码。
# ... Pod spec ...
spec:
containers:
- name: my-app
image: my-app
env:
- name: DATABASE_URL
valueFrom:
configMapKeyRef:
name: my-app-config
key: database.url
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: my-app-config
5. Ingress
管理集群外部访问内部服务的 HTTP/HTTPS 路由规则,是更高级的 7 层负载均衡器。
高频配置片段:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app-ingress
annotations:
kubernetes.io/ingress.class: "nginx" # 【重要】指定 Ingress 控制器
spec:
rules:
- host: myapp.example.com # 域名
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app-service # 转发到的 Service
port:
number: 80 # Service 的端口
tls: # TLS 配置,用于 HTTPS
- hosts:
- myapp.example.com
secretName: my-tls-secret # 存储证书的 Secret
关键说明:
- 需要先安装 Ingress 控制器(如 Nginx Ingress Controller, Traefik)。
annotations用于指定或配置控制器。 rules: 定义路由规则,根据不同的host和path将流量导向不同的后端service。tls: 用于配置 HTTPS,证书需要提前存放到secret中。
6. PersistentVolumeClaim (PVC)
为 Pod 申请持久化存储,而不需要关心后端存储的具体细节(如 NFS, Cloud Disk 等)。
高频配置片段:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-app-pvc
spec:
accessModes: # 访问模式
- ReadWriteOnce # 可被单个节点以读写模式挂载
resources:
requests:
storage: 10Gi # 申请的存储空间大小
# storageClassName: "fast-ssd" # 指定存储类,动态供给时使用
在 Pod 中挂载 PVC:
# ... Pod spec ...
spec:
containers:
- name: my-app
image: my-app
volumeMounts:
- name: data-storage
mountPath: /data
volumes:
- name: data-storage
persistentVolumeClaim:
claimName: my-app-pvc # 使用上面创建的 PVC
关键说明:
accessModes:ReadWriteOnce(RWO):单节点读写。ReadOnlyMany(ROX):多节点只读。ReadWriteMany(RWX):多节点读写。storageClassName: 如果留空,则使用默认的 StorageClass,由集群管理员配置。
总结与最佳实践
- 多用 Deployment,少用裸 Pod:保证应用的自愈和弹性伸缩。
- 始终定义资源请求和限制 (resources):这是集群稳定性的基石。
- 使用标签 (labels) 进行关联:Service、Deployment 都通过标签选择器与 Pod 关联。
- 配置与镜像分离:使用 ConfigMap 和 Secret 管理配置,避免将配置硬编码到镜像中。
- 通过 Service 访问 Pod:不要直接通过 Pod IP 访问,因为 Pod 是临时的。
- Ingress 作为 HTTP 流量入口:代替大量使用
NodePort类型的 Service。 - PVC 用于有状态应用的数据持久化:实现存储与计算分离。
掌握以上这些 YAML 配置,你就能应对绝大多数 Kubernetes 的日常应用部署和管理场景。在实际操作中,可以使用 kubectl explain <resource>.<field> 命令来查询某个字段的详细说明,这是非常有用的学习工具。