使用 MicroK8s 架設 Kubernetes 叢集,無論是本機的開發環境,或是實際運作的生產環境,都有一些應該注意的事情。本篇文章著重在「連線管理」部分,分享我過往的一些研究心得與筆記。
頻繁的更動節點 IP 怎麼辦
在 Windows 環境搭配 Hyper-V 安裝 MicroK8s 叢集時,預設會使用 Hyper-V 內建的 Default Switch
做為預設的虛擬交換器(vSwitch),但由於 Default Switch
的特殊性,它有以下幾點限制:
-
連線類型(Connection type)預設採用「內部網路」(Internel network
)
這意味著使用 Default Switch
的 VM 只能從「本機」進行連接,從外部網路是無法連上的,也無法實現 Port forwarding (通訊埠轉發)
-
透過 DHCP 伺服器自動配發 IP 地址
由於 Default Switch
使用了 Windows 內建的 Internet Connection Sharing (ICS) 機制,而正式這個機制配發了動態的私有 IP 地址給 VM 使用,並提供了相當基礎的 NAT 機制,讓你的 VM 可以連接到外部網路。
透過 ICS 機制取得 IP 地址有好有壞。好的地方是,建立好的 VM 會自動配發 IP 地址,簡化網路管理。壞的地方是,這個 DHCP 伺服器無法停用,也無法自行指定 IP 範圍。更糟的地方是,你無法對 VM 設定「靜態 IP 地址」(Static IP Address),而且只要電腦重開機後,這個 DHCP 伺服器就會配發全新的 IP 地址給 VM 使用,而且這個 IP 是無法事先設定或預測的。
-
所有使用 Default Switch
的 VM 都會擁有一個本機可存取的網域名稱(Domain Name)
因為 IP 無法固定的緣故,這個 ICS 機制還會自動維護一份本機的 hosts.ics
檔案,路徑如下:
%systemroot%\system32\drivers\etc\hosts.ics
這個檔案與我們常用的 hosts
檔案放在同一個資料夾下,但是你不用特別維護 hosts.ics
檔案。
基本上,你只要在建立好 VM 之後的幾秒鐘內,系統就會自動更新 hosts.ics
檔案,提供你一個 *.mshome.net
的域名。例如你的 VM 名稱如果是 microk8s-vm
的話,那麼你就會有一個 microk8s-vm.mshome.net
域名可以直接取得這台 VM 的當時的 IP 地址 (請記得重開機 IP 就會變更),這點倒是相當的便利。不過,這個域名是不能改的,改了也沒用,因為隨時可能會被 Hyper-V 覆寫。
上述限制,正是 MicroK8s 在最簡單的 microk8s install
安裝好環境後,其 VM 的 IP 會在每次重開機後變更的原因! 🔥
其解決方案有兩個:
-
調整 KUBECONFIG
設定檔,改用 microk8s-vm.mshome.net
做為預設的伺服器位址
kubectl config set-cluster microk8s-cluster --server=https://microk8s-vm.mshome.net:16443
microk8s kubectl config set-cluster microk8s-cluster --server=https://microk8s-vm.mshome.net:16443
-
每次重開機後,自動執行以下命令,更新 KUBECONFIG
設定檔中的 server
IP 地址
# 更新 microk8s kubectl 命令專用的 KUBECONFIG 內容
microk8s config > $env:LOCALAPPDATA\MicroK8s\config
# 更新 kubectl 命令專用的 KUBECONFIG 內容
microk8s config > ~/.kube/config
-
不要使用 Default Switch
虛擬交換器
你可以參考我先前的 利用 Multipass 在區域網路架設一套 MicroK8s 叢集環境 文章,額外建立一個 External network
虛擬交換器,直接讓 VM 取得外部網路的 IP 地址。
設定 k 別名
我在 Linux 的 Shell 環境下,幾乎都會用 k
來取代 kubectl
命令,簡化指令輸入的時間。若是在 Windows 環境下,你可以透過 PowerShell 的 Set-Alias 來做到一樣的功能。
以下有 2 種不同用法:
-
簡單的 k
對應到 kubectl
這是在有事先安裝 kubectl.exe
工具並設定好 PATH
環境變數的前提下才能這樣設定:
Set-Alias -Name k -Value kubectl
-
透過 k
去執行 microk8s kubectl
命令的話,也可以這樣寫:
注意: 透過這種方式執行 kubectl
非常慢,建議不要這樣用。
function RunKubectl([Parameter(ValueFromRemainingArguments = $true)]$params) {
& microk8s.exe kubectl $params
}
Set-Alias -Name k -Value RunKubectl
同樣的技巧,也可以用在執行 microk8s
的時候,因為打這個命令實在太花時間,我可以簡化成 mks
就好 👍
function RunMicroK8s([Parameter(ValueFromRemainingArguments = $true)]$params) {
& microk8s.exe $params
}
Set-Alias -Name mks -Value RunMicroK8s
常見的 KUBECONFIG 管理
以下是一些管理 KUBECONFIG
的常見命令:
-
預設的 KUBECONFIG
路徑
~/.kube/config
-
指定自訂的 KUBECONFIG
路徑
$env:KUBECONFIG = '~/.kube/microk8s-config'
清除 KUBECONFIG
環境變數設定:
$env:KUBECONFIG = ''
-
取得目前 KUBECONFIG
中的叢集名稱
k config get-clusters
-
取得目前 KUBECONFIG
中的叢集設定
# 僅顯示重要參數並隱藏憑證的內容(因為內容很長)
k config view
# 顯示完整的原始內容
k config view --raw
-
設定目前 KUBECONFIG
中的叢集相關參數
k config set-cluster -h
# 重新指定叢集節點的 kube-apiserver 端點
k config set-cluster microk8s-cluster --server=https://microk8s-vm.mshome.net:16443
# 變更 CA 根憑證內容
k config set-cluster microk8s-cluster --embed-certs --certificate-authority=~/.kube/e2e/kubernetes.ca.crt
# 設定跳過 TLS 有效性驗證
k config set-cluster microk8s-cluster --insecure-skip-tls-verify=true
-
設定目前 KUBECONFIG
中的 Context 設定
所謂的 Context
就是一個連線到 K8s 叢集的連線情境,這個情境包含了 NAME
(情境名稱)、CLUSTER
(叢集名稱)、AUTHINFO
(認證資訊) 與 NAMESPACE
(命名空間) 等 4 個欄位。一個 KUBECONFIG
可以包含多種連線情境,而且可以任意切換。你可以一個叢集設定好幾組情境,也可以每個情境連到不同的叢集,你可以自由搭配。
# 列出目前所有的連線情境
k config get-contexts
# 切換到不同的連線情境
kubectl config use-context myaks
# 設定 microk8s 連線情境改用不同的使用者登入
k config set-context microk8s --user=admin
# 修改目前的連線情境改用 admin 來連線
k config set-context --current --user=admin
# 修改目前的連線情境改用 willh 為預設命名空間
k config set-context --current --namespace=default
# 列出 KUBECONFIG 中所有使用者
k config get-users
# 建立/更新 cluster-admin 使用者的 Bearer Token
k config set-credentials cluster-admin --token=uXFGweU9l35q
# 建立/更新 cluster-admin 使用者的 Private Key
k config set-credentials cluster-admin --client-key=~/.kube/admin.key
# 建立/更新 cluster-admin 使用者的 Client Certificate (用戶端憑證)
k config set-credentials cluster-admin --client-certificate=~/.kube/admin.crt --embed-certs=true
關於 MicroK8s 叢集重要的認證檔
進入到 MicroK8s 叢集主節點後,可以找到幾個重要的設定檔,這些設定檔決定了叢集要如何對使用者進行驗證,其主要目錄如下:
$ ll /var/snap/microk8s/current/credentials/
total 32
drwxrwx--- 2 root microk8s 4096 Aug 15 13:56 ./
drwxr-xr-x 13 root root 4096 Aug 17 15:37 ../
-rw-rw---- 1 root microk8s 1869 Aug 15 13:56 client.config
-rw-rw---- 1 root microk8s 1879 Aug 15 13:56 controller.config
-rw-rw---- 1 root microk8s 486 Aug 15 13:56 known_tokens.csv
-rw-rw---- 1 root microk8s 1873 Aug 15 13:56 kubelet.config
-rw-rw---- 1 root microk8s 1877 Aug 15 13:56 proxy.config
-rw-rw---- 1 root microk8s 1877 Aug 15 13:56 scheduler.config
各檔案說明如下:
-
known_tokens.csv
這裡記錄了所有系統使用者的 Bearer Token 清單
預設 MicroK8s 都是使用 Bearer Token 來驗證使用者,預設會從 /var/snap/microk8s/3582/args/kube-apiserver
啟動參數定義檔載入這個 known_tokens.csv
檔案。
--cert-dir=${SNAP_DATA}/certs
--service-cluster-ip-range=10.152.183.0/24
--authorization-mode=AlwaysAllow
--service-account-key-file=${SNAP_DATA}/certs/serviceaccount.key
--client-ca-file=${SNAP_DATA}/certs/ca.crt
--tls-cert-file=${SNAP_DATA}/certs/server.crt
--tls-private-key-file=${SNAP_DATA}/certs/server.key
--kubelet-client-certificate=${SNAP_DATA}/certs/server.crt
--kubelet-client-key=${SNAP_DATA}/certs/server.key
--secure-port=16443
--token-auth-file=${SNAP_DATA}/credentials/known_tokens.csv
--insecure-port=0
--storage-backend=dqlite
--storage-dir=${SNAP_DATA}/var/kubernetes/backend/
--allow-privileged=true
--service-account-issuer='https://kubernetes.default.svc'
--service-account-signing-key-file=${SNAP_DATA}/certs/serviceaccount.key
--feature-gates=RemoveSelfLink=false
-
client.config
系統管理員專用的預設 KUBECONFIG
設定檔,預設使用者名稱為 admin
-
controller.config
各 controller
預設使用的 KUBECONFIG
設定檔,預設使用者名稱為 controller
-
kubelet.config
各 kubelet
設使用的 KUBECONFIG
設定檔,預設使用者名稱為 kubelet
-
proxy.config
各 kube-proxy
設使用的 KUBECONFIG
設定檔,預設使用者名稱為 kubeproxy
-
scheduler.config
各 scheduler
設使用的 KUBECONFIG
設定檔,預設使用者名稱為 admin
相關連結