The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

利用 Multipass 在區域網路架設一套 MicroK8s 叢集環境

我之前有篇 使用 MicroK8s 架設 Kubernetes 叢集的完整過程解析 文章,講解了完整的 MicroK8s 體驗的過程。雖然你可以在 Windows 上輕鬆的架設出一套 Kubernetes 叢集,但是由於 MicroK8s 的底層使用到了 Multipass 工具來建立虛擬機器(VM),事實上透過 Multipass 建立的 VM 在每次重開機的時候都會變更 IP 地址,因此只要 VM 重開機,基本上叢集就會壞掉,因為所有 Worker Nodes 將無法找到 Control Plane 的 IP 地址。這篇文章我來說說這個問題的解決方法!

首先,你必須先透過 Multipass 建立一台 Ubuntu VM,你可以參考我的 如何替 Multipass 建立的 VM 設定一組固定 IP 地址 文章,先建立一個擁有固定 IP 地址microk8s-vm 虛擬機。

  1. 檢查 Multipass 可用的網路清單

    multipass networks --format yaml
    
  2. 設定預設的 Bridge 網路名稱

    假設我們的 External 虛擬交換器名稱為 LANBridge

    multipass set local.bridged-network=LANBridge
    
  3. 透過 Multipass 建立虛擬機器 (microk8s-vm) 並指定網路與設定一張手動的網路介面

    我們特別給 microk8s-vm 這台虛擬機擁有 2 vCore, 50GB Disk, 2GB Memory 的規格。

    從 Disk 方面來說,Multipass 預設建立的 VM 磁碟大小只有 5GB 而已,對 Kubernetes 來說是不夠的,建議調整到 50GB 左右!

    而在 CPU 方面,大多數內建的系統 Pods 都會設定 Requests and limits100m (即 0.1 顆 CPU 核心),但是系統 Pods 隨著你安裝的 MicroK8s Add ons 越來越多,執行的 Pods 也會很容易超過 10 個,因此整個叢集若 CPU 數只有 1 核心的話,很多應用程式將無法成功啟動,因此預設值也是遠遠不夠用的,因此我們先給 2 核心來用。

    multipass launch --name 'microk8s-vm' --bridged --disk 50G --cpus 2 --mem 2G
    

    注意: 之後所建立的 Worker Nodes 都需要跟 Control Plane 有著相同的 Network 設定,這樣兩邊的網路才能暢通。

  4. 查詢網路介面資訊 (包含 IP 資訊)

    multipass exec 'microk8s-vm' -- ip -br address show scope global
    

    此時你應該會看到三張網路介面:

    eth0             UP             172.29.217.133/20
    eth1             UP             192.168.1.12/24
    

    這裡的 eth0Multipass 內部使用的網路介面,這個 IP 地址每次 VM 重開機都會變更。

    而這個 eth1 的 IP 為 Bridge 網路透過區域網路的 DHCP Server 自動取得的 IP 地址,我們將手動調整為固定 IP 地址。

  5. 手動調整 VM 的固定 IP 地址

    編輯 /etc/netplan/50-cloud-init.yaml 網路設定:

    multipass exec 'microk8s-vm' -- sudo vi /etc/netplan/50-cloud-init.yaml
    

    調整 extra0 網路介面設定後的檔案內容長這樣:

    network:
        ethernets:
            default:
                dhcp4: true
                match:
                    macaddress: 52:54:00:d1:11:e1
            extra0:
                addresses: [192.168.1.101/24]
                gateway4: 192.168.1.1
                nameservers:
                   addresses: [168.95.1.1, 8.8.8.8]
                match:
                    macaddress: 52:54:00:2d:44:64
        version: 2
    
  6. 透過「重新開機」套用網路更新

    multipass restart 'microk8s-vm'
    
  7. 查詢網路介面資訊 (包含 IP 資訊)

    multipass exec 'microk8s-vm' -- ip -br address show scope global
    

    此時你應該會看到三張網路介面:

    eth0             UP             172.29.217.133/20
    eth1             UP             192.168.1.101/24
    

    其中 eth1192.168.1.101 就會是一個固定的 IP 地址!👍

  8. 我們拿 microk8s-vm 來架設 MicroK8s 的 Control Plane (master)

    multipass exec 'microk8s-vm' -- sudo snap install microk8s --classic
    multipass exec 'microk8s-vm' -- sudo usermod -a -G microk8s ubuntu
    
    # 在 microk8s-vm 虛擬機中啟動 MicroK8s 服務
    multipass exec 'microk8s-vm' -- microk8s start
    
  9. 透過本機使用 microk8s.exe 工具程式管理 MicroK8s 叢集

    # 取得 MicroK8s 專用的 config 內容
    mkdir $env:LOCALAPPDATA\MicroK8s -Force
    microk8s config > $env:LOCALAPPDATA\MicroK8s\config
    
    # 取得 KUBECONFIG 憑證連線資訊
    microk8s config > ~/.kube/config
    
    # 測試可否從本機管理 MicroK8s
    microk8s enable dns storage
    microk8s kubectl get sc
    

    由於我們先前設定了固定 IP 地址,這裡的 microk8s config 預設就會採用額外的 IP 地址當成我們主要的連線目標,其中 TLS 憑證也會自動加入這個 IP 作為憑證別名 (alt_names),你可以透過以下檔案查看憑證申請時的 OpenSSL 設定檔:

    multipass exec 'microk8s-vm' -- sudo cat /var/snap/microk8s/current/certs/csr.conf
    
  10. 建立 MicroK8s 的工作節點 (Worker Nodes)

    # node1
    multipass launch --name 'node1' --bridged --disk 10G
    multipass exec 'node1' -- sudo snap install microk8s --classic
    multipass exec 'node1' -- sudo usermod -a -G microk8s ubuntu
    
    # node2
    multipass launch --name 'node2' --bridged --disk 10G
    multipass exec 'node2' -- sudo snap install microk8s --classic
    multipass exec 'node2' -- sudo usermod -a -G microk8s ubuntu
    
  11. node1node2 加入 MicroK8s 叢集

    # 產生加入叢集的命令
    multipass exec 'microk8s-vm' -- microk8s add-node
    
    # 記得要選取使用固定 IP 的那行命令,確保工作節點未來可以持續連到 control plane 節點
    multipass exec 'node1' -- microk8s join 192.168.1.101:25000/d06855a366499b47c8ce106015664bff/aea0aaad938e
    
    # 產生加入叢集的命令
    multipass exec 'microk8s-vm' -- microk8s add-node
    
    # 記得要選取使用固定 IP 的那行命令,確保工作節點未來可以持續連到 control plane 節點
    multipass exec 'node2' -- microk8s join 192.168.1.101:25000/dae59f9219ab4aec33d90fcfc09f88a2/aea0aaad938e
    

    請記得選用 microk8s-vm 的固定 IP 地址喔!

  12. 查看 MicroK8s 叢集狀態

    multipass exec 'microk8s-vm' -- microk8s status
    multipass exec 'microk8s-vm' -- microk8s kubectl cluster-info
    multipass exec 'microk8s-vm' -- microk8s kubectl get no -o wide
    multipass exec 'microk8s-vm' -- microk8s kubectl version --short
    
  13. 從本機取得 MicroK8s 叢集資訊

    kubectl cluster-info
    kubectl get no -o wide
    kubectl version --short
    
  14. 設定 MetalLB Loadbalancer 功能 (Add on: MetalLB)

    microk8s enable metallb:192.168.1.101-192.168.1.101
    

    部署測試應用程式

    kubectl apply -f https://k8s.io/examples/application/guestbook/redis-leader-deployment.yaml
    kubectl apply -f https://k8s.io/examples/application/guestbook/redis-leader-service.yaml
    kubectl apply -f https://k8s.io/examples/application/guestbook/redis-follower-deployment.yaml
    kubectl apply -f https://k8s.io/examples/application/guestbook/redis-follower-service.yaml
    kubectl apply -f https://k8s.io/examples/application/guestbook/frontend-deployment.yaml
    kubectl apply -f https://k8s.io/examples/application/guestbook/frontend-service.yaml
    

    查看服務狀態

    kubectl get service frontend
    

    將應用程式對外服務改成 LoadBalancer

    kubectl patch svc/frontend -p '{\"spec\": {\"type\": \"LoadBalancer\"}}'
    

    查看服務狀態 (此時應該可以取得一個外部的 IP 地址)

    kubectl get service frontend
    

    嘗試連線 http://192.168.1.101/ 看有沒有頁面出現!

    刪除範例應用程式

    kubectl delete -f https://k8s.io/examples/application/guestbook/redis-leader-deployment.yaml
    kubectl delete -f https://k8s.io/examples/application/guestbook/redis-leader-service.yaml
    kubectl delete -f https://k8s.io/examples/application/guestbook/redis-follower-deployment.yaml
    kubectl delete -f https://k8s.io/examples/application/guestbook/redis-follower-service.yaml
    kubectl delete -f https://k8s.io/examples/application/guestbook/frontend-deployment.yaml
    kubectl delete -f https://k8s.io/examples/application/guestbook/frontend-service.yaml
    
  15. 設定 Ingress 服務

    microk8s enable ingress
    

    建立一個 ingress-service.yml 檔案:

    apiVersion: v1
    kind: Service
    metadata:
      name: ingress
      namespace: ingress
    spec:
      selector:
        name: nginx-ingress-microk8s
      type: LoadBalancer
      # loadBalancerIP is optional. MetalLB will automatically allocate an IP
      # from its pool if not specified. You can also specify one manually.
      # loadBalancerIP: x.y.z.a
      ports:
        - name: http
          protocol: TCP
          port: 80
          targetPort: 80
        - name: https
          protocol: TCP
          port: 443
          targetPort: 443
    

    套用 ingress-service.yml 檔案:

    kubectl apply -f ./ingress-service.yml
    

    現在 Ingress 已經取得了一個 Load Balancer IP 地址,當你連到 http://192.168.1.101/ 將會看到一個來自 nginx 的 404 Not Found 頁面!

    部署測試應用程式

    kubectl apply -f https://k8s.io/examples/application/guestbook/redis-leader-deployment.yaml
    kubectl apply -f https://k8s.io/examples/application/guestbook/redis-leader-service.yaml
    kubectl apply -f https://k8s.io/examples/application/guestbook/redis-follower-deployment.yaml
    kubectl apply -f https://k8s.io/examples/application/guestbook/redis-follower-service.yaml
    kubectl apply -f https://k8s.io/examples/application/guestbook/frontend-deployment.yaml
    kubectl apply -f https://k8s.io/examples/application/guestbook/frontend-service.yaml
    

    建立一個 ingress.yml 檔案:

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: minimal-ingress
      annotations:
        nginx.ingress.kubernetes.io/rewrite-target: /
    spec:
      rules:
      - http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: frontend
                port:
                  number: 80
    

    套用 ingress.yml 檔案:

    kubectl apply -f ./ingress.yml
    

    現在 Ingress 已經設定完成,當你連到 http://192.168.1.101/ 將會看到 Guestbook 應用程式的頁面!

刪除所有已建立資源

multipass delete node1 node2 microk8s-vm
multipass purge

相關連結