K8s高频YAML配置用法详解


K8s高频YAML配置用法详解

对于 Kubernetes 用户来说,80% 的日常操作都围绕着 20% 的 YAML 配置。掌握这些高频配置的写法和含义,是玩转 K8s 的关键。

核心概念:必须理解的字段

在深入具体资源之前,有几个在所有资源中几乎都会出现的顶级字段:

  • apiVersion: 定义该资源所属的 API 组和版本。
  • 核心组(如 Pod、Service):v1
  • 有组名的(如 Deployment):apps/v1batch/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: 配置应用运行时的参数和文件,常与 ConfigMapSecret 联动。

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 快速调整。
  • selectortemplate.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: 定义路由规则,根据不同的 hostpath 将流量导向不同的后端 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,由集群管理员配置。

总结与最佳实践

  1. 多用 Deployment,少用裸 Pod:保证应用的自愈和弹性伸缩。
  2. 始终定义资源请求和限制 (resources):这是集群稳定性的基石。
  3. 使用标签 (labels) 进行关联:Service、Deployment 都通过标签选择器与 Pod 关联。
  4. 配置与镜像分离:使用 ConfigMap 和 Secret 管理配置,避免将配置硬编码到镜像中。
  5. 通过 Service 访问 Pod:不要直接通过 Pod IP 访问,因为 Pod 是临时的。
  6. Ingress 作为 HTTP 流量入口:代替大量使用 NodePort 类型的 Service。
  7. PVC 用于有状态应用的数据持久化:实现存储与计算分离。

掌握以上这些 YAML 配置,你就能应对绝大多数 Kubernetes 的日常应用部署和管理场景。在实际操作中,可以使用 kubectl explain <resource>.<field> 命令来查询某个字段的详细说明,这是非常有用的学习工具。