本文獨立部落格閱讀地址:https://ryan4yin.space/posts/kubernetes-deployemnt-using-kubeadm/
本文由個人筆記 ryan4yin/knowledge 整理而來,不保證正確
本地 Kubernetes 叢集安裝工具
雲上的 Kubernetes 叢集,基本上各雲廠商都支援一鍵部署。這裡主要關注本地部署,或者叫做裸機(baremetal)部署
本文介紹的方法適合開發測試使用,安全性、穩定性、長期可用性等方案都可能還有問題。
本文主要參考官方文件,與其他大部分的叢集安裝文件,內容應該都差不多。不過會多提幾句 metrics-server(HPA 需要)、etcd 備份、volume provider(如果你需要 PV)相關內容.
本文未考慮國內網路環境,建議在路由器上整個科學代理,或者自行調整文中的部分命令。
kubernetes 是一個元件化的系統,安裝過程有很大的靈活性,很多元件都有多種實現,這些實現各有特點,讓初學者眼花繚亂。
而且要把這些元件一個個安裝配置好並且能協同工作,也是很不容易的。
因此社群出現了各種各樣的安裝方案,下面介紹下幾種支援裸機(Baremetal)部署的工具:
- kubeadm: 社群的叢集安裝工具,目前已經很成熟了。
- 使用難度:簡單
- k3s: 輕量級 kubernetes,資源需求小,部署非常簡單,適合開發測試用或者邊緣環境
- 支援 airgap 離線部署
- 使用難度:超級簡單
- alibaba/sealer: 支援將整個 kubernetes 打包成一個映象進行交付,而且部署也非常簡單。
- 使用難度:超級簡單
- 這個專案目前還在發展中,不過貌似已經有很多 toB 的公司在使用它進行 k8s 應用的交付了。
- kubespray: 適合自建生產級別的叢集,是一個大而全的 kubernetes 安裝方案,自動安裝容器執行時、k8s、網路外掛等元件,而且各元件都有很多方案可選,但是感覺有點複雜。
- 使用難度:中等
- 支援 airgap 離線部署,但是以前我試用過是有坑,現在不知道咋樣了
- 底層使用了 kubeadm 部署叢集
筆者為了學習 Kubernetes,下面採用官方的 kubeadm 進行部署(不要問為啥不二進位制部署,問就是懶),容器執行時使用 containerd,網路外掛則使用目前最潮的基於 eBPF 的 Cilium.
kubernetes 官方介紹了兩種高可用叢集的拓撲結構:「Stacked etcd topology」和「External etcd topology」,簡單起見,本文使用第一種「堆疊 Etcd 拓撲」結構,建立一個三 master 的高可用叢集。
參考:
- Kubernetes Docs - Installing kubeadm
- Kubernetes Docs - Creating Highly Available clusters with kubeadm
1. 節點的環境準備
首先準備三臺 Linux 虛擬機器,系統按需選擇,然後調整這三臺機器的設定:
- 節點配置:
- master:不低於 2c/3g,硬碟 20G
- 主節點效能也受叢集 Pods 個數的影響,上述配置應該可以支撐到每個 Worker 節點跑 100 個 Pod.
- worker:看需求,建議不低於 2c/4g,硬碟不小於 20G,資源充分的話建議 40G.
- master:不低於 2c/3g,硬碟 20G
- 處於同一網路內並可互通(通常是同一區域網)
- 各主機的 hostname 和 mac/ip 地址以及
/sys/class/dmi/id/product_uuid
,都必須唯一- 這裡最容易出問題的,通常是 hostname 衝突!
- 必須關閉 swap,kubelet 才能正常工作!
方便起見,我直接使用 ryan4yin/pulumi-libvirt 自動建立了五個虛擬機器,並設定好了 ip/hostname.
本文使用了 opensuse leap 15.3 的 KVM cloud image 進行安裝測試。
1.1 iptables 設定
目前 kubernetes 的容器網路,預設使用的是 bridge 模式,這種模式下,需要使 iptables
能夠接管 bridge 上的流量。
配置如下:
sudo modprobe br_netfilter
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF
cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF
sudo sysctl --system
1.2 開放節點埠
區域網環境的話,建議直接關閉防火牆。這樣所有埠都可用,方便快捷。
通常我們的雲上叢集,也是關閉防火牆的,只是會通過雲服務提供的「安全組」來限制客戶端 ip
Control-plane 節點,也就是 master,需要開放如下埠:
Protocol | Direction | Port Range | Purpose | Used By |
---|---|---|---|---|
TCP | Inbound | 6443* | Kubernetes API server | All |
TCP | Inbound | 2379-2380 | etcd server client API | kube-apiserver, etcd |
TCP | Inbound | 10250 | kubelet API | Self, Control plane |
TCP | Inbound | 10251 | kube-scheduler | Self |
TCP | Inbound | 10252 | kube-controller-manager | Self |
Worker 節點需要開發如下埠:
Protocol | Direction | Port Range | Purpose | Used By |
---|---|---|---|---|
TCP | Inbound | 10250 | kubelet API | Self, Control plane |
TCP | Inbound | 30000-32767 | NodePort Services† | All |
另外通常我們本地測試的時候,可能更想直接在 80
443
8080
等埠上使用 NodePort
,
就需要修改 kube-apiserver 的 --service-node-port-range
引數來自定義 NodePort 的埠範圍,相應的 Worker 節點也得開放這些埠。
2. 安裝 containerd
首先是環境配置:
cat <<EOF | sudo tee /etc/modules-load.d/containerd.conf
overlay
br_netfilter
nf_conntrack
EOF
sudo modprobe overlay
sudo modprobe br_netfilter
sudo modprobe nf_conntrack
# Setup required sysctl params, these persist across reboots.
cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes-cri.conf
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF
# Apply sysctl params without reboot
sudo sysctl --system
安裝 containerd+nerdctl:
wget https://github.com/containerd/nerdctl/releases/download/v0.11.1/nerdctl-full-0.11.1-linux-amd64.tar.gz
tar -axvf nerdctl-full-0.11.1-linux-amd64.tar.gz
# 這裡簡單起見,rootless 相關的東西也一起裝進去了,測試嘛就無所謂了...
mv bin/* /usr/local/bin/
mv lib/systemd/system/containerd.service /usr/lib/systemd/system/
systemctl enable containerd
systemctl start containerd
nerdctl
是一個 containerd 的命令列工具,但是它的容器、映象與 Kubernetes 的容器、映象是完全隔離的,不能互通!
目前只能通過 crictl
來檢視、拉取 Kubernetes 的容器、映象,下一節會介紹 crictl 的安裝。
3. 安裝 kubelet/kubeadm/kubectl
# 一些全域性都需要用的變數
CNI_VERSION="v0.8.2"
CRICTL_VERSION="v1.17.0"
# kubernetes 的版本號
# RELEASE="$(curl -sSL https://dl.k8s.io/release/stable.txt)"
RELEASE="1.22.1"
# kubelet 配置檔案的版本號
RELEASE_VERSION="v0.4.0"
# 架構
ARCH="amd64"
# 安裝目錄
DOWNLOAD_DIR=/usr/local/bin
# CNI 外掛
sudo mkdir -p /opt/cni/bin
curl -L "https://github.com/containernetworking/plugins/releases/download/${CNI_VERSION}/cni-plugins-linux-${ARCH}-${CNI_VERSION}.tgz" | sudo tar -C /opt/cni/bin -xz
# crictl 相關工具
curl -L "https://github.com/kubernetes-sigs/cri-tools/releases/download/${CRICTL_VERSION}/crictl-${CRICTL_VERSION}-linux-${ARCH}.tar.gz" | sudo tar -C $DOWNLOAD_DIR -xz
# kubelet/kubeadm/kubectl
cd $DOWNLOAD_DIR
sudo curl -L --remote-name-all https://storage.googleapis.com/kubernetes-release/release/${RELEASE}/bin/linux/${ARCH}/{kubeadm,kubelet,kubectl}
sudo chmod +x {kubeadm,kubelet,kubectl}
# kubelet/kubeadm 配置
curl -sSL "https://raw.githubusercontent.com/kubernetes/release/${RELEASE_VERSION}/cmd/kubepkg/templates/latest/deb/kubelet/lib/systemd/system/kubelet.service" | sed "s:/usr/bin:${DOWNLOAD_DIR}:g" | sudo tee /etc/systemd/system/kubelet.service
sudo mkdir -p /etc/systemd/system/kubelet.service.d
curl -sSL "https://raw.githubusercontent.com/kubernetes/release/${RELEASE_VERSION}/cmd/kubepkg/templates/latest/deb/kubeadm/10-kubeadm.conf" | sed "s:/usr/bin:${DOWNLOAD_DIR}:g" | sudo tee /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
systemctl enable --now kubelet
# 驗證 kubelet 啟動起來了,但是目前還沒有初始化配置,過一陣就會重啟一次
systemctl status kubelet
試用 crictl:
export CONTAINER_RUNTIME_ENDPOINT='unix:///var/run/containerd/containerd.sock'
# 列出所有 pods,現在應該啥也沒
crictl pods
# 列出所有映象
crictl images
4. 為 master 的 kube-apiserver 建立負載均衡實現高可用
根據 kubeadm 官方文件 Kubeadm Docs - High Availability Considerations 介紹,要實現 kube-apiserver 的高可用,目前最知名的負載均衡方式是 keepalived+haproxy,另外也可以考慮使用 kube-vip 等更簡單的工具。
簡單起見,我們直接用 kube-vip 吧,參考了 kube-vip 的官方文件:Kube-vip as a Static Pod with Kubelet.
P.S. 我也見過有的安裝工具會直接拋棄 keepalived,直接在每個節點上跑一個 nginx 做負載均衡,配置裡寫死了所有 master 的地址...
首先使用如下命令生成 kube-vip 的配置檔案,以 ARP 為例(生產環境建議換成 BGP):
cat <<EOF | sudo tee add-kube-vip.sh
# 你的虛擬機器網路卡,opensuse/centos 等都是 eth0,但是 ubuntu 可能是 ens3
export INTERFACE=eth0
# 用於實現高可用的 vip,需要和前面的網路介面在同一網段內,否則就無法路由了。
export VIP=192.168.122.200
# 生成 static-pod 的配置檔案
mkdir -p /etc/kubernetes/manifests
nerdctl run --rm --network=host --entrypoint=/kube-vip ghcr.io/kube-vip/kube-vip:v0.3.8 \
manifest pod \
--interface $INTERFACE \
--vip $VIP \
--controlplane \
--services \
--arp \
--leaderElection | tee /etc/kubernetes/manifests/kube-vip.yaml
EOF
bash add-kube-vip.sh
三個 master 節點都需要跑下上面的命令(worker 不需要),建立好 kube-vip 的 static-pod 配置檔案。
在完成 kubeadm 初始化後,kubelet 會自動把它們拉起為 static pod.
5. 使用 kubeadm 建立叢集
其實需要執行的就是這條命令:
# 極簡配置:
cat <<EOF | sudo tee kubeadm-config.yaml
apiVersion: kubeadm.k8s.io/v1beta3
kind: InitConfiguration
nodeRegistration:
criSocket: "/var/run/containerd/containerd.sock"
imagePullPolicy: IfNotPresent
---
kind: ClusterConfiguration
apiVersion: kubeadm.k8s.io/v1beta3
kubernetesVersion: v1.22.1
clusterName: kubernetes
certificatesDir: /etc/kubernetes/pki
imageRepository: k8s.gcr.io
controlPlaneEndpoint: "192.168.122.200:6443" # 填 apiserver 的 vip 地址,或者整個域名也行,但是就得加 /etc/hosts 或者內網 DNS 解析
networking:
serviceSubnet: "10.96.0.0/16"
podSubnet: "10.244.0.0/16"
etcd:
local:
dataDir: /var/lib/etcd
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: systemd
# 讓 kubelet 從 certificates.k8s.io 申請由叢集 CA Root 簽名的 tls 證書,而非直接使用自簽名證書
# 如果不啟用這個, 安裝 metrics-server 時就會遇到證書報錯,後面會詳細介紹。
serverTLSBootstrap: true
EOF
# 檢視 kubeadm 預設的完整配置,供參考
kubeadm config print init-defaults > init.default.yaml
# 執行叢集的初始化,這會直接將當前節點建立為 master
# 成功執行的前提:前面該裝的東西都裝好了,而且 kubelet 已經在後臺執行了
# `--upload-certs` 會將生成的叢集證書上傳到 kubeadm 伺服器,在兩小時內加入叢集的 master 節點會自動拉證書,主要是方便叢集建立。
kubeadm init --config kubeadm-config.yaml --upload-certs
kubeadm 應該會報錯,提示你有些依賴不存在,下面先安裝好依賴項。
sudo zypper in -y socat ebtables conntrack-tools
再重新執行前面的 kubeadm 命令,應該就能正常執行了,它做的操作有:
- 拉取控制面的容器映象
- 生成 ca 根證書
- 使用根證書為 etcd/apiserver 等一票工具生成 tls 證書
- 為控制面的各個元件生成 kubeconfig 配置
- 生成 static pod 配置,kubelet 會根據這些配置自動拉起 kube-proxy 以及其他所有的 k8s master 元件
執行完會給出三部分命令:
- 將
kubeconfig
放到$HOME/.kube/config
下,kubectl
需要使用該配置檔案連線 kube-apiserver - control-plane 節點加入叢集的命令:
- 這裡由於我們提前新增了 kube-vip 的 static-pod 配置,這裡的 preflight-check 會報錯,需要新增此引數忽略該報錯 -
--ignore-preflight-errors=DirAvailable--etc-kubernetes-manifests
kubeadm join 192.168.122.200:6443 --token <token> \ --discovery-token-ca-cert-hash sha256:<hash> \ --control-plane --certificate-key <key> \ --ignore-preflight-errors=DirAvailable--etc-kubernetes-manifests
- 這裡由於我們提前新增了 kube-vip 的 static-pod 配置,這裡的 preflight-check 會報錯,需要新增此引數忽略該報錯 -
- worker 節點加入叢集的命令:
kubeadm join 192.168.122.200:6443 --token <token> \ --discovery-token-ca-cert-hash sha256:<hash>
跑完第一部分 kubeconfig
的處理命令後,就可以使用 kubectl 檢視叢集狀況了:
k8s-master-0:~/kubeadm # kubectl get no
NAME STATUS ROLES AGE VERSION
k8s-master-0 NotReady control-plane,master 79s v1.22.1
k8s-master-0:~/kubeadm # kubectl get po --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-78fcd69978-6tlnw 0/1 Pending 0 83s
kube-system coredns-78fcd69978-hxtvs 0/1 Pending 0 83s
kube-system etcd-k8s-master-0 1/1 Running 6 90s
kube-system kube-apiserver-k8s-master-0 1/1 Running 4 90s
kube-system kube-controller-manager-k8s-master-0 1/1 Running 4 90s
kube-system kube-proxy-6w2bx 1/1 Running 0 83s
kube-system kube-scheduler-k8s-master-0 1/1 Running 7 97s
現在在其他節點執行前面列印出的加入叢集的命令,就可以搭建好一個高可用的叢集了。
所有節點都加入叢集后,通過 kubectl 檢視,應該是三個控制面 master,兩個 worker:
k8s-master-0:~/kubeadm # kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master-0 NotReady control-plane,master 26m v1.22.1
k8s-master-1 NotReady control-plane,master 7m2s v1.22.1
k8s-master-2 NotReady control-plane,master 2m10s v1.22.1
k8s-worker-0 NotReady <none> 97s v1.22.1
k8s-worker-1 NotReady <none> 86s v1.22.1
現在它們都還處於 NotReady 狀態,需要等到我們把網路外掛安裝好,才會 Ready.
現在再看下叢集的證書籤髮狀態:
❯ kubectl get csr --sort-by='{.spec.username}'
NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION
csr-95hll 6m58s kubernetes.io/kube-apiserver-client-kubelet system:bootstrap:q8ivnz <none> Approved,Issued
csr-tklnr 7m5s kubernetes.io/kube-apiserver-client-kubelet system:bootstrap:q8ivnz <none> Approved,Issued
csr-w92jv 9m15s kubernetes.io/kube-apiserver-client-kubelet system:bootstrap:q8ivnz <none> Approved,Issued
csr-rv7sj 8m11s kubernetes.io/kube-apiserver-client-kubelet system:bootstrap:q8ivnz <none> Approved,Issued
csr-nxkgx 10m kubernetes.io/kube-apiserver-client-kubelet system:node:k8s-master-0 <none> Approved,Issued
csr-cd22c 10m kubernetes.io/kubelet-serving system:node:k8s-master-0 <none> Pending
csr-wjrnr 9m53s kubernetes.io/kubelet-serving system:node:k8s-master-0 <none> Pending
csr-sjq42 9m8s kubernetes.io/kubelet-serving system:node:k8s-master-1 <none> Pending
csr-xtv8f 8m56s kubernetes.io/kubelet-serving system:node:k8s-master-1 <none> Pending
csr-f2dsf 8m3s kubernetes.io/kubelet-serving system:node:k8s-master-2 <none> Pending
csr-xl8dg 6m58s kubernetes.io/kubelet-serving system:node:k8s-worker-0 <none> Pending
csr-p9g24 6m52s kubernetes.io/kubelet-serving system:node:k8s-worker-1 <none> Pending
能看到有好幾個 kubernetes.io/kubelet-serving
的證書還處於 pending 狀態,
這是因為我們在 kubeadm 配置檔案中,設定了 serverTLSBootstrap: true
,讓 Kubelet 從叢集中申請 CA 簽名證書,而不是自簽名導致的。
設定這個引數的主要目的,是為了讓 metrics-server 等元件能使用 https 協議與 kubelet 通訊,避免為 metrics-server 新增引數 --kubelet-insecure-tls
.
目前 kubeadm 不支援自動批准 kubelet 申請的證書,需要我們手動批准一下:
# 批准 Kubelet 申請的所有證書
kubectl certificate approve csr-cd22c csr-wjrnr csr-sjq42 csr-xtv8f csr-f2dsf csr-xl8dg csr-p9g24
在未批准這些證書之前,所有需要呼叫 kubelet api 的功能都將無法使用,比如:
- 檢視 pod 日誌
- 獲取節點 metrics
- 等等
5.1 常見問題
5.1.1 使用國內映象源
如果你沒有科學環境,kubeadm 預設的映象倉庫在國內是拉不了的。
如果對可靠性要求高,最好是自建私有映象倉庫,把映象推送到私有倉庫。
可以通過如下命令列出所有需要用到的映象地址:
❯ kubeadm config images list --kubernetes-version v1.22.1
k8s.gcr.io/kube-apiserver:v1.22.1
k8s.gcr.io/kube-controller-manager:v1.22.1
k8s.gcr.io/kube-scheduler:v1.22.1
k8s.gcr.io/kube-proxy:v1.22.1
k8s.gcr.io/pause:3.5
k8s.gcr.io/etcd:3.5.0-0
k8s.gcr.io/coredns/coredns:v1.8.4
使用 skopeo
等工具或指令碼將上述映象拷貝到你的私有倉庫,或者圖方便(測試環境)也可以考慮網上找找別人同步好的映象地址。將映象地址新增到 kubeadm-config.yaml
中再部署。
5.1.2 重置叢集配置
建立叢集的過程中出現任何問題,都可以通過在所有節點上執行 kubeadm reset
來還原配置,然後重新走 kubeadm 的叢集建立流程。
但是要注意幾點:
kubeadm reset
會清除包含 kube-vip 配置在內的所有 static-pod 配置檔案,所以 master 節點需要重新跑下前面給的 kube-vip 命令,生成下 kube-vip 配置。kubeadm reset
不會重置網路介面的配置,master 節點需要手動清理下 kube-vip 新增的 vip:ip addr del 192.168.122.200/32 dev eth0
.- 如果你在安裝了網路外掛之後希望重灌叢集,順序如下:
- 通過
kubectl delete -f xxx.yaml
/helm uninstall
刪除所有除網路之外的其他應用配置 - 刪除網路外掛
- 先重啟一遍所有節點,或者手動重置所有節點的網路配置
- 建議重啟,因為我不知道該怎麼手動重置... 試了
systemctl restart network
並不會清理所有虛擬網路介面。
- 建議重啟,因為我不知道該怎麼手動重置... 試了
- 通過
如此操作後,再重新執行叢集安裝,應該就沒啥毛病了。
6. 驗證叢集的高可用性
雖然網路外掛還沒裝導致叢集所有節點都還沒 ready,但是我們已經可以通過 kubectl 命令來簡單驗證叢集的高可用性了。
首先,我們將前面放置在 k8s-master-0 的認證檔案 $HOME/.kube/config
以及 kunbectl 安裝在另一臺機器上,比如我直接放我的宿主機。
然後在宿主機上跑 kubectl get node
命令驗證叢集的高可用性:
- 三個主節點都正常執行時,kubectl 命令也正常
- pause 或者 stop 其中一個 master,kubectl 命令仍然能正常執行
- 再 pause 第二個 master,kubectl 命令應該就會卡住,並且超時,無法使用了
- resume 恢復停掉的兩個 master 之一,會發現 kubectl 命令又能正常執行了
到這裡 kubeadm 的工作就完成了,接下來再安裝網路外掛,叢集就可用了。
7. 安裝網路外掛
社群有很多種網路外掛可選,比較知名且效能也不錯的,應該是 Calico 和 Cilium,其中 Cilium 主打基於 eBPF 的高效能與高可觀測性。
下面分別介紹這兩個外掛的安裝方法。(注意只能安裝其中一個網路外掛,不能重複安裝。)
需要提前在本機安裝好 helm,我這裡使用宿主機,因此只需要在宿主機安裝:
# 一行命令安裝,也可以自己手動下載安裝包,都行
curl https://raw.githubusercontent.com/helm/helm/master/scripts/get-helm-3 | bash
# 或者 opensuse 直接用包管理器安裝
sudo zypper in helm
7.1 安裝 Cilium
官方文件:https://docs.cilium.io/en/v1.10/gettingstarted/k8s-install-kubeadm/
cilium 通過 eBPF 提供了高效能與高可觀測的 k8s 叢集網路,
另外 cilium 還提供了比 kube-proxy 更高效的實現,可以完全替代 kube-proxy.
這裡我們還是先使用 kube-proxy 模式,先熟悉下 cilium 的使用:
helm repo add cilium https://helm.cilium.io/
helm search repo cilium/cilium -l | head
helm install cilium cilium/cilium --version 1.10.4 --namespace kube-system
可以通過 kubectl get pod -A
檢視 cilium 的安裝進度,當所有 pod 都 ready 後,叢集就 ready 了~
cilium 也提供了專用的客戶端:
curl -L --remote-name-all https://github.com/cilium/cilium-cli/releases/latest/download/cilium-linux-amd64.tar.gz{,.sha256sum}
sha256sum --check cilium-linux-amd64.tar.gz.sha256sum
sudo tar xzvfC cilium-linux-amd64.tar.gz /usr/local/bin
rm cilium-linux-amd64.tar.gz{,.sha256sum}
然後使用 cilium 客戶端檢查網路外掛的狀態:
$ cilium status --wait
/¯¯\
/¯¯\__/¯¯\ Cilium: OK
\__/¯¯\__/ Operator: OK
/¯¯\__/¯¯\ Hubble: disabled
\__/¯¯\__/ ClusterMesh: disabled
\__/
DaemonSet cilium Desired: 5, Ready: 5/5, Available: 5/5
Deployment cilium-operator Desired: 2, Ready: 2/2, Available: 2/2
Containers: cilium Running: 5
cilium-operator Running: 2
Cluster Pods: 2/2 managed by Cilium
Image versions cilium quay.io/cilium/cilium:v1.10.4@sha256:7d354052ccf2a7445101d78cebd14444c7c40129ce7889f2f04b89374dbf8a1d: 5
cilium-operator quay.io/cilium/operator-generic:v1.10.4@sha256:c49a14e34634ff1a494c84b718641f27267fb3a0291ce3d74352b44f8a8d2f93: 2
cilium 還提供了命令,自動建立 pod 進行叢集網路的連線性測試:
❯ cilium connectivity test
ℹ️ Monitor aggregation detected, will skip some flow validation steps
✨ [kubernetes] Creating namespace for connectivity check...
✨ [kubernetes] Deploying echo-same-node service...
✨ [kubernetes] Deploying same-node deployment...
✨ [kubernetes] Deploying client deployment...
✨ [kubernetes] Deploying client2 deployment...
✨ [kubernetes] Deploying echo-other-node service...
✨ [kubernetes] Deploying other-node deployment...
...
ℹ️ Expose Relay locally with:
cilium hubble enable
cilium status --wait
cilium hubble port-forward&
? Running tests...
...
---------------------------------------------------------------------------------------------------------------------
✅ All 11 tests (134 actions) successful, 0 tests skipped, 0 scenarios skipped.
通過 kubectl get po -A
能觀察到,這個測試命令會自動建立一個 cilium-test
名字空間,並在啟動建立若干 pod 進行詳細的測試。
整個測試流程大概會持續 5 分多鐘,測試完成後,相關 Pod 不會自動刪除,使用如下命令手動刪除:
kubectl delete namespace cilium-test
7.2 安裝 Calico
官方文件:https://docs.projectcalico.org/getting-started/kubernetes/self-managed-onprem/onpremises
也就兩三行命令。安裝確實特別簡單,懶得介紹了,看官方文件吧。
但是實際上 calico 的細節還蠻多的,建議通讀下它的官方文件,瞭解下 calico 的架構。
8. 檢視叢集狀態
官方的 dashboard 個人感覺不太好用,建議直接在本地裝個 k9s 用,特別爽。
sudo zypper in k9s
然後就可以愉快地玩耍了。
9. 安裝 metrics-server
這一步可能遇到的問題:Enabling signed kubelet serving certificates
如果需要使用 HPA 以及簡單的叢集監控,那麼 metrics-server 是必須安裝的,現在我們安裝一下它。
首先,跑 kubectl 的監控命令應該會報錯:
❯ kubectl top node
error: Metrics API not available
k9s 裡面應該也看不到任何監控指標。
現在通過 helm 安裝它:
helm repo add metrics-server https://kubernetes-sigs.github.io/metrics-server/
helm search repo metrics-server/metrics-server -l | head
helm upgrade --install metrics-server metrics-server/metrics-server --version 3.5.0 --namespace kube-system
metrics-server 預設只會部署一個例項,如果希望高可用,請參考官方配置:metrics-server - high-availability manifests
等 metrics-server 啟動好後,就可以使用 kubectl top
命令啦:
❯ kubectl top node
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
k8s-master-0 327m 16% 1465Mi 50%
k8s-master-1 263m 13% 1279Mi 44%
k8s-master-2 289m 14% 1282Mi 44%
k8s-worker-0 62m 3% 518Mi 13%
k8s-worker-1 115m 2% 659Mi 8%
❯ kubectl top pod
No resources found in default namespace.
❯ kubectl top pod -A
NAMESPACE NAME CPU(cores) MEMORY(bytes)
kube-system cilium-45nw4 9m 135Mi
kube-system cilium-5x7jf 6m 154Mi
kube-system cilium-84sr2 7m 160Mi
kube-system cilium-operator-78f45675-dp4b6 2m 30Mi
kube-system cilium-operator-78f45675-fpm5g 1m 30Mi
kube-system cilium-tkhl4 6m 141Mi
kube-system cilium-zxbvm 5m 138Mi
kube-system coredns-78fcd69978-dpxxk 3m 16Mi
kube-system coredns-78fcd69978-ptd9p 1m 18Mi
kube-system etcd-k8s-master-0 61m 88Mi
kube-system etcd-k8s-master-1 50m 85Mi
kube-system etcd-k8s-master-2 55m 83Mi
kube-system kube-apiserver-k8s-master-0 98m 462Mi
kube-system kube-apiserver-k8s-master-1 85m 468Mi
kube-system kube-apiserver-k8s-master-2 85m 423Mi
kube-system kube-controller-manager-k8s-master-0 22m 57Mi
kube-system kube-controller-manager-k8s-master-1 2m 23Mi
kube-system kube-controller-manager-k8s-master-2 2m 23Mi
kube-system kube-proxy-j2s76 1m 24Mi
kube-system kube-proxy-k6d6z 1m 18Mi
kube-system kube-proxy-k85rx 1m 23Mi
kube-system kube-proxy-pknsc 1m 20Mi
kube-system kube-proxy-xsq4m 1m 15Mi
kube-system kube-scheduler-k8s-master-0 3m 25Mi
kube-system kube-scheduler-k8s-master-1 4m 21Mi
kube-system kube-scheduler-k8s-master-2 5m 21Mi
kube-system kube-vip-k8s-master-0 4m 17Mi
kube-system kube-vip-k8s-master-1 2m 16Mi
kube-system kube-vip-k8s-master-2 2m 17Mi
kube-system metrics-server-559f85484-5b6xf 7m 27Mi
10. 為 etcd 新增定期備份能力
請移步 etcd 的備份與恢復
11. 安裝 Volume Provisioner
在我們學習使用 Prometheus/MinIO/Tekton 等有狀態應用時,它們預設情況下會通過 PVC 宣告需要的資料卷。
為了支援這個能力,我們需要在叢集中部署一個 Volume Provisioner.
對於雲上環境,直接接入雲服務商提供的 Volume Provisioner 就 OK 了,方便省事而且足夠可靠。
而對於 bare-metal 環境,比較有名的應該是 rook-ceph,但是這個玩意部署複雜,維護難度又高,不適合用來測試學習,也不適合生產環境。
對於開發、測試環境,或者個人叢集,建議使用:
- local 資料卷,適合資料可丟失,且不要求分散式的場景,如開發測試環境
- NFS 資料卷,適合資料可丟失,對效能要求不高,並且要求分散式的場景。比如開發測試環境、或者線上沒啥壓力的應用
- https://github.com/kubernetes-sigs/nfs-subdir-external-provisioner
- https://github.com/kubernetes-csi/csi-driver-nfs
- NFS 資料的可靠性依賴於外部 NFS 伺服器,企業通常使用群暉等 NAS 來做 NFS 伺服器
- 如果外部 NFS 伺服器出問題,應用就會崩。
- 直接使用雲上的物件儲存,適合希望資料不丟失、對效能要求不高的場景。
- 直接使用 https://github.com/rclone/rclone mount 模式來儲存資料,或者直接同步資料夾資料到雲端(可能會有一定資料丟失)。