跳到主要内容

K8s架构与核心概念

1. 整体架构

K8s 集群分两类节点:

┌─────── Control Plane(master)────────┐
│ │
│ ┌──────────┐ ┌─────────────────┐ │
│ │ kube-api │ ←→ │ etcd │ │
│ │ server │ │ (KV 存储集群) │ │
│ └──────────┘ └─────────────────┘ │
│ ↑ │
│ │ │
│ ┌────┴──────┐ ┌──────────────────┐ │
│ │ scheduler │ │ controller-mgr │ │
│ └───────────┘ └──────────────────┘ │
│ │
└────────────────────────────────────────┘

┌─────────── Worker Node ────────────────┐
│ │
│ ┌─────────┐ ┌──────────┐ ┌────────┐│
│ │ kubelet │ │kube-proxy│ │ CRI ││
│ │ │ │ │ │ (容器) ││
│ └─────────┘ └──────────┘ └────────┘│
│ │
│ Pod Pod Pod ... │
└────────────────────────────────────────┘

1.1 Control Plane 组件

组件职责
kube-apiserverREST API 入口,所有交互必经
etcd强一致性 KV,保存集群所有状态。挂了集群停摆
kube-scheduler决定新 Pod 调度到哪个节点
kube-controller-manager各种控制器(Deployment、ReplicaSet、Node、Service 等)的总进程
cloud-controller-manager云厂商集成(LB、磁盘、节点)

1.2 Worker Node 组件

组件职责
kubelet节点代理,管理 Pod 生命周期
kube-proxy维护 Service 的 iptables / IPVS 规则
CRI(容器运行时)containerd / CRI-O,跑容器
CNI(网络插件)Calico、Flannel、Cilium 等

2. 控制器模式(声明式核心)

K8s 不是命令式("启动 3 个 Pod"),是声明式("我要 3 个 Pod 跑着")。控制器循环:

while (true) {
current = 实际状态(从 apiserver 读)
desired = 期望状态(yaml 声明)
if (current != desired) {
采取行动让两者收敛
}
sleep(短)
}

举例:Deployment 控制器看到 replicas: 3 但只有 2 个 Pod → 创建 1 个;看到节点挂了 1 个 Pod → 在另一节点起。

理解这个模式才能理解为什么"删 Pod 它会自动回来"——是控制器在维持期望状态。要真删,删上层资源(Deployment)。

3. 核心资源对象

3.1 工作负载

资源用途
Pod最小调度单位,1+ 容器
Deployment无状态应用,滚动更新、扩缩容
StatefulSet有状态(数据库)+ 稳定网络标识 + 顺序
DaemonSet每节点一个 Pod(日志收集、节点监控)
Job一次性任务
CronJob定时任务

3.2 网络

资源用途
ServicePod 集合的稳定 IP + DNS
Ingress7 层路由(HTTP host/path → service)
NetworkPolicyPod 级防火墙
EndpointSliceService 后端 Pod 列表(自动维护)

3.3 配置/存储

资源用途
ConfigMap非敏感配置
Secret密钥/密码(base64,不是加密)
PersistentVolume / PVC存储
StorageClass存储类型(动态供应)

3.4 集群

资源用途
Namespace资源隔离(团队、环境)
Node工作节点
ServiceAccountPod 身份
Role / RoleBinding权限

4. 命名空间

kubectl get ns
kubectl create ns frontend
kubectl get pods -n frontend
kubectl get pods --all-namespaces

Namespace 隔离的:

  • 资源名(同 ns 下不能重名)
  • DNS(<svc>.<ns>.svc.cluster.local
  • 资源配额(ResourceQuota)

不隔离的:节点、PV、ClusterRole。

约定:

  • kube-system 系统组件
  • default 默认 ns,生产别用
  • <team>-<env>frontend-prodfrontend-staging

5. 标签与选择器

K8s 用标签做关联(Service 找哪些 Pod、Deployment 管哪些 Pod)。

metadata:
labels:
app: my-frontend
version: v1.0.0
tier: web
# Service 通过 selector 关联 Pod
spec:
selector:
app: my-frontend
# 标签查询
kubectl get pods -l app=my-frontend
kubectl get pods -l 'tier in (web,api)'
kubectl get pods -l 'env!=prod'

6. kubectl 与 API

任何 yaml kubectl apply -f 实际是发 HTTP PUT 到 apiserver。理解这点对调试 RBAC、查 audit log 重要。

kubectl proxy &
curl http://localhost:8001/api/v1/namespaces/default/pods | jq
kubectl get --raw=/api/v1/namespaces/default/pods

API 资源类型:

kubectl api-resources # 全部
kubectl api-versions # 所有 group/version
kubectl explain deployment.spec.template # 字段说明

7. kubeconfig

~/.kube/config 描述如何连集群:

apiVersion: v1
clusters:
- name: prod
cluster:
server: https://k8s.prod.example.com
certificate-authority-data: ...
contexts:
- name: prod-frontend
context:
cluster: prod
namespace: frontend
user: alice
current-context: prod-frontend
users:
- name: alice
user:
client-certificate-data: ...
client-key-data: ...
kubectl config get-contexts
kubectl config use-context staging
kubectl config set-context --current --namespace=frontend

工具:kubectx / kubens 切换 context / namespace 极快。

8. 常见反模式

  • 裸 Pod:不用 Deployment,崩了不会重建
  • default ns 跑生产:无隔离
  • 不打 label:service / hpa 找不到 pod
  • 依赖 etcd 数据:etcd 是 K8s 内部,不是业务数据库
  • kubectl 直接连生产 master:CI / 自动化用 ServiceAccount + 限定 namespace

9. 延伸阅读