Kubernetes 的 YAML:核心清单模式
Kubernetes 完全通过 YAML 清单进行配置。每个 Pod、Deployment、Service 和 Ingress 都在 YAML 中定义。掌握这些模式对于使用容器编排的每个人来说都至关重要。本指南通过生产就绪的示例介绍最重要的资源类型。
四个必需字段
每个 Kubernetes 清单都需要:
apiVersion: apps/v1 # 此资源类型的 API 版本
kind: Deployment # 资源类型
metadata: # 资源标识
name: my-app
namespace: production
labels:
app: my-app
spec: # 期望状态规范
# ... 资源特定配置
Deployment
最常见的资源——管理一组相同的 Pod:
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-server
labels:
app: api-server
environment: production
spec:
replicas: 3
selector:
matchLabels:
app: api-server
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: api-server
spec:
containers:
- name: api
image: myapp/api:v1.2.3
ports:
- containerPort: 8080
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: db-credentials
key: url
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 15
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
关键模式
始终设置资源请求和限制:没有它们,单个 Pod 可能会消耗所有节点资源。
始终配置健康探针:
livenessProbe:如果 Pod 无响应则重启readinessProbe:在 Pod 就绪之前停止发送流量
使用特定的镜像标签:生产环境中永远不要使用 latest——它会使回滚变得不可能。
Service
将 Pod 暴露给网络流量:
apiVersion: v1
kind: Service
metadata:
name: api-server
spec:
type: ClusterIP
selector:
app: api-server
ports:
- port: 80
targetPort: 8080
protocol: TCP
Service 类型:
- ClusterIP(默认):仅限集群内部访问
- NodePort:在每个节点 IP 的静态端口上暴露
- LoadBalancer:配置云负载均衡器
- ExternalName:映射到 DNS 名称
ConfigMap 和 Secret
ConfigMap(非敏感数据)
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
LOG_LEVEL: "info"
MAX_CONNECTIONS: "100"
config.yaml: |
server:
port: 8080
timeout: 30s
Secret(敏感数据)
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
type: Opaque
stringData:
url: "postgres://user:password@db:5432/myapp"
api-key: "sk-1234567890"
在 Pod 中使用
# 作为环境变量
env:
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: app-config
key: LOG_LEVEL
# 作为挂载文件
volumes:
- name: config
configMap:
name: app-config
Ingress
将外部 HTTP 流量路由到 Service:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-ingress
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- api.example.com
secretName: tls-secret
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-server
port:
number: 80
Horizontal Pod Autoscaler
根据 CPU 或自定义指标自动扩缩 Pod:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-server-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-server
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
常见错误
1. 缩进错误
YAML 缩进在 Kubernetes 中至关重要。一个多余的空格会完全改变结构。使用我们的 YAML 验证器 验证您的清单。
2. 标签不匹配
Service 选择器必须与 Pod 标签完全匹配。不匹配意味着 Service 找不到任何 Pod 来路由流量。
3. 缺少资源限制
没有资源限制的 Pod 会导致其他工作负载资源不足。始终包含请求(保证最小值)和限制(允许最大值)。
4. 可变的镜像标签
使用 latest 或其他可变标签会使回滚变得不可能,部署也变得不可预测。请固定到特定版本或使用不可变的摘要。
多文档清单
使用 --- 作为文档分隔符,在一个文件中组合相关资源:
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-server
spec:
# ... deployment spec
---
apiVersion: v1
kind: Service
metadata:
name: api-server
spec:
# ... service spec
了解更多 YAML 语法模式,请参阅我们的 YAML 语法教程。
常见问题
应该手写 Kubernetes YAML 还是使用生成器?
建议先手写 YAML 以理解其结构。在生产环境中,使用 Helm(模板化清单)、Kustomize(基于覆盖的自定义)或 CDK8s(基于代码的生成)等工具。这些工具减少重复,并能在不复制清单的情况下实现环境特定的配置。
如何调试 Kubernetes YAML 错误?
使用 kubectl apply --dry-run=client -f manifest.yaml 进行验证而不实际应用。对于语法错误,kubectl explain deployment.spec.template.spec.containers 可以显示预期的结构。kubeval 和 kubeconform 工具可以在部署前根据 Kubernetes API 模式进行验证。
相关资源
- YAML 验证器 — 验证 Kubernetes 清单
- Docker Compose 的 YAML — Docker YAML 模式
- YAML 代码检查最佳实践 — 在部署前发现错误