原文連結:https://fuckcloudnative.io/posts/deploy-k3s-cross-public-cloud/
最近一兩年各大雲服務商都出了各種福利活動,很多小夥伴薅了一波又一波羊毛,比如騰訊雲 1C2G 95/年
真香系列,華為雲和阿里雲也都有類似的活動,薅個兩三臺就能搭建一個 Kubernetes
叢集。但是跨雲服務商搭建 Kubernetes
叢集並不像我們想象中的那麼容易,首先就是原生的 Kubernetes
元件本身對資源的消耗量很大,而云伺服器的資源非常有限,經不起這麼大傢伙的折騰,對此我們可以選擇使用輕量級 Kubernetes 發行版:k3s
。
k3s
將安裝 Kubernetes 所需的一切打包進僅有 60MB
大小的二進位制檔案中,並且完全實現了 Kubernetes API。為了減少執行 Kubernetes 所需的記憶體,k3s
刪除了很多不必要的驅動程式,並用附加元件對其進行替換。由於它只需要極低的資源就可以執行,因此它能夠在任何 512MB
記憶體以上的裝置上執行叢集。
其實 k3s 的安裝非常簡單,分分鐘就能搞定,但對於公有云來說,還是有很多坑的,比如內網不通、公網 IP 不在伺服器上該咋辦?本文就為你一一解決這些難題,讓天下的雲羊毛都成為 k3s 的後宮!
1. 下載二進位制檔案
首先來解決第一個難題:k3s 二進位制檔案的下載。國內下載 GitHub
速度基本都是以幾個 kb
為單位,不忍直視,如果下載內容都是程式碼,有很多辦法可以解決,比如通過碼雲中轉啊、直接通過 CDN
下載啊,什麼?你不知道可以通過 CDN 下載?好吧沒關係,現在我告訴你了:https://cdn.con.sh/。
但是上面的 CDN 並不能下載 release
裡的內容,要想下載 release 裡的內容,可以使用這個網站:https://toolwa.com/github/。開啟網站,輸入 release 裡面的檔案下載連結,點選起飛即可加速下載。
當然,如果你會魔法上網的話,上面的所有花裡胡哨的方法都可以無視,直接下載就好啦(本文選擇使用版本 v1.17.6+k3s1
):
$ wget https://github.com/rancher/k3s/releases/download/v1.17.6+k3s1/k3s -O /usr/local/bin/k3s
$ chmod +x /usr/local/bin/k3s
需要在所有節點中下載上述二進位制檔案。
2. 升級核心
k3s 的預設網路外掛是 flannel
,預設模式是 vxlan
模式,建議使用 wireguard
模式,原因不解釋了,不知道 wireguard
是啥的自己去搜一下。
wireguard 對核心的要求比較高,而 CentOS 7.x
的預設核心是不滿足要求的,需要升級核心(如果你的作業系統是 CentOS 7.x 的話)。步驟如下:
① 載入公鑰
$ rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
② 升級安裝 elrepo
$ rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
③ 載入 elrepo-kernel 後設資料
$ yum --disablerepo=\* --enablerepo=elrepo-kernel repolist
④ 安裝最新版本的核心
$ yum --disablerepo=\* --enablerepo=elrepo-kernel install kernel-ml.x86_64 -y
⑤ 刪除舊版本工具包
$ yum remove kernel-tools-libs.x86_64 kernel-tools.x86_64 -y
⑥ 安裝新版本工具包
$ yum --disablerepo=\* --enablerepo=elrepo-kernel install kernel-ml-tools kernel-ml-devel kernel-ml-headers -y
⑦ 檢視核心插入順序
$ grep "^menuentry" /boot/grub2/grub.cfg | cut -d "'" -f2
CentOS Linux (3.10.0-1127.10.1.el7.x86_64) 7 (Core)
CentOS Linux (5.7.2-1.el7.elrepo.x86_64) 7 (Core)
CentOS Linux (0-rescue-96820b9851c24560b5f942f2496b9aeb) 7 (Core)
預設新核心是從頭插入,預設啟動順序也是從 0 開始。
⑧ 檢視當前實際啟動順序
$ grub2-editenv list
saved_entry=CentOS Linux (3.10.0-1127.10.1.el7.x86_64) 7 (Core)
⑨ 設定預設啟動
$ grub2-set-default 'CentOS Linux (5.7.2-1.el7.elrepo.x86_64) 7 (Core)'
最後重啟檢查:
$ reboot
$ uname -r
注意:叢集中的所有節點都需要升級核心。
3. 安裝 wireguard
核心升級了之後,就可以安裝 wireguard 了,也很簡單,步驟如下:
$ yum install epel-release https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm
$ yum install yum-plugin-elrepo
$ yum install kmod-wireguard wireguard-tools
注意:叢集中的所有節點都需要安裝。
4. 部署控制平面
下面就可以在控制節點上啟動控制平面的元件了,這裡我們選擇手動部署,這樣比較方便修改引數。先建立一個 Service Unit 檔案:
$ cat > /etc/systemd/system/k3s.service <<EOF
[Unit]
Description=Lightweight Kubernetes
Documentation=https://k3s.io
Wants=network-online.target
[Install]
WantedBy=multi-user.target
[Service]
Type=notify
EnvironmentFile=/etc/systemd/system/k3s.service.env
KillMode=process
Delegate=yes
# Having non-zero Limit*s causes performance problems due to accounting overhead
# in the kernel. We recommend using cgroups to do container-local accounting.
LimitNOFILE=1048576
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity
TimeoutStartSec=0
Restart=always
RestartSec=5s
ExecStartPre=-/sbin/modprobe br_netfilter
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/local/bin/k3s \
server \
--tls-san <public_ip> \
--node-ip <public_ip> \
--node-external-ip <public_ip> \
--no-deploy servicelb \
--flannel-backend wireguard \
--kube-proxy-arg "proxy-mode=ipvs" "masquerade-all=true" \
--kube-proxy-arg "metrics-bind-address=0.0.0.0"
EOF
- 將
<public_ip>
替換成控制節點的公網 IP。 - flannel 使用
wireguard
協議來跨主機通訊。 - kube-proxy 使用
ipvs
模式。
啟動 k3s 控制平面並設定開機自啟:
$ systemctl enable k3s --now
檢視叢集元件健康狀況:
$ kubectl get cs
NAME STATUS MESSAGE ERROR
scheduler Healthy ok
controller-manager Healthy ok
這裡的輸出沒有 etcd
,因為 k3s 的預設資料儲存是 Sqlite
,對於小型資料庫十分友好。Kubernetes 控制平面中發生的更改更多是與頻繁更新部署、排程 Pod 等有關,因此對於幾個節點的小型叢集而言,資料庫不會造成太大負載,能省下不少資源,真香!
5. 加入計算節點
部署好控制平面之後,就可以加入計算節點了。首先在計算節點上建立 Service Unit 檔案:
$ cat > /etc/systemd/system/k3s-agent.service <<EOF
[Unit]
Description=Lightweight Kubernetes
Documentation=https://k3s.io
Wants=network-online.target
[Install]
WantedBy=multi-user.target
[Service]
Type=exec
EnvironmentFile=/etc/systemd/system/k3s-agent.service.env
KillMode=process
Delegate=yes
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
TasksMax=infinity
TimeoutStartSec=0
Restart=always
RestartSec=5s
ExecStartPre=-/sbin/modprobe br_netfilter
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/local/bin/k3s agent \
--node-external-ip <public_ip> \
--node-ip <public_ip> \
--kube-proxy-arg "proxy-mode=ipvs" "masquerade-all=true" \
--kube-proxy-arg "metrics-bind-address=0.0.0.0"
EOF
環境變數檔案 /etc/systemd/system/k3s-agent.service.env
中需要加入兩個環境變數:
- K3S_URL :
API Server
的 URL,一般格式為:https://<master_ip>:6443
。其中 <master_ip> 是控制節點的公網 IP。 - K3S_TOKEN : 加入叢集所需的 token,可以在控制節點上檢視
/var/lib/rancher/k3s/server/node-token
檔案。
/etc/systemd/system/k3s-agent.service.env
內容如下:
K3S_URL=https://<master_ip>:6443
K3S_TOKEN=xxxxxxxx
啟動 k3s-agent 並設定開啟自啟:
$ systemctl enable k3s-agent --now
檢視節點狀態:
$ kubectl get node
NAME STATUS ROLES AGE VERSION
blog-k3s01 Ready master 3d6h v1.17.6+k3s1
blog-k3s02 Ready <none> 3d3h v1.17.6+k3s1
6. 內網不互通的解決辦法
這裡會遇到一個問題,不同節點的 flannel
使用的是內網 IP 來進行通訊,而我們的雲伺服器是內網不互通的,而且公網 IP 也不在伺服器上。可以看一下 node 的 annotations
:
$ kubectl get node blog-k3s02 -o yaml
apiVersion: v1
kind: Node
metadata:
annotations:
flannel.alpha.coreos.com/backend-data: '"xxxxx"'
flannel.alpha.coreos.com/backend-type: extension
flannel.alpha.coreos.com/kube-subnet-manager: "true"
flannel.alpha.coreos.com/public-ip: 192.168.0.11
...
可以看到 flannel
給節點打的註解中的節點 IP 是內網 IP。要想讓 flannel 使用公網 IP 進行通訊,需要額外新增一個註解 public-ip-overwrite
,然後 flannel 會基於這個 IP 配置網路。按照官方文件的說法,如果你的 node 設定了 ExternalIP
,flannel 會自動給 node 新增一個註解 public-ip-overwrite
,但我不知道該如何給 node 設定 ExternalIP
,乾脆就直接手動加註解吧:
$ kubectl annotate nodes <master> flannel.alpha.coreos.com/public-ip-overwrite=<master_pub_ip>
$ kubectl annotate nodes <node> flannel.alpha.coreos.com/public-ip-overwrite=<node_pub_ip>
加了註解之後,flannel 的 public-ip
就會被修改為公網 IP。然後在各個節點上重啟各自的 k3s 服務,檢視 wireguard
連線狀況:
$ wg show flannel.1
interface: flannel.1
public key: ONDgJCwxxxxxxxJvdWpoOKTxQA=
private key: (hidden)
listening port: 51820
peer: MKKaanTxxxxxxxV8VpcHq4CSRISshw=
endpoint: <pub_ip>:51820
allowed ips: 10.42.4.0/24
latest handshake: 26 seconds ago
transfer: 133.17 KiB received, 387.44 KiB sent
persistent keepalive: every 25 seconds
可以看到通訊端點被改成了公網 IP,大功告成!
7. metrics-server 問題解決
還有一個問題就是 metrics-server
無法獲取 cpu、記憶體等利用率核心指標。需要修改 metrics-server
的 manifests,使用以下命令線上編輯 metrics-server
的 manifests:
$ kubectl -n kube-system edit deploy metrics-server
然後加入以下執行引數後儲存退出:
-command:
- /metrics-server
- --kubelet-preferred-address-types=ExternalIP
- --kubelet-insecure-tls
這樣就可以讓 metrics-server 使用公網 IP 來和 node 通訊了。修改成功後就可以看到核心指標了:
$ kubectl top nodes
NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
blog-k3s01 193m 9% 886Mi 22%
blog-k3s02 41m 2% 1292Mi 32%
$ kubectl top pod -n kube-system
NAME CPU(cores) MEMORY(bytes)
coredns-848b6cc76f-zq576 8m 14Mi
local-path-provisioner-58fb86bdfd-bzdfl 2m 9Mi
metrics-server-bdfc79c97-djmzk 1m 12Mi
到這裡跨雲服務商部署 k3s 基本上就大功告成了,下一篇文章將會教你如何打通家裡到雲上 k3s 的網路,讓你家中所有裝置都可以直接訪問 Pod IP、svc IP,甚至可以直接訪問 svc 域名,敬請期待。
Kubernetes 1.18.2 1.17.5 1.16.9 1.15.12離線安裝包釋出地址http://store.lameleg.com ,歡迎體驗。 使用了最新的sealos v3.3.6版本。 作了主機名解析配置優化,lvscare 掛載/lib/module解決開機啟動ipvs載入問題, 修復lvscare社群netlink與3.10核心不相容問題,sealos生成百年證書等特性。更多特性 https://github.com/fanux/sealos 。歡迎掃描下方的二維碼加入釘釘群 ,釘釘群已經整合sealos的機器人實時可以看到sealos的動態。