Kubernetes 五维度交互学习工具

不是"一个系统",是五个不同抽象层级的知识体系

学习顺序建议:① 核心对象 → ② 控制平面 → ⑤ 工具链 → ④ 网络模型 → ③ 运行时机制

概念层 ① 核心抽象对象 — 你写 YAML 时操作的东西

一句话:K8s 不是直接操作容器,而是通过一层资源对象抽象来管理容器——你声明"我想要什么状态",K8s 负责让你的集群变成那个状态。

核心对象层级(从低到高)

1
Pod
最小的调度单元,包含一个或多个共享网络和存储的容器。Pod 不是容器,是容器的包装和调度原子。同一个 Pod 内的容器通过 localhost 通信,共享卷。
2
Deployment
管理 Pod 的控制器,负责维持指定数量的 Pod 副本、滚动更新、回滚。你通常不直接创建 Pod,而是创建 Deployment 来替你管理 Pod。
3
Service
为一组 Pod 提供稳定的网络端点。Pod IP 会变,Service IP 不变。四种类型:ClusterIP(集群内) / NodePort(节点端口暴露) / LoadBalancer(云LB) / ExternalName(DNS别名)。
4
Ingress
集群的HTTP/HTTPS 入口路由器,基于域名和路径规则将外部流量导向不同 Service。需要 Ingress Controller(如 nginx、traefik)配合。
5
ConfigMap / Secret
配置分离机制。ConfigMap 存非敏感配置(明文),Secret 存敏感数据(Base64 编码,不是加密)。通过环境变量或卷挂载注入容器。

关键关系

# 典型应用部署的最小 YAML 结构
apiVersion: apps/v1
kind: Deployment          # 声明"我要管理 Pod"
metadata:
  name: my-app
spec:
  replicas: 3             # 维持 3 个副本
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app       # Service 通过这个 label 找到 Pod
    spec:
      containers:
      - name: app
        image: my-app:1.0
        envFrom:
        - configMapRef:
            name: app-config   # 配置分离
---
apiVersion: v1
kind: Service             # 声明"为这组 Pod 提供稳定访问点"
metadata:
  name: my-app
spec:
  selector:
    app: my-app           # 匹配 Pod 的 label
  ports:
  - port: 80
    targetPort: 8080
---
apiVersion: networking.k8s.io/v1
kind: Ingress             # 声明"外部流量从哪进来"
metadata:
  name: my-app
spec:
  rules:
  - host: app.example.com
    http:
      paths:
      - path: /
        backend:
          service:
            name: my-app
            port: 80
面试口诀:"Pod 是原子,Deployment 管副本,Service 做发现,Ingress 做入口,ConfigMap 做配置"

架构层 ② 控制平面 — 集群的大脑

一句话:控制平面是 K8s 的大脑和神经系统,负责接收指令、存储状态、做出调度决策、维持期望状态。

控制平面组件(Master 节点运行)

1
kube-apiserver
整个集群的统一入口,唯一的 REST API 端点。所有组件(包括 kubectl)都通过它读写状态。无状态,可水平扩展。
2
etcd
分布式键值存储,保存集群的所有状态数据(配置、运行时状态、Secret)。控制平面的唯一状态源,其他组件都是无状态的。
3
kube-scheduler
负责把未调度的 Pod 绑定到合适的 Node。考虑资源请求、亲和性/反亲和性、污点/容忍度等约束,但不执行部署——只做决定。
4
kube-controller-manager
运行多个控制器,每个负责一种资源的自动化维护:Deployment Controller(维持副本数)、Endpoint Controller(维护 Service 端点)、Node Controller(节点健康)等。
5
cloud-controller-manager
与云厂商 API 交互的控制器(创建云负载均衡器、管理云路由等),将 K8s 与特定云基础设施解耦。

工作节点组件

关键交互流程

用户 kubectl apply
    ↓
kube-apiserver(接收请求,验证,写入 etcd)
    ↓
etcd(持久化状态变更)
    ↓
各 Controller  Watch 到变更 → 采取行动
    ↓
kube-scheduler 发现未绑定 Pod → 选择 Node → 绑定
    ↓
目标 Node 的 kubelet 通过 CRI 创建容器
    ↓
kube-proxy 更新网络规则
核心记忆点:etcd 是唯一有状态的,apiserver 是唯一入口,scheduler 只选不建,kubelet 在节点上干活

机制层 ③ 容器运行时 — 底层原理

一句话:K8s 不直接运行容器——它通过标准化的 CRI(Container Runtime Interface) 调用容器运行时,运行时再利用 Linux 内核机制实现隔离。

运行时层级

1
CRI — Container Runtime Interface
K8s 与容器运行时的标准接口。kubelet 只认 CRI,不关心底层是 containerd 还是 CRI-O。这是解耦的关键设计。
2
containerd / CRI-O
高层容器运行时,管理镜像拉取、存储、容器生命周期。containerd 源自 Docker 捐赠给 CNCF,是现在的事实标准。
3
runc
OCI 标准的底层容器运行时,真正创建和运行容器进程。接收一个 OCI bundle(rootfs + config.json),配置 namespace 和 cgroup,启动容器进程。
4
Linux Namespace + Cgroup
Namespace 做隔离(PID、Network、Mount、UTS、IPC、User、Cgroup namespace)— 让容器以为自己在独立系统中。Cgroup 做资源限制(CPU、内存、IO)— 防止一个容器耗尽宿主机资源。

形式化表述(精确机制)

容器 ≠ 虚拟机
容器 = 一组被 namespace 隔离 + cgroup 限制的 Linux 进程

运行时调用链:
kubelet --(gRPC/CRI)--> containerd --(OCI/runc)--> runc --(clone syscall + namespace/cgroup setup)--> 容器进程
常见误区:容器不是"轻量级虚拟机"。容器和宿主机共享同一个内核(没有 Hypervisor,没有硬件虚拟化),只是进程被隔离了视角和资源。Docker 的早期" shipping container "比喻帮助了传播,但也造成了大量错误理解——比如以为容器有独立内核。
面试常问:Namespace 负责隔离(能看到什么),Cgroup 负责限制(能用多少)

机制层 ④ 网络模型 — 通信原理

一句话:K8s 给每个 Pod 一个独立的 IP(IP-per-Pod),所有 Pod 可以在不经过 NAT 的情况下直接通信,Service 在这个扁平网络之上提供虚拟 IP 和负载均衡。

三层网络模型

1
Pod 网络(CNI 层)
每个 Pod 获得一个独立 IP(来自 CNI 插件分配的网段),同一节点上的 Pod 通过虚拟网桥通信,跨节点通过路由或 Overlay 网络通信。CNI 插件负责实现:Calico(BGP路由)、Flannel(VXLAN Overlay)、Cilium(eBPF) 等。
2
Service 网络(Cluster IP)
Service 拥有一个虚拟 ClusterIP(来自 Service CIDR,不绑定任何网卡),通过 kube-proxy 在节点上维护 iptables/IPVS 规则,将访问 ClusterIP 的流量 DNAT 到后端 Pod IP。这是四层负载均衡(TCP/UDP)。
3
Ingress(七层路由)
Ingress 在 Service 之上提供HTTP/HTTPS 层的路由(基于 Host 和 Path),由 Ingress Controller 实现。本质是一个反向代理配置自动生成器。

流量路径全景

外部流量
  → Ingress Controller (NodePort/LoadBalancer)
    → 根据 Host/Path 路由到 Service ClusterIP
      → kube-proxy 的 iptables/IPVS 规则 DNAT 到 Pod IP
        → CNI 插件路由到目标 Pod 的 veth 接口
          → 容器进程处理请求

核心设计原则:
- Pod IP 可路由但短命(重建会变)
- Service ClusterIP 是虚拟的、稳定的
- 所有 Pod ↔ Pod 通信不经 NAT(扁平网络)
面试陷阱:Service 的 ClusterIP 是"虚拟"的——没有对应的真实网卡,只在 iptables/IPVS 规则中存在。如果你从 Pod 内 curl ClusterIP,iptables 在出方向就把目标地址改成了某个 Pod 的真实 IP。
三层记忆:CNI 给 Pod 发 IP → Service 提供虚拟 IP 做负载均衡 → Ingress 做七层路由

工具层 ⑤ 运维工具链 — 日常操作

一句话:K8s 的所有操作都围绕声明式配置 + 控制器循环——你描述期望状态,系统持续收敛。

核心工具

1
kubectl — 命令行工具
与 apiserver 交互的 CLI。kubectl apply -f(声明式,推荐)、kubectl get/describe/logs(查询)、kubectl exec(进容器调试)。所有命令最终都是 REST API 调用
2
YAML 清单 — 声明式配置
K8s 的核心交互语言。每个资源对象都有 4 段:apiVersion / kind / metadata / spec。spec 描述期望状态,status 由系统填充反映实际状态。
3
Helm — 包管理器
K8s 的"apt/yum",用模板语言(Go template)管理复杂应用的 YAML。一个 Chart 包含模板 + 默认值 + 依赖定义,实现可配置、可版本化、可复用的应用部署。
4
调试三板斧
kubectl describe pod <name>(看 Events 定位问题)→ kubectl logs <pod>(看容器日志)→ kubectl exec -it <pod> -- sh(进容器排查)。80% 的问题靠这三条。

声明式 vs 命令式

命令式(Imperative):告诉系统"怎么做"
  kubectl run nginx --image=nginx
  kubectl scale deployment nginx --replicas=3
  → 适合临时调试,不推荐用于生产

声明式(Declarative):告诉系统"要什么状态"
  kubectl apply -f deployment.yaml
  → 配置就是代码,可版本控制,可审计,可回滚
  → 控制器持续对比 spec 和 status,自动纠偏
生产最佳实践:所有资源配置都应该用 Git 管理(GitOps),通过 CI/CD pipeline 的 kubectl apply 或 Helm 部署到集群。永远不要手敲 kubectl runkubectl edit 到生产环境。
工作流口诀:写 YAML → kubectl apply → kubectl get 看状态 → kubectl describe 查问题 → kubectl logs 看日志
五维度关系总览:
③ 容器运行时(runc/namespace/cgroup)是物理基础 → ② 控制平面(apiserver/etcd/scheduler)是控制大脑 → ① 核心对象(Pod/Deployment/Service)是你操作的抽象层 → ④ 网络模型(CNI/ClusterIP/Ingress)让一切能通信 → ⑤ 工具链(kubectl/Helm/YAML)是你日常使用的接口。

形式化表述:这是一个经典的控制论系统——控制平面(②)通过 Watch-Notify 机制监视 etcd 的状态变更,各控制器计算当前状态(status)与期望状态(spec)的差值,通过控制循环(reconciliation loop)驱动工作节点(kubelet + ③)执行操作,使实际状态收敛到期望状态。网络层(④)提供通信基础设施,工具层(⑤)提供人机接口。