教你5分鐘在Ubuntu 22.04架設Kubernetes Cluster

教你5分鐘在Ubuntu 22.04架設Kubernetes Cluster

話說[前篇]處理好Notebook、Hyper-V網路與VM網路之間的問題之後,在MicroK8s的幫助下,從Kubernetes到Kubernetes Cluster幾乎都是一行指令就能完成。

安裝MicroK8s:

sudo snap install microk8s --classic --channel=1.25

建立與加入Cluster:

microk8s add-node

方便代表看不到細節。因為想要瞭解細節,因此又花了一些時間學習如何從無到有設定與安裝Kubernetes與建置Kubernetes Cluster。

伺服器準備

文件建議RAM超過2GiB即可。

注意,請把Hyper-V的動態記憶體管理取消。不然在安裝時可能會看到記憶體不足無法安裝的訊息。

修改/etc/hosts,IP與Hostname清單。這部分請依你的架構與規劃自行調整。

192.168.56.10 k8s-master
192.168.56.20 k8s-worker1
192.168.56.30 k8s-worker2

要5分鐘完成架設的前提是先把VM及相關網路環境設定好。

Kubernetes安裝前執行環境準備

請複制以下Bash Script到master及worker1、worker2上執行:

sudo sh SetupK8sEnv.sh

SetupK8sEnv.sh修改為你儲存檔案的名稱。

這份指令碼就是本篇的精華,說明我都盡量寫在裡面了,它花了我一個週末的時間去串出來的。指令碼會跑很多資訊出來,這是我不斷在找執行問題,因此沒有過濾,如果你不想看那麼多訊息,那麼請自行修改加上>/dev/null 2>&1到不想看的指令後面,例如:apt update >/dev/null 2>&1

注意,[Step 2]如果是在正式機,請考慮好關閉Firewall的風險。這只是我個人架Lab環境,我不想再被底層網路搞到。
[Step 3][Step 4]的組態檔名稱可任意命名,網路也有看到用k8s.conf簡稱來命名的。

透過kubeadm安裝Kubernetes Cluster

在master我們進行初始化:

sudo kubeadm config images pull

這個動作是選擇性的,只是讓等一下初始化的動作快一點。現在不做,等一下初始化一樣會自動下載。這也可以順便確定一下剛剛跑的Script有沒有問題。
另外這裡建議快照(檢查點)一下。如果你跟我一樣很想多玩幾種Pod Network的話。

初始化指令其實很簡單:

kubeadm init

kubeadm init會幫忙我們進行許多事,而且有許多參數,如果你的網路環境是需要討論與設計的,建議讀一下文件,我這裡不多說明,實驗環境一切從簡(預設)。

在我的筆電雙網卡環境下,最後我是指定兩個參數:

# Pod network add-on: Flannel
sudo kubeadm init --apiserver-advertise-address=192.168.56.10 --pod-network-cidr=10.244.0.0/16
# Pod network add-on: calico
sudo kubeadm init --apiserver-advertise-address=192.168.56.10 --pod-network-cidr=192.168.0.0/16

簡單來說,因為我有雙網卡,因此我指定--apiserver-advertise-address到Internal網卡去。另外,初始化後,它會請你設定Pod network addons10.244.0.0/16Flannel預設值。192.168.0.0/16calico預設值,先指定好,等一下處理可以快一點。(時間快到了…)

建議用calico,calico功能比較完整。連Flannel的文件都建議用calico,Flannel文件自己舉例說,如果想要「network policy」功能,請找類似Calico的專案。

跑完kubeadm init如果看到initialized successfully,這樣代表第一台master成功了。

Your Kubernetes control-plane has initialized successfully!

To start using your cluster, you need to run the following as a regular user:

  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config

Alternatively, if you are the root user, you can run:

  export KUBECONFIG=/etc/kubernetes/admin.conf

You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
  https://kubernetes.io/docs/concepts/cluster-administration/addons/

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 192.168.56.10:6443 --token token \
        --discovery-token-ca-cert-hash sha256:hash

最後二行指令我有簡化,先複製下來等等worker會用到。如果不小心被你clear了,請參考文件 執行 kubeadm token create --print-join-command 可以找回來。

按畫面說明,第一件事執行那三行指令:

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

第二件事是開始套Pod Network。

如果是選--pod-network-cidr=10.244.0.0/16的人,請執行以下指令:

kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml

這部分約需等1分鐘。當然,你也可以下載yml組態檔回來修改:

curl -fsSLO https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
sudo nano kube-flannel.yml

在net-conf.json可以設定cidr:

net-conf.json: |
  {
    "Network": "10.244.0.0/16",
    "Backend": {
      "Type": "vxlan"
    }
  }

另外,像我是雙網卡,可以在/opt/bin/flanneld加入一個--iface=eth0的參數。

eth0是我Internal網卡名稱。你可以透過ip a來查詢你的網卡名稱。

containers:
- name: kube-flannel
 #image: flannelcni/flannel:v0.20.1 for ppc64le and mips64le (dockerhub limitations may apply)
  image: docker.io/rancher/mirrored-flannelcni-flannel:v0.20.1
  command:
  - /opt/bin/flanneld
  args:
  - --ip-masq
  - --kube-subnet-mgr
  - --iface=eth0

最後套用:

kubectl apply -f kube-flannel.yml

這是套用Pod Network前,coredns未能生效:

$ kubectl get pods -A
NAMESPACE     NAME                                 READY   STATUS    RESTARTS   AGE
kube-system   coredns-565d847f94-8kmxl             0/1     Pending   0          8m14s
kube-system   coredns-565d847f94-dppwv             0/1     Pending   0          8m14s
kube-system   etcd-k8s-master                      1/1     Running   0          8m27s
kube-system   kube-apiserver-k8s-master            1/1     Running   0          8m27s
kube-system   kube-controller-manager-k8s-master   1/1     Running   0          8m28s
kube-system   kube-proxy-vdds4                     1/1     Running   0          8m15s
kube-system   kube-scheduler-k8s-master            1/1     Running   0          8m28s

這是套用Pod Network後,flannel及coredns都已生效。

$ kubectl get pods -A
NAMESPACE      NAME                                 READY   STATUS    RESTARTS   AGE
kube-flannel   kube-flannel-ds-zvm2j                1/1     Running   0          2m22s
kube-system    coredns-565d847f94-8kmxl             1/1     Running   0          10m
kube-system    coredns-565d847f94-dppwv             1/1     Running   0          10m
kube-system    etcd-k8s-master                      1/1     Running   0          11m
kube-system    kube-apiserver-k8s-master            1/1     Running   0          11m
kube-system    kube-controller-manager-k8s-master   1/1     Running   0          11m
kube-system    kube-proxy-vdds4                     1/1     Running   0          10m
kube-system    kube-scheduler-k8s-master            1/1     Running   0          11m

在Pod Network生效後,才能做第三件事,到worker1及worker2去執行kubeadm join,也就是之前畫面上顯示的最後二行:

sudo kubeadm join 192.168.56.10:6443 --token token \
     --discovery-token-ca-cert-hash sha256:hash

等跑完確認一下node情況:

$ kubectl get nodes -o wide
NAME          STATUS   ROLES           AGE   VERSION   INTERNAL-IP     EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
k8s-master    Ready    control-plane   48m   v1.25.3   192.168.56.10   <none>        Ubuntu 22.04.1 LTS   5.15.0-52-generic   containerd://1.6.9
k8s-worker1   Ready    <none>          23m   v1.25.3   192.168.56.20   <none>        Ubuntu 22.04.1 LTS   5.15.0-52-generic   containerd://1.6.9
k8s-worker2   Ready    <none>          21m   v1.25.3   192.168.56.30   <none>        Ubuntu 22.04.1 LTS   5.15.0-52-generic   containerd://1.6.9

確認一下pod情況:

$ kubectl get pods -A -o wide
NAMESPACE      NAME                                 READY   STATUS    RESTARTS   AGE   IP              NODE          NOMINATED NODE   READINESS GATES
kube-flannel   kube-flannel-ds-58vlj                1/1     Running   0          66m   192.168.56.30   k8s-worker2   <none>           <none>
kube-flannel   kube-flannel-ds-bhg5d                1/1     Running   0          68m   192.168.56.20   k8s-worker1   <none>           <none>
kube-flannel   kube-flannel-ds-zvm2j                1/1     Running   0          85m   192.168.56.10   k8s-master    <none>           <none>
kube-system    coredns-565d847f94-8kmxl             1/1     Running   0          93m   10.244.0.2      k8s-master    <none>           <none>
kube-system    coredns-565d847f94-dppwv             1/1     Running   0          93m   10.244.0.3      k8s-master    <none>           <none>
kube-system    etcd-k8s-master                      1/1     Running   0          93m   192.168.56.10   k8s-master    <none>           <none>
kube-system    kube-apiserver-k8s-master            1/1     Running   0          93m   192.168.56.10   k8s-master    <none>           <none>
kube-system    kube-controller-manager-k8s-master   1/1     Running   0          93m   192.168.56.10   k8s-master    <none>           <none>
kube-system    kube-proxy-8r8mf                     1/1     Running   0          68m   192.168.56.20   k8s-worker1   <none>           <none>
kube-system    kube-proxy-nfvhv                     1/1     Running   0          66m   192.168.56.30   k8s-worker2   <none>           <none>
kube-system    kube-proxy-vdds4                     1/1     Running   0          93m   192.168.56.10   k8s-master    <none>           <none>
kube-system    kube-scheduler-k8s-master            1/1     Running   0          93m   192.168.56.10   k8s-master    <none>           <none>

賀!4:59秒完成任務!(亂掰)

calico network

其實calico文件寫的不錯,在cidr設對的情況下,我跟著文件做沒碰到問題。就以下二行:

kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.24.4/manifests/tigera-operator.yaml
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.24.4/manifests/custom-resources.yaml

一樣,如果你需要修改yml裡的組態:

curl -fsSLO https://raw.githubusercontent.com/projectcalico/calico/v3.24.4/manifests/tigera-operator.yaml
curl -fsSLO https://raw.githubusercontent.com/projectcalico/calico/v3.24.4/manifests/custom-resources.yaml
# 需要修改custom-resources.yaml的cidr為你的`kubeadm init`的設定值

接著套用:

kubectl create -f tigera-operator.yaml
kubectl create -f custom-resources.yaml
# 等待所有Pod狀態為`Running`。(在我的Surfact Pro上花費約3-4分鐘)
# 注意官網說明,namespace也許和其他套件安裝不一樣:「The Tigera operator installs resources in the calico-system namespace. Other install methods may use the kube-system namespace instead.」
watch kubectl get pods -n calico-system

watch我對它不熟,我在SSH按Ctrl+C結束它。

對,我不能一開始介紹它,因為calico光init就花了快4分鐘,我不能對題目不負責任。這也是先介紹Flannel的原因。哈哈!最後我在執行以下指令和得到跟calico官網不一樣的回應,我猜我是全新主機而且是剛剛才新架設的K8s Cluster,但使用上沒有問題。

kubectl taint nodes --all node-role.kubernetes.io/control-plane-
kubectl taint nodes --all node-role.kubernetes.io/master-
# error: taint "node-role.kubernetes.io/master" not found

安裝 calicoctl(選擇性)

基本上,安裝 Kubernetes Cluster 到前一步已經全部完成。另外可以再安裝 calicoctl。如果未來想進行Calico的查詢或設定,就能此calicoctl幫忙。

cd /usr/local/bin/
sudo curl -L https://github.com/projectcalico/calico/releases/latest/download/calicoctl-linux-amd64 -o calicoctl
sudo chmod +x ./calicoctl

calicoctl --help

進一步瞭解 calicoctl 請查看文件

小結

準備建置 VM 環境工作是最花時間的,整理成指令碼(Bash Script)之後就很輕鬆了。而透過kubeadm init幫忙架設Kubernetes Cluster也沒什麼難處,主要是後續要讀一下想選用的Pod Network方案的文件。尤其是一開始cidr沒設好,或不是你想要的預設值,就需要瞭解一下如何修改。當Pod Network正確套用之後,Welcome Kubernetes Cluster World!

注意一下這些指令碼,如果裡面帶版本v1.26.x、v3.24.x等,最好都再去官網確認一下版本資訊。例如,此文件裡的 Calico 撰文當下是 v3.24.4,後續回來查這篇文件使用時,Calico 已經更新至 v3.26.1。SetupK8sEnv.sh 也是,裡面的版本比之撰文當下也更新了 2 版,指令碼本身沒問題,我就不為版號去更新它了。

2 則留言:

  1. 請問如果筆電想玩K8s配備需要什麼樣的規格比較合適呢,謝謝

    回覆刪除
    回覆
    1. 不確定你想玩那一種,如果是文章裡VM等級的話,大概需要以下資源:
      CPU: 2 + 2 + 2 = 6 core
      RAM: 4 + 2 + 2 = 8 GB
      Disk: 20 + 20 + 20 = 60 GB

      如果只是練習,我蠻建立用 https://kind.sigs.k8s.io 去玩,一點虛擬化資源就可以玩上面三台的東西。

      刪除

感謝您的留言,如果我的文章你喜歡或對你有幫助,按個「讚」或「分享」它,我會很高興的。