11. 容器化 vs 虚拟化-K8s-工作负载实战

文章目录

  • 前言
  • [一、Pod 定向部署到指定节点](#一、Pod 定向部署到指定节点)
    • [🤔 配置解读](#🤔 配置解读)
    • [🛠️ 完整实现步骤](#🛠️ 完整实现步骤)
      • [步骤 1:为目标节点添加标签和污点](#步骤 1:为目标节点添加标签和污点)
      • [步骤 2:部署应用 Pod](#步骤 2:部署应用 Pod)
    • [💡 机制总结](#💡 机制总结)
    • 工作负载Deployment的apiVersion
    • service和deployment的标签选择器
      • [🆚 核心区别对比表](#🆚 核心区别对比表)
      • [🛠️ 语法结构差异详解](#🛠️ 语法结构差异详解)
        • [1. Deployment 的选择器](#1. Deployment 的选择器)
        • [2. Service 的选择器](#2. Service 的选择器)
      • [💡 为什么会有这种设计差异?](#💡 为什么会有这种设计差异?)
      • [🚀 总结建议](#🚀 总结建议)

前言

``‌

  。


一、Pod 定向部署到指定节点

节点选择器 (nodeSelector) 和 污点与容忍 (Taints and Tolerations) 的结合使用。

这种组合策略非常有效,它通过"推拉结合"的方式,确保您的应用 Pod 能够精准且独占地运行在目标节点上。

yaml 复制代码
nodeSelector:     # 节点选择器
   environment: uat-xc
 tolerations:      # 污点容忍
   - effect: NoSchedule
     key: environment
     operator: Equal
     value: uat-xc

🤔 配置解读

配置可以从两个方面来理解:

  1. nodeSelector (拉取策略)
  • 作用 :这是一个"吸引"规则。它告诉 Kubernetes 调度器:"请把这个 Pod 调度到拥有 environment: uat-xc 标签的节点上。"
  • 前提 :目标节点必须已经打上了 environment: uat-xc 这个标签。
  1. tolerations (容忍策略)
  • 作用:这是一个"通行证"或"免疫"规则。它允许 Pod "容忍"节点上的特定"污点"。
  • 前提:为了让这个容忍生效,您需要在目标节点上添加一个对应的污点。

🛠️ 完整实现步骤

为了让配置完全生效,实现 Pod 定向部署到指定节点,需要完成以下两个步骤:

步骤 1:为目标节点添加标签和污点

假设目标节点名为 node-01,需要使用 kubectl 命令为其添加标签和污点。

  • 添加标签 (匹配 nodeSelector)

    bash 复制代码
    kubectl label nodes node-01 environment=uat-xc

    这条命令为 node-01 节点添加了 environment=uat-xc 标签,满足了 Pod 中 nodeSelector 的要求。

  • 添加污点 (匹配 tolerations)

    bash 复制代码
    kubectl taint nodes node-01 environment=uat-xc:NoSchedule

    这条命令为 node-01 节点添加了一个污点。这个污点会阻止所有没有对应容忍配置的 Pod 调度到该节点上。

步骤 2:部署应用 Pod

使用章节开头提供的 YAML 配置部署应用。这个 Pod 因为同时具备了 nodeSelectortolerations,所以:

  • 只会 被调度到带有 environment=uat-xc 标签的节点。
  • 能够 容忍 environment=uat-xc:NoSchedule 这个污点。

因此,这个 Pod 最终会被精准地部署到 node-01 上,而其他没有对应容忍配置的普通 Pod 则无法进入该节点,从而实现了资源的独占。

💡 机制总结

机制 作用 配置位置 效果
节点选择器 (nodeSelector) 吸引 Pod 到特定节点 Pod 的 YAML 文件 Pod 只能被调度到带有匹配标签的节点上。
污点与容忍 (Taints & Tolerations) 排斥不匹配的 Pod 污点在节点 上,容忍在Pod 节点拒绝没有对应容忍的 Pod 调度。

通过结合使用这两种机制,您可以实现强大而灵活的调度策略,确保关键应用运行在专属的、经过优化的硬件资源上。

工作负载Deployment的apiVersion

在 Kubernetes 中,工作负载 DeploymentapiVersion 取决于你使用的 Kubernetes 集群版本。

目前主流且推荐使用的版本是 apps/v1

  1. 📊 版本对照表

为了让你更直观地了解不同版本的对应关系,我整理了下表:

Kubernetes 版本 推荐的 apiVersion 状态 说明
v1.9.0 及以后 apps/v1 当前标准 生产环境的标准配置,稳定且长期支持。
v1.6.0 - v1.8.0 apps/v1beta2 ⚠️ 已废弃 早期过渡版本,现已不再使用。
v1.6.0 之前 extensions/v1beta1 ❌ 已移除 极早期的版本,在新版集群中已不可用。
  1. 📝 配置示例

在编写 Deployment 的 YAML 文件时,标准的头部配置如下:

yaml 复制代码
apiVersion: apps/v1  # 这里指定 API 版本
kind: Deployment     # 资源类型
metadata:
  name: my-app-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-container
        image: nginx:latest
  1. 💡 关键注意事项

selector 字段是必须的

在使用 apiVersion: apps/v1 时,必须spec 下显式定义 selector 字段,且 matchLabels 必须与 template.metadata.labels 中的标签保持一致。这是 apps/v1 与旧版本的一个显著区别,旧版本有时允许隐式生成选择器。

如何确认你的集群版本

如果你不确定当前集群支持哪个版本,可以通过以下命令查看集群版本信息:

bash 复制代码
kubectl version

或者直接尝试获取 Deployment 资源来验证 API 路径:

bash 复制代码
kubectl explain deployment

总结 :除非你在维护非常古老的遗留系统,否则请始终使用 apiVersion: apps/v1

service和deployment的标签选择器

在 Kubernetes 中,Service 和 Deployment 的标签选择器(Selector)虽然核心目的都是"根据标签找到 Pod",但它们在 YAML 语法结构强制程度 以及匹配逻辑上有着显著的区别。

简单来说:Deployment 的选择器更严格且语法嵌套更深,而 Service 的选择器更灵活且语法扁平。

以下是详细的对比分析:

🆚 核心区别对比表

特性 Deployment 选择器 Service 选择器
YAML 语法路径 spec.selector.matchLabels spec.selector
语法结构 嵌套结构 :必须包含 matchLabelsmatchExpressions 字段。 扁平结构 :直接写键值对,不需要 matchLabels 包装。
强制性 必填:必须显式定义,且必须与 Pod 模板标签匹配。 可选:如果不填,Service 依然可以创建(通常用于无头 Service 或手动管理 Endpoints)。
匹配逻辑 严格匹配:通常要求选择器是 Pod 标签的子集或完全一致。 超集匹配:只要 Pod 拥有选择器中指定的键值对即可,Pod 可以拥有额外标签。
主要作用 生命周期管理:决定 Deployment 管理哪些 Pod,负责创建、删除、更新。 流量路由:决定 Service 将流量转发给哪些 Pod(生成 Endpoints)。

🛠️ 语法结构差异详解

1. Deployment 的选择器

Deployment 中,选择器位于 spec.selector 下,并且必须 使用 matchLabels(或 matchExpressions)来包裹具体的标签。

  • 关键点spec.selector.matchLabels 中的标签必须与 spec.template.metadata.labels 中的标签完全匹配(或者前者是后者的子集)。如果两者不一致,API Server 会直接报错拒绝创建。
yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-deployment
spec:
  replicas: 3
  selector:                # 1. 定义选择器
    matchLabels:           # 2. 必须使用 matchLabels 包裹
      app: my-app
      version: v1
  template:
    metadata:
      labels:              # 3. Pod 模板的标签
        app: my-app        # 必须包含 selector 中的所有键值对
        version: v1        # 必须包含 selector 中的所有键值对
        env: prod          # 可以包含额外的标签
    spec:
      containers:
      - name: nginx
        image: nginx
2. Service 的选择器

Service 中,选择器直接位于 spec.selector 下,直接 写键值对,不需要 matchLabels 这一层。

  • 关键点 :Service 的匹配逻辑是"包含即匹配"。只要 Pod 身上贴了 app: my-app 这个标签,不管 Pod 还有没有其他标签(比如 env: prod),都会被这个 Service 选中并加入负载均衡池。
yaml 复制代码
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector:                # 1. 直接写键值对,无需 matchLabels
    app: my-app            # 2. 只要 Pod 有这个标签就会被选中
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080

💡 为什么会有这种设计差异?

  • Deployment (控制器) :它需要非常明确地知道"哪些 Pod 是我生的"以及"我要管理哪些 Pod"。使用 matchLabels 这种显式的结构,配合严格的匹配检查,可以防止控制器误删或误管不属于它的 Pod,保证集群状态的稳定性。
  • Service (网络抽象) :它的目标是"把流量送给符合条件的 Pod"。使用扁平的键值对结构更简洁,且支持"超集匹配"(即 Pod 标签是选择器的超集),这使得 Service 可以灵活地聚合不同类型的 Pod(例如,你可以创建一个选择器 app: backend,它同时选中了 dbcache 两种角色的 Pod,只要它们都有 app: backend 标签)。

🚀 总结建议

  1. 写 Deployment 时 :一定要检查 selector.matchLabelstemplate.metadata.labels 是否一致,这是新手最容易报错的地方。
  2. 写 Service 时 :直接写 selector 键值对即可,确保它能覆盖到你想要暴露的 Pod 标签。
  3. 排错技巧 :如果你发现 Service 没有流量,使用 kubectl get endpoints <service-name> 查看是否有 IP。如果没有,通常是因为 Service 的 selector 写错了,或者 Pod 的标签没打对。

本文的引用仅限自我学习如有侵权,请联系作者删除。

参考知识

<>


相关推荐
极客先躯2 小时前
高级java每日一道面试题-2026年01月18日-实战篇[Docker]-如何清理仓库中的旧镜像?
java·运维·docker·容器
张忠琳4 小时前
【kubernetes v1.21】(controller-manager part 1)kube-controller-manager 核心架构与启动流程
云原生·架构·kubernetes
qq_452396235 小时前
第十五篇:《Docker 与 Kubernetes 集成:从 Swarm 到 K8s 的迁移》
docker·容器·kubernetes
HackTwoHub5 小时前
K8s综合渗透测试工具,集成信息搜集、权限逃逸、横向移动,一站式搞定全流程渗透测试工作
人工智能·安全·web安全·云原生·容器·kubernetes·系统安全
做个文艺程序员5 小时前
第05篇:K8s CI/CD 全流程:GitOps × ArgoCD × Harbor——Java SaaS 从代码提交到生产部署一键直达
ci/cd·kubernetes·argocd
人工智能培训5 小时前
数字孪生建模常用方式有哪些?
人工智能·深度学习·机器学习·容器·知识图谱
lpfasd1235 小时前
docker中默认网络的作用和注意事项
网络·docker·容器
IT策士6 小时前
第 37 篇 k8s之调度进阶:亲和性、污点与容忍
云原生·容器·kubernetes
EntyIU6 小时前
DOCKER_CHEATSHEET
运维·docker·容器