YAML 在 Kubernetes 中扮演着核心角色,是声明式配置的主要格式。理解 YAML 在 Kubernetes 中的应用对于容器编排和云原生开发至关重要。
Kubernetes YAML 的基本结构
标准的 Kubernetes 资源 YAML 结构
yamlapiVersion: apps/v1 # API 版本 kind: Deployment # 资源类型 metadata: # 元数据 name: nginx-deployment namespace: default labels: app: nginx spec: # 规格说明 replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.21 ports: - containerPort: 80
核心 YAML 字段详解
1. apiVersion
指定 Kubernetes API 的版本,不同的资源类型可能使用不同的 API 版本。
yaml# 常见的 API 版本 apiVersion: v1 # 核心资源(Pod, Service, ConfigMap) apiVersion: apps/v1 # 应用资源(Deployment, StatefulSet, DaemonSet) apiVersion: networking.k8s.io/v1 # 网络资源(Ingress, NetworkPolicy) apiVersion: batch/v1 # 批处理资源(Job, CronJob) apiVersion: rbac.authorization.k8s.io/v1 # RBAC 资源
2. kind
指定要创建的 Kubernetes 资源类型。
yaml# 常见的资源类型 kind: Pod kind: Service kind: Deployment kind: StatefulSet kind: DaemonSet kind: ConfigMap kind: Secret kind: Ingress kind: PersistentVolume kind: PersistentVolumeClaim
3. metadata
包含资源的元数据,如名称、命名空间、标签、注解等。
yamlmetadata: name: my-app # 资源名称(必填) namespace: production # 命名空间(默认为 default) labels: # 标签(用于选择器和组织) app: my-app version: v1.0 environment: production annotations: # 注解(用于存储元数据) description: "Main application" contact: "team@example.com"
4. spec
定义资源的期望状态,这是最复杂的部分,内容因资源类型而异。
常见 Kubernetes 资源的 YAML 示例
Pod
yamlapiVersion: v1 kind: Pod metadata: name: nginx-pod labels: app: nginx spec: containers: - name: nginx image: nginx:1.21 ports: - containerPort: 80 resources: requests: memory: "64Mi" cpu: "250m" limits: memory: "128Mi" cpu: "500m" env: - name: ENVIRONMENT value: "production" volumeMounts: - name: config-volume mountPath: /etc/config volumes: - name: config-volume configMap: name: nginx-config
Deployment
yamlapiVersion: apps/v1 kind: Deployment metadata: name: web-app labels: app: web-app spec: replicas: 3 strategy: type: RollingUpdate rollingUpdate: maxSurge: 1 maxUnavailable: 0 selector: matchLabels: app: web-app template: metadata: labels: app: web-app spec: containers: - name: web-app image: myapp:1.0 ports: - containerPort: 8080 livenessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 30 periodSeconds: 10 readinessProbe: httpGet: path: /ready port: 8080 initialDelaySeconds: 5 periodSeconds: 5
Service
yamlapiVersion: v1 kind: Service metadata: name: web-service spec: type: ClusterIP # ClusterIP, NodePort, LoadBalancer, ExternalName selector: app: web-app ports: - protocol: TCP port: 80 # Service 端口 targetPort: 8080 # 目标 Pod 端口 name: http - protocol: TCP port: 443 targetPort: 8443 name: https
ConfigMap
yamlapiVersion: v1 kind: ConfigMap metadata: name: app-config data: # 键值对形式 database.url: "postgresql://db.example.com:5432/myapp" cache.ttl: "3600" # 文件形式 nginx.conf: | server { listen 80; server_name localhost; location / { proxy_pass http://backend:8080; } }
Secret
yamlapiVersion: v1 kind: Secret metadata: name: app-secret type: Opaque data: # Base64 编码的值 username: YWRtaW4= password: cGFzc3dvcmQ= stringData: # 明文值(自动编码) api-key: "your-api-key-here"
高级 YAML 特性在 Kubernetes 中的应用
1. 多文档 YAML
使用 --- 分隔符在一个文件中定义多个资源。
yaml--- apiVersion: v1 kind: ConfigMap metadata: name: app-config data: config.yaml: | key: value --- apiVersion: apps/v1 kind: Deployment metadata: name: app-deployment spec: replicas: 2 selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: containers: - name: app image: myapp:latest
2. 使用 ConfigMap 和 Secret
yamlapiVersion: v1 kind: Pod metadata: name: config-demo spec: containers: - name: app image: myapp:latest env: # 从 ConfigMap 读取环境变量 - name: DATABASE_URL valueFrom: configMapKeyRef: name: app-config key: database.url # 从 Secret 读取环境变量 - name: API_KEY valueFrom: secretKeyRef: name: app-secret key: api-key # 挂载 ConfigMap 作为文件 volumeMounts: - name: config-volume mountPath: /etc/config volumes: - name: config-volume configMap: name: app-config
3. 资源限制和请求
yamlapiVersion: v1 kind: Pod metadata: name: resource-limits spec: containers: - name: app image: myapp:latest resources: requests: memory: "256Mi" cpu: "500m" limits: memory: "512Mi" cpu: "1000m"
4. 健康检查
yamlapiVersion: v1 kind: Pod metadata: name: health-check spec: containers: - name: app image: myapp:latest livenessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 5 failureThreshold: 3 readinessProbe: httpGet: path: /ready port: 8080 initialDelaySeconds: 5 periodSeconds: 5 timeoutSeconds: 3 failureThreshold: 3
YAML 最佳实践
1. 使用命名空间组织资源
yamlapiVersion: v1 kind: Namespace metadata: name: production --- apiVersion: apps/v1 kind: Deployment metadata: name: app namespace: production spec: # ...
2. 使用标签和选择器
yamlmetadata: labels: app: myapp version: v1.0 environment: production tier: backend spec: selector: matchLabels: app: myapp environment: production
3. 使用注解存储元数据
yamlmetadata: annotations: description: "Main application deployment" contact: "team@example.com" git-commit: "abc123" deployment-date: "2024-01-01"
4. 使用资源限制
yamlresources: requests: memory: "256Mi" cpu: "500m" limits: memory: "512Mi" cpu: "1000m"
常见错误和解决方案
1. 缩进错误
yaml# ❌ 错误:缩进不一致 spec: containers: - name: app image: myapp:latest ports: - containerPort: 8080 - containerPort: 8443 # 缩进不一致 # ✅ 正确:一致的缩进 spec: containers: - name: app image: myapp:latest ports: - containerPort: 8080 - containerPort: 8443
2. 类型错误
yaml# ❌ 错误:端口应该是数字 ports: - containerPort: "8080" # 字符串 # ✅ 正确:使用数字 ports: - containerPort: 8080
3. 必填字段缺失
yaml# ❌ 错误:缺少 selector apiVersion: apps/v1 kind: Deployment metadata: name: app spec: replicas: 3 # 缺少 selector # ✅ 正确:包含 selector apiVersion: apps/v1 kind: Deployment metadata: name: app spec: replicas: 3 selector: matchLabels: app: myapp
工具和验证
kubectl 验证
bash# 验证 YAML 语法 kubectl apply --dry-run=client -f deployment.yaml # 验证并查看生成的资源 kubectl apply --dry-run=server -f deployment.yaml # 查看差异 kubectl diff -f deployment.yaml
YAML Linter
bash# 使用 yamllint yamllint deployment.yaml # 使用 kubeval kubeval deployment.yaml
掌握 Kubernetes YAML 的使用对于云原生应用开发至关重要,它提供了声明式配置的强大能力。