Featured image of post K8s 从零到实战 00(番外):Minikube 快速体验

K8s 从零到实战 00(番外):Minikube 快速体验

对照实验:一条 minikube start 体验全自动集群,再拆解它背后的四层套娃结构、三条网络通道与 kicbase 缓存兜底链——含国内网络三次踩坑实录。

定位:主线(Lima + kubeadm,见 00(上)、00(下))之外的对照实验——用一条命令体验"工具帮你把集群全装好"的感觉, 从而理解主线手动搭建的每一步都被工具藏到了哪里。 体验完建议删掉,主线继续走 阶段 0(上)。

0. Minikube 与主线的区别

维度Minikube主线:Lima + kubeadm
集群怎么来一条命令,全自动每个组件亲手装
节点形态Docker 容器(或虚拟机)里的"模拟节点"完整的 Rocky Linux 虚拟机
组件可见性黑盒(etcd/apiserver 藏在容器里)透明(systemd 服务,可查可拆)
对应生产偏离较多1:1 对应
适合快速用 k8s 跑应用学懂 k8s 本身

1. 安装(Mac 上执行)

1
2
3
4
5
brew install minikube

# 验证
minikube version
# 预期输出:minikube version: v1.x.x

驱动选择:用 --driver=docker——你已装 Docker Desktop,minikube 直接复用它, 不需要再开一台虚拟机(这也是它轻量的原因:k8s 节点就是一个 Docker 容器)。

2. 启动集群(国内网络参数必加)

1
minikube start --driver=docker --image-mirror-country=cn
  • --image-mirror-country=cn:k8s 组件镜像改从阿里云镜像站拉取(registry.cn-hangzhou.aliyuncs.com/google_containers),不加会因为 gcr.io 被墙而卡死。 它等价于主线 kubeadm 配置里的 imageRepository: registry.aliyuncs.com/google_containers(阶段 1 会写到),只是一个走命令行开关、一个写进配置文件
  • 首次启动要下载节点基础镜像(约 1GB),耐心等几分钟

预期输出(结尾):

1
🏄  Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default

3. 验证集群

1
2
# 集群状态
minikube status

实测输出(2026-09-13,minikube v1.36.0 / k8s v1.33.1):

1
2
3
4
5
6
minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured
1
2
# 节点(minikube 自动配好了 Mac 上的 kubectl 上下文)
kubectl get nodes
1
2
NAME       STATUS   ROLES           AGE   VERSION
minikube   Ready    control-plane   52s   v1.33.1
1
2
# 系统组件
kubectl get pods -n kube-system
1
2
3
4
5
6
7
8
NAME                               READY   STATUS    RESTARTS   AGE
coredns-746c97786-gpmv9            1/1     Running   0          51s
etcd-minikube                      1/1     Running   0          57s
kube-apiserver-minikube            1/1     Running   0          57s
kube-controller-manager-minikube   1/1     Running   0          57s
kube-proxy-6v4nl                   1/1     Running   0          52s
kube-scheduler-minikube            1/1     Running   0          57s
storage-provisioner                1/1     Running   0          56s
1
2
3
4
# 终极验证:跑一个真 Pod(和主线的验收标准一样)
kubectl run nginx-test --image=nginx
kubectl get pods -w        # 看到 Running 后 Ctrl+C
kubectl delete pod nginx-test
1
2
NAME         READY   STATUS              RESTARTS   AGE
nginx-test   0/1     ContainerCreating   0          5s

⚠️ 若 ContainerCreating 超过一两分钟不动,是节点内的 containerd 拉不动 docker.io (Docker Hub 被墙),解法见第 5 节表格第 4 行(实测 2026-09-13 即遇到此情况); 用 kubectl describe pod nginx-test 看 Events,卡在 Pulling image "nginx" 即是。

🔍 对比观察点(体验的价值所在): 上面的命令和主线一模一样——这就是"工具标准化"的好处。 但你想想:swap 谁关的?SELinux 谁管的?pause 镜像谁换的?CNI 谁装的? 全被 minikube 藏掉了。这些答案你都知道,因为你亲手做过——这就是主线带给你的。

4. 日常管理命令

1
2
3
4
5
6
7
minikube stop            # 停止集群(数据保留)
minikube start           # 再次启动(不用再加参数,配置已记住)
minikube delete          # 彻底删除集群(体验完用它)
minikube ip              # 查看节点 IP
minikube ssh             # 进入节点容器里看看
minikube dashboard       # 打开 Web 控制台(可选,会再拉几个镜像)
minikube logs            # 启动失败时看日志

5. 国内网络预案(启动卡住时看这里)

现象原因解法
提示 cannot pull kicbase image,转而从 GitHub 下载 kicbase-vX.X.X-arm64.tar,几十 KB/s--image-mirror-country=cn 只管 K8s 组件镜像;kicbase 底座(约 1.2GB)拉取失败后,minikube 兜底从 GitHub Release 直下 tar 包,国内直连要几个小时① Ctrl+C;② 手动拉底座镜像(tag 以启动日志"正在拉取基础镜像 vX"为准):docker pull registry.cn-hangzhou.aliyuncs.com/google_containers/kicbase:v0.0.47;③ 重跑加 --base-image=registry.cn-hangzhou.aliyuncs.com/google_containers/kicbase:v0.0.47,命中本地镜像,下载整段跳过
想让 GitHub 兜底下载本身变快minikube 本体的 HTTP 下载会读 Shell 的代理变量开 Clash 后带变量重跑:HTTPS_PROXY=http://127.0.0.1:7897 minikube start --driver=docker --image-mirror-country=cn(代理也会被自动注入节点容器)
k8s 组件镜像拉取失败(preload 阶段卡住)gcr.io 被墙,或此时直连阿里云被拦确认 --image-mirror-country=cn;仍卡住就 Ctrl+C,开 Clash、带上面的代理变量重跑
Pod 的镜像(nginx 等)拉不动,ContainerCreating 卡住docker.io 被墙。注意:kubectl 跑的 Pod 由节点容器内的 containerd 拉镜像,Docker Desktop 的 registry-mirrors 管不到它① 重建集群时加 --registry-mirror=https://docker.m.daocloud.io;② 或镜像名直接带前缀:kubectl run nginx-test --image=docker.m.daocloud.io/library/nginx(可配合 minikube image pull <镜像> 先手动拉进节点);③ kubectl describe pod <名> 看 Events 确认是否卡在 Pulling
全都不行Mac 直连被拦(公司安全软件)打开 Clash(允许局域网),Docker Desktop → Settings → Resources → Proxies 填 http://127.0.0.1:7897

原理:一次 minikube start 里藏着三条网络通道,代理配置各有各的地盘

通道谁在发请求代理怎么配
① minikube CLI 自己的 HTTP 下载(GitHub 兜底 tar 包等)Mac 上的 minikube 进程shell 环境变量 HTTPS_PROXY=...,它自己会读
② dockerd 拉镜像(kicbase、业务镜像)Docker Desktop 虚拟机里的 dockerd看不到 shell 变量;只能配 Docker Desktop → Settings → Resources → Proxies
③ 节点容器内拉 K8s 组件镜像minikube 节点容器里的 containerdminikube 检测到 ① 的代理变量后会自动注入节点(127.0.0.1 自动换成 host.docker.internal,前提是 Clash 开了 Allow LAN)

Clash 的另一个坑:规则模式下,阿里云这类国内域名默认走 DIRECT(直连),根本没上代理节点。 所以"开了 Clash" ≠ “走了代理”——直连被安全软件限速时,走 DIRECT 的流量照样慢。 要让国内站点也过代理,得切全局(Global)模式。 排查时先想清楚当前卡在哪个通道,再决定改哪边的配置。

实战记录(2026-09-13):首次启动时 kicbase 拉取失败转 GitHub(74KB/s,ETA 4 小时+), 实测当时 Mac 直连阿里云镜像站只有 11KB/s——与 Lima 虚拟机那次是同根因(企业安全软件拦截)。 排查中发现 kicbase 镜像本地已存在(docker images | grep kicbase 确认), 于是用 --base-image 直接指向本地镜像跳过下载。注意这只解决了底座镜像, 后续 preload 阶段还要从阿里云拉几百 MB 的 K8s 组件镜像,网络不好时仍需代理。

实战记录 2(同日):中途 Ctrl+C 后重跑依然很慢,且开 Clash + HTTPS_PROXY 无效。 查 ~/.minikube/logs/lastStart.txt 发现剧情已变: 上次没下完的 tar 包(464MB/1.17GB)残留在 ~/.minikube/cache/kic/ 里, minikube 误判"有缓存",加载时报 tag ... not found in tarball(残缺包), 随后走第二兜底——从 docker.io(Docker Hub,被墙) 拉 kicbase/stable。 而 HTTPS_PROXY 只对 minikube 本体的 HTTP 下载生效,管不到 Docker Desktop 里 dockerd 的拉取 (dockerd 走代理要在 Docker Desktop → Settings → Resources → Proxies 里配)。 解法:删掉残缺缓存包 rm ~/.minikube/cache/kic/arm64/kicbase_*.tar, 加 --base-image 指向本地完好镜像重跑。

教训:minikube 启动卡住时,先看 ~/.minikube/logs/lastStart.txt 确认到底卡在哪一步、在连谁, 再决定对策——不同阶段(CLI 下载 / dockerd 拉取 / 节点内 containerd 拉取)走的网络通道完全不同。

实战记录 3(同日):集群验证时 kubectl run nginx-test --image=nginx 卡 ContainerCreating, kubectl describe pod 显示 Pulling image "nginx" 超百秒——节点内 containerd 直连 docker.io 被墙 (通道 ③,Docker Desktop 的镜像代理设置管不到)。 解法:minikube image pull docker.m.daocloud.io/library/nginx 预拉进节点(约 6 分钟), 删掉旧 Pod 后用带前缀的镜像名重建,5 秒 Running。

注意:minikube 跑在 Docker Desktop 的虚拟机里,它的网络是 Docker Desktop 管的, 和你 Lima 虚拟机的 192.168.5.x/192.168.64.x 完全是两个世界,互不影响。 排查思路可复用主线的分层法(阶段 0(上)附录 A)。

6. 体验完收拾干净

1
2
minikube delete
# Docker Desktop 里的 minikube 容器会被删除;brew uninstall minikube 可卸载本体

7. 原理深挖:一条命令背后发生了什么

7.1 四层套娃:你的 Pod 实际跑在哪

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
macOS(你的 Mac)
└── Docker Desktop 的 Linux 虚拟机
    │   容器共享宿主机内核,macOS 的内核不是 Linux,
    │   所以 Mac 上要跑 Linux 容器必须先有这台 Linux VM
    └── minikube 节点容器(kicbase 镜像)
        │   一个"假装自己是台完整服务器"的容器:内置 systemd、containerd、kubeadm
        ├── systemd ── 管理 kubelet(和主线 Rocky 虚拟机里一模一样的形态)
        ├── containerd ── 节点自己的容器运行时(独立于 Docker Desktop 的 dockerd)
        ├── 控制面静态 Pod:etcd / apiserver / scheduler / controller-manager
        │   (清单位于 /etc/kubernetes/manifests,kubeadm 的标准做法)
        └── 你的业务 Pod(nginx-test 就跑在这里)

要点:minikube 节点不是虚拟机,而是 Docker Desktop 那台 Linux VM 里的一个容器。 kicbase(Kubernetes in Container)的绝活是把 systemd 塞进容器, 于是 kubelet、containerd 都能以真实服务器的形态运行—— 你在主线阶段 0/1 亲手做的每件事,它都在这个容器里替你预置好了。

7.2 对照主线:它把哪些步骤藏掉了

主线亲手做(阶段 0/1)minikube 藏到哪
关 swap、注释 fstabkicbase 镜像本身无 swap
SELinux 设宽容、关防火墙容器里没有这套安全体系
加载 br_netfilter、调 sysctl节点容器启动时自动完成
装 containerd、配 certs.d 镜像代理containerd 内置于 kicbase;--registry-mirror 可注入代理配置
kubeadm init、证书签发minikube 在节点内调用内置 kubeadm 自动完成
装 CNI 插件内置轻量 CNI(kindnet)默认装好
写 kubeconfig、切上下文自动写入 ~/.kube/config 并设为当前上下文

7.3 kubectl 是怎么连上"容器里的集群"的

  1. API server 在节点容器内部监听 8443
  2. Docker 把容器的 8443 映射到 Mac 的 127.0.0.1:<随机端口>
  3. minikube 把 server 地址 + CA + 客户端证书写进 ~/.kube/config 的 minikube 上下文

动手验证(两个端口应一致):

1
2
docker port minikube                        # 8443/tcp -> 127.0.0.1:xxxxx
kubectl config view --minify | grep server  # server: https://127.0.0.1:xxxxx

7.4 进节点亲眼看看(强烈建议)

1
2
3
4
5
minikube ssh                                # 进节点容器
sudo systemctl status kubelet --no-pager    # kubelet 就是 systemd 服务,和主线一致
ls /etc/kubernetes/manifests                # 控制面静态 Pod 清单,kubeadm 同款
sudo crictl images                          # 节点内 containerd 的镜像(前缀全是阿里云)
exit

看完你就明白:minikube ≈ 把"阶段 0 + 阶段 1 的全部手工"自动化后塞进一个容器。 它替你省掉的每一步,都是你主线练过的每一步。

7.5 缓存与兜底链(呼应第 5 节实战记录)

  • K8s 组件镜像:minikube 先在 Mac 侧下载成 tar 存到 ~/.minikube/cache/images/,再装进节点——所以第二次 start 飞快
  • kicbase 底座的获取兜底链:本地 docker 已有 → 镜像仓库拉取(cn 参数指向阿里云)→ GitHub Release 直下 tar 包 → docker.io/kicbase/stable;缓存 tar 在 ~/.minikube/cache/kic/,残缺缓存会投毒(实战记录 2)
  • minikube image pull <镜像> = 替你进节点让 containerd 拉镜像(通道 ③),拉完业务 Pod 秒起(实战记录 3)

7.6 为什么说它"偏离生产"

  • 节点是容器不是虚拟机:没有独立内核(与 Docker Desktop 的 VM 共享)、systemd 是被改造塞进容器的、网络是 docker 桥接而非真实节点网卡
  • 单节点:控制面和业务负载挤在一起,练不到多节点、高可用
  • 结论:它适合"用 K8s 跑东西",不适合"理解 K8s 怎么活的"——所以本篇只是番外,主线 Lima + kubeadm 才是正菜

小结

Minikube 一分钟给你集群,主线一天教你集群——两个都体验过, 你就同时拥有了"用的效率"和"修的底气"。回主线:阶段 1「搭建集群」(系列第 1 篇,即将发布)。

使用 Hugo 构建
主题 Stack 由 Jimmy 设计