🐳 Docker & Kubernetes 架构全景

深入解析容器化技术与容器编排核心组件的关系

📚 核心概念 & 关键机制

🔌 Service 如何找到 Pod?— Label Selector 机制

这是最容易困惑的地方,Service 不是通过 IP 找 Pod 的,而是通过 Label Selector(标签选择器)

  • Pod 上有标签(Labels):例如 app=web version=v1
  • Service 定义 Selectorselector: app=web
  • K8S 自动匹配:所有带 app=web 标签的 Pod 都会被该 Service 发现
  • 动态更新:新创建的 Pod 如果标签匹配,会自动加入 Service 的负载均衡池

👉 类比:Service 是个"招聘负责人",Label 是"技能标签",有对应技能的 Pod 都会被"录用"(加入负载均衡)。

📦 Pod 与 Container 的关系

Pod 是 K8S 的调度单元,Container 是 Docker 的运行实例。

  • 每个 Pod 有一个 Pause 容器:负责持有网络命名空间(Network Namespace),提供共享网络
  • 用户容器共享网络:同一 Pod 内的所有容器共享同一个 IP 和端口空间,localhost 可以直接通信
  • 共享存储:通过 Volume 挂载,同一 Pod 内容器可以访问同一份数据

⚙️ Ingress Controller vs Ingress — 别搞混了!

  • Ingress = 路由规则的"配置文件"(类似 nginx.conf),是 K8S 的 API 对象
  • Ingress Controller = 实际执行路由的"服务器"(类似 NGINX 进程),它本身是一个 Pod
  • 类比:Ingress 是"菜谱",Ingress Controller 是"厨师"

🔄 请求流向:从用户到容器

👤
用户请求
HTTP/HTTPS
⚙️
Ingress Controller
NGINX/Traefik
🔌
Service
负载均衡
📦
Pod
调度单元
🐳
Container
Docker容器

外部请求进入 K8S 集群的完整链路

📊 架构全景图(含 Label Selector 机制)

🌐 外部访问层 👤 外部用户 / 客户端 Browser / API Client / Mobile App 🔗 Ingress 层(流量入口) ⚙️ Ingress Controller 实际处理流量的反向代理 例:NGINX Ingress Controller ← 它本身是一个 Pod(运行 NGINX) 📋 Ingress HTTP/HTTPS 路由规则定义 定义:域名 / 路径 / TLS ← 这是 K8S 资源对象(配置) ① 收到HTTP请求 ② 读取路由规则 🔌 Service 层(服务发现 & 负载均衡) 🔌 Service A ClusterIP: 10.0.0.1 selector: app=web 🔌 Service B ClusterIP: 10.0.0.2 selector: app=api 🔌 Service C NodePort: 30001 selector: app=db ③ 根据Ingress规则转发到对应Service 📦 Pod 层(应用运行单元)— 通过 Label 被 Service 发现 Label: app=web ✅ ← 被 Service A 通过 selector 匹配 📦 Pod A1 Container: nginx IP: 192.168.1.11 label: app=web 📦 Pod A2 Container: nginx IP: 192.168.1.12 label: app=web Label: app=api ✅ 📦 Pod B1 Container: api-srv IP: 192.168.1.21 label: app=api 📦 Pod B2 Container: api-srv IP: 192.168.1.22 label: app=api Label: app=db ✅ 📦 Pod C1 Container: mysql IP: 192.168.1.31 label: app=db ④ Service 通过 Label Selector 匹配 Pod 🐳 Docker 层(容器运行时)— 每个 Pod 内运行的实际容器 🐳 nginx容器 镜像: nginx:1.25 🐳 nginx容器 🐳 mysql容器 Pod 为容器提供共享网络和存储,容器是实际运行应用的地方 🚀 Deployment 层(声明式管理 Pod 副本) 🚀 Deployment A replicas: 2 strategy: RollingUpdate 管理 ReplicaSet → 确保2个Pod运行 🚀 Deployment B replicas: 2 🚀 Deployment C replicas: 1 管理 🖥️ Node 层(物理机/虚拟机 — K8S 工作节点) 🖥️ Node 1(工作节点) 运行 Pod A1, A2, B1 + Docker + Kubelet 🖥️ Node 2(工作节点) 运行 Pod B2, C1 + Docker + Kubelet

🔍 核心机制深解:Service 如何通过 Label Selector 找到 Pod

📋 完整工作流

  1. Pod 被打标签:创建 Pod 时,在 metadata.labels 中定义标签,如 app: web
  2. Service 定义 Selector:在 spec.selector 中写明要匹配的标签
  3. K8S 自动建立关联:K8S 的控制器会持续监听,所有标签匹配的 Pod 自动加入该 Service 的 Endpoints 列表
  4. 负载均衡:Service 收到请求后,根据 Endpoints 列表将请求转发到某个 Pod
  5. 动态更新:当有新 Pod 创建(标签匹配)或旧 Pod 删除时,Endpoints 列表会自动更新

📝 实际 YAML 示例

# Pod 的定义(注意 metadata.labels)
apiVersion: v1
kind: Pod
metadata:
  labels:
    app: web        # ← 这个标签会被 Service 匹配
    version: v1
spec:
  containers:
  - name: nginx
    image: nginx:1.25

---
# Service 的定义(注意 spec.selector)
apiVersion: v1
kind: Service
metadata:
  name: service-a
spec:
  selector:
    app: web      # ← 匹配所有带 "app: web" 标签的 Pod
  ports:
  - port: 80
    targetPort: 8080
  type: ClusterIP

K8S 会自动发现所有 labels: app=web 的 Pod,并将它们加入 Service A 的负载均衡池。

🏗️ 完整层级关系(从下到上)

① 基础设施层 物理机 / 虚拟机(Node)— K8S 的工作节点
② 容器运行时层 Docker / containerd — 负责拉取镜像和运行容器
③ Pod 层 K8S 最小调度单元 — 包含一个或多个共享网络的容器
④ Deployment 层 管理 Pod 副本数量 — 负责滚动更新、回滚、自愈
⑤ Service 层 稳定访问入口 + 负载均衡 — 通过 Label Selector 发现 Pod
⑥ Ingress Controller 层 实际处理外部流量的反向代理(NGINX)— 本身是一个 Pod
⑦ Ingress 层 HTTP 路由规则定义(K8S 资源对象)— 被 Controller 读取

注意:③→④→⑤ 可类比为:容器 → 管理容器的副本集 → 暴露服务的入口