Minikube 入門初體驗

文章轉載:分佈式實驗室

原文鏈接:http://33h.co/9024v

我使用 Docker Desktop 在 Mac 中啓用 Docker 和 Kubernetes 已經有一段時間了。儘管它瘋狂地吞噬着 CPU 和內存,讓粉絲們瘋狂。但隨着 “當面” 彈出強制升級 Docker 的彈窗和軟件許可的變更,是時候爲本地 Kubernetes 開發尋找其他替代品了。

這篇文章只會專注於 Mac 平臺。如果你在 Linux 上嘗試過,請告訴我情況如何。

卸載 Docker Desktop


讓我們先從刪除 Docker Desktop 開始。

brew uninstall docker

這不僅會擺脫 Docker,還會擺脫 Hyperkit 以及 Docker 守護進程。Docker 守護進程允許我們構建鏡像並適用交互式的 Docker CLI 與之對話。當然還包括 Kubernetes 集羣和 kubectl 二進制(除非你有單獨部署)。如果你沒有使用 Homebrew,那麼就需要相應地卸載這些工具。

然後,讓我們把這些工具逐一找回來。

安裝 Hyperkit


Hyperkit 仍然是在 Mac 上本地運行 Kubernetes 集羣的一個可行的選擇,我們先來安裝它。

brew install hyperkit

確認安裝正確。

❯ hyperkit -v
hyperkit: 0.20200908Homepage:https://github.com/docker/hyperkit
License: BSD

安裝 Docker CLI


我們是想擺脫 Docker Desktop,但並不是 Docker 本身。Docker 仍然是一個很有用的、開源的容器管理工具,如果你有一堆 Dockerfiles 需要處理,Docker CLI 會很有用。

brew install docker

注意:千萬不要運行 brew install --cask docker。這會安裝 Docker Desktop 集成版本,我們又要重頭來過。

這僅僅會安裝 Docker CLI,但不會安裝 Docker 守護程序 dockerd。你可以通過運行 docker info 看到這一點。

❯ docker info
Client:
 Context:    default
 Debug Mode: falseServer:
ERROR: Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

安裝 Kubectl


brew install kubectl

這一點沒什麼可說的。

安裝 Minikube(和 Docker 守護進程)


隨着 Hyperkit 的部署,我們已經準備好部署 Kubernetes 集羣了。並且,在這個過程中啓動了一個 Docker 守護程序。

brew install minikube

在我們開始使用 Kubernetes 集羣之前,這裏有一些小知識需要了解。

使用哪一種驅動?

換句話說,我們是將 Kubernetes 部署在虛擬機、容器還是直接部署在裸金屬服務器上?根據操作系統的不同,這裏有多種選擇 [1]。我們將使用 Mac 的 Hyperkit 驅動。

使用哪一種容器運行時?

可用的選項:Docker、containerd 和 cri-o。鑑於 Kubernetes 本身正在遠離 Docker 而轉向 Containerd,Containerd 是一個不錯的選擇。但由於我們希望 Docker 守護程序能夠構建 Docker 鏡像,所以我們還是使用 Docker 吧。

設定 CPU 和內存限制

和 Docker Desktop 一樣,設置正確的 CPU 和內存限制總是明智,特別是如果你打算運行許多 Pod。

minikube config set cpus 6
minikube config set memory 12g

最後,啓動 Kubernetes 集羣。

❯ minikube start --kubernetes-version=v1.19.14 --driver=hyperkit --container-runtime=docker

使用命令行選項 - kubernetes-version 來部署特定版本的 Kubernetes。不用這個標誌的話,默認部署最新的版本。我需要部署一個較早的版本來滿足我的需要。

以下是上述命令的輸出。

😄  minikube v1.23.0 on Darwin 11.5.2
    ▪ MINIKUBE_ACTIVE_DOCKERD=minikube
✨  Using the hyperkit driver based on user configuration
👍  Starting control plane node minikube in cluster minikube
💾  Downloading Kubernetes v1.19.14 preload ...     
    > preloaded-images-k8s-v12-v1...: 470.78 MiB / 470.78 MiB  100.00% 6.17 MiB
🔥  Creating hyperkit VM (CPUs=6, Memory=12288MB, Disk=20000MB) ...
❗  This VM is having trouble accessing https://k8s.gcr.io
💡  To pull new external images, you may need to configure a proxy: https://minikube.sigs.k8s.io/docs/reference/networking/proxy/
🐳  Preparing Kubernetes v1.19.14 on Docker 20.10.8 ...
    ▪ Generating certificates and keys ...
    ▪ Booting up control plane ...
    ▪ Configuring RBAC rules ...
🔎  Verifying Kubernetes components...
    ▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5
🌟  Enabled addons: storage-provisioner, default-storageclass
❗  /usr/local/bin/kubectl is version 1.22.1, which may have incompatibilites with Kubernetes 1.19.14.
    ▪ Want kubectl v1.19.14? Try 'minikube kubectl -- get pods -A'
🏄  Done! kubectl is now configured to use "minikube" cluster and "default" namespace by default

如果你在本地運行 dnsmasq,在集羣中可能會出現 DNS 解析失敗。你可以卸載它或者在 dnsmasq.conf 中添加 listen-address=192.168.64.1。更多信息可以在這裏 [2] 找到。

Kube Config 的上下文已經設置好了。我們可以用 kubectl 來檢查集羣,如下所示。

❯ minikube kubectl get nodes
NAME       STATUS   ROLES    AGE    VERSION
minikube   Ready    master   7m6s   v1.19.14

由於我們已經安裝了 kubectl 二進制程序,我們可以直接使用它。

此時,我們已經有了一個 Kubernetes 集羣,由於我們使用了 Docker 驅動,Docker 守護程序也在運行。所以在我們使用守護進程之前,讓我們先設置環境變量。

eval $(minikube docker-env)

確認 Docker 守護進程是正常工作的。

❯ docker info
Client:
 Context:    default
 Debug Mode: falseServer:
 Containers: 14
  Running: 14
  Paused: 0
  Stopped: 0
 Images: 10
 Server Version: 20.10.8
 Storage Driver: overlay2
  Backing Filesystem: extfs
 ...

下面是我們的 Minikube 集羣在 K9S 中的樣子。

新安裝的 Minikube 集羣的 K9S 截圖

需要 Docker Compose?


用以下命令安裝 Docker-Compose。

brew install docker-compose

暴露 Services 到 Minikube 外部


對於本地開發,通常是通過瀏覽器或 CLI 從電腦訪問服務。端口轉發總是一個選擇,但有時 Ingress 或負載均衡器也是有用的。讓我們看看它們是如何與 Minikube 一起工作的。

處理 Ingress 資源

我們現在有了一個 Kubernetes 集羣,也可以在上面部署應用程序。但我們如何訪問 Ingress 資源呢?Minikube 有一個答案,就是 addons(附加組件)。

❯ minikube addons enable ingress
    ▪ Using image k8s.gcr.io/ingress-nginx/controller:v1.0.0-beta.3
    ▪ Using image k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.0
    ▪ Using image k8s.gcr.io/ingress-nginx/kube-webhook-certgen:v1.0
🔎  Verifying ingress addon...

這會部署 Nginx Ingress 控制器。更重要的是,它會把 Nginx 服務部署以 NodePort 的形式部署,並將 Minikube 的 IP 直接指向 Ingress。讓我們先找到這個 IP。

❯ minikube ip
192.168.64.12

我們在 80 端口調用上述 IP,我們應該可以從 Nginx 得到響應。

❯ curl http://192.168.64.12
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>

記住,Ingress 依賴於 DNS 工作,它應該被解析到 Minikube 的 IP 上。如果後端服務之一調用該 DNS,除非明確配置了,否則會解析失敗。這個時候,另一個附加組件可以來拯救你。

❯ minikube addons enable ingress-dns
    ▪ Using image cryptexlabs/minikube-ingress-dns:0.3.0

這將在 Kubernetes 集羣內啓動一個 DNS 服務器,監聽在 Minikube 的 IP 上。此外,還需要一個自定義的解析器,以強制自定義頂級域名(如. test,不要使用. local)的 DNS 解析被重定向到上面啓動的 DNS 服務器。Minikube Ingress DNS[3] 文檔很好地解釋了這一點。按照文檔裏描述的步驟操作,你將會部署成功一個帶有自定義 DNS 的 Ingress。

負載均衡類型的 Service

部署負載均衡器類型的服務,並從主機上訪問它,就像你在雲端部署時一樣,這不是很好嗎?多虧了 metalb 插件,讓這變得很簡單。

minikube addons enable metallb

這將部署另外兩個 Pod,負責爲負載均衡器類型的 Service 分配一個外部 IP。如果不這樣做,這些服務的外部 IP 將始終處於 “pending” 狀態。

在使用 metallb 之前,還有一個步驟。默認情況下,metallb 沒有辦法知道哪個範圍的 IP 可以分配給負載均衡器的服務。運行下面的命令來提供一個範圍。

❯ minikube addons configure metallb
-- Enter Load Balancer Start IP: 192.168.64.5
-- Enter Load Balancer End IP: 192.168.64.15
    ▪ Using image metallb/speaker:v0.9.6
    ▪ Using image metallb/controller:v0.9.6
✅  metallb was successfully configured

基於你的 Minikube IP,分配一個小範圍的 IP,包括 Minikube IP。現在,每當你部署一個負載均衡器服務時,這個範圍內的一個 IP 將被分配。

其他問題


登錄到遠程鏡像倉庫

你可能仍然有舊的~/.docker/config.json,其中 credsStore 設置爲 osxkeychain 或 desktop。這在新的配置中不會起作用。爲了解決這個問題,我們來安裝 Docker Credential Helper。

brew install docker-credential-helper

密鑰憑證還是會像以前一樣存儲在 MacOS Keychain 中。如果這不起作用,一個快速的解決方法是刪除~/.docker/config.json 文件,然後再次登錄到鏡像倉庫。

保留 Docker 鏡像和持久化存儲卷聲明

Added 7th Sept 2021

Docker Desktop 的一個好處是,你可以關閉 Kubernetes 集羣,以後再啓動它,用相同的 Docker 鏡像和持久化卷運行你的 Pod。例如,在 Kubernetes 中運行本地數據庫時,這就很有用。能夠在多次重啓中仍然保持有效的持久化卷是很方便的。

在 Minikube 中,如果我用 minikube stop 關閉集羣(和 Hyperkit 虛擬機),它會刪除 Docker 鏡像和所有持久化卷,這很麻煩。但幸運的是,Minikube 提供了一種防止刪除的方法。我們可以暫停 Kubernetes 集羣和 Hyperkit VM,而不是停止它。

minikube pause

該命令會終止 Kubernetes 集羣,但不會刪除 Hyperkit 虛擬機。這就釋放了更多的 CPU,同時仍然保留了所有的 Docker 鏡像和持久化卷。但是,等一下,它變得更好!它不會停止 dockerd 守護進程。所以你可以繼續使用 Docker CLI,只是別忘了用 eval $(minikube docker-env) 設置一下 docker 環境。

當你想恢復在 Kubernetes 集羣上的工作時,可以運行以下命令。

minikube unpause

而你將擁有所有的系統 Pod,包括附加組件 Addons。這甚至在筆記本電腦重新啓動後,也能正常工作!

在 Docker 容器中綁定掛載

Added 7th Sept 2021

一些在 Reddit[4]上的好心人指出,Docker 容器中的綁定掛載 (-v) 在 Minikube 和 Docker 的配置中並不能工作。這是 Docker 容器的一個常見操作,他理論上應該可以正常工作。

由於存在 Hyperkit 作爲中間層,掛載一個卷其實是分成兩步操作的。首先,讓我們把筆記本上的磁盤掛載到 Hyperkit VM 上。

minikube mount /myvolume:/test

這將把本地文件夾 / myvolume 掛載到 Hyperkit VM 的 / test 路徑下。這個進程仍然是活躍的,所以你不應該關閉這個終端。

在另一個終端上,運行 Docker 容器,並將 / test 卷綁定到容器內的一個路徑上。

docker run --rm -it -v /test:/inside busybox /bin/sh

這將在容器內的 Hyperkit VM 上掛載 / test 卷,路徑爲 / inside。實際上,這會使得筆記本電腦上 / myvolume 下的所有處在容器內的文件和文件夾處於讀寫模式。很好!

總結


在週日下午花了幾個小時後,我對這個新的配置相當滿意。我們擺脫了 Docker Desktop,用 Hyperkit 和 Minikube 取代了它。我們仍然可以使用 Docker API 來管理 Docker 文件,並在本地 Kubernetes 集羣中部署應用程序。最重要的是,我的筆記本可以愉快地運行,額外的資源可以用來運行 Slack、Notion 和其他 Electron 應用程序;-)

相關鏈接:

  1. https://minikube.sigs.k8s.io/docs/drivers/

  2. https://minikube.sigs.k8s.io/docs/drivers/hyperkit/

  3. https://minikube.sigs.k8s.io/docs/handbook/addons/ingress-dns/

  4. https://www.reddit.com/r/kubernetes/comments/pjlt52/goodbye_docker_desktop_hello_minikube/hbyi4m5?utm_source=share&utm_medium=web2x&context=3

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/EkqhY7MTXy4bSOcFf7uxtg