再见 Docker 桌面,你好 Minikube!
很长一段时间以来,我一直在使用 Docker Desktop 在 Mac 中启用 Docker 和 Kubernetes。尽管它像疯了一样吃掉 CPU 和内存,让粉丝们疯狂。随着强制升级 Docker 和软件许可证更改的“面对面”弹出窗口,是时候到其他地方寻找本地 Kubernetes 开发需求了。 这篇文章只关注 Mac。如果您在 Linux 上尝试过,请告诉我结果如何。 您在使用 Apple
很长一段时间以来,我一直在使用 Docker Desktop 在 Mac 中启用 Docker 和 Kubernetes。尽管它像疯了一样吃掉 CPU 和内存,让粉丝们疯狂。随着强制升级 Docker 和软件许可证更改的“面对面”弹出窗口,是时候到其他地方寻找本地 Kubernetes 开发需求了。
这篇文章只关注 Mac。如果您在 Linux 上尝试过,请告诉我结果如何。
您在使用 Apple M1 Silicon (ARM64) 吗?跳转到文章末尾以获取 M1 特定说明。
卸载 Docker 桌面
让我们先从删除 Docker Desktop 开始。
冲泡卸载码头工人
这不仅将摆脱 Docker,还将摆脱 Hyperkit、允许构建映像的 Docker 守护程序、与守护程序交互的 Docker CLI、Kubernetes 集群和 kubectl 二进制文件(除非您将其单独部署)。如果您没有使用 Homebrew,请相应地卸载该工具。
让我们一一取回这些工具。
安装Hyperkit
Hyperkit 仍然是 Mac 上本地 Kubernetes 集群的可行选择。让我们安装它。
冲泡安装超级套件
确保它安装正确。
❯ hyperkit -v
hyperkit:0.20200908主页:https://github.com/docker/hyperkit
许可证:BSD
安装 Docker CLI
我们想摆脱 Docker Desktop,而不是 Docker 本身。 Docker 仍然是一个有用的开源容器管理工具,如果你有一堆 Dockerfile 需要处理,Docker CLI 会很有用。
酿造安装码头工人
注意:不要运行
brew install --cask docker
。这将安装 Docker Desktop,我们将回到开始的地方!
这将安装 Docker CLI,但不会安装 Docker 守护程序 (dockerd
)。您可以通过运行docker info
看到这一点。
❯码头信息
客户:
上下文:默认
调试模式:假服务器:
错误:无法连接到 unix:///var/run/docker.sock 上的 Docker 守护程序。 docker 守护进程是否正在运行?
安装 Kubectl
酿造安装 kubectl
这里没什么好说的。
安装 Minikube(和 Docker 守护进程)
部署 Hyperkit 后,我们就可以部署 Kubernetes 集群,并在此过程中获得一个 Docker 守护进程。
冲泡安装 minikube
在我们开始使用 Kubernetes 集群之前,需要了解以下一些有用的信息:
用什么驱动?
换句话说,我们是在 VM、Containers 中部署 Kubernetes 还是直接在裸机中部署?有各种选项可以在这里找到取决于操作系统。我们将使用适用于 Mac (AMD64) 的 Hyperkit 驱动程序和适用于 M1 的 Podman 驱动程序(见本文末尾)。
使用什么容器运行时?
可用选项——docker、containerd 和 cri-o。 Containerd 是一个不错的选择,因为 Kubernetes 本身正在从 Docker 转向 Containerd。但是由于我们希望 Docker 守护进程能够构建 docker 映像,所以让我们使用 Docker。
设置CPU、内存限制
就像使用 Docker Desktop 一样,设置正确的 CPU 和内存限制是明智的,特别是如果您打算运行多个 pod。
minikube 配置集 cpu 6
minikube 配置集内存 12g
最后,让我们启动 Kubernetes 集群。
❯ minikube 启动 --kubernetes-versionu003dv1.19.14 --driveru003dhyperkit --container-runtimeu003ddocker
使用标志--kubernetes-version
来部署特定的 Kubernetes 版本。删除标志以简单地部署最新版本。我正在部署一个旧版本以满足我的需要。
这是上述命令的输出:
😄 达尔文 11.5.2 上的 minikube v1.23.0
▪ MINIKUBE_ACTIVE_DOCKERDu003dminikube
✨ 使用基于用户配置的 hyperkit 驱动
👍 在集群 minikube 中启动控制平面节点 minikube
💾 下载 Kubernetes v1.19.14 预加载...
预加载图像-k8s-v12-v1...:470.78 MiB / 470.78 MiB 100.00% 6.17 MiB
🔥 创建 hyperkit VM (CPUsu003d6, Memoryu003d12288MB, Disku003d20000MB) ...
❗ 此虚拟机无法访问https://k8s.gcr.io
💡 要拉取新的外部镜像,可能需要配置代理:https://minikube.sigs.k8s.io/docs/reference/networking/proxy/
🐳 在 Docker 20.10.8 上准备 Kubernetes v1.19.14 ...
▪ 生成证书和密钥...
▪ 启动控制平面...
▪ 配置 RBAC 规则...
🔎 验证 Kubernetes 组件...
▪ 使用镜像 gcr.io/k8s-minikube/storage-provisioner:v5
🌟 启用插件:storage-provisioner、default-storageclass❗ /usr/local/bin/kubectl 是 1.22.1 版本,可能与 Kubernetes 1.19.14 不兼容。
▪ 想要 kubectl v1.19.14?尝试“minikube kubectl -- 获取 pods -A”
🏄 完成! kubectl 现在配置为默认使用“minikube”集群和“default”命名空间
如果您在本地运行
dnsmasq
,则集群内的 DNS 解析可能会出现故障。您可以卸载它或将listen-address=192.168.64.1
添加到dnsmasq.conf
。更多信息可以在这里找到。
上下文已经设置好了。我们可以使用kubectl
检查集群,如下所示:
❯ minikube kubectl 获取节点
姓名 状态 角色 年龄 版本
minikube Ready master 7m6s v1.19.14
由于我们已经部署了 kubectl 二进制文件,我们可以直接使用它。
此时,我们有一个 Kubernetes 集群,并且当我们使用 Docker 驱动程序时,Docker 守护程序也在运行。在我们可以使用守护进程之前,让我们设置环境变量。
评估 $(minikube docker-env)
让我们确认 docker 守护进程是可访问的。
❯码头信息
客户:
上下文:默认
调试模式:假服务器:
容器:14
跑步:14
暂停:0
停止:0
图片:10
服务器版本:20.10.8
存储驱动程序:overlay2
支持文件系统:extfs
...
这是 Minikube 集群与 K9S 的外观。
! zoz100037](https://devpress-image.s3.cn-north-1.jdcloud-oss.com/a/fab94d4a56_1*K4FCX7goEtekfksg9ZOGdA.jpg)
新安装的 Minikube 集群的 K9S 快照
需要 Docker Compose?
使用以下命令安装 Docker Compose:
酿造安装码头工人撰写
在 Minikube 之外暴露服务
对于本地开发,通常通过浏览器或 CLI 从笔记本电脑访问服务。端口转发始终是一种选择,但有时 Ingress 或负载均衡器很有用。让我们看看他们如何与 Minikube 一起工作。
处理Ingress资源
我们有一个 Kubernetes 集群,我们可以在其中部署我们的应用程序。但是我们如何访问 Ingress 资源呢? Minikube 有一个插件的答案。
❯ minikube 插件启用入口
▪ 使用镜像 k8s.gcr.io/ingress-nginx/controller:v1.0.0-beta.3
▪ 使用镜像 k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.0
▪ 使用镜像 k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.0
🔎 验证入口插件...
这将部署 Nginx 入口控制器。更重要的是,它将Nginx服务部署为NodePort
,并将Minikube IP直接指向Ingress。让我们先找到IP。
❯丑医生p
192.168.64.12
让我们在端口 80 上调用上面的 IP,我们应该得到 Nginx 的响应。
❯ 卷曲http://192.168.64.12
<html>
<head><title>404 未找到</title></head>
<正文>
<center><h1>404 未找到</h1></center>
<hr><center>nginx</center>
</正文>
</html>
请记住,Ingress 在 DNS 上工作,它应该解析到 Minikube IP。如果后端服务之一调用该 DNS,除非明确配置,否则它将失败。另一个救援插件!
❯ minikube 插件启用 ingress-dns
▪ 使用镜像 cryptexlabs/minikube-ingress-dns:0.3.0
这会在 Kubernetes 集群内的 Minikube IP 上启动 DNS 服务器。还需要自定义解析器来强制将自定义 TLD(如 .test,不要使用 .local)的 DNS 解析重定向到上面启动的 DNS 服务器。Minikube Ingress DNS 文档很好地解释了这一点。按照那里的步骤,您将使用自定义 DNS 进行有效的 Ingress 设置。
负载均衡服务
部署负载均衡器类型的服务并像在云中部署一样从主机访问它不是很好吗?感谢metallb
插件,这非常简单。
minikube 插件启用 metallb
这将部署另外两个 pod,它们负责将外部 IP 分配给负载均衡器服务。没有这个,服务将永远拥有pending
外部 IP。
在使用metallb
之前还有一个步骤。默认情况下,metallb
无法知道哪些 IP 范围可用于分配给负载均衡器服务。运行以下命令以提供范围。
❯ minikube 插件配置 metallb
-- 输入负载均衡器起始IP:192.168.64.5
-- 输入负载均衡端IP:192.168.64.15
▪ 使用图像 metallb/speaker:v0.9.6
▪ 使用镜像 metallb/controller:v0.9.6
✅ metallb 配置成功
根据您的 Minikube IP,分配包含 Minikube IP 的小范围 IP。现在,无论何时部署负载均衡器服务,都会分配此范围内的 IP。
其他问题
登录远程注册表
您可能仍将旧的~/.docker/config.json
设置为credsStore
或osxkeychain
或desktop
。这在新设置中不起作用。为了解决这个问题,让我们安装 Docker Credential Helper。
brew install docker-credential-helper
凭据将像以前一样存储在 MacOS 钥匙串中。如果这不起作用,快速修复是删除~/.docker/config.json
文件并再次登录到注册表。
保留 Docker 镜像和持久卷声明
2021 年 9 月 7 日添加
Docker Desktop 的一个好处是您可以关闭 Kubernetes 集群,稍后再启动它并使用相同的 Docker 映像和持久卷运行您的 pod。例如,在 Kubernetes 中运行本地数据库时,这很有用。使持久卷在重新启动时可用很方便。
使用 Minikube,如果我使用minikube stop
关闭集群(和 Hyperkit VM),它会删除 Docker 映像和所有持久卷。这很烦人。幸运的是,Minikube 提供了一种防止删除的方法。我们可以_pause_它,而不是停止 Kubernetes 集群和 Hyperkit VM。
丑陋的爪子回来
此命令会终止 Kubernetes 集群,但不会删除 Hyperkit VM。这可以释放更多 CPU,同时仍保留所有 Docker 映像和持久卷。但是等等,它会变得更好!它不会停止 docker 守护进程。所以你可以继续使用 Docker CLI,只是不要忘记使用eval $(minikube docker-env)
设置 docker 环境。
当您想继续在 Kubernetes 集群上工作时,请运行以下命令:
丑陋的
您将拥有所有系统 pod,包括插件。这甚至可以在笔记本电脑重新启动时使用!
Docker 容器中的绑定挂载
2021 年 9 月 7 日添加
Reddit上的好人指出,在 Docker 容器中绑定挂载(-v)
不适用于 Minikube 和 Docker 设置。这是 Docker 容器的常见操作,应该可以正常工作。
由于中间的 Hyperkit VM,挂载卷是一个两步操作。首先,让我们将笔记本电脑上的磁盘挂载到 Hyperkit VM。
minikube 挂载 /myvolume:/test
这将在 Hyperkit VM 内的路径/test
上挂载本地文件夹/myvolume
。该过程保持活动状态,因此您应该不理会此终端。
在另一个终端中,运行 Docker 容器并将/test
卷绑定到容器内的路径。
docker run --rm -it -v /test:/inside busybox /bin/sh
这会将/test
卷挂载到容器内的 Hyperkit VM 上,路径为/inside
。实际上,这会使容器内笔记本电脑上/myvolume
下的所有文件和文件夹处于读写模式。甜的!
苹果Silicon M1呢?
2022 年 2 月 5 日添加
上个月我终于拿到了 Apple M1!从那时起,我一直试图找出一种不使用 Docker 桌面来运行 Minikube 的方法......直到现在 :)
基于 ARM64 的 Apple M1 存在一些挑战。刚开始,Hyperkit 无法在 M1 上运行,而可能永远不会在上运行。我们需要一个替代工具来创建虚拟机。进入波德曼。
根据他们的网站,Podman 是 Docker 的直接替代品。字面意思是alias docker=podman
。令人兴奋的消息是 Podman 为 Apple M1 添加了支持!我们将使用 Podman 机器(与 docker 机器不同)功能使自己成为虚拟机。在底层,Podman 和 Docker Desktop 都使用QEMU来发挥它们的魔力。
首先安装 Podman。
冲泡安装播客
创建具有所需规格的虚拟机。
❯ podman machine init --cpus 6 --memory 12288 --disk-size 50 --image-path next
下载虚拟机镜像:fedora-coreos-35.20220131.1.0-qemu.aarch64.qcow2.xz:完成
解压压缩文件❯ podman 机器启动
INFO[0000] 正在等待客户...
INFO[0000] 监听 tcp://127.0.0.1:7777
INFO[0000] 到 /var/folders/2x/wz0vrff903q0p3lpn959b8zw0000gn/T/podman/qemu_podman-machine-default.sock 的新连接
等待虚拟机...
机器“podman-machine-default”成功启动
要使用 Podman 服务的根目的地,需要进行一些小调整才能使其与 Minikube 一起使用。如果没有这个调整,Minikube 将失败并显示“错误:请求的 cgroup 控制器 `cpu`不可用:OCI 运行时错误”。
❯ podman 系统连接默认 podman-machine-default-root ❯ podman 系统连接列表
名称身份 URI
podman-machine-default /Users/x/.ssh/podman-machine-default ssh://core@localhost:57623/run/user/1000/podman/podman.sock
podman-machine-default-root* /Users/x/.ssh/podman-machine-default ssh://root@localhost:57623/run/podman/podman.sock
有了这个 Podman 就设置好了。下一步是使用 Podman 驱动程序启动 Minikube 集群。不幸的是,由于未公开的侦听器端点,我们需要做一些小改动并在本地编译 Minikube 以使其与 Podman 一起使用。请按照以下步骤操作。学分:https://github.com/kubernetes/minikube/issues/12658#issuecomment-999840079
❯ git clonehttps://github.com/kubernetes/minikube.git
❯ CD 很丑
❯ sed -i.bak 's/fmt.Sprintf("--publishu003d%s::%d", pm.ListenAddress, pm.ContainerPort)/fmt.Sprintf("--publishu003d%d", pm. ContainerPort)/g' pkg/drivers/kic/oci/oci.go && rm pkg/drivers/kic/oci/oci.go.bak
❯ 制作 minikube-darwin-arm64
sed
命令是解决 Minikube 中“connect tcp 192.168.127.2:39951: connection was denied”错误的解决方法。默认情况下,监听器绑定到127.0.0.1
。解决方法强制它在0.0.0.0
上监听。希望这将很快包含在即将发布的版本中,我们不需要这种解决方法。
最后用 Podman 驱动和cri-o
容器运行时启动集群。确保使用已编译的二进制文件。
❯ ./out/minikube-darwin-arm64 start --kubernetes-versionu003dv1.22.5 --driveru003dpodman --container-runtimeu003dcri-o -p minipod
😄 [minipod] minikube v1.25.1 on Darwin 12.2 (arm64)
✨ 使用基于用户配置的podman(实验性)驱动
👍 在集群 minipod 中启动控制平面节点 minipod
🚜 拉取基础镜像...
E0205 23:11:56.616067 71622 cache.go:203] 下载 kic 工件时出错:尚未实现,请参阅问题 #8426
🔥 创建 podman 容器 (CPUsu003d6, Memoryu003d11264MB) ...
🎁 在 CRI-O 1.22.1 上准备 Kubernetes v1.22.5 ...
E0205 23:13:05.499833 71622 start.go:126] 无法获取主机 IP:RoutableHostIPFromInside 目前仅适用于 linux
▪ kubelet.housekeeping-intervalu003d5m
▪ 生成证书和密钥...
▪ 启动控制平面...
▪ 配置 RBAC 规则...
🔗 配置 CNI(容器网络接口)...
🔎 验证 Kubernetes 组件...
▪ 使用镜像 gcr.io/k8s-minikube/storage-provisioner:v5
🌟 启用插件:storage-provisioner, default-storageclass
🏄 完成! kubectl 现在配置为默认使用“minipod”集群和“default”命名空间
这样,我们就有了一个在没有 Docker 桌面的 Apple M1 上运行的 Minikube 集群!
结论
在周日下午花了几个小时后,我对设置非常满意。我们摆脱了 Docker Desktop 并用 Hyperkit (Podman for M1) 和 Minikube 取而代之。我们仍然可以使用 Docker API 来管理 Dockerfiles 并在本地 Kubernetes 集群中部署应用程序。最重要的是,笔记本电脑运行良好,额外的资源可供 Slack、Notion 和其他 Electron 应用程序使用;-)
资源
1.容器运行时介绍
2.Minikube 文档
3.Podman 文档
更多推荐
所有评论(0)