1. 为什么本地开发还需要一个迷你集群很多刚接触容器编排的朋友都会卡在同一个坎上Kubernetes 的全套生产集群动辄三台起步的节点、复杂的网络插件、证书轮换、etcd 高可用光是搭起来就得折腾一整天结果只是想验证一个 Deployment 的滚动更新策略或者测一下 ConfigMap 热加载到底生不生效。这种“杀鸡用牛刀”的痛点在本地开发场景里特别明显而 minikube 就是冲着这个痛点来的。minikube 的本质是在你本机跑一个单节点的 Kubernetes 集群它把控制平面和 worker 节点压缩到一台机器里用虚拟机或者容器当“节点载体”。你在里面能跑 Pod、Service、Deployment、Ingress能玩 RBAC、能测 PVCAPI 行为和真实集群几乎一致但资源占用和搭建成本低了一个数量级。它解决的核心问题就是让开发者在本地拥有一块可以随便折腾、随时推倒重来的 Kubernetes 试验田。这篇文章面向的是手里有一台 Ubuntu 18.04 机器、想入门 Kubernetes 或者需要一个本地验证环境的开发者。不管你之前有没有碰过 kubectl只要你会用基本的 Linux 命令跟着走就能把集群跑起来。我会把每一步背后的原因讲清楚把踩过的坑提前标出来让你少走弯路。2. 环境准备与方案选型2.1 为什么是 Ubuntu 18.04 这个时间点Ubuntu 18.04 是个 LTS 版本很多公司的开发机和 CI 镜像至今还停留在这一代。它的内核是 4.15对容器运行时和 cgroup 的支持已经足够成熟但和更新的 20.04、22.04 相比有些工具链的默认版本偏旧这恰恰是安装 minikube 时最容易出问题的地方。比如默认的 conntrack 版本、iptables 的后端选择、systemd 的 cgroup 驱动这些细节在 18.04 上都有它自己的脾气。我之所以强调这个版本背景是因为网上大量教程是写给更新系统的直接照搬到 18.04 上经常卡在驱动或者依赖上。所以这一节我会先把地基打牢把可能冲突的东西提前处理掉。2.2 驱动选型Docker 还是虚拟机minikube 支持多种驱动常见的有 virtualbox、kvm2、docker、none。选哪个直接决定了你后面顺不顺。驱动资源占用启动速度隔离性适用场景virtualbox中慢好想完全模拟独立节点kvm2中较快好有硬件虚拟化且追求性能docker低快一般本机资源紧张、快速验证none最低最快差直接在宿主机跑风险高我的建议是如果你机器有硬件虚拟化且内存 8G 以上用 kvm2如果只是想快速跑起来、机器配置一般用 docker 驱动最省事。none 驱动虽然快但它会直接改动宿主机的网络和系统组件容易把开发机搞乱新手不建议碰。这里有个关键点docker 驱动要求你的 Docker 版本不能太老而且 minikube 会以容器的方式跑节点容器里再跑容器对 cgroup 和存储驱动有要求。Ubuntu 18.04 默认的 Docker 如果是从 apt 装的版本可能偏低建议用官方源装一个较新的稳定版。2.3 硬件与系统前置检查在动手之前先确认几件事能省掉后面一半的报错。CPU 虚拟化是否开启grep -E vmx|svm /proc/cpuinfo有输出说明支持。内存至少 2G 给集群推荐 4G 以上否则跑两个 Pod 就 OOM。磁盘留出 20G 空间minikube 的镜像和缓存会越滚越大。关闭 swapKubernetes 对 swap 很敏感不关会导致 kubelet 启动异常。关闭 swap 的命令是sudo swapoff -a要永久生效就编辑/etc/fstab把 swap 那行注释掉。这一步很多人忽略结果 kubelet 反复重启排查半天才发现是 swap 没关。提示Ubuntu 18.04 默认可能没装 conntrack而 minikube 的 kubelet 依赖它做网络连接跟踪缺了会直接报错。提前sudo apt install -y conntrack装上。3. 核心组件安装与配置实操3.1 安装 kubectl 命令行工具kubectl 是你和集群对话的唯一入口先把它装好。最稳妥的方式是从官方源拉取而不是用 apt 里那个可能过时的版本。curl -LO https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl kubectl version --client这里用install而不是mv是因为它会自动设置正确的权限和属主避免出现“权限不够无法执行”的问题。装完用kubectl version --client验证只要打印出客户端版本就说明没问题。注意此时还没有集群所以kubectl version不带--client会报连接错误这是正常的别慌。3.2 安装 minikube 本体minikube 就是一个二进制文件下载下来放到 PATH 里即可。curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 sudo install minikube-linux-amd64 /usr/local/bin/minikube minikube version下载源有时候会慢如果卡住可以换个时间段重试或者用国内镜像地址替换。装完minikube version能打印版本号就成。3.3 Docker 驱动的准备与验证如果你决定用 docker 驱动先确认 Docker 正常工作。docker info | grep -i cgroup输出里会显示 Cgroup DriverUbuntu 18.04 上常见的是 cgroupfs 或者 systemd。minikube 的 docker 驱动对这两者都兼容但如果你后面遇到 kubelet 报 cgroup 相关的错多半是这里驱动不一致导致的。解决办法是让 Docker 和 kubelet 用同一个驱动通常统一成 systemd 更稳。另外当前用户要能免 sudo 使用 docker否则 minikube 调用时会权限不足。把用户加入 docker 组sudo usermod -aG docker $USER newgrp dockernewgrp让当前会话立即生效省得重新登录。验证一下docker ps不报权限错就行。3.4 启动集群的关键参数启动命令看着简单但参数选对了能省很多事。minikube start --driverdocker --image-mirror-countrycn --cpus2 --memory4096逐个解释这些参数为什么这么设--driverdocker明确指定驱动避免 minikube 自动探测时选错。--image-mirror-countrycn这个参数非常关键。minikube 启动时需要拉取 kubelet、kubeadm 等基础镜像默认从境外源拉国内网络下经常超时。指定 cn 后会走国内镜像源速度提升明显。--cpus2给集群分配 2 核低于这个数控制平面组件会跑得很吃力。--memory40964G 内存是舒适线2G 是底线再低就容易 OOM。第一次启动会下载几百兆的镜像耐心等几分钟。看到Done! kubectl is now configured to use minikube就说明成功了。注意如果启动过程中卡在 “Pulling images” 很久多半是镜像源问题。可以先用minikube delete清掉再带上镜像参数重启。别在卡住的时候反复 CtrlC容易留下半成品状态。4. 集群验证与基础操作4.1 确认集群健康状态集群起来之后第一件事是看它到底健不健康。minikube status kubectl get nodes kubectl get pods -Aminikube status会显示 host、kubelet、apiserver 的状态全是 Running 才算正常。kubectl get nodes应该看到一个名为 minikube 的节点状态是 Ready。kubectl get pods -A列出所有命名空间的 Podkube-system 里那些核心组件都应该是 Running。如果节点状态是 NotReady八成是网络插件还没就绪等一两分钟再刷。如果一直 NotReady去看kubectl describe node minikube的事件通常能定位到具体原因比如镜像没拉下来或者 cgroup 配置不对。4.2 部署第一个应用验证链路光看系统 Pod 还不够得自己跑一个应用把镜像拉取、调度、服务暴露整条链路走通。kubectl create deployment hello-minikube --imagekicbase/echo-server:1.0 kubectl expose deployment hello-minikube --typeNodePort --port8080 kubectl get svc hello-minikube这里用kubectl create deployment是命令式操作适合快速验证。expose把 Deployment 暴露成 Service类型选 NodePort这样在本地就能通过节点 IP 加端口访问。拿到端口后用minikube service hello-minikube --url可以直接打印出可访问的地址省得自己拼 IP。访问通了说明从镜像拉取到网络转发整条链路都没问题。这一步跑通你的 minikube 就算真正可用了。4.3 常用运维命令速查日常开发中高频用到的命令整理成表方便随时查。操作命令查看集群状态minikube status停止集群minikube stop删除集群minikube delete查看节点 IPminikube ip打开仪表盘minikube dashboard进入节点 SSHminikube ssh查看插件列表minikube addons list启用插件minikube addons enable ingressminikube dashboard会启动一个 Web 界面可视化查看集群资源对新手特别友好。minikube ssh能直接进到节点内部排查网络和文件系统问题时很有用。5. 常见问题与排查技巧实录5.1 启动失败的高频原因minikube 启动失败是最让人头疼的因为报错信息往往很笼统。我把踩过的坑整理成排查表。现象可能原因解决方向卡在 Pulling images镜像源不通加--image-mirror-countrycnkubelet 反复重启swap 没关sudo swapoff -a权限拒绝用户不在 docker 组加入组并重新登录端口被占用8443 等端口冲突换端口或关掉占用进程内存不足分配内存太小提高--memory值conntrack 缺失依赖没装apt install conntrack排查的核心思路是先看minikube logs它会打印节点内部组件的日志比表面报错详细得多。如果日志也看不出就minikube ssh进去用journalctl -u kubelet看 kubelet 的详细日志绝大多数启动问题都能在这里找到答案。5.2 网络访问不通的排查应用部署了但访问不了是另一个高频问题。排查顺序建议这样走先确认 Pod 本身是 Runningkubectl get pods。再看 Service 的 Endpoints 有没有绑定到 Podkubectl get endpoints。如果 Endpoints 为空多半是 Service 的 selector 和 Pod 的 label 对不上。如果 Endpoints 正常但访问不通检查 Service 类型和端口映射。在 docker 驱动下NodePort 的访问方式比较特殊因为节点本身是个容器。这时候用minikube service name --url是最省心的它会自动处理好端口转发直接给你一个能用的地址。提示docker 驱动下宿主机的网络和集群网络是隔离的直接用minikube ip拿到的 IP 在宿主机上不一定能访问。遇到这种情况用minikube service或者kubectl port-forward做端口转发更靠谱。5.3 资源清理与重来minikube 用久了镜像和缓存会占不少空间。定期清理是个好习惯。minikube stop # 停止但保留状态 minikube delete # 彻底删除集群 docker system prune -a # 清理 docker 无用镜像minikube delete会把集群相关的容器、网络、卷全部清掉下次start就是全新的。如果你只是想省资源用stop就够了状态还在下次启动快很多。我个人的习惯是每个实验项目单独一个集群做完就 delete避免不同项目的配置互相干扰。5.4 几个容易被忽略的细节第一minikube 的默认 Kubernetes 版本可能不是你想要的。启动时可以用--kubernetes-version指定比如--kubernetes-versionv1.23.0这在需要和线上环境对齐版本时很重要。第二minikube addons里有很多实用插件比如 ingress、metrics-server、dashboard。默认只开了一部分需要什么手动 enable。metrics-server 开了之后kubectl top才能用看资源占用很方便。第三如果你在虚拟机里再跑 minikube会形成嵌套虚拟化性能损耗很大。这种场景下优先用 docker 驱动别用 kvm2 或 virtualbox。第四Ubuntu 18.04 的 iptables 默认可能是 nftables 后端某些老版本 Kubernetes 对它支持不好。如果遇到网络规则不生效可以切回 legacy 后端sudo update-alternatives --set iptables /usr/sbin/iptables-legacy。6. 把本地集群用出生产味道6.1 用命名空间隔离实验本地集群虽然只有一个节点但命名空间该用还得用。不同实验放不同 namespace互不干扰清理起来也干净。kubectl create namespace demo kubectl config set-context --current --namespacedemo把当前上下文切到 demo 命名空间后后续所有命令默认都在这个空间里操作不用每次带-n。实验做完直接kubectl delete namespace demo里面所有资源一次性清空比逐个删省事得多。6.2 本地镜像怎么让集群用上开发时经常需要跑自己构建的镜像。docker 驱动下有个便利minikube 和宿主机共用 Docker 守护进程的镜像缓存所以你在宿主机docker build出来的镜像集群里能直接用只要把镜像拉取策略设成IfNotPresent或者Never。eval $(minikube docker-env) docker build -t myapp:dev .eval $(minikube docker-env)这行会把当前终端的 Docker 环境指向 minikube 内部的守护进程之后 build 的镜像就直接进到集群里了。这个技巧能省掉推送到镜像仓库再拉的步骤本地迭代速度飞快。用完想切回宿主机 Docker执行eval $(minikube docker-env -u)即可。6.3 配置持久化存储测有状态应用时离不开 PVC。minikube 默认带了一个 storage-provisioner 插件能动态创建 hostPath 类型的 PV。你只要声明 PVC它会自动绑定。apiVersion: v1 kind: PersistentVolumeClaim metadata: name: demo-pvc spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Giapply 之后kubectl get pvc应该能看到状态变成 Bound。如果一直是 Pending检查 storage-provisioner 这个 Pod 是不是正常运行。hostPath 类型的存储在单节点下够用但别指望它有真正的数据冗余本地验证而已。6.4 资源限制与请求的实践本地集群资源有限给 Pod 设 resources 很重要否则一个失控的容器能把整个集群拖垮。resources: requests: memory: 128Mi cpu: 100m limits: memory: 256Mi cpu: 500mrequests 是调度依据limits 是硬上限。本地集群里 requests 别设太高不然 Pod 调度不上去一直 Pending。我一般 requests 给得很小limits 给到实际需要的 1.5 倍左右既保证能调度又防止单个 Pod 吃光资源。7. 我个人的使用体会minikube 这东西用对了驱动和参数十分钟就能跑起来用错了能折腾一整天。我早期最大的教训就是没关 swap 也没装 conntrackkubelet 一直起不来日志翻半天才定位到。后来养成习惯装之前先把前置检查过一遍基本就没再翻过车。另一个体会是镜像源这个参数千万别省。国内网络环境下不加--image-mirror-countrycn第一次启动大概率卡在拉镜像上那种等待特别消磨耐心。加上之后几分钟就绪。最后分享一个小技巧如果你经常需要重建集群可以把启动参数写成一个 shell 脚本或者 alias比如alias mkstartminikube start --driverdocker --image-mirror-countrycn --cpus2 --memory4096下次一条命令搞定不用每次回忆参数。这个集群后续还可以往多节点方向扩展minikube 支持--nodes3模拟多节点拓扑用来练调度策略和亲和性规则也够用了。
阅读完成 · 觉得有帮助?