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-apiserver | REST 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 网络
| 资源 | 用途 |
|---|---|
| Service | Pod 集合的稳定 IP + DNS |
| Ingress | 7 层路由(HTTP host/path → service) |
| NetworkPolicy | Pod 级防火墙 |
| EndpointSlice | Service 后端 Pod 列表(自动维护) |
3.3 配置/存储
| 资源 | 用途 |
|---|---|
| ConfigMap | 非敏感配置 |
| Secret | 密钥/密码(base64,不是加密) |
| PersistentVolume / PVC | 存储 |
| StorageClass | 存储类型(动态供应) |
3.4 集群
| 资源 | 用途 |
|---|---|
| Namespace | 资源隔离(团队、环境) |
| Node | 工作节点 |
| ServiceAccount | Pod 身份 |
| 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-prod、frontend-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. 延伸阅读
- Kubernetes 官方教程
- 《Kubernetes in Action》Marko Lukša — K8s 入门最佳书
- kubectl 速查表
- Kubernetes the Hard Way — 从零搭集群