首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >闯进 Kubernetes 的世界(六)

闯进 Kubernetes 的世界(六)

作者头像
JanYork_简昀
发布于 2025-06-15 03:57:11
发布于 2025-06-15 03:57:11
18100
代码可运行
举报
运行总次数:0
代码可运行

第六章:K8s YAML 配置深度解析:核心属性与通用结构

在之前的章节中,我们已经通过 YAML 文件部署了应用程序。

你可能已经注意到,这些 YAML 文件虽然看起来相似,但各自的字段和结构都有其特定的含义。本章将带你深入探索 Kubernetes YAML 配置文件的奥秘。

我们将不再仅仅是复制代码,而是逐行解析你已经使用过的 K8s 资源(如 Pod、Deployment、StatefulSet、Service、ConfigMap、Secret、PVC)的 YAML 结构,详细解释每个核心属性的含义、作用以及它们如何协同工作,让你真正理解“声明式”管理的精髓。

通过本章的学习,你将能够:

  • 掌握 K8s YAML 配置文件的通用骨架和核心元数据。
  • 理解 Pod 生命周期、容器配置、资源管理等相关属性。
  • 深入解析 Deployment 和 StatefulSet 如何通过 Pod 模板管理应用程序副本。
  • 掌握 Service 的各种网络暴露方式和端口映射规则。
  • 理解 ConfigMap 和 Secret 如何存储和注入配置/敏感数据。
  • 解析 PVC 如何声明和管理持久化存储。
6.1 K8s YAML 配置文件的通用结构

所有 Kubernetes 资源的 YAML 文件都遵循一个通用的顶级结构。理解这四个顶级字段是解析任何 K8s YAML 的起点。

apiVersion (API 版本)

  • 含义: 指定你正在使用的 Kubernetes API 版本。K8s 的 API 是分版本的,以支持功能的演进和兼容性。
  • 格式: 通常是 group/version 的形式(例如 apps/v1)。对于属于 core API 组的核心对象(如 Pod, Service, ConfigMap, Secret, PVC, Namespace 等),其组名被省略,直接写作 v1
  • 作用: 告诉 K8s API Server 如何解析这个 YAML 文件。不同的 apiVersion 可能对应不同的字段或行为。
  • 示例:
    • v1:用于 Pod, Service, ConfigMap, Secret, PVC, Namespace 等核心对象。
    • apps/v1:用于 Deployment, StatefulSet, DaemonSet, ReplicaSet 等控制器。
    • networking.k8s.io/v1:用于 Ingress 等网络相关对象。

kind (对象类型)

  • 含义: 明确指定你正在定义或操作的 Kubernetes 资源的类型。
  • 格式: 一个字符串,对应 K8s API 中定义的资源类型名称。
  • 作用: K8s API Server 会根据 kind 字段来调用对应的控制器处理这个对象。
  • 示例:Pod, Deployment, Service, StatefulSet, ConfigMap, Secret, PersistentVolumeClaim

metadata (元数据)

  • 含义: 描述该 Kubernetes 对象的元信息,例如名称、标签、注解等。几乎所有 K8s 对象都包含 metadata 字段。
  • 作用: 提供对象的身份标识、组织管理和额外信息。
  • 常见属性:
    • 含义: 一组键值对,用于存储非识别性元数据。它们不用于 K8s 对象的选择或调度。
    • 作用: 存储工具信息、部署描述、构建版本信息等,不会影响 K8s 核心行为。
    • 示例:kubernetes.io/change-cause: "Upgraded app to v2.0", checksum/config: "abcdef123"
    • 含义: 一组键值对,用于标识和组织 Kubernetes 对象。
    • 作用:
    • 示例:app: redis-cluster, env: production, tier: frontend
    • 选择器 (Selectors): K8s 控制器(如 Deployment)和 Service 通过标签选择器来识别和管理它们所属的 Pod。
    • 组织和查询: 方便用户通过标签过滤和查询资源,例如 kubectl get pods -l app=redis-cluster
    • 含义: 对象所属的命名空间。命名空间用于在集群内对资源进行逻辑隔离。
    • 默认值: 如果不指定,默认为 default 命名空间。
    • 作用: 资源隔离,权限管理。
    • 示例:default, kube-system, my-app-ns
    • 含义: 对象的唯一名称。在同一个命名空间(namespace)内,同类型对象的 name 必须是唯一的。
    • 约束: 必须符合 DNS 子域名规范(长度不超过 253 个字符,只能包含小写字母、数字、连字符),且不能以连字符开头或结尾。
    • 作用: 用于引用该对象,如 kubectl get <kind> <name>。
    • 示例:redis-cluster-config, postgres-deployment
    • name:
    • namespace:
    • labels:
    • annotations:
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: <API版本>
kind:<对象类型>
metadata:
name:<对象名称>
namespace:<命名空间,可选>
labels:
    <>:<>
annotations:
    <>:<>
spec:
# 此处是该对象类型特有的配置,定义期望状态
# 例如,Deployment 会有 replicas, selector, template 等
# Pod 会有 containers, volumes 等
# Service 会有 ports, selector, type 等
status:
# 此处是 K8s 自动填充的实际状态,不需手动配置

spec (规范/期望状态)

  • 含义: 定义了你希望 Kubernetes 实现的该资源的期望状态。这部分是每个 kind 特有的,并且包含了该资源的大部分配置细节。
  • 作用: 你告诉 K8s “我想要什么”,而不是“怎么做”。K8s 控制器会不断地将集群的实际状态与 spec 中定义的期望状态进行比对,并采取行动使其达到一致。
  • 示例:Deploymentspec 包含 replicastemplateServicespec 包含 portsselectorPodspec 包含 containersvolumes 等。

status (实际状态)

  • 含义: 描述了资源的当前实际状态。这个字段由 Kubernetes API Server 自动填充和更新,你通常不会在 YAML 文件中定义它
  • 作用: 提供了 K8s 内部对资源的实时监控和反馈,如 Pod 的运行状态、Service 分配的 IP、Deployment 的就绪副本数等。
  • 示例: 通过 kubectl describe 命令可以看到 status 字段的详细内容。
6.2 Pod YAML 属性深度解析

Pod 是 Kubernetes 中最小的可部署和可调度的计算单元。理解 Pod 的 YAML 配置是理解其他控制器(如 Deployment, StatefulSet)的基础,因为它们都包含一个 Pod 模板。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: v1
kind:Pod
metadata:
name:my-app-pod
labels:
    app:my-app
spec:
containers:# 容器列表
-name:my-app-container
    image:my-app:v1.0
    imagePullPolicy:IfNotPresent# 镜像拉取策略
    ports:
    -containerPort:8080
      name:http-port
     # hostPort: 8080 # (可选) 将容器端口映射到宿主机端口,不推荐在生产环境使用
    env:# 环境变量
    -name:ENV_VAR_NAME
      value:"env_var_value"
    -name:DB_PASSWORD
      valueFrom:# 值来源于其他 K8s 资源
        secretKeyRef:# 从 Secret 中获取
          name:my-secret
          key:password
    volumeMounts:# 卷挂载点
    -name:my-data-volume
      mountPath:/app/data
      readOnly:false
    resources:# 资源请求与限制
      requests:# 资源请求,用于调度
        memory:"64Mi"
        cpu:"250m"# 0.25limits:# 资源限制,防止过度使用
        memory:"128Mi"
        cpu:"500m"# 0.5livenessProbe:# 活性探针,判断容器是否活着
      httpGet:
        path:/healthz
        port:8080
      initialDelaySeconds:5
      periodSeconds:5
    readinessProbe:# 就绪探针,判断容器是否准备好接收流量
      httpGet:
        path:/ready
        port:8080
      initialDelaySeconds:5
      periodSeconds:5
volumes:# Pod 可用的卷定义
-name:my-data-volume
    persistentVolumeClaim:# 使用 PVC
      claimName:my-pvc
-name:my-config-volume
    configMap:# 使用 ConfigMap
      name:my-app-config
nodeSelector:# 节点选择器
    disktype:ssd
tolerations:# 容忍度,允许 Pod 调度到有污点(Taints)的节点
   -key:"app"
     operator:"Exists"# 匹配存在 app 这个 key 的所有污点
     effect:"NoSchedule"
   -key:"hardware"
     operator:"Equal"# 匹配 key 为 hardware 且 value 为 gpu 的污点
     value:"gpu"
     effect:"NoExecute"
restartPolicy:Always# Pod 重启策略

spec.containers (容器列表)

  • 含义: 定义 Pod 中要运行的所有容器。一个 Pod 可以包含一个或多个紧密耦合的容器。
  • name: 容器的名称,在 Pod 内部必须是唯一的。
  • image: 容器使用的镜像名称(例如 nginx:latest, my-app:v1.0)。
  • imagePullPolicy:
    • IfNotPresent (默认值): 如果本地已存在该镜像,则不拉取;否则拉取。
    • Always: 每次启动 Pod 时都尝试拉取最新镜像。
    • Never: 永不拉取镜像,只使用本地已存在的镜像。
    • 含义: 控制 K8s 何时尝试拉取容器镜像。
    • 值:
    • 作用: 影响部署速度和镜像更新行为。
  • ports:
    • 含义: 声明容器内部应用程序监听的端口。这仅仅是一个信息性声明,容器的端口默认是不对外暴露的。Service 会利用这个信息来配置转发规则。
    • containerPort: 容器内部应用程序监听的实际端口号。
    • name: 端口的名称,方便在 Service 中引用。
    • hostPort: (可选) 直接将容器的端口映射到 Node 上的对应端口。不推荐在生产环境中使用,因为它可能导致端口冲突并限制 Pod 的调度。
  • env (环境变量):
    • 含义: 允许环境变量的值从其他 K8s 资源中动态获取,而非硬编码。
    • configMapKeyRef: 从 ConfigMap 中获取某个键的值。
    • secretKeyRef: 从 Secret 中获取某个键的值(常用于密码)。
    • fieldRef: 获取 Pod 自身的某个字段值,如 metadata.name (Pod 名称)、status.podIP (Pod IP)。
    • resourceFieldRef: 获取容器的资源请求或限制值,如 limits.cpu
    • name: ConfigMap 的名称。
    • key: ConfigMap 中键的名称。
    • name: Secret 的名称。
    • key: Secret 中键的名称。
    • 含义: 向容器内部注入环境变量。
    • name 环境变量的名称。
    • value 环境变量的静态值。
    • valueFrom:
  • volumeMounts (卷挂载点):
    • 含义: 定义 Pod 内部卷(spec.volumes 中定义)在容器文件系统中的挂载位置。
    • name 必须与 spec.volumes 中定义的卷的 name 匹配。
    • mountPath 卷在容器内部的绝对路径。
    • readOnly (可选) 如果为 true,则卷以只读模式挂载。
  • resources (资源请求与限制):
    • cpu: CPU 使用的上限。如果容器尝试使用超过限制的 CPU,可能会被 K8s 限制或扼流。
    • memory: 内存使用的上限。如果容器尝试使用超过限制的内存,K8s 可能会终止该容器(OOMKilled),并可能触发 Pod 重启。
    • cpu: CPU 请求量,单位是 millicores (毫核,1 核 = 1000m)。例如 250m 表示 0.25 个 CPU 核。
    • memory: 内存请求量,单位是字节(例如 Mi - 兆字节,Gi - 吉字节)。例如 64Mi
    • 含义: 定义容器对计算资源(CPU 和内存)的需求和限制。
    • requests (请求): 容器启动所需的最小资源量。K8s 调度器会根据这些请求将 Pod 放置到有足够资源的 Node 上。
    • limits (限制): 容器可以使用的最大资源量。
    • 作用: 确保集群资源高效利用和 Pod 稳定运行,防止一个 Pod 耗尽 Node 所有资源。
  • livenessProbe (活性探针):
    • httpGet: 发送 HTTP GET 请求。
    • tcpSocket: 尝试建立 TCP 连接。
    • exec: 在容器内执行命令。
    • 含义: 用于判断容器是否“活着”,即应用程序是否还在运行。如果探针失败,K8s 会终止并重启该容器。
    • 类型:
    • initialDelaySeconds 容器启动后首次执行探针的延迟时间。
    • periodSeconds 探针执行的频率。
    • 作用: 提高应用程序的弹性,自动恢复故障容器。
  • readinessProbe (就绪探针):
    • 含义: 用于判断容器是否“准备好”接收请求。如果探针失败,K8s 会将该 Pod 从 Service 的 Endpoints 列表中移除,不再向其发送流量,但 Pod 本身不会被重启。
    • 类型、参数同 livenessProbe
    • 作用: 确保流量只发送给完全就绪的 Pod,避免请求发送到尚未完全启动或正在维护的实例。

spec.volumes (卷定义)

  • 含义: 定义 Pod 内部可用的存储卷。这些卷可以被 Pod 中的一个或多个容器挂载(通过 volumeMounts)。
  • name 卷的名称,用于在 volumeMounts 中引用。
  • 类型:
    • 含义:Secret 中的数据作为文件挂载到 Pod 内部。
    • secretName 要引用的 Secret 的名称。
    • 作用: 安全地将敏感数据(如证书、密钥)注入为文件。
    • 含义:ConfigMap 中的数据作为文件挂载到 Pod 内部。
    • name 要引用的 ConfigMap 的名称。
    • 作用: 方便地将配置注入为文件。
    • 含义: 引用一个已经存在的 PersistentVolumeClaim,实现持久化存储。
    • claimName 要引用的 PVC 的名称。
    • 作用: 将持久化数据存储在 Pod 外部,保证数据不随 Pod 的生命周期而丢失。
    • persistentVolumeClaim:
    • configMap:
    • secret:
    • emptyDir: 临时目录,随 Pod 生命周期而存在,Pod 删除时数据丢失。
    • hostPath: 将 Node 上的文件或目录挂载到 Pod 中(不推荐生产环境使用,除非特殊需要)。

spec.nodeSelector (节点选择器)

  • 含义: 一组键值对,用于将 Pod 调度到带有特定标签的 Node 上。
  • 作用: 强制将 Pod 运行在满足特定条件的 Node 上,例如具有特定硬件(GPU)、特定区域或特定磁盘类型的 Node。
  • 示例:disktype: ssd 会将 Pod 调度到带有 disktype=ssd 标签的 Node。

spec.tolerations (容忍度)

  • 含义: 用于允许 Pod 调度到具有污点 (Taints) 的节点上。Node 的污点可以排斥没有相应容忍度的 Pod。
  • 作用: 与 Node 的污点 (Taints) 配合使用,实现 Node 专用化(例如,只允许某些特定应用运行在某些 Node 上),或者驱逐不符合要求的 Pod。
  • 示例: 如果 Node 有污点 key=value:NoSchedule,Pod 需要有对应的 toleration 才能被调度到该 Node。

spec.restartPolicy (重启策略)

  • 含义: 定义 Pod 中所有容器的重启策略。
  • 值:
    • Always (默认值): 容器终止后总是重启。通常用于长期运行的服务(Deployment)。
    • OnFailure: 只有当容器以非零退出码(表示失败)终止时才重启。
    • Never: 容器终止后永不重启。通常用于一次性任务(Job)。
  • 作用: 控制 Pod 中容器的故障恢复行为。
6.3 Deployment/StatefulSet YAML 属性深度解析

DeploymentStatefulSet 是 Kubernetes 中最常用的两种工作负载控制器,它们负责管理 Pod 的生命周期,确保运行指定数量的 Pod 副本。虽然它们都是管理 Pod 的,但由于其设计目标不同,在 YAML 配置上也有一些关键区别。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# Deployment 示例 YAML
apiVersion:apps/v1
kind:Deployment
metadata:
name:my-app-deployment
labels:
    app:my-app
spec:
replicas:3# 期望的 Pod 副本数量
selector:# Pod 选择器,识别 Deployment 管理的 Pod
    matchLabels:
      app:my-app
template:# Pod 模板,用于创建新的 Pod
    metadata:
      labels:
        app:my-app
    spec:
      containers:
      -name:my-app-container
        image:my-app:v1.0
strategy:# 更新策略
    type:RollingUpdate# 滚动更新
    rollingUpdate:
      maxUnavailable:25%# 更新时允许不可用的 Pod 数量
      maxSurge:25%       # 更新时允许超出期望数量的 Pod 数量
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
# StatefulSet 示例 YAML
apiVersion:apps/v1
kind:StatefulSet
metadata:
name:my-stateful-app
labels:
    app:my-stateful-app
spec:
serviceName:my-stateful-app-headless# 关联的 Headless Service 名称
replicas:3# 期望的 Pod 副本数量
selector:# Pod 选择器,识别 StatefulSet 管理的 Pod
    matchLabels:
      app:my-stateful-app
template:# Pod 模板,用于创建新的 Pod
    metadata:
      labels:
        app:my-stateful-app
    spec:
      containers:
      -name:my-stateful-app-container
        image:my-stateful-app:v1.0
        volumeMounts:
        -name:my-data-volume
          mountPath:/data
volumeClaimTemplates:# 卷声明模板,为每个 Pod 自动创建 PVC
-metadata:
      name:my-data-volume
    spec:
      accessModes:["ReadWriteOnce"]
      resources:
        requests:
          storage:1Gi

spec.replicas (副本数量)

  • 含义: 定义控制器(Deployment 或 StatefulSet)期望运行的 Pod 副本总数量。
  • 作用: K8s 控制器会不断调整 Pod 的数量,使其与 replicas 值保持一致。如果你将 replicas 从 3 改为 5,K8s 会自动创建两个新 Pod。
  • 示例:replicas: 3 表示你希望有 3 个应用程序 Pod 正在运行。

spec.selector (选择器)

  • 含义: 定义控制器如何识别和管理它所属的 Pod。它包含一组标签(matchLabels)来匹配 Pod 的标签。
  • matchLabels:
    • 含义: 一组键值对标签。Pod 模板 (spec.template.metadata.labels) 中的标签必须与此处的 matchLabels 完全匹配,否则控制器将无法找到或管理这些 Pod。
    • 作用: 这是控制器与 Pod 之间建立关联的关键机制。
  • 示例:selector: { matchLabels: { app: my-app } } 意味着该控制器将管理所有带有 app: my-app 标签的 Pod。

spec.template (Pod 模板)

  • 含义: 这是定义 Pod 期望状态的模板。控制器使用这个模板来创建新的 Pod。
  • 结构: 它的结构与我们之前在 6.2 节中详细解析的 Pod YAML 的 metadataspec 部分完全相同
  • template.metadata.labels:
    • 含义: 定义通过此模板创建的所有 Pod 将带有的标签。
    • 关键点: 定义的标签集合必须包含父控制器(Deployment/StatefulSet)的 spec.selector.matchLabels 字段中定义的所有标签(可以包含更多标签)。这是控制器识别其管理的 Pod 的关键。
  • template.spec:
    • 含义: 定义通过此模板创建的 Pod 的容器、卷、端口、环境变量等所有详细配置。
    • 作用: 确保控制器创建的每个 Pod 都具有相同的、你期望的配置。

Deployment 特有属性:

  • spec.strategy (更新策略)
    • RollingUpdate (默认值):
    • Recreate:
    • maxUnavailable:
    • maxSurge:
    • 含义: 在更新过程中,允许在任何时间点不可用的 Pod 最大数量(可以是百分比或绝对数量)。
    • 作用: 控制更新期间服务的可用性。例如,25% 意味着在更新过程中,最多有 25% 的 Pod 副本可以处于不可用状态。
    • 含义: 在更新过程中,可以超出期望副本数(spec.replicas)的 Pod 最大数量(可以是百分比或绝对数量)。
    • 作用: 控制更新期间资源的过度使用。例如,25% 意味着在更新期间,K8s 最多可以创建比 replicas 多 25% 的新 Pod。
    • 含义: 滚动更新策略。K8s 会逐个地替换旧版本的 Pod,而不是一次性停止所有旧 Pod 并启动新 Pod。这能确保在更新过程中服务不中断。
    • rollingUpdate: 进一步配置滚动更新行为。
    • 含义: 重新创建策略。K8s 会先停止所有旧版本的 Pod,然后启动所有新版本的 Pod。
    • 优点: 简单。
    • 缺点:在服务更新期间,旧的 Pod 会被完全终止,然后新的 Pod 才会启动,这会导致一段时间的服务不可用,即会造成服务中断。
    • 适用场景: 对停机不敏感的应用,或者旧版本和新版本之间存在不兼容的数据库模式更改等情况。
    • 含义: 定义当 Deployment 的 Pod 模板(spec.template)发生变化时,K8s 如何更新现有 Pod。
    • type:

StatefulSet 特有属性:

  • spec.serviceName (关联的 Headless Service 名称)
    • 含义: 指定一个无头服务 (Headless Service) 的名称。StatefulSet 依赖于此 Headless Service 来管理其 Pod 的网络身份(稳定的网络标识)。
    • 作用: StatefulSet 的每个 Pod 都会获得一个基于 Pod 名称和此 Headless Service 名称的稳定 DNS 名称,例如 redis-0.redis-service.default.svc.cluster.local。这对于有状态应用的发现和互联至关重要。
    • 示例:serviceName: my-stateful-app-headless
  • spec.volumeClaimTemplates (卷声明模板)
    • 含义: 一个 PVC 模板列表,用于为 StatefulSet 创建的每个 Pod 自动生成一个唯一的 PersistentVolumeClaim (PVC)。
    • 作用: 为 StatefulSet 的每个 Pod 提供独立的、稳定的持久化存储,并且该存储的生命周期独立于 Pod 的生命周期。这对于数据库、消息队列等有状态应用至关重要。注意,volumeClaimTemplates 中定义的每个 PVC 模板,都必须spec.template.spec.containers[*].volumeMounts 中被至少一个容器挂载,StatefulSet 控制器才会为每个 Pod 实例创建对应的 PVC。
    • metadata.name 在 PVC 模板中,这个 name 会作为实际创建的 PVC 名称的一部分(例如 my-data-volume-my-stateful-app-0)。
    • spec 此处与 6.6 节将详细解析的 PVC 的 spec 完全相同,定义了每个 Pod 请求的存储容量、访问模式和 StorageClass 等。

通过理解 Deployment 和 StatefulSet 的这些核心属性,你就能更好地控制应用程序的部署、更新和扩缩容行为,特别是对于有状态应用,StatefulSet 提供的稳定性和有序性是其独特的优势。

6.4 Service YAML 属性深度解析

Service 是 Kubernetes 中实现服务发现和负载均衡的核心抽象。它定义了一组 Pod 的逻辑集合以及访问这些 Pod 的策略。无论 Pod 如何创建、销毁或移动,Service 都为客户端提供一个稳定的网络入口。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: v1
kind:Service
metadata:
name:my-app-service
labels:
    app:my-app
spec:
selector:# 后端 Pod 选择器
    app:my-app
ports:# 端口映射列表
-protocol:TCP# 协议类型
    port:80      # Service 监听的端口
    targetPort:8080# 后端 Pod 容器监听的端口
    nodePort:30080# (可选,仅当 type 为 NodePort 时有效) Node 上暴露的端口
    name:http    # 端口名称
type:ClusterIP# Service 类型
clusterIP:10.96.0.10# (可选,仅当 type 为 ClusterIP 时有效) Service 的虚拟 IP
  • spec.selector (后端 Pod 选择器)
    • 含义: 一个键值对集合,Service 使用这些标签来查找并管理作为其后端的 Pod。
    • 作用: Service 会持续监控带有这些标签的 Pod,并将这些 Pod 的 IP 和端口添加到其Endpoints 列表中。所有发往 Service 的流量都会被转发到这些 Endpoints。
    • 重要性: 这是 Service 与后端 Pod 关联的唯一方式。如果这里的 selector 与任何 Pod 的 metadata.labels 都不匹配,那么 Service 将没有后端 Pod,也就无法提供服务。
    • 示例:selector: { app: my-app } 表示该 Service 将把所有带有 app: my-app 标签的 Pod 作为其后端。
  • spec.ports (端口映射列表)
    • 含义: 端口的名称。在一个 Service 中如果暴露了多个端口,可以使用名称来区分。
    • 作用: 提高可读性,某些高级 Service 特性(如 Ingress)可能会通过端口名称来引用。
    • 示例:name: http, name: grpc
    • 含义: 当 Service 类型为 NodePort 时,此字段指定 K8s 在集群中每个 Node 上打开的端口号。
    • 作用: 外部客户端可以通过任何 Node 的 IP 地址加上这个 nodePort 来访问 Service。
    • 范围: Kubernetes 默认使用 30000-32767 范围内的端口作为 NodePort。集群管理员可以配置此范围。
    • 自动分配: 如果不指定,K8s 会自动从上述范围内分配一个可用的端口。
    • 示例:nodePort: 30080
    • 含义: 后端 Pod 中容器实际监听的端口号(或端口名称)。
    • 作用: Service 将接收到的流量从 port 转发到后端 Pod 的 targetPort
    • 可以是数字: 例如 targetPort: 8080
    • 可以是字符串(端口名称): 如果容器的 ports 字段中定义了 name,这里也可以直接引用端口名称,例如 targetPort: http-server。使用名称的好处是,如果容器实际监听的端口号发生变化,只要名称不变,Service 就无需修改。
    • 示例: 如果 Pod 内部的应用程序在 8080 端口监听 HTTP 请求,那么这里就设置为 targetPort: 8080
    • 含义: Service 自身监听的端口号。客户端将请求发送到 Service 的这个端口。
    • 作用: 这是 Service 的虚拟端口,在集群内部或通过外部暴露时,客户端就是通过这个端口访问 Service。
    • 示例:port: 80 表示 Service 在端口 80 上监听请求。
    • 含义: 传输层协议。
    • 值:TCP (默认), UDP, SCTP
    • 作用: 决定了 Service 监听和转发的协议类型。
    • 含义: 定义 Service 如何将传入的流量映射到后端 Pod 上的端口。一个 Service 可以暴露多个端口。
    • protocol:
    • port:
    • targetPort:
    • nodePort (仅当 type: NodePort 时有效)
    • name:
  • spec.type (Service 类型)
    • ClusterIP (默认值):
    • NodePort:
    • LoadBalancer:
    • ExternalName:
    • 含义: Service 分配一个集群内部的虚拟 IP 地址。只能从集群内部访问。
    • 适用场景: 集群内部服务间的通信(例如,前端 Pod 访问后端数据库 Pod)。
    • 优点: 简单,安全,不暴露到集群外部。
    • 含义: 除了 ClusterIP 功能外,还在集群的每个 Node 上打开一个静态端口。
    • 适用场景: 开发/测试环境,或者自有服务器集群,需要通过 Node 的 IP 地址和特定端口访问服务。
    • 优点: 易于设置,无需额外依赖。
    • 缺点: 端口范围受限,依赖 Node IP,高可用性需要外部负载均衡。
    • 含义: 在支持的云环境中(如 AWS、GCP、Azure),会自动向云服务商请求一个外部负载均衡器。该负载均衡器会分配一个公网 IP 地址,并将流量转发到 Service。
    • 适用场景: 生产环境中最常用的外部暴露方式,需要高可用性、稳定公网 IP 和自动负载均衡。
    • 优点: 稳定的公网 IP,自动负载均衡,高可用性强。
    • 缺点: 依赖云提供商,可能会产生额外费用。
    • 含义: 将 Service 映射到集群外部的 DNS 名称。它不涉及代理,只是简单地返回一个 CNAME 记录。
    • 适用场景: 将集群内部的流量重定向到集群外部的服务(例如,遗留的数据库服务)。
    • 含义: 定义 Service 如何被暴露到集群外部。这是 Service 最重要的属性之一。
    • 值:
  • spec.clusterIP (Service 的虚拟 IP,仅当 type: ClusterIPNodePort 时有效)
    • 含义: Service 被分配的集群内部虚拟 IP 地址。
    • 自动分配: 如果不指定,K8s 会自动分配一个集群 IP。
    • 作用: 集群内部 Pod 通过这个 IP 地址访问 Service。
    • 注意: 对于 LoadBalancer 类型的 Service,通常不会显式设置 clusterIP,它会自动分配一个,并且外部流量主要通过负载均衡器的 IP 访问。对于 ExternalName Service,此字段始终为空。

通过对 Service YAML 属性的深入理解,你现在应该能够根据你的应用程序需求,灵活选择和配置合适的 Service 类型,并精确控制其网络行为。

6.5 ConfigMap 与 Secret YAML 属性深度解析

ConfigMapSecret 都是 Kubernetes 中用于存储和分发配置数据的方式。它们的关键区别在于,ConfigMap 用于存储非敏感的配置数据,而 Secret 则专为存储敏感数据而设计。尽管如此,它们在结构和使用方式上有很多相似之处。

6.5.1 ConfigMap:非敏感配置的灵活之道

ConfigMap 允许你将配置数据与应用程序镜像解耦,从而提高应用的可移植性和可管理性。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: v1
kind:ConfigMap
metadata:
name:my-app-config
data:# 键值对数据
config.yaml:|# 完整文件内容作为值
    server:
      port:8080
    database:
      host:postgres-service
      name:my_database
log_level:DEBUG# 单个键值对
feature_flag:"true"

data (键值对数据)

  • 含义: 存储实际的配置数据。这里定义的是一系列键值对。
  • 作用: K8s 会将这些数据注入到 Pod 中,作为环境变量或文件。
  • 格式:
    • 普通的键值对:key: value。值可以是任何字符串。
    • 多行字符串或文件内容: 对于多行内容,你可以使用 YAML 的字面量块指示符 | (保留换行符) 或 > (折叠换行符) 来表示。这在存储完整的配置文件(如 config.yamlnginx.conf)时非常有用。
  • 重要提示:ConfigMap 中的数据是明文存储的,不应包含任何敏感信息。
6.5.2 Secret:敏感数据的安全卫士

Secret 用于存储敏感信息,例如密码、OAuth Token、SSH 密钥等。虽然 K8s 会对 Secret 中的数据进行 Base64 编码,但这并非加密,只是一种传输编码。为了真正的安全性,数据在 Etcd 中存储时可能需要额外的加密配置。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: v1
kind:Secret
metadata:
name:my-app-secret
type:Opaque# Secret 的类型
data:# Base64 编码的键值对数据
username:dXNlcg==# 'user' 的 Base64 编码
password:cGFzc3dvcmQxMjM=# 'password123' 的 Base64 编码
stringData:# (可选) 方便地直接写入明文数据,K8s 会自动 Base64 编码
db_connection_string:"jdbc:postgresql://postgres-service:5432/mydb"
  • data (Base64 编码的键值对数据)
    • 含义: 存储实际的敏感数据。在 YAML 文件中定义 data 字段时,每个值都必须是 Base64 编码后的字符串。Kubernetes API Server 不会自动对 data 下的值进行编码,如果直接写入明文会导致错误(如 cannot unmarshal string into Go struct field Secret.data of type []uint8)。
    • 作用: K8s 会将这些 Base64 编码后的数据解码并注入到 Pod 中,作为环境变量或文件。
    • 如何生成 Base64 编码: 在 Linux/macOS 终端中,你可以使用 echo -n 'your_plain_text' | base64 来生成。例如,echo -n 'mypassword' | base64 会输出 bXlwYXNzd29yZA==
    • 重要提示: 务必确保这里的 value 是 Base64 编码后的结果,否则会遇到 cannot unmarshal number into Go struct field Secret.data of type []uint8 类似的错误。
  • stringData (可选:明文字符串数据)
    • 含义:stringData 字段仅用于在创建或更新 Secret 时提供明文输入。一旦 Secret 被创建或更新,stringData 字段的内容会被 Kubernetes API Server 转换为 Base64 编码格式并存储在 data 字段中。随后通过 kubectl get secret -o yaml 或其他 API 查询只能看到 data 字段(包含 Base64 编码值),stringData 字段本身在查询结果中是不可见的。
    • 作用: 提高了 Secret YAML 的可读性,避免了手动 Base64 编码的步骤。
    • 注意:stringData 中的字段在 Secret 创建后不会再显示在 kubectl get secret <name> -o yaml 的输出中,它们会被转换到 data 字段,且 data 字段的值是 Base64 编码的。
  • type (Secret 类型)
    • Opaque (默认值): 通用类型,用于存储任意用户定义的数据。这是最常用的类型。
    • kubernetes.io/dockerconfigjson: 用于存储 Docker 镜像仓库的认证凭据(通常由 kubectl create secret docker-registry 命令创建)。
    • kubernetes.io/service-account-token: Service Account 自动生成的 Token Secret。
    • kubernetes.io/tls: 用于存储 TLS 证书和私钥(通常由 kubectl create secret tls 命令创建)。
    • 含义: 定义 Secret 的用途类型,这有助于 K8s 验证和管理。
    • 值:
    • 作用: 类型字段提供了关于 Secret 内容的提示,并可能触发 K8s 的特定行为(如自动挂载 Service Account Token)。
6.5.3 ConfigMap 与 Secret 的注入方式

一旦 ConfigMapSecret 被创建,它们可以通过以下两种主要方式注入到 Pod 的容器中:

  1. 作为环境变量注入:
    • 在 Pod 的 spec.containers.env 字段中使用 valueFrom 引用 configMapKeyRefsecretKeyRef
    • 优点:简单,直接在容器内作为环境变量使用。
    • 缺点:环境变量值一旦设置,容器重启前不会自动更新。如果需要更新,通常需要滚动更新 Deployment/StatefulSet 来触发 Pod 重建或重启。
  2. 作为文件卷挂载:
    • 在 Pod 的 spec.volumes 中定义一个 configMapsecret 类型的卷。
    • spec.containers.volumeMounts 中将这个卷挂载到容器的特定路径。
    • 优点:可以挂载整个 ConfigMap/Secret 为多个文件,更接近传统配置文件方式;ConfigMap/Secret 的更新在 Pod 运行时会自动反映到挂载的文件中(通常在几秒到一分钟内),无需重启 Pod。这是因为 Kubelet 会定期检查并同步挂载的 ConfigMap/Secret。
    • 缺点:需要应用程序能够从文件中读取配置。

理解 ConfigMapSecret 的这些属性及其注入方式,是你安全有效地管理应用程序配置和敏感数据的关键。

6.6 PersistentVolumeClaim (PVC) YAML 属性深度解析

PersistentVolumeClaim (PVC) 是用户向 Kubernetes 请求持久化存储的一种声明。它抽象了底层存储的细节,允许 Pod 简单地“声明”所需的存储,而不必关心具体的存储实现(如 NFS、云盘、iSCSI 等)。PVC 会与一个 PersistentVolume (PV) 绑定,而 PV 则代表了集群中实际的物理存储资源。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
apiVersion: v1
kind:PersistentVolumeClaim
metadata:
name:my-app-pvc
labels:
    app:my-app
spec:
accessModes:# 访问模式
    -ReadWriteOnce# 只允许单个节点读写
resources:# 资源请求
    requests:
      storage:5Gi# 请求 5 GB 存储空间
storageClassName:standard-ssd# 引用的 StorageClass 名称
selector:# (可选) 用于选择特定 PV 的标签选择器
    matchLabels:
      tier:premium
    matchExpressions:
      -{key:environment,operator:In,values:[dev,prod]}
  • spec.accessModes (访问模式)
    • ReadWriteOnce (RWO):卷可以被单个节点以读写方式挂载。这是最常见的模式,适用于大多数单 Pod 应用程序(如我们的 PostgreSQL)。
    • ReadOnlyMany (ROX):卷可以被多个节点以只读方式挂载。适用于多个 Pod 同时读取共享数据。
    • ReadWriteMany (RWX):卷可以被多个节点以读写方式挂载。这通常需要特定的共享存储解决方案(如 NFS)。
    • ReadWriteOncePod (RWOP): 卷可以被单个 Pod 以读写方式挂载(Kubernetes 1.22+ Beta, 1.27+ GA)。这比 RWO 更严格,确保即使 Node 上有多个 Pod 也能保证只有一个 Pod 使用该卷。
    • 含义: 定义了存储卷可以被 Pod 以何种方式挂载和访问。
    • 作用: 限制了哪些 Pod 可以访问该卷以及访问权限。
    • 常见值:
  • spec.resources.requests.storage (请求的存储空间)
    • 含义: 用户请求的存储卷大小。
    • 作用: K8s 会尝试找到一个至少满足这个大小的 PV 来绑定,或者(如果使用 StorageClass 动态供应)创建一个指定大小的存储卷。
    • 单位: 可以使用 Gi (吉字节), Mi (兆字节) 等。
    • 示例:storage: 5Gi 表示请求 5 吉字节的存储空间。
  • spec.storageClassName (引用的 StorageClass 名称)
    • storageClassName 被指定时,K8s 会尝试使用该 StorageClass 定义的规则来动态供应(即按需创建)一个 PV。
    • 如果集群中存在一个默认的 StorageClass 并且 PVC 未指定 storageClassName,那么 K8s 也会使用默认的 StorageClass 进行动态供应。
    • 如果指定了 storageClassName: "" (空字符串),则表示 PVC 不希望使用动态供应,而希望绑定到没有任何 StorageClass 的现有 PV。这通常用于静态供应场景。
    • 含义: 指定 PVC 希望使用的 StorageClass 的名称。
    • 作用:
    • 重要性:StorageClass 是实现 K8s 存储自动化和多样化的关键。它定义了存储的提供者(如云提供商的 EBS、GCE Persistent Disk)、性能层级(如 SSD、HDD)和回收策略等。
  • spec.selector (可选:用于选择特定 PV 的标签选择器)
    • 含义: 如果你希望 PVC 绑定到集群中已经存在的某个特定的 PV(而非动态创建),可以通过这个选择器来指定 PV 必须拥有的标签。
    • 作用: 在静态供应场景中,当你需要 PVC 精确匹配到某个预先创建好的 PV 时使用。
    • 注意: 如果同时指定了 storageClassNameselector,那么只有当两者都能满足条件时,PVC 才会绑定。通常在动态供应场景下,selector 不会使用。

通过对 PVC YAML 属性的深入理解,你现在能够更清晰地声明你的应用程序对持久化存储的需求,并利用 K8s 的存储自动化能力。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-06-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 木有枝枝 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 第六章:K8s YAML 配置深度解析:核心属性与通用结构
    • 6.1 K8s YAML 配置文件的通用结构
    • 6.2 Pod YAML 属性深度解析
    • 6.3 Deployment/StatefulSet YAML 属性深度解析
    • 6.4 Service YAML 属性深度解析
    • 6.5 ConfigMap 与 Secret YAML 属性深度解析
      • 6.5.1 ConfigMap:非敏感配置的灵活之道
      • 6.5.2 Secret:敏感数据的安全卫士
      • 6.5.3 ConfigMap 与 Secret 的注入方式
    • 6.6 PersistentVolumeClaim (PVC) YAML 属性深度解析
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档