从零搞懂 Kubernetes:架构剖析 + YAML 实战 + 常用命令速查
从零搞懂 Kubernetes:架构剖析 + YAML 实战 + 常用命令速查
写在前面:本文基于 Kubernetes v1.36(代号 Haru)编写,适用于 v1.30+ 版本集群。文中所有示例均经过实测验证,可直接复制使用。
一、为什么需要 Kubernetes?
在容器化时代,Docker 解决了"应用打包"的问题,但当规模从几个容器膨胀到成百上千个时,运维噩梦才刚刚开始:
| 痛点 | 具体场景 |
|---|---|
| 规模管理 | 手动 docker run 启动 200 个容器?不现实 |
| 故障自愈 | 容器崩溃后谁来自动拉起? |
| 滚动更新 | 如何做到零停机发布新版本、出问题秒级回滚? |
| 负载均衡 | 请求怎么均匀分发到后端多个实例? |
| 资源调度 | 哪个节点剩余资源最多?哪个节点最适合跑这个服务? |
Kubernetes(简称 K8s)正是为解决上述问题而生的容器编排平台。它的核心价值可以浓缩为四句话:
- 声明式管理 —— 你只管写"我想要什么",K8s 负责把现实掰到你想要的样子
- 自动化运维 —— 调度、部署、伸缩、自愈,全程无需人工干预
- 解耦架构 —— 应用逻辑与底层基础设施彻底分离,上云下云随意迁移
- 生态可扩展 —— 通过 CRD、Operator、Webhook 等机制无限延伸能力边界
二、K8s 集群架构全景图
K8s 采用经典的 控制平面(Control Plane)+ 工作节点(Worker Node) 分层架构。控制平面是"大脑",工作节点是"手脚",两者通过 API Server 紧密协作。
下面逐一拆解每个组件的职责,这是面试高频考点,建议熟记。
2.1 控制平面四大核心
🧠 kube-apiserver —— 集群唯一入口
- 暴露 REST API,是所有内部和外部通信的唯一通道
- 所有组件(kubectl、kubelet、控制器等)都必须通过它来读写集群状态
- 无状态设计,可以水平扩展多实例
- 负责认证(Authentication)、授权(Authorization)、准入控制(Admission Control)
- 唯一与 etcd 直接对话的组件,安全边界非常清晰
💡 记忆技巧:把 API Server 想象成公司前台——所有访客(请求)都必须先登记,由前台统一转达。
💾 etcd —— 集群唯一真相源
- 高可用的分布式键值存储,基于 Raft 共识算法保证强一致性
- 持久化存储所有集群数据:Pod、Service、ConfigMap、Secret 等一切对象的配置和状态
- 生产环境建议部署 3 / 5 / 7 节点的 etcd 集群以保证高可用
- 只有 API Server 能直接访问 etcd,简化了安全模型和一致性保证
⚠️ 血的教训:etcd 数据务必定期备份!它是整个集群的"命根子",丢了就全完了。
📋 kube-scheduler —— 智能调度器
- 监听 API Server,发现未被调度的新 Pod
- 采用 “过滤 → 评分” 两阶段算法,为 Pod 挑选最优 Node
- 考虑因素包括:
- 资源需求:CPU、内存的 Request 和 Limit
- 亲和性规则:NodeSelector、NodeAffinity、PodAffinity/AntiAffinity
- 数据局部性:优先调度到已有相关数据的节点
- 干扰度(Disruption):避免把高负载 Pod 堆到同一节点
- 只做决策,不负责执行——实际拉起容器是 kubelet 的活
🤖 kube-controller-manager —— 自动驾驶系统
- 运行一系列控制循环(Control Loop),不断将"实际状态"向"期望状态"靠拢
- 每个控制器逻辑上独立,但编译为单个二进制文件、运行在一个进程中
- 核心控制器一览:
| 控制器 | 职责 |
|---|---|
| Node Controller | 监控节点健康,宕机时标记并驱逐 Pod |
| ReplicaSet Controller | 确保指定数量的 Pod 副本始终运行 |
| Endpoints Controller | 维护 Service 与 Pod 的映射关系 |
| ServiceAccount Controller | 为新命名空间创建默认账户和 Token |
| Deployment Controller | 管理滚动更新和回滚 |
2.2 工作节点三大组件
👷 kubelet —— 节点上的"工头"
- 与控制平面通信的节点代理
- 监听 API Server 下发的指令,管理本节点 Pod 的完整生命周期
- 通过 CRI(容器运行时接口) 调用底层运行时拉镜像、启容器
- 定期向 API Server 上报节点和 Pod 的状态
- 执行 存活探针(LivenessProbe) 和 就绪探针(ReadinessProbe)
- ⚠️ 只管理 K8s 创建的容器,不管"野生"容器
🔀 kube-proxy —— 网络代理与负载均衡
- 维护节点上的网络规则,实现 Service 的流量转发
- 支持三种模式:
- iptables(默认):利用内核 netfilter 规则,性能不错
- ipvs(推荐):基于内核 L4 负载均衡,性能更优,支持更多算法
- userspace(已废弃):早期方案,性能差
- 类比:就像公司电话总机,把打进来的外部电话(请求)转接到正确的分机(Pod)
📦 Container Runtime —— 容器的真正执行者
- 负责下载镜像、解压、运行容器
- K8s 通过 CRI 标准接口 对接多种运行时,不绑定某一种
- 常见选择:
- containerd(当前主流,轻量高效)
- CRI-O(专为 K8s 设计,极简主义)
- Docker Engine(已废弃内置支持,内部仍用 containerd)
三、Pod:K8s 的最小调度单元
3.1 什么是 Pod?
Pod 是 K8s 中最小的可部署计算单元。可以把 Pod 理解为一个"逻辑主机"——它封装了:
- 一个或多个应用容器
- 共享的存储卷(Volume)
- 独立的网络 IP
- 管理容器运行方式的策略
关键特性:
- K8s 调度的最小单位是 Pod,不是容器
- Pod 内的容器共享网络命名空间(同一 IP、可 localhost 通信)
- Pod 内的容器共享存储卷
- Pod 内的容器同生共死(生命周期一致)
3.2 单容器 vs 多容器 Pod
单容器 Pod(最常见):一个 Pod 只跑一个应用容器,Pod 就是这个容器的"壳"。
多容器 Pod(Sidecar 模式):当多个容器需要紧密协作时使用。典型场景:
- 日志收集:主容器跑业务,Sidecar 容器负责采集日志并推送到 ELK
- 服务网格:主容器跑应用,Sidecar(如 Envoy)处理流量劫持和治理
- 适配器模式:主容器输出非标准格式,Sidecar 做格式转换
📌 经验法则:如果容器之间不需要共享网络/存储,就拆成独立 Pod;如果必须 localhost 通信或共享文件,才放同一个 Pod。
四、YAML 资源清单文件详解
K8s 的声明式管理依赖 YAML 文件来描述"期望状态"。一个标准的资源清单包含四个根字段:
apiVersion: apps/v1 # API 版本,不同资源对应不同版本
kind: Deployment # 资源类型
metadata: # 元数据(名称、标签、命名空间等)
name: my-app
namespace: production
spec: # 期望状态(核心配置区)
replicas: 3
# ... 具体配置因资源类型而异
# status: # 当前状态(由 K8s 自动维护,用户不写)
4.1 各字段说明
| 字段 | 说明 |
|---|---|
apiVersion | API 版本号,可用 kubectl api-resources 查看所有资源对应的版本 |
kind | 资源种类,如 Pod、Deployment、Service、ConfigMap、Ingress 等 |
metadata | 资源的身份标识:name(必填)、namespace(默认 default)、labels 等 |
spec | 资源的期望状态描述,不同 kind 结构完全不同 |
4.2 一个完整的 Deployment 示例
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx-container
image: nginx:1.25
ports:
- containerPort: 80
env:
- name: ENV_VAR_NAME
value: "production"
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 10
volumes:
- name: config-volume
configMap:
name: nginx-config
4.3 探针机制(重点)
| 探针类型 | 作用 | 失败后果 |
|---|---|---|
| LivenessProbe | 检测容器是否存活 | 杀死容器并重启 |
| ReadinessProbe | 检测容器是否就绪 | 从 Service 后端摘除,不接收流量 |
| StartupProbe | 检测慢启动应用是否就绪 | 在成功前不会执行 liveness 检查 |
三种探针都支持 httpGet、tcpSocket、exec 三种检测方式。
五、kubectl 常用命令速查表
kubectl 命令的通用语法:
kubectl [command] [TYPE] [NAME] [flags]
5.1 资源查看类
# 查看所有 Pod(默认命名空间)
kubectl get pods
# 查看所有命名空间的 Pod
kubectl get pods -A
kubectl get pods --all-namespaces
# 查看指定命名空间的服务
kubectl get svc -n <namespace>
# 查看所有 Deployment
kubectl get deployments
# 宽格式输出(含节点信息)
kubectl get pods -o wide
# 查看节点状态
kubectl get nodes
# 以 YAML 格式导出资源定义(常用于备份)
kubectl get pod <pod-name> -o yaml
# 动态监听资源变化(类似 tail -f)
kubectl get pods -w
5.2 资源详情与诊断
# 查看 Pod 详细信息(含事件、IP、状态)
kubectl describe pod <pod-name>
# 查看 Node 详细信息
kubectl describe node <node-name>
# 查看 Deployment 详情
kubectl describe deployment <deployment-name>
5.3 创建 / 更新 / 删除
# 从 YAML 文件创建资源(首次创建用)
kubectl create -f manifest.yaml
# 创建或更新资源(声明式,推荐日常使用)
kubectl apply -f manifest.yaml
# 从 URL 直接创建
kubectl apply -f https://example.com/manifest.yaml
# 删除 YAML 定义的资源
kubectl delete -f manifest.yaml
# 删除指定 Pod
kubectl delete pod <pod-name>
# 强制删除卡在 Terminating 的 Pod
kubectl delete pod <pod-name> --force --grace-period=0
# 删除命名空间下所有 Pod
kubectl delete pods --all -n <namespace>
5.4 日志与调试(排障利器)
# 查看 Pod 日志
kubectl logs <pod-name>
# 多容器 Pod 中查看指定容器日志
kubectl logs <pod-name> -c <container-name>
# 实时跟踪日志(类似 tail -f)
kubectl logs -f <pod-name>
# 查看上一次崩溃的日志(排障超有用)
kubectl logs -p <pod-name>
# 进入 Pod 交互式终端
kubectl exec -it <pod-name> -- /bin/bash
# 多容器 Pod 中进入指定容器
kubectl exec -it <pod-name> -c <container-name> -- /bin/sh
# 不进入交互模式,直接执行命令
kubectl exec <pod-name> -- ls /app
5.5 端口转发
# 本地 8080 → Pod 80
kubectl port-forward <pod-name> 8080:80
# 本地 8080 → Service 80
kubectl port-forward service/<service-name> 8080:80
# 后台运行
kubectl port-forward <pod-name> 8080:80 &
5.6 辅助命令
# 查看所有资源类型及其 API 版本
kubectl api-resources
# 查看 YAML 字段含义(官方文档内嵌,超好用)
kubectl explain pod.spec.containers
# 查看集群信息
kubectl cluster-info
# 切换命名空间(避免每次 -n)
kubectl config set-context --current --namespace=test-dev
六、实战:从零部署一个 Nginx 服务
理论讲完,动手才是王道。下面演示如何在本地 K8s 环境(Minikube / Kind / Docker Desktop 均可)部署一套完整的 Nginx 服务。
6.1 创建命名空间
# 01-namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: web-demo
6.2 创建 Deployment
# 02-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
namespace: web-demo
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "50m"
limits:
memory: "128Mi"
cpu: "100m"
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 5
6.3 创建 Service 暴露服务
# 03-service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
namespace: web-demo
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP
6.4 一键部署 & 验证
# 依次创建资源
kubectl apply -f 01-namespace.yaml
kubectl apply -f 02-deployment.yaml
kubectl apply -f 03-service.yaml
# 也可以用 --- 分隔符合并到一个文件,一条命令搞定
kubectl apply -f all-in-one.yaml
# 查看部署进度
kubectl get pods -n web-demo -w
# 查看 Service 详情和端口映射
kubectl get svc -n web-demo
# 进入 Pod 内部验证
kubectl exec -it -n web-demo <pod-name> -- /bin/bash
# 查看 Pod 日志
kubectl logs -n web-demo <pod-name>
# 端口转发到本地,浏览器访问验证
kubectl port-forward -n web-demo svc/nginx-svc 8080:80
# 浏览器打开 http://127.0.0.1:8080 即可看到 Nginx 欢迎页
6.5 合并版 YAML(一个文件搞定)
# all-in-one.yaml
apiVersion: v1
kind: Namespace
metadata:
name: web-demo
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
namespace: web-demo
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
resources:
requests:
memory: "64Mi"
cpu: "50m"
limits:
memory: "128Mi"
cpu: "100m"
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
namespace: web-demo
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
type: ClusterIP
💡 使用
---分隔符可以在一个 YAML 文件中定义多个资源,K8s 会按顺序依次创建。
七、排障思路总结
当 Pod 出现异常时,推荐按以下顺序排查:
kubectl get pods → 看状态(Pending? CrashLoopBackOff?)
kubectl describe pod <pod-name> → 看事件(镜像拉取失败?调度失败?)
kubectl logs <pod-name> → 看应用日志
kubectl logs -p <pod-name> → 看上一次崩溃日志
kubectl exec -it <pod-name> -- sh → 进容器排查
kubectl get events -n <ns> → 看命名空间级别事件
八、学习建议
- 先跑通再理解:用 Minikube 或 Kind 在本地搭一套单节点集群,把本文所有命令敲一遍
- 善用
kubectl explain:这是内置的官方文档,比翻网页快得多 - 从 Pod → Deployment → Service 的顺序逐步学习,不要一上来就搞 Ingress + Istio
- 多看官方文档:kubernetes.io 的中文文档质量已经很高了
参考资源:
- Kubernetes 官方文档:https://kubernetes.io/zh-cn/docs/
- Kubernetes v1.36 Release Notes
kubectl api-resources/kubectl explain命令输出
更多推荐
所有评论(0)