Kubernetes 管的不是容器,
是你「想要的状态」
学过 Docker 后再看 K8s 会卡在"组件太多、名词太抽象"。这份讲义换个思路:先讲透 K8s 唯一的核心思想——你只描述"我想要什么",它负责让现实一直保持成那样。理解了这条主线,后面 Pod、Service、Deployment 这些就都是为它服务的零件。遇到易考易混处会用橙色「考点」框点一下。
K8s 是什么 + 集群长什么样
Docker 管一台机器上的几个容器;当容器有几十上百个、还要跨多台机器、自动重启、自动扩容时,就需要一个"总调度系统"——这就是 Kubernetes(K8s)。
核心思想:声明式 + 自愈(最重要,先记牢)
- 声明式:你描述"想要的结果",而不是"一步步怎么做"。
- 自愈:Pod 挂了、节点宕了,K8s 自动重建/迁移,维持期望副本数。
- Helm 是 K8s 的包管理器(类比手机应用商店 / apt / npm),用 Chart 一键安装整套应用。
架构控制面(大脑)+ 工作节点(干活的)
一个 K8s 集群分两部分:控制面 Control Plane 负责决策与记账,工作节点 Node 负责真正跑你的容器。
CNI 插件(Calico、Flannel、Cilium 等)负责给 Pod 分配 IP、打通 Pod 间网络——它解决的是"网络",而存储是 CSI 的事。
Pod:K8s 的最小运行单位
K8s 不直接管"容器",而是管 Pod。Pod 是调度和运行的最小单位,里面可以装一个或多个紧密协作的容器。
概念Pod 是什么
- initContainer(初始化容器):在主容器之前先跑的"准备工序",按顺序串行执行,前一个成功才跑下一个,全部成功后才启动主容器(常用于等依赖、初始化数据)。
生命周期Pod 的状态、重启策略、优雅终止
- 阶段(phase):
Pending(待调度)、Running、Succeeded、Failed、Unknown。 - restartPolicy(重启策略):只有
Always/OnFailure/Never三种。 - 优雅终止:删 Pod 时不会立刻杀,先发
SIGTERM让程序收尾,等terminationGracePeriodSeconds(默认 30 秒),仍不退出才发SIGKILL强杀。 - QoS 等级:
Guaranteed/Burstable/BestEffort三档,资源紧张时优先牺牲 BestEffort。
控制器:谁来保证 Pod 一直按期望跑
你几乎从不直接创建 Pod,而是创建"控制器",由它替你维持 Pod。不同场景用不同控制器。
家族常见控制器一览
| 控制器 | 干什么 / 何时用 |
|---|---|
| ReplicaSet | 保证指定数量的 Pod 副本一直在跑(Deployment 底层就靠它) |
| Deployment | 管理无状态应用,声明式 + 支持滚动更新/回滚(最常用) |
| StatefulSet | 管理有状态应用(数据库等):稳定名字 + 有序启停 + 独立存储 |
| DaemonSet | 保证每个节点跑一个 Pod(日志/监控 agent、网络插件) |
| Job / CronJob | 一次性任务 / 定时任务 |
| 对比 | Deployment | StatefulSet |
|---|---|---|
| Pod 名称 | 随机哈希 | 有序号(mysql-0、mysql-1) |
| 网络标识 | 不稳定 | 稳定 |
| 存储 | 共享或不持久 | 每个 Pod 独立 PVC |
| 启停顺序 | 并行 | 顺序(0→N,删除逆序) |
| 适用 | 无状态应用 | 有状态应用(数据库) |
backoffLimit 限制(默认 6 次)。滚动更新怎么做到"换版本不停服"
两个旋钮控制节奏:maxUnavailable(最多允许几个不可用)、maxSurge(最多额外多起几个)。以 maxUnavailable=0, maxSurge=1 为例推一遍:
maxUnavailable=0→ 任何时刻可用数不能低于期望数,即不能先删旧的。maxSurge=1→ 总数最多到"期望+1",即允许临时多起一个。- 结论:只能先起 1 个新 Pod、就绪后再删 1 个旧 Pod,如此逐个替换 → 零中断、较慢。
kubectl rollout undo deploy/web # 回滚到上一个版本
maxUnavailable=0, maxSurge=1 = 先创建新 Pod、再删旧 Pod;② 回滚用 kubectl rollout undo。Service & Ingress:怎么找到 Pod、怎么对外暴露
Pod 会被随时重建,IP 一直变。想稳定地访问它们,就要在前面加一层固定入口——这就是 Service;想按域名/路径把外部 HTTP 流量分发出去,再加一层 Ingress。
Service一组 Pod 的"固定门牌 + 负载均衡"
- 用 Service 名称(DNS)访问:集群内 CoreDNS 把 Service 名解析成稳定的 ClusterIP,所以代码里写服务名而不是写死 IP。
- Headless Service(
clusterIP: None):不分配 ClusterIP、不做负载均衡,DNS 直接返回各 Pod 的 IP 列表(常配合 StatefulSet 直连某个 Pod)。 - ExternalName:不代理流量,只返回一条 CNAME,把集群内的服务名映射到一个外部域名(让内部用统一名字访问外部服务)。
- 查后端:
kubectl get endpoints或describe svc都能看 Service 关联了哪些 Pod。
Ingress七层"大堂经理",按域名/路径分流
Service 偏 4 层;Ingress 在更上层,按 HTTP 的域名和路径(如 /api 进后端、/ 进前端)把外部请求分发到不同 Service,还能统一管 HTTPS 证书。
探针:Liveness vs Readiness
K8s 怎么知道你的容器"是不是还活着""能不能接客"?靠两种探针。它俩名字像,效果完全不同,是高频考点。
两种探针一个管重启,一个管流量
| Liveness 存活探针 | Readiness 就绪探针 | |
|---|---|---|
| 它问什么 | "你还活着吗?" | "你准备好接客了吗?" |
| 失败后果 | 重启容器 | 从 Service 的 Endpoints 摘除(不再转发流量,但不重启) |
| 用途 | 程序死锁/卡死时自动救活 | 启动慢/临时繁忙时,先别给它发请求 |
配置与存储:ConfigMap / Secret / PV / PVC
代码不该把配置和密码写死。配置外置用 ConfigMap/Secret;数据要持久化、活得比 Pod 久,就用 PV/PVC。
配置ConfigMap vs Secret
| ConfigMap | Secret | |
|---|---|---|
| 用途 | 非敏感配置(参数、配置文件) | 敏感信息(密码、token、证书) |
| 数据形式 | 明文 | base64 编码(注意:只是编码,不是加密) |
存储PV 与 PVC
- 绑定主要看容量、访问模式、StorageClass是否匹配(也可用标签选择器辅助筛选);PVC 不必指定具体 PV 名(动态供给会自动建 PV)。
- 访问模式:
ReadWriteOnce(RWO)、ReadOnlyMany(ROX)、ReadWriteMany(RWX)。 - 回收策略(Retain/Delete/Recycle)决定删 PVC 后 PV 上的数据怎么处理。
调度与资源:Pod 该去哪、能用多少
两个问题:① 怎么控制 Pod 调度到哪些节点(Taint/Toleration、nodeSelector);② 怎么声明 Pod 的资源用量(requests/limits),以及自动扩缩(HPA)和命名空间配额(ResourceQuota)。
调度Taint(污点)与 Toleration(容忍)
资源requests / limits / HPA / ResourceQuota
requests 像订位时说"我至少要一张能坐 4 人的桌"——调度器据此预留资源、选节点;limits 是"上限",真用超了会被限流(CPU)或杀掉(内存 OOM)。- requests:调度依据(预留下限);limits:运行上限。两者作用不同。
- HPA(水平自动扩缩):按 CPU/内存(或自定义指标)使用率,自动增减 Pod 副本数(需 metrics-server)。
- ResourceQuota:限制单个 Namespace 内的资源总量与对象数量。
网络与安全:谁能通、谁能做什么
先记住 K8s 网络的"默认全通"原则,再看怎么用 NetworkPolicy 收紧、用 RBAC 管权限、用 SecurityContext 收紧 Pod。
网络模型三条硬性原则
- 每个 Pod 有独立 IP;同一 Pod 内的容器共享这个 IP。
- 所有 Pod 之间可以不经 NAT 直接用 IP 互通(默认扁平、全通)。
- Service 只是可选的稳定入口,Pod 并非"必须经 Service"才能通信。
权限RBAC 与 SecurityContext
- RBAC:控制"谁(用户/ServiceAccount)能对什么资源做什么操作"。
Role只在某个 Namespace 内有效;ClusterRole作用于整个集群。 - SecurityContext:收紧 Pod/容器的权限,可设运行用户、Linux Capabilities、SELinux 标签,也能用
runAsNonRoot: true禁止以 root 运行。
runAsNonRoot 限制 root——"不能限制 root 权限"是错误说法。kubectl 命令地图 & 排错速查
最后把高频命令按"做什么"归类。记住每条命令的用途,选择题里的命令辨析就稳了。
命令地图看 / 改 / 调试
| 命令 | 用途 |
|---|---|
| kubectl get pods -o wide | 列资源;-o wide 显示 Pod 在哪个节点 |
| kubectl get pods -w | -w(watch)持续监听资源变化 |
| kubectl describe pod | 看详细信息 + 事件(排错首选) |
| kubectl logs --tail=100 -f | 看日志末尾 100 行并持续跟踪 |
| kubectl exec -it … -- sh | 进容器开交互终端(-i 输入、-t 伪终端) |
| kubectl explain pod.spec | 查 API 资源字段文档 |
| kubectl top pod/node | 看 CPU/内存用量(需 metrics-server) |
| kubectl version | 看客户端/服务端版本 |
| kubectl get events --sort-by=.metadata.creationTimestamp | 看事件并按时间排序 |
| kubectl run test --image=busybox -it --rm | 跑一个临时测试容器,退出即删 |
两组易混apply/create 与 安全删节点
- apply vs create:
create是命令式、只能创建(对象已存在会报错);apply是声明式,能创建也能更新(反复对账)。 - 安全删节点:先
kubectl drain <node>驱逐 Pod(并标记不可调度),等工作负载迁走后再kubectl delete node。直接删或关机会中断业务。
describe、看字段文档用 explain、持续监听用 -w、节点定位用 -o wide;② apply 可建可改、create 只能建;③ 安全删节点 = 先 drain 再 delete;④ 临时容器用 kubectl run ... --rm。