本地集群与 kubectl
这一课你将能做到
- 在本机用 minikube(或 kind)起一个可用集群,并用 kubectl 验证 Node 就绪
- 跑通最小闭环:创建 Pod → 暴露 Service → 浏览器/curl 访问成功
- 掌握日常五命令 get / describe / logs / exec / apply,理解 kubeconfig 与 context 的作用
为什么要学
看十遍文档不如亲手把一个 Pod 跑起来。K8s 的「手感」来自三个动作的循环:改期望(apply)→ 看事件(describe)→ 读日志(logs)。本站联调时你习惯 docker logs 看 backend;到集群里只是把入口换成 kubectl,肌肉记忆可以直接迁移。另外,面试里「你本地怎么搭 K8s 环境」是验证真动手的送分题——答出 minikube/kind 的选型理由,就赢过大多数只会背书的人。
环境选型先想清楚:
| 方案 | 适合 | 一句话 |
|---|
| minikube | 入门首选,插件丰富 | ingress/metrics-server 一键开,教程最多 |
| kind | CI、轻量、多节点实验 | 基于 Docker,启动快 |
| Docker Desktop 自带 K8s | 已装 Docker Desktop | 最省事但可玩性低 |
| 云托管(ACK/EKS 等) | 接近生产 | 要花钱,后期再上 |
本课以 minikube 为主线,前提:Windows + Docker Desktop 已安装且在运行。
先建立图像
你的 Windows 笔记本
├─ kubectl(客户端,发指令)
└─ minikube 起的「本地集群」(跑在一个 Docker 容器里)
├─ 控制平面组件(API Server / etcd / Scheduler…)
└─ 一个 Node(与控制平面同机)
kubectl 的一切操作都通过 ~/.kube/config(kubeconfig)找到集群地址与凭证
kubeconfig 直觉:它就是 kubectl 的「通讯录」。kubectl config get-contexts 列出所有记录过的集群,current-context 是当前拨给谁。以后连公司集群、连本地集群,切换的就是这份文件——连错 context 等于对错误环境发布,动手前先看一眼。
跟着做
步骤 1:安装 minikube
Windows PowerShell:
winget install -e --id Kubernetes.minikube
重开终端验证:
minikube version
前提检查:Docker Desktop 正在运行(minikube 默认用它当驱动)。kubectl 上一课已装好。
步骤 2:启动集群并验证
minikube start --driver=docker
首次会下载镜像,等几分钟。完成后验证三连:
kubectl get nodes
kubectl cluster-info
kubectl config current-context
应看到节点 Ready、控制平面地址、当前 context 为 minikube。到这一步,第一课那条「connection refused」已经修掉了。
步骤 3:跑第一个工作负载
kubectl run hello --image=nginx:1.27-alpine --port=80
kubectl get pods -w
-w 是 watch 模式,盯着状态从 ContainerCreating 变为 Running(Ctrl+C 退出)。--port=80 只是声明容器监听 80,不会映射到宿主机——对外访问靠下一步。
步骤 4:暴露 Service 并访问
kubectl expose pod hello --type=NodePort --port=80
kubectl get svc hello
minikube service hello --url
用最后一条输出的 URL 打开浏览器,应看到 nginx 欢迎页。注意 NodePort 端口落在 30000-32767 区间。
kubectl port-forward pod/hello 8080:80
# 另开一个终端
curl http://127.0.0.1:8080
步骤 5:练熟排错三板斧
kubectl describe pod hello # 事件全景
kubectl logs hello # 应用日志
kubectl exec -it hello -- sh -c "wget -qO- 127.0.0.1 | head -3" # 进容器验证
对照本站 backend:以后 Pod 异常时,先 describe 找事件,再 logs 找原因——事件告诉你「发生了什么」,日志告诉你「应用为什么」。
步骤 6:学会集群的暂停、销毁与清理
kubectl delete svc hello
kubectl delete pod hello
minikube status # 集群健康状态
minikube stop # 停机(不删数据,下次 start 恢复)
minikube delete # 彻底销毁重置(搞乱环境时的后悔药)
把今天用到的命令整理进速查表:start/stop/status、run/expose/get/describe/logs/exec/port-forward/delete。
讲清楚要点
- kubectl 只是 API 客户端:它不在集群里,只把命令翻译成对 API Server 的 REST 调用。「kubectl 装在哪」不重要,「kubeconfig 指向哪个集群」才重要。
- 本地集群也是真集群:API、对象模型、调度逻辑与云端一致,学到的 YAML 原样可迁移;差别只在存储类、负载均衡器等基础设施相关部分。
- Pod 名常带随机后缀:日常查询用标签
-l app=xxx,别把 Pod 名复制粘贴进脚本。
- Events 藏在 describe 里:STATUS 列只有 Pending/Running 这种「结果」,Events 才有「原因」。排错先 describe。
- 本机端口冲突高发:Compose 已占 3000/8080/3306 的话,port-forward 换 18080 这类空闲端口,避免「访问到的其实是宿主机旧进程」的乌龙。
- 镜像不会自动共享:minikube 是独立的 Docker 环境,本机
docker build 的镜像对它不可见——要么推仓库,要么 minikube image load(第 12 课实战用)。
你可能会懵的地方
-
kubectl version 报连不上 server?
客户端已装但集群没起或 kubeconfig 为空。跑 minikube status 检查;没起就 minikube start。
-
minikube 和 Docker Desktop 的 K8s 开关冲突吗?
会。两者都启用时 context 列表有两个集群,操作前务必 kubectl config current-context 确认指向。建议学习期只用 minikube,关掉 Docker Desktop 的 K8s。
-
kind 用户怎么访问服务?
kind 没有 minikube service 命令,以 kubectl port-forward 为主,或建集群时在 kind 配置里加 extraPortMappings。本 track 后续都给 port-forward 等价写法。
-
kubectl run 和 YAML 该用哪个?
run 是命令式冒烟(一次性、不可复现);YAML + apply 是声明式工程实践(进 Git、可重放)。本课用 run 图快,从下一课起全面转 YAML。
-
CrashLoopBackOff 是网络问题吗?
多半不是。它是「容器进程反复退出」的退避状态,用 logs --previous 看上一次崩溃现场。常见原因:命令错、缺环境变量、连不上依赖(比如 MySQL 没起)、探针误杀。
错法对照
| 错法 | 问题 | 正解 |
|---|
| 不看 context 直接 apply | 打到错误集群/命名空间 | 每次先 config current-context |
| 删 Pod 期望「应用卸载」 | 被控制器管理时会自动重建 | 想清楚删的是 Pod 还是上层对象 |
忽略 -n 命名空间 | 「明明创建了却看不到」 | 明确 -n 或设默认命名空间 |
镜像用 latest 不锁版本 | 行为难复现 | 学习阶段钉死 tag(如 1.27-alpine) |
| 实验资源从不清理 | get all 一屏垃圾 | 课末 delete,或 minikube delete 重来 |
卡点急救
minikube start 失败,报虚拟化相关错误:确认 Docker Desktop 在跑(docker ps 能通);再看任务管理器 CPU 页「虚拟化:已启用」,未启用需进 BIOS 开 VT-x/AMD-V。
- Pod 一直
ErrImagePull / ImagePullBackOff:kubectl describe pod 看 Events 里报的镜像名与错误——拼写、tag 是否存在、网络是否可达;本地构建的镜像要 minikube image load 镜像:tag。
- NodePort 浏览器打不开:先用
minikube service hello --url 拿正确地址(minikube ip 通常不是 127.0.0.1);仍不通改用 port-forward 验证 Pod 本身是否正常,再排查防火墙。
面试常问
-
kubectl apply 的完整流程是什么?
kubectl 读取清单并与本地做 diff → 发 HTTPS 请求到 API Server → 经过认证、鉴权、准入控制(Admission)→ 写入 etcd → 相关控制器(如 ReplicaSet Controller)监听到变更并调谐 → kubelet 在目标节点创建容器。一句话总结:「apply 只是向 API Server 提交期望,真正干活的是后面的控制循环」。
-
minikube、kind、k3s 有什么区别?各用在哪?
minikube:功能完整的本地集群,驱动可选虚拟机/容器,插件生态最全,适合本地学习;kind:用 Docker 容器模拟节点,启动快,适合 CI 与多节点实验;k3s:轻量化发行版,单二进制几百 MB,适合边缘设备与资源受限环境。共同点:都实现标准 K8s API,kubectl 操作无差别。
-
kubeconfig 里有什么?多集群怎么切换?
三段:clusters(地址与 CA 证书)、users(身份凭证)、contexts(cluster+user+namespace 的组合)。kubectl config use-context <名> 切换,kubectl config get-contexts 查看。多集群是常态,发布脚本应显式指定 context 防止误发。
自测三问
kubectl get pods 与 kubectl describe pod 分别回答什么问题?
- port-forward 和 NodePort 各适合什么场合?
- 为什么「minikube 里的镜像和本机 Docker 的镜像不共享」?解决办法是什么?
小结一句话
minikube 把「一个真集群」装进笔记本,kubectl 是唯一的对话窗口;跑通 run→expose→访问→describe/logs 后,你已具备后面所有课程的实验底座——下一课用 YAML 正式认识最小调度单元 Pod。
延伸