1. 为什么要在Windows上折腾本地Kubernetes
1.1 本地K8s的真实需求场景
很多人第一次接触Kubernetes都是在公司的测试集群或者云厂商的托管服务上,点点鼠标就能拿到一个能用的集群。但一旦回到自己的Windows笔记本上,想复现一个YAML、验证一个Operator的行为、或者单纯想搞明白Service和Ingress到底怎么串起来的,就发现没有集群可用了。这时候你有几个选择:开一个云上的托管集群,按小时计费;或者在自己机器上搭一个本地集群,随时开关,不花一分钱。
我个人的习惯是后者。原因很简单,本地集群的反馈循环极短,改一个配置几秒钟就能看到结果,而且不用担心把公司的共享集群搞坏。尤其是调试CRD、Webhook、NetworkPolicy这类容易把集群弄挂的东西,本地环境是最安全的试验田。
Windows用户在这个场景下有个天然的优势:WSL2。它本质上是一个轻量级的虚拟机,跑着一个完整的Linux内核,但和Windows的文件系统、网络、进程之间有很好的互操作性。这意味着你可以在Windows上写代码、用IDE,然后在WSL2里跑Docker和Kubernetes,两边无缝切换。这个体验比开一个VMware虚拟机再SSH进去要好得多。
1.2 Kind和Minikube到底选哪个
这是每个Windows用户搭本地K8s时遇到的第一个选择题。两个工具都能在本地跑起一个符合CNCF认证的Kubernetes集群,但设计哲学和使用场景有明显差异。
Kind的全称是Kubernetes in Docker,它的核心思路是把整个Kubernetes集群跑在一个Docker容器里。每个节点就是一个容器,控制平面和工作节点都是容器。这意味着它的启动速度极快,通常20到30秒就能拉起一个多节点集群。而且因为节点就是容器,你可以很方便地模拟多节点拓扑,比如一个控制平面加三个工作节点,这在测试调度策略、节点亲和性的时候特别有用。Kind的另一个优势是它对CI/CD非常友好,很多开源项目都用Kind来做集成测试。
Minikube的历史更久,生态更成熟。它支持多种驱动,在Windows上可以用Docker驱动、Hyper-V驱动,甚至VirtualBox驱动。Minikube的一个显著特点是它内置了很多addon,比如Dashboard、Ingress、Metrics Server,一条命令就能启用。对于刚入门的人来说,Minikube的minikube dashboard命令能直接打开一个Web界面,看到集群里的Pod、Service、Deployment,这种可视化体验对理解K8s的概念很有帮助。
我的建议是这样的:如果你已经比较熟悉K8s的基本概念,主要需求是快速验证YAML和调试应用,选Kind。如果你刚开始学K8s,需要一个带Dashboard的、开箱即用的环境,选Minikube。当然,两个都装也不冲突,我自己的机器上就是两个都有,根据场景切换。
1.3 WSL2方案相比传统虚拟机的优势
在WSL2出现之前,Windows上跑Linux容器和K8s的标准做法是装一个VirtualBox或者Hyper-V虚拟机,然后在里面跑Docker和Minikube。这个方案能用,但有几个让人难受的地方。
首先是资源占用。一个完整的Linux虚拟机,即使是最小化安装,也要吃掉2GB内存和20GB磁盘。而WSL2的发行版通常只占几百MB内存,磁盘占用也小得多。其次是启动速度,虚拟机从开机到SSH可用通常要一两分钟,WSL2的发行版启动是秒级的。第三是文件系统互操作性,虚拟机和Windows之间的文件共享需要配置共享文件夹或者用SMB,而WSL2直接挂载了Windows的盘符,在/mnt/c下面就能访问C盘的所有文件。
还有一个容易被忽略的点是网络。WSL2的网络是NAT模式,Windows主机可以通过localhost访问WSL2里暴露的端口,这在开发时非常方便。你不需要去查虚拟机的IP地址,直接在Windows的浏览器里访问localhost:30000就能看到NodePort服务。
注意:WSL2的localhost转发只对监听在0.0.0.0或者127.0.0.1的端口有效。如果服务只监听在WSL2的内部IP上,Windows主机是访问不到的。这个问题在配置Ingress和NodePort时经常遇到,后面会详细说。
2. 环境准备:从零开始配置WSL2
2.1 确认Windows版本和硬件条件
WSL2对Windows版本有硬性要求。你需要Windows 10的2004版本(内部版本19041)或更高,或者Windows 11的任何版本。检查方法很简单,按Win+R,输入winver,回车,就能看到当前版本号。
硬件方面,WSL2依赖虚拟化技术,所以你的CPU必须支持虚拟化,并且在BIOS里开启了。大部分近五年的笔记本和台式机都支持,但有些品牌机出厂时默认关闭了。检查方法:打开任务管理器,切换到“性能”标签页,看CPU那一栏,如果“虚拟化”显示“已启用”,就没问题。如果显示“已禁用”,需要重启进BIOS,找到Intel VT-x或者AMD-V的选项,把它打开。
内存方面,我建议至少16GB。Kubernetes本身加上Docker镜像,再跑几个测试应用,8GB会非常紧张。磁盘方面,WSL2的虚拟磁盘文件会随着使用逐渐增大,建议C盘至少留出50GB的可用空间。
2.2 安装WSL2和Ubuntu发行版
安装WSL2现在非常简单,微软把它做成了一条命令的事情。以管理员身份打开PowerShell,输入:
wsl --install这条命令会自动完成几件事:启用“适用于Linux的Windows子系统”和“虚拟机平台”两个Windows功能,下载并安装WSL2内核更新包,然后把Ubuntu设置为默认发行版并安装。整个过程需要重启一次电脑。
重启之后,Ubuntu会自动启动,让你设置用户名和密码。这个用户名和密码是Linux系统内部的,和Windows账户无关。设置完成后,你就进入了一个完整的Ubuntu环境。
如果你已经装过WSL1,想升级到WSL2,可以先用wsl --list --verbose查看当前版本,然后用wsl --set-version Ubuntu 2来升级。升级过程会把整个文件系统转换一遍,可能需要几分钟,取决于你的数据量。
实操心得:安装完成后,建议立刻运行
wsl --update来确保WSL2内核是最新版本。旧版本的内核在内存回收和网络性能上有一些已知问题,更新后体验会好很多。
2.3 配置WSL2的资源限制
WSL2默认会占用宿主机的很大一部分资源,尤其是内存。它有一个动态内存分配机制,会随着使用逐渐增加,但不会主动释放。这意味着你跑完一个内存密集型的任务后,WSL2可能还占着好几个GB的内存不放。
解决办法是在Windows用户目录下创建一个.wslconfig文件。路径是C:\Users\你的用户名\.wslconfig。文件内容如下:
[wsl2] memory=8GB processors=4 swap=2GB localhostForwarding=true这里我把内存限制在8GB,处理器限制在4个核心,交换分区2GB。你可以根据自己的机器配置调整。localhostForwarding=true是默认开启的,但显式写出来更放心,它保证了Windows主机可以通过localhost访问WSL2里的服务。
改完这个文件后,需要运行wsl --shutdown来关闭WSL2,然后重新打开Ubuntu,配置才会生效。
2.4 在WSL2里安装Docker
Kind和Minikube的Docker驱动都需要一个可用的Docker环境。在WSL2的Ubuntu里安装Docker,我推荐用官方的一键脚本:
curl -fsSL https://get.docker.com | sh安装完成后,把当前用户加入docker组,这样就不用每次都sudo了:
sudo usermod -aG docker $USER然后退出终端重新登录,或者运行newgrp docker让组变更生效。验证一下:
docker run hello-world如果能看到“Hello from Docker!”的输出,说明Docker安装成功了。
注意:不要用
sudo apt install docker.io来安装,Ubuntu仓库里的Docker版本通常比较旧,而且和官方版本的配置路径有差异,后面用Kind的时候可能会遇到奇怪的问题。用官方脚本安装是最稳妥的。
3. 用Kind搭建Kubernetes集群
3.1 安装Kind和kubectl
Kind的安装非常简单,它就是一个二进制文件。在WSL2的Ubuntu里运行:
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.20.0/kind-linux-amd64 chmod +x ./kind sudo mv ./kind /usr/local/bin/kindkubectl是Kubernetes的命令行客户端,也是必须的:
curl -LO "https://dl.k8s.io/release/v1.28.0/bin/linux/amd64/kubectl" chmod +x kubectl sudo mv kubectl /usr/local/bin/kubectl验证安装:
kind version kubectl version --client两个命令都能输出版本号,就说明安装成功了。
3.2 创建单节点集群和多节点集群
Kind最简单的用法就是一条命令:
kind create cluster --name my-cluster这条命令会创建一个名为my-cluster的单节点集群。Kind会自动下载一个节点镜像,然后启动一个Docker容器作为这个节点。整个过程大概需要30秒到1分钟,取决于你的网络速度。
创建完成后,Kind会自动把kubeconfig写入~/.kube/config,kubectl可以直接使用。运行kubectl get nodes应该能看到一个名为my-cluster-control-plane的节点,状态是Ready。
如果你需要多节点集群,比如一个控制平面加两个工作节点,就需要一个配置文件:
kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 nodes: - role: control-plane - role: worker - role: worker保存为kind-multi-node.yaml,然后运行:
kind create cluster --name multi-node --config kind-multi-node.yaml这个集群会有三个节点,调度器可以把Pod分配到两个工作节点上。这对于测试Pod反亲和性、节点选择器、污点和容忍度这些特性非常有用。
3.3 配置端口映射让Windows能访问服务
Kind集群跑在Docker容器里,默认情况下Windows主机是访问不到集群内部的服务的。如果你在集群里部署了一个NodePort服务,在WSL2里可以用localhost:30000访问,但在Windows的浏览器里就不行。
解决办法是在创建集群时配置端口映射。修改配置文件:
kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 nodes: - role: control-plane extraPortMappings: - containerPort: 30000 hostPort: 30000 protocol: TCP - containerPort: 80 hostPort: 8080 protocol: TCP这里我把容器的30000端口映射到宿主机的30000端口,把容器的80端口映射到宿主机的8080端口。这样在Windows的浏览器里访问localhost:30000和localhost:8080就能到达集群内部。
实操心得:端口映射只在集群创建时生效,创建后无法修改。如果你需要改端口,只能删掉集群重建。所以建议一开始就把可能用到的端口都映射上,比如30000-30010这一段,还有80和443。
3.4 验证集群状态和基本操作
集群创建好后,先确认节点状态:
kubectl get nodes -o wide然后部署一个测试应用:
kubectl create deployment nginx --image=nginx:alpine kubectl expose deployment nginx --port=80 --type=NodePort查看Pod和Service:
kubectl get pods kubectl get svc如果Pod状态是Running,Service的NodePort在30000-32767之间,就说明集群工作正常。你可以用kubectl port-forward把服务转发到本地,然后在Windows浏览器里访问:
kubectl port-forward svc/nginx 8080:80然后在Windows浏览器里打开http://localhost:8080,应该能看到Nginx的欢迎页面。
4. 用Minikube搭建Kubernetes集群
4.1 安装Minikube和必要组件
Minikube的安装同样简单:
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 sudo install minikube-linux-amd64 /usr/local/bin/minikubeMinikube在WSL2里推荐使用Docker驱动。启动集群:
minikube start --driver=docker --cpus=4 --memory=6g这里我指定了4个CPU和6GB内存。Minikube会下载一个基础镜像,然后启动一个Docker容器作为节点。第一次启动可能需要几分钟,因为要下载镜像和初始化集群。
启动完成后,Minikube会自动配置kubectl的上下文。运行kubectl get nodes应该能看到一个名为minikube的节点。
4.2 启用Dashboard和Ingress等常用插件
Minikube的一大优势是内置了很多addon。查看可用插件:
minikube addons list启用Dashboard:
minikube addons enable dashboard minikube dashboardminikube dashboard命令会自动在Windows的默认浏览器里打开Kubernetes Dashboard。这个界面可以直观地看到集群里的所有资源,对于学习和演示非常方便。
启用Ingress:
minikube addons enable ingress启用Metrics Server:
minikube addons enable metrics-server启用后,你可以用kubectl top nodes和kubectl top pods查看资源使用情况。
4.3 在Windows浏览器访问Minikube服务
Minikube在WSL2里跑的时候,Windows主机访问服务有两种方式。
第一种是用minikube service命令:
minikube service nginx --url这个命令会输出一个URL,通常是http://127.0.0.1:随机端口。因为WSL2的localhost转发,这个URL在Windows浏览器里也能直接打开。
第二种是用kubectl port-forward,和Kind的方式一样。
第三种是配置NodePort,然后通过WSL2的IP访问。获取WSL2的IP:
hostname -I然后在Windows浏览器里访问http://WSL2的IP:NodePort。不过WSL2的IP每次重启都会变,所以这种方式不太稳定,还是推荐前两种。
注意:Minikube的Dashboard默认只监听在127.0.0.1,如果你在Windows浏览器里打不开,可以试试
minikube dashboard --url,它会输出一个完整的URL,复制到浏览器里打开。
4.4 Minikube的暂停、恢复和删除
Minikube的一个便利之处是支持暂停和恢复:
minikube pause minikube unpause暂停后,集群的容器会被停止,但状态会保留。恢复后,集群会回到暂停前的状态。这对于需要临时释放资源的场景很有用。
删除集群:
minikube delete这个命令会删除所有相关的容器和配置。如果你想保留配置但重置集群,可以用minikube delete --keep-context。
5. 两个方案的对比与选型建议
5.1 启动速度、资源占用和功能对比
| 对比项 | Kind | Minikube |
|---|---|---|
| 启动速度 | 20-30秒 | 1-3分钟 |
| 内存占用 | 较低,约1-2GB | 较高,约2-4GB |
| 多节点支持 | 原生支持,配置简单 | 需要额外配置,较复杂 |
| Dashboard | 需要手动安装 | 内置addon,一键启用 |
| Ingress | 需要手动安装 | 内置addon |
| 镜像加载 | kind load docker-image | minikube image load |
| 持久化存储 | 需要配置hostPath | 内置hostPath和storage-provisioner |
| CI友好度 | 非常高 | 一般 |
从表格可以看出,Kind在速度和资源占用上有明显优势,适合快速迭代和CI场景。Minikube在功能完整性上更好,适合学习和功能验证。
5.2 什么场景用Kind,什么场景用Minikube
我的经验是这样的:
如果你在开发一个Kubernetes Operator或者Controller,需要频繁地创建和销毁集群来测试,用Kind。它的启动速度让你可以在几十秒内完成一次完整的测试循环。
如果你在学习K8s的网络、存储、调度这些概念,需要一个能直观看到集群状态的工具,用Minikube。Dashboard和内置addon能帮你省去很多配置的麻烦。
如果你在准备CKA或者CKAD考试,两个都练一练。考试环境是真实的K8s集群,但本地练习时Kind和Minikube都能覆盖大部分考点。
如果你在搭建一个本地的开发环境,需要长期运行,Minikube的稳定性和功能完整性更好一些。Kind的集群在Docker重启后有时会出现状态不一致的问题,需要重建。
5.3 镜像加载的坑和解决方案
这是Windows+WSL2+Kind/Minikube组合里最容易踩的坑。
问题描述:你在WSL2里用docker build构建了一个镜像,然后想在Kind集群里用这个镜像。但Kind集群的节点是独立的Docker容器,它看不到你本地Docker里的镜像。如果你在Deployment里指定imagePullPolicy: Never,Pod会报ErrImageNeverPull。
Kind的解决方案:
kind load docker-image my-app:latest --name my-cluster这条命令会把本地Docker里的镜像加载到Kind集群的所有节点里。
Minikube的解决方案:
minikube image load my-app:latest或者,你可以在Minikube里配置一个本地Registry,然后让Docker把镜像推送到这个Registry,Minikube从Registry拉取。这种方式更接近生产环境,但配置起来麻烦一些。
实操心得:我习惯在构建镜像时打两个标签,一个是
my-app:latest,一个是my-app:dev。加载到集群时用dev标签,Deployment里也用dev标签,并且设置imagePullPolicy: IfNotPresent。这样每次重新构建后,只需要重新load一次,然后删除Pod让它重建,就能用到新镜像。
6. 常见问题排查与避坑指南
6.1 WSL2内存占用过高怎么办
这是WSL2最常见的问题。表现是:跑完一个内存密集型的任务后,Windows的任务管理器里显示Vmmem进程占了好几个GB的内存,而且不释放。
原因:WSL2的Linux内核有一个内存回收机制,但它比较保守,不会主动把内存还给Windows。尤其是当你在WSL2里跑了Docker和Kubernetes,各种缓存和缓冲区会占用大量内存。
解决方案有三个层次:
第一,在.wslconfig里设置内存上限,前面已经说过了。这能防止WSL2无限增长。
第二,定期运行wsl --shutdown来彻底关闭WSL2,释放所有内存。这个命令会关闭所有WSL2发行版,下次打开时会重新启动。缺点是所有运行中的服务都会停止,包括Kubernetes集群。
第三,在WSL2内部手动释放缓存:
sudo sync && echo 3 | sudo tee /proc/sys/vm/drop_caches这个命令会清理页缓存、目录项缓存和inode缓存。但它不会释放被进程占用的内存,只是释放缓存部分。
我的习惯是每天下班前运行一次wsl --shutdown,第二天早上重新启动。这样既能释放内存,又能让集群从一个干净的状态开始。
6.2 Kind集群启动失败排查
Kind集群启动失败通常有几个原因:
Docker服务没启动。检查docker ps是否能正常输出。如果报“Cannot connect to the Docker daemon”,说明Docker服务没跑起来。在WSL2里,Docker通常是用systemd管理的,运行sudo systemctl start docker。
端口冲突。如果你之前创建过集群,端口可能还被占用。运行docker ps -a查看所有容器,把旧的Kind容器删掉:docker rm -f $(docker ps -aq -f name=kind)。
磁盘空间不足。Kind的节点镜像有好几百MB,如果WSL2的磁盘满了,创建会失败。用df -h检查磁盘使用情况。
内核版本不兼容。极少数情况下,WSL2的内核版本太旧会导致Kind启动失败。运行wsl --update更新内核。
排查时,加上--verbosity=5参数可以看到详细的日志:
kind create cluster --name debug --verbosity=56.3 Minikube驱动选择错误
Minikube在WSL2里如果用了错误的驱动,会报各种奇怪的错误。比如用了none驱动,Minikube会尝试直接在WSL2里安装Kubernetes组件,这通常会失败,因为WSL2的systemd支持不完整。
正确的做法是始终用--driver=docker。如果你之前用其他驱动创建过集群,先删除:
minikube delete minikube start --driver=docker如果minikube start卡在“Pulling base image”很久,可能是网络问题。可以配置国内镜像源:
minikube start --driver=docker --image-mirror-country=cn这个参数会让Minikube从国内的镜像仓库拉取基础镜像,速度会快很多。
6.4 服务无法从Windows访问的排查思路
这个问题我遇到过很多次,排查思路可以总结成一个流程:
第一步,确认Pod本身是健康的。kubectl get pods看状态,kubectl logs看日志。
第二步,在WSL2内部用curl测试服务。如果是NodePort,用curl localhost:NodePort。如果是ClusterIP,用kubectl port-forward然后curl localhost:转发端口。如果WSL2内部能访问,说明集群没问题,问题出在网络转发上。
第三步,检查WSL2的localhost转发是否生效。在Windows的PowerShell里运行curl http://localhost:端口。如果不行,检查.wslconfig里的localhostForwarding是否为true。
第四步,检查防火墙。Windows Defender防火墙有时会阻止WSL2的端口转发。可以临时关闭防火墙测试一下。如果确认是防火墙问题,需要添加一条入站规则,允许WSL2的虚拟网卡通信。
第五步,如果以上都不行,试试用WSL2的IP直接访问。在WSL2里运行hostname -I获取IP,然后在Windows浏览器里访问http://IP:端口。如果这样能访问,说明是localhost转发的问题,可以重启WSL2试试。
实操心得:我发现在Windows 11的某些版本上,localhost转发偶尔会失效。重启WSL2(
wsl --shutdown然后重新打开)通常能解决。如果频繁出现,可以考虑在Windows里配一个端口转发规则,把Windows的端口转发到WSL2的IP上。不过WSL2的IP会变,所以这个方案需要配合脚本动态更新。
6.5 常见问题速查表
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
kind create cluster卡住 | 镜像下载慢 | 配置Docker镜像加速 |
Pod状态ErrImageNeverPull | 镜像没加载到集群 | kind load docker-image |
| Windows无法访问NodePort | 端口没映射 | 重建集群,加extraPortMappings |
minikube start报驱动错误 | 驱动选择不对 | 用--driver=docker |
| WSL2内存占用高 | 内存回收不及时 | 设置.wslconfig上限,定期wsl --shutdown |
kubectl报连接拒绝 | kubeconfig没配好 | kind export kubeconfig或minikube update-context |
| Dashboard打不开 | 监听地址不对 | 用minikube dashboard --url获取完整URL |
| 集群重启后Pod全挂 | 节点容器重启 | 删除集群重建,或检查Docker服务 |
7. 进阶技巧:让本地K8s更好用
7.1 配置kubectl多集群切换
当你同时有Kind和Minikube集群时,kubeconfig里会有多个context。用kubectl config get-contexts查看所有context,用kubectl config use-context切换。
我给集群起名时习惯加上前缀,比如kind-dev、minikube-test,这样在切换时一目了然。Kind创建集群时可以用--name指定名字,Minikube用--profile指定。
如果觉得每次切换太麻烦,可以装一个kubectx工具:
sudo apt install kubectx然后就可以用kubectx kind-dev快速切换了。
7.2 用本地Registry加速镜像分发
每次构建镜像都要kind load或者minikube image load,时间长了也很烦。一个更好的方案是在本地跑一个Registry,然后让Kind和Minikube都从这个Registry拉镜像。
启动Registry:
docker run -d -p 5000:5000 --name registry registry:2然后配置Kind集群使用这个Registry。在Kind的配置文件里加上:
containerdConfigPatches: - |- [plugins."io.containerd.grpc.v1.cri".registry.mirrors."localhost:5000"] endpoint = ["http://localhost:5000"]这样Kind集群里的containerd就会把localhost:5000的请求转发到宿主机的Registry。构建镜像时打上localhost:5000/my-app:latest的标签,推送到Registry,然后Deployment里用这个镜像地址,就不需要每次load了。
7.3 持久化存储的配置
Kind和Minikube默认都不提供动态存储供应。如果你部署的应用需要PVC,Pod会一直处于Pending状态。
Minikube的解决方案比较简单,它内置了一个storage-provisioneraddon,默认就是启用的。你创建一个PVC,它会自动创建一个hostPath的PV。
Kind没有内置的存储供应。你需要手动安装一个,比如local-path-provisioner:
kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisioner/master/deploy/local-path-storage.yaml然后把它设置为默认StorageClass:
kubectl patch storageclass local-path -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'这样PVC就能正常绑定了。
7.4 资源清理和集群重置的最佳实践
本地集群用久了,会积累很多无用的镜像、容器和卷。定期清理能释放不少磁盘空间。
清理Docker资源:
docker system prune -a --volumes这个命令会删除所有停止的容器、未使用的镜像、未使用的网络和卷。执行前确认没有重要的数据。
清理Kind集群:
kind delete cluster --name my-cluster清理Minikube集群:
minikube delete --profile my-profile如果只是想重置集群状态但保留配置,Minikube可以用minikube delete然后minikube start。Kind没有类似的功能,只能删了重建。
实操心得:我习惯在
~/.bashrc里加几个alias,比如alias kc='kubectl config use-context'、alias kgn='kubectl get nodes'、alias kgp='kubectl get pods'。这些简写能省不少打字时间。另外,kubectl的命令补全也建议配上:
source <(kubectl completion bash) echo "source <(kubectl completion bash)" >> ~/.bashrc这样按Tab键就能自动补全资源名和命令,效率提升很明显。
7.5 在Windows端使用VS Code连接WSL2开发
既然集群跑在WSL2里,代码最好也在WSL2里写。VS Code的Remote-WSL扩展能让你在Windows上使用VS Code的界面,但代码和终端都在WSL2里运行。
安装Remote-WSL扩展后,在WSL2的终端里进入项目目录,运行code .,VS Code就会自动打开并连接到WSL2。你可以在VS Code里直接打开终端,运行kubectl命令,编辑YAML文件,所有操作都在Linux环境下完成,但界面是Windows的,体验非常流畅。
这个组合是我目前找到的Windows上开发Kubernetes应用最舒服的方式。Windows负责图形界面和浏览器,WSL2负责所有命令行和容器操作,两边通过localhost无缝互通。
7.6 用Skaffold实现自动构建和部署
如果你在开发一个需要频繁修改和部署的应用,Skaffold能帮你自动化整个流程。它会监听代码变化,自动构建镜像、加载到集群、更新Deployment。
安装Skaffold:
curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/latest/skaffold-linux-amd64 chmod +x skaffold sudo mv skaffold /usr/local/bin在项目根目录创建skaffold.yaml:
apiVersion: skaffold/v4beta6 kind: Config build: artifacts: - image: my-app docker: dockerfile: Dockerfile deploy: kubectl: {}然后运行skaffold dev,它会自动完成构建、加载、部署的循环。你修改代码后,几秒钟内就能看到新的Pod跑起来。
这个工具在Kind和Minikube上都能用,但Kind的加载速度更快,因为kind load比minikube image load快不少。
7.7 监控和日志的本地方案
本地集群虽然小,但基本的监控和日志还是需要的。Minikube可以一键启用Metrics Server,Kind需要手动装。
安装Metrics Server:
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yamlKind集群里Metrics Server默认会报TLS错误,需要加一个参数:
kubectl patch deployment metrics-server -n kube-system --type=json -p='[{"op":"add","path":"/spec/template/spec/containers/0/args/-","value":"--kubelet-insecure-tls"}]'日志方面,我推荐用kubectl logs配合stern。Stern可以同时查看多个Pod的日志,并且支持颜色区分和过滤:
curl -Lo stern https://github.com/stern/stern/releases/latest/download/stern_linux_amd64 chmod +x stern sudo mv stern /usr/local/bin然后stern my-app就能看到所有匹配my-app的Pod的日志,修改代码后Pod重建,日志会自动切换,非常方便。
8. 我个人的一些经验体会
这套Windows+WSL2+Kind/Minikube的组合,我从2021年开始用,中间踩过不少坑,也总结出了一些自己的习惯。
第一个习惯是给每个项目单独建一个Kind集群。Kind创建集群很快,删掉也很快,所以我不喜欢在一个集群里塞多个项目的资源。每个项目一个集群,命名用项目名,kubeconfig里的context也清晰。项目结束后直接kind delete cluster,干干净净。
第二个习惯是永远不在WSL2里存重要数据。WSL2的虚拟磁盘虽然稳定,但偶尔会遇到文件系统损坏的情况。我的代码都放在Windows的目录里,通过/mnt/c/Users/...访问,WSL2里只放Docker镜像和集群数据。这样即使WSL2出问题,重装一遍也不影响代码。
第三个习惯是定期更新Kind和Minikube的版本。这两个工具迭代很快,新版本通常会修复一些网络和存储的bug。我一般每个月检查一次更新,用kind version和minikube version看当前版本,然后去官网看最新版本,有重要更新就升级。
第四个习惯是给WSL2分配固定的资源。我在.wslconfig里写死了8GB内存和4个CPU,这样不管Windows上开了多少应用,WSL2都不会抢太多资源。虽然有时候跑大镜像会慢一点,但整体体验更稳定。
最后一个建议是,不要在这套环境上跑生产负载。本地集群的稳定性和安全性都没法和真正的生产环境比。它的定位就是开发和测试,验证完了就部署到真正的集群上。我见过有人把本地Kind集群当成长期运行的环境,结果Docker一重启,所有数据都没了。这种教训还是避免为好。