# Create a kind cluster with Podman ## Preface 本篇文章會介紹如何安裝 kind、設定 node provider 為 podman,並實作建立一座 kind Cluster ## kind 簡介 kind is a tool for running local Kubernetes clusters using Podman/Docker container “nodes”. kind was primarily designed for testing Kubernetes itself, but may be used for local development or CI/CD. ## OS 環境設定 ### SLES 15 SP5 ```bash! # 1.在 SLES 15 SP5 上安裝 4.8.3 版本的 podman 和 netavark $ sudo SUSEConnect -p sle-module-containers/15.5/x86_64 $ sudo zypper -n install podman-4.8.3-150500.3.9.1 netavark-1.5.0-150500.1.4 # 2. 啟動 cgroup v2 ## 2.1. 在 GRUB_CMDLINE_LINUX_DEFAULT 這個變數中添加 "systemd.unified_cgroup_hierarchy=1" $ sudo nano /etc/default/grub ... GRUB_CMDLINE_LINUX_DEFAULT="splash=silent mitigations=auto quiet security=apparmor crashkernel=302M,high crashkernel=72M,low systemd.unified_cgroup_hierarchy=1" ## 2.2. update GRUB 讓設定永久生效 $ sudo grub2-mkconfig -o /boot/grub2/grub.cfg # 3. 設定 Pomdman 的 networkBackend 為 netavark $ sudo cp /usr/share/containers/containers.conf /etc/containers/containers.conf ## 3.1. 修改設定檔,將 networkBackend 的值改為 netavark $ sudo nano /etc/containers/containers.conf [network] network_backend = "netavark" ## 3.2. 重設 Podman $ sudo podman system reset --force # 4. 設定 kind 使用 Podman 建立 node $ sudo nano /etc/profile ... ## 添加以下字串進去 export KIND_EXPERIMENTAL_PROVIDER="podman" # 5. 重新開機 $ sudo init 6 # 6. 檢查 podman 網路是否成功 $ podman info --format {{.Host.NetworkBackend}} netavark # 7. 檢查 cgroup 版本 $ podman info | grep 'cgroupVersion' cgroupVersion: v2 # 8. 檢查 kind 的 node provider 是否設為 podman $ env | grep KIND_EXPERIMENTAL_PROVIDER KIND_EXPERIMENTAL_PROVIDER=podman ``` ### Ubuntu server 22.04 ```bash! # 1. 下載 podman,版本 v4.8.3 $ curl -fsSL -o podman-linux-amd64.tar.gz https://github.com/mgoltzsche/podman-static/releases/download/v4.8.3/podman-linux-amd64.tar.gz && \ tar -xzf podman-linux-amd64.tar.gz && \ sudo cp -r podman-linux-amd64/usr podman-linux-amd64/etc / > To restart containers with restart-policy=always on boot, enable the podman-restart systemd service # 2. 下載 netavark、aardvark-dns 和一些必要套件 $ sudo apt update && sudo apt-get install -y \ containernetworking-plugins \ protobuf-compiler \ cargo \ make \ jq \ uidmap && \ sudo apt autoremove $ git clone https://github.com/containers/netavark.git && \ cd netavark/ && \ sudo make && \ sudo cp ./bin/netavark /usr/local/lib/podman/ $ git clone https://github.com/containers/aardvark-dns.git && \ cd aardvark-dns/ && \ sudo make && \ sudo cp ./bin/aardvark-dns /usr/local/lib/podman/ # 3. 修改設定檔,將 networkBackend 的值改為 netavark $ sudo nano /etc/containers/containers.conf [network] network_backend = "netavark" ## 3.1. 重設 Podman $ sudo podman system reset --force # 4. 設定 kind 使用 Podman 建立 node $ sudo nano /etc/profile ... ## 添加以下字串進去 export KIND_EXPERIMENTAL_PROVIDER="podman" # 5. 重新開機 $ sudo init 6 # 6. 檢查 podman 網路是否成功 $ podman info --format {{.Host.NetworkBackend}} netavark # 7. 檢查 cgroup 版本 $ podman info | grep 'cgroupVersion' cgroupVersion: v2 # 8. 檢查 kind 的 node provider 是否設為 podman $ env | grep KIND_EXPERIMENTAL_PROVIDER KIND_EXPERIMENTAL_PROVIDER=podman ``` ### Google Cloud Shell <font color=red>以下設定在 Google Cloud Shell 被重製後都會失效。</font> ```bash! # 1. 移除 docker $ sudo apt-get remove -y docker-ce \ docker-ce-cli \ containerd.io \ docker-buildx-plugin \ docker-compose-plugin $ sudo apt autoremove # 2. 啟用 IPV6 $ sudo nano /etc/sysctl.conf ... net.ipv6.conf.all.disable_ipv6=0 net.ipv6.conf.default.disable_ipv6=0 net.ipv6.conf.lo.disable_ipv6=0 $ sudo sysctl -w net.ipv6.conf.all.disable_ipv6=0 $ sudo sysctl -w net.ipv6.conf.default.disable_ipv6=0 $ sudo sysctl -w net.ipv6.conf.lo.disable_ipv6=0 $ sudo sysctl -p # 3. 下載 podman,版本 v4.8.3 $ curl -fsSL -o podman-linux-amd64.tar.gz https://github.com/mgoltzsche/podman-static/releases/download/v4.8.3/podman-linux-amd64.tar.gz && \ tar -xzf podman-linux-amd64.tar.gz && \ sudo cp -r podman-linux-amd64/usr podman-linux-amd64/etc / # 4. 下載 netavark、aardvark-dns 和一些必要套件 $ sudo apt update && sudo apt-get install -y \ containernetworking-plugins \ protobuf-compiler \ cargo \ make \ jq \ uidmap && \ sudo apt autoremove $ git clone https://github.com/containers/netavark.git && \ cd netavark/ && \ sudo make && \ sudo cp ./bin/netavark /usr/local/lib/podman/ $ git clone https://github.com/containers/aardvark-dns.git && \ cd aardvark-dns/ && \ sudo make && \ sudo cp ./bin/aardvark-dns /usr/local/lib/podman/ # 5. 修改設定檔,將 networkBackend 的值改為 netavark $ sudo nano /etc/containers/containers.conf [network] network_backend = "netavark" ## 5.1. 重設 Podman $ sudo podman system reset --force # 6. 設定 kind 使用 Podman 建立 node $ sudo nano /etc/profile ... ## 添加以下字串進去 export KIND_EXPERIMENTAL_PROVIDER="podman" # 7. 檢查 podman 網路是否成功 $ podman info --format {{.Host.NetworkBackend}} netavark # 8. 檢查 cgroup 版本 $ podman info | grep 'cgroupVersion' cgroupVersion: v2 # 9. 檢查 kind 的 node provider 是否設為 podman $ sudo su - k130 $ env | grep KIND_EXPERIMENTAL_PROVIDER KIND_EXPERIMENTAL_PROVIDER=podman ``` ## 安裝 kind ```bash! # 1. 安裝 kind $ curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.23.0/kind-linux-amd64 && \ chmod +x ./kind && \ sudo mv ./kind /usr/local/bin/kind # 2. 檢查 Podman 版本 $ sudo podman version Client: Podman Engine Version: 4.8.3 API Version: 4.8.3 Go Version: go1.21.8 Built: Tue Mar 19 20:00:00 2024 OS/Arch: linux/amd64 # 3. 檢查 kind 版本 $ sudo kind --version kind version 0.23.0 ``` ## 建立 Cluster ```bash! $ mkdir ~/k8s $ echo 'kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 name: c30 networking: podSubnet: "10.244.0.0/16" serviceSubnet: "10.98.0.0/12" disableDefaultCNI: true nodes: - role: control-plane image: docker.io/kindest/node:v1.30.0 - role: worker image: docker.io/kindest/node:v1.30.0' > ~/k8s/c30.yaml $ sudo kind create cluster --config ~/k8s/c30.yaml enabling experimental podman provider Creating cluster "c30" ... ✓ Ensuring node image (docker.io/kindest/node:v1.30.0) 🖼 ✓ Preparing nodes 📦 📦 ✓ Writing configuration 📜 ✓ Starting control-plane 🕹️ ✓ Installing StorageClass 💾 ✓ Joining worker nodes 🚜 Set kubectl context to "kind-c30" You can now use your cluster with: kubectl cluster-info --context kind-c30 Not sure what to do next? 😅 Check out https://kind.sigs.k8s.io/docs/user/quick-start/ ``` ### kind Cluster 設定檔詳解 ```yaml= kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 name: c30 networking: podSubnet: "10.244.0.0/16" serviceSubnet: "10.98.0.0/12" disableDefaultCNI: true nodes: - role: control-plane image: docker.io/kindest/node:v1.30.0 - role: worker image: docker.io/kindest/node:v1.30.0 ``` - `kind: Cluster`,指定要設定的是 KIND Cluster - `apiVersion: kind.x-k8s.io/v1alpha4`,KIND 設定檔的版號,不同的版號在設定檔中的一些設定值或選項,它們的含意會變得不同。 - `name: c30`,設定 KIND Cluster 的名字,這裡取名 `c30`。 - `neteorking`,設定 Cluster 的網路,有很多設定可以客製化。 - `podSubnet`,設定 pod 會得到的 IP 範圍。 - `serviceSubnet`,設定 Kubernetes service 會得到的 IP 範圍。 - `disableDefaultCNI: true`,KIND 會附帶一個簡單的網路實作(“kindnetd”),這是根據標準的 CNI 插件實現的(如 `ptp`, `host-local` 等)和簡單的 netlink routes。 - 這個 CNI 也會處理 IP 偽裝。 - 可以選擇關閉預設的 CNI 設定,改安裝其他的 CNI。這是一個進階用戶功能,支援有限,但已知很多常見的 CNI 設定檔都能正常運作,例如 Calico。。 ## 檢查 c30 Cluster ```bash! $ sudo kind get clusters enabling experimental podman provider c30 $ sudo kind get nodes --name c30 enabling experimental podman provider c30-control-plane c30-worker $ sudo podman ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3eb5630a3ee3 docker.io/kindest/node:v1.30.0 38 minutes ago Up 38 minutes 127.0.0.1:40297->6443/tcp c30-control-plane f0d28b8e2a4e docker.io/kindest/node:v1.30.0 38 minutes ago Up 37 minutes c30-worker ``` ## 設定 K8S Node ```bash! $ mkdir ~/cni/ $ curl -sL "$(curl -sL https://api.github.com/repos/containernetworking/plugins/releases/latest | jq -r '.assets[].browser_download_url' | grep 'linux-amd64.*.tgz$')" -o ~/cni/cni-plugins.tgz # 如果上面那行錯誤,就執行這行命令 $ curl -sL https://github.com/containernetworking/plugins/releases/download/v1.5.0/cni-plugins-linux-amd64-v1.5.0.tgz -o ~/cni/cni-plugins.tgz $ tar xf ~/cni/cni-plugins.tgz -C ~/cni; rm ~/cni/cni-plugins.tgz $ sudo podman cp ~/cni/bridge c30-control-plane:/opt/cni/bin/bridge $ sudo podman cp ~/cni/bridge c30-worker:/opt/cni/bin/bridge ``` ## 登入 Control Plane ```bash! $ sudo podman exec -it c30-control-plane bash root@c30-control-plane:/# cat /etc/os-release PRETTY_NAME="Debian GNU/Linux 12 (bookworm)" NAME="Debian GNU/Linux" VERSION_ID="12" VERSION="12 (bookworm)" VERSION_CODENAME=bookworm ID=debian HOME_URL="https://www.debian.org/" SUPPORT_URL="https://www.debian.org/support" BUG_REPORT_URL="https://bugs.debian.org/" ``` ## 安裝 Canal 網路套件 ```bash! # 在 c30-control-plane 中執行已下命令 $ kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.28.0/manifests/canal.yaml ## 檢查 Canal 網路套件 $ kubectl -n kube-system get pods NAME READY STATUS RESTARTS AGE calico-kube-controllers-6df7596dbd-c2smj 1/1 Running 0 7m17s canal-kmjk9 2/2 Running 0 7m17s canal-vtxlq 2/2 Running 0 7m18s coredns-7db6d8ff4d-2mrc7 1/1 Running 1 63m coredns-7db6d8ff4d-cjhnn 1/1 Running 0 63m etcd-c30-control-plane 1/1 Running 0 64m kube-apiserver-c30-control-plane 1/1 Running 0 64m kube-controller-manager-c30-control-plane 1/1 Running 2 (5m57s ago) 64m kube-proxy-8jrdn 1/1 Running 0 63m kube-proxy-l9dpx 1/1 Running 0 63m kube-scheduler-c30-control-plane 1/1 Running 2 (5m ago) 64m ``` ## 檢測 KIND K8S ```bash! $ kubectl run nginx --image=quay.io/cloudwalker/nginx pod/nginx created $ kubectl get pods nginx -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx 1/1 Running 0 10m 10.244.1.5 c30-worker <none> <none> $ curl $(kubectl get pods nginx --no-headers -o custom-columns=ip:.status.podIP) <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> $ kubectl delete pod nginx pod "nginx" deleted $ exit ``` ## 關閉 c30 Cluster ```bash! $ sudo podman ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3eb5630a3ee3 docker.io/kindest/node:v1.30.0 About an hour ago Up About an hour 127.0.0.1:40297->6443/tcp c30-control-plane f0d28b8e2a4e docker.io/kindest/node:v1.30.0 About an hour ago Up About an hour c30-worker $ sudo podman stop c30-control-plane c30-worker c30-worker c30-control-plane ``` ## 刪除 c30 Cluster ```bash! $ sudo kind get clusters enabling experimental podman provider c30 $ sudo kind delete clusters c30 enabling experimental podman provider Deleted nodes: ["c30-control-plane" "c30-worker"] Deleted clusters: ["c30"] $ sudo podman ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES ``` ## 管理不同叢集 在建立 Kind 叢集後,預設情況下,如果未設定 `$KUBECONFIG` 環境變數,則 K8s 叢集入口憑證檔會儲存在 `${HOME}/.kube/config` 中。 不過因為我們建 kind 的時候有加 `sudo` ,所以 `kubeconfig` 會放在 `/root` 底下,如果有多個叢集的話,會 append 進同一個 `kubeconfig` 檔案裡面。 ```bash! # 1. 檢視在 KubeConfig 中定義的所有叢集 $ sudo kubectl config get-clusters NAME kind-c30 kind-c29 # 2. 檢視在 KubeConfig 中定義的所有 Contexts $ sudo kubectl config get-contexts CURRENT NAME CLUSTER AUTHINFO NAMESPACE kind-c29 kind-c29 kind-c29 * kind-c30 kind-c30 kind-c30 # 3. 檢視當前所在的 Contexts $ sudo kubectl config current-context kind-c30 # 4. 切換要管理的 K8s 叢集 $ sudo kubectl config use-context kind-c29 Switched to context "kind-c29". # 5. 檢視 C29 叢集 Node 狀態 $ sudo kubectl get nodes NAME STATUS ROLES AGE VERSION c29-control-plane Ready control-plane 23m v1.29.1 c29-worker Ready <none> 22m v1.29.1 ``` >### What is context meaning? > > * kubeconfig 檔案中的 Context 元素用於將存取叢集的參數集中在一個方便的名稱下。 > * 每個 context 有三個參數: > * cluster:集群的網址或名稱 > * namespace:要使用的 K8s namespace > * user:登入的使用者 > * kubectl 指令 預設會使用 目前設定檔 (`KubeConfig`) 裡 `current context` 的參數來存取要管理的 Kubernetes 集群。
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up