最近兩年一直在使用 kubeadm 部署 Kubernetes 集群,總體來說配合一些自己小腳本還有一些自動化工具還算是方便;但是全容器化穩定性確實擔憂,也遇到過莫名其妙的證書過期錯誤,最后重啟大法解決這種問題;所以也在探索比較方便的二進制部署方式,比如這個 k0s。
一、k0s 介紹
The Simple, Solid & Certified Kubernetes Distribution.
k0s 可以認為是一個下游的 Kubernetes 發行版,與原生 Kubernetes 相比,k0s 并未閹割大量 Kubernetes 功能;k0s 主要閹割部分基本上只有樹內 Cloud provider,其他的都與原生 Kubernetes 相同。
k0s 自行編譯 Kubernetes 源碼生成 Kubernetes 二進制文件,然后在安裝后將二進制文件釋放到宿主機再啟動;這種情況下所有功能幾乎與原生 Kubernetes 沒有差異。
二、k0sctl 使用
k0sctl 是 k0s 為了方便快速部署集群所提供的工具,有點類似于 kubeadm,但是其擴展性要比 kubeadm 好得多。在多節點的情況下,k0sctl 通過 SSH 鏈接目標主機然后按照步驟釋放文件并啟動 Kubernetes 相關服務,從而完成集群初始化。
2.1、k0sctl 安裝集群
安裝過程中會自動下載相關鏡像,需要保證所有節點可以扶墻,如何離線安裝后面講解。安裝前保證目標機器的 hostname 為非域名形式,否則可能會出現一些問題。以下是一個簡單的啟動集群示例:
首先安裝 k0sctl:
#安裝k0sctl
wgethttps://github.com/k0sproject/k0sctl/releases/download/v0.9.0/k0sctl-linux-x64
chmod+xk0sctl-linux-x64
mvk0sctl-linux-x64/usr/local/bin/k0sctl
然后編寫 k0sctl.yaml 配置文件:
apiVersion:k0sctl.k0sproject.io/v1beta1
kind:Cluster
metadata:
name:k0s-cluster
spec:
hosts:
-ssh:
address:10.0.0.11
user:root
port:22
keyPath:/Users/bleem/.ssh/id_rsa
role:controller+worker
-ssh:
address:10.0.0.12
user:root
port:22
keyPath:/Users/bleem/.ssh/id_rsa
role:controller+worker
-ssh:
address:10.0.0.13
user:root
port:22
keyPath:/Users/bleem/.ssh/id_rsa
role:controller+worker
-ssh:
address:10.0.0.14
user:root
port:22
keyPath:/Users/bleem/.ssh/id_rsa
role:worker
-ssh:
address:10.0.0.15
user:root
port:22
keyPath:/Users/bleem/.ssh/id_rsa
role:worker
k0s:
version:1.21.2+k0s.1
config:
apiVersion:k0s.k0sproject.io/v1beta1
kind:Cluster
metadata:
name:k0s
spec:
api:
address:10.0.0.11
port:6443
k0sApiPort:9443
sans:
-10.0.0.11
-10.0.0.12
-10.0.0.13
storage:
type:etcd
etcd:
peerAddress:10.0.0.11
network:
kubeProxy:
disabled:false
mode:ipvs
最后執行 apply 命令安裝即可,安裝前確保你的操作機器可以 SSH 免密登陸所有目標機器:
?tmpk0sctlapply-cbak.yaml
?????????????????????????????????????█████████████████████
?????????????????????????????????????█████████
?????????????????????????????????????█████████
?????????????????????????????????????█████████
?????????????????????????????????????██████████████████████
k0sctl0.0.0Copyright2021,k0sctlauthors.
Anonymizedtelemetryofusagewillbesenttotheauthors.
Bycontinuingtousek0sctlyouagreetotheseterms:
https://k0sproject.io/licenses/eula
INFO==>Runningphase:Connecttohosts
INFO[ssh]10.0.0.15connected
INFO[ssh]10.0.0.11connected
INFO[ssh]10.0.0.12connected
INFO[ssh]10.0.0.14connected
INFO[ssh]10.0.0.13connected
INFO==>Runningphase:Detecthostoperatingsystems
INFO[ssh]10.0.0.11isrunningUbuntu20.04.2LTS
INFO[ssh]10.0.0.12isrunningUbuntu20.04.2LTS
INFO[ssh]10.0.0.14isrunningUbuntu20.04.2LTS
INFO[ssh]10.0.0.13isrunningUbuntu20.04.2LTS
INFO[ssh]10.0.0.15isrunningUbuntu20.04.2LTS
INFO==>Runningphase:Preparehosts
INFO==>Runningphase:Gatherhostfacts
INFO[ssh]10.0.0.11discoveredens33asprivateinterface
INFO[ssh]10.0.0.13discoveredens33asprivateinterface
INFO[ssh]10.0.0.12discoveredens33asprivateinterface
INFO==>Runningphase:Downloadk0sonhosts
INFO[ssh]10.0.0.11downloadingk0s1.21.2+k0s.1
INFO[ssh]10.0.0.13downloadingk0s1.21.2+k0s.1
INFO[ssh]10.0.0.12downloadingk0s1.21.2+k0s.1
INFO[ssh]10.0.0.15downloadingk0s1.21.2+k0s.1
INFO[ssh]10.0.0.14downloadingk0s1.21.2+k0s.1
......
稍等片刻后帶有三個 Master 和兩個 Node 的集群將安裝完成:
#注意:目標機器 hostname 不應當為域名形式,這里的樣例是已經修復了這個問題
k1.node?~k0skubectlgetnode-owide
NAMESTATUSROLESAGEVERSIONINTERNAL-IPEXTERNAL-IPOS-IMAGEKERNEL-VERSIONCONTAINER-RUNTIME
k1.nodeReady10mv1.21.2+k0s10.0.0.11Ubuntu20.04.2LTS5.4.0-77-genericcontainerd://1.4.6
k2.nodeReady10mv1.21.2+k0s10.0.0.12Ubuntu20.04.2LTS5.4.0-77-genericcontainerd://1.4.6
k3.nodeReady10mv1.21.2+k0s10.0.0.13Ubuntu20.04.2LTS5.4.0-77-genericcontainerd://1.4.6
k4.nodeReady10mv1.21.2+k0s10.0.0.14Ubuntu20.04.2LTS5.4.0-77-genericcontainerd://1.4.6
k5.nodeReady10mv1.21.2+k0s10.0.0.15Ubuntu20.04.2LTS5.4.0-77-genericcontainerd://1.4.6
2.2、k0sctl 的擴展方式
與 kubeadm 不同,k0sctl 幾乎提供了所有安裝細節的可定制化選項,其通過三種行為來完成擴展:
-
文件上傳:k0sctl 允許定義在安裝前的文件上傳,在安裝之前 k0sctl 會把已經定義的相關文件全部上傳到目標主機,包括不限于 k0s 本身二進制文件、離線鏡像包、其他安裝文件、其他輔助腳本等。
-
Manifests 與 Helm:當將特定的文件上傳到 Master 節點的 /var/lib/k0s/manifests 目錄時,k0s 在安裝過程中會自動應用這些配置,類似 kubelet 的 static pod 一樣,只不過 k0s 允許全部資源(包括不限于 Deployment、DaemonSet、namespace 等);同樣也可以直接在 k0sctl.yaml 添加 Helm 配置,k0s 也會以同樣的方式幫你管理。
-
輔助腳本:可以在每個主機下配置 hooks 選項來實現執行一些特定的腳本(文檔里沒有,需要看源碼),以便在特定情況下做點騷操作。
2.3、k0sctl 使用離線鏡像包
基于上面的擴展,k0s 還方便的幫我們集成了離線鏡像包的自動導入,我們只需要定義一個文件上傳,將鏡像包上傳到 /var/lib/k0s/images/ 目錄后,k0s 會自定將其倒入到 containerd 中而無需我們手動干預:
apiVersion:k0sctl.k0sproject.io/v1beta1
kind:Cluster
metadata:
name:k0s-cluster
spec:
hosts:
-ssh:
address:10.0.0.11
user:root
port:22
keyPath:/Users/bleem/.ssh/id_rsa
role:controller+worker
#files配置將會在安裝前將相關文件上傳到目標主機
files:
-name:image-bundle
src:/Users/bleem/tmp/bundle_file
#在該目錄下的image壓縮包將會被自動導入到containerd中
dstDir:/var/lib/k0s/images/
perm:0755
......
關于 image 壓縮包(bundle_file)如何下載以及自己自定義問題請參考官方 Airgap install[1] 文檔。
2.4、切換 CNI 插件
默認情況下 k0s 內部集成了兩個 CNI 插件:Calico 和 kube-router;如果我們使用其他的 CNI 插件例如 Flannel,我們只需要將默認的 CNI 插件設置為 custom,然后將 Flannel 的部署 yaml 上傳到一臺 Master 的 /var/lib/k0s/manifests 目錄即可,k0s 會自動幫我門執行 apply -f xxxx.yaml 這種操作。
下面是切換到 Flannel 的樣例,需要注意的是 Flannel 官方鏡像不會幫你安裝 CNI 的二進制文件,我們需要借助文件上傳自己安裝(CNI GitHub 插件下載地址[2]):
apiVersion:k0sctl.k0sproject.io/v1beta1
kind:Cluster
metadata:
name:k0s-cluster
spec:
hosts:
-ssh:
address:10.0.0.11
user:root
port:22
keyPath:/Users/bleem/.ssh/id_rsa
role:controller+worker
files:
#將Flannel的yaml放到Manifests里(需要單獨創建一個目錄)
-name:flannel
src:/Users/bleem/tmp/kube-flannel.yaml
dstDir:/var/lib/k0s/manifests/flannel
perm:0644
#自己安裝一下CNI插件
-name:cni-plugins
src:/Users/bleem/tmp/cni-plugins/*
dstDir:/opt/cni/bin/
perm:0755
k0s:
version:v1.21.2+k0s.1
config:
apiVersion:k0s.k0sproject.io/v1beta1
kind:Cluster
metadata:
name:k0s
spec:
api:
address:10.0.0.11
port:6443
k0sApiPort:9443
sans:
-10.0.0.11
-10.0.0.12
-10.0.0.13
storage:
type:etcd
network:
podCIDR:10.244.0.0/16
serviceCIDR:10.96.0.0/12
#這里指定CNI為custom自定義類型,這樣
#k0s就不會安裝Calico/kube-router了
provider:custom
2.5、上傳 k0s 二進制文件
除了普通文件、鏡像壓縮包等,默認情況下 k0sctl 在安裝集群時還會在目標機器上下載 k0s 二進制文件;當然在離線環境下這一步也可以通過一個簡單的配置來實現離線上傳:
apiVersion:k0sctl.k0sproject.io/v1beta1
kind:Cluster
metadata:
name:k0s-cluster
spec:
hosts:
-ssh:
address:10.0.0.11
user:root
port:22
keyPath:/Users/bleem/.ssh/id_rsa
role:controller+worker
#聲明需要上傳二進制文件
uploadBinary:true
#指定二進制文件位置
k0sBinaryPath:/Users/bleem/tmp/k0s
files:
-name:flannel
src:/Users/bleem/tmp/kube-flannel.yaml
dstDir:/var/lib/k0s/manifests/flannel
perm:0644
......
2.6、更換鏡像版本
默認情況下 k0s 版本號與 Kubernetes 保持一致,但是如果期望某個組件使用特定的版本,則可以直接配置這些內置組件的鏡像名稱:
apiVersion:k0sctl.k0sproject.io/v1beta1
kind:Cluster
metadata:
name:k0s-cluster
spec:
hosts:
-ssh:
address:10.0.0.11
user:root
port:22
keyPath:/Users/bleem/.ssh/id_rsa
role:controller+worker
uploadBinary:true
k0sBinaryPath:/Users/bleem/tmp/k0s
files:
-name:flannel
src:/Users/bleem/tmp/kube-flannel.yaml
dstDir:/var/lib/k0s/manifests/flannel
perm:0644
......
k0s:
version:v1.21.2+k0s.1
config:
apiVersion:k0s.k0sproject.io/v1beta1
kind:Cluster
metadata:
name:k0s
spec:
api:
address:10.0.0.11
port:6443
k0sApiPort:9443
sans:
-10.0.0.11
-10.0.0.12
-10.0.0.13
#指定內部組件的鏡像使用的版本
images:
#konnectivity:
#image:us.gcr.io/k8s-artifacts-prod/kas-network-proxy/proxy-agent
#version:v0.0.21
#metricsserver:
#image:gcr.io/k8s-staging-metrics-server/metrics-server
#version:v0.3.7
kubeproxy:
image:k8s.gcr.io/kube-proxy
version:v1.21.3
#coredns:
#image:docker.io/coredns/coredns
#version:1.7.0
#calico:
#cni:
#image:docker.io/calico/cni
#version:v3.18.1
#node:
#image:docker.io/calico/node
#version:v3.18.1
#kubecontrollers:
#image:docker.io/calico/kube-controllers
#version:v3.18.1
#kuberouter:
#cni:
#image:docker.io/cloudnativelabs/kube-router
#version:v1.2.1
#cniInstaller:
#image:quay.io/k0sproject/cni-node
#version:0.1.0
default_pull_policy:IfNotPresent
#default_pull_policy:Never
2.7、調整 Master 組件參數
熟悉 Kubernetes 的應該清楚,Master 上三大組件:apiserver、controller、scheduler 管控整個集群;在 k0sctl 安裝集群的過程中也允許自定義這些組件的參數,這些調整通過修改使用的 k0sctl.yaml 配置文件完成。
spec.api.extraArgs:用于自定義 kube-apiserver 的自定義參數(KV map)
spec.scheduler.extraArgs:用于自定義 kube-scheduler 的自定義參數(KV map)
spec.controllerManager.extraArgs:用于自定義 kube-controller-manager 自定義參數(KV map)
spec.workerProfiles:用于覆蓋 kubelet-config.yaml 中的配置,該配置最終將于默認的 kubelet-config.yaml 合并
除此之外在 Host 配置中還有一個 InstallFlags 配置用于傳遞 k0s 安裝時的其他配置選項。
三、k0s HA 搭建
其實上面的第二部分主要都是介紹 k0sctl 一些基礎功能,為的就是給下面這部分 HA 生產級部署做鋪墊。
就目前來說,k0s HA 僅支持獨立負載均衡器的 HA 架構;即外部需要有一個高可用的 4 層負載均衡器,其他所有 Node 節點鏈接這個負載均衡器實現 Master 的高可用。在使用 k0sctl 命令搭建 HA 集群時很簡單,只需要添加一個外部負載均衡器地址即可;以下是一個完整的,全離線狀態下的 HA 集群搭建配置。
3.1、外部負載均衡器
在搭建之前我們假設已經有一個外部的高可用的 4 層負載均衡器,且負載均衡器已經負載了以下端口:
6443(for Kubernetes API):負載均衡器 6443 負載所有 Master 節點的 6443
9443(for controller join API):負載均衡器 9443 負載所有 Master 節點的 9443
8132(for Konnectivity agent):負載均衡器 8132 負載所有 Master 節點的 8132
8133(for Konnectivity server):負載均衡器 8133 負載所有 Master 節點的 8133
以下為一個 Nginx 4 層代理的樣例:
error_logsyslog:server=unix:/dev/lognotice;
worker_processesauto;
events{
multi_accepton;
useepoll;
worker_connections1024;
}
stream{
upstreamkube_apiserver{
least_conn;
server10.0.0.11:6443;
server10.0.0.12:6443;
server10.0.0.13:6443;
}
upstreamkonnectivity_agent{
least_conn;
server10.0.0.11:8132;
server10.0.0.12:8132;
server10.0.0.13:8132;
}
upstreamkonnectivity_server{
least_conn;
server10.0.0.11:8133;
server10.0.0.12:8133;
server10.0.0.13:8133;
}
upstreamcontroller_join_api{
least_conn;
server10.0.0.11:9443;
server10.0.0.12:9443;
server10.0.0.13:9443;
}
server{
listen0.0.0.0:6443;
proxy_passkube_apiserver;
proxy_timeout10m;
proxy_connect_timeout1s;
}
server{
listen0.0.0.0:8132;
proxy_passkonnectivity_agent;
proxy_timeout10m;
proxy_connect_timeout1s;
}
server{
listen0.0.0.0:8133;
proxy_passkonnectivity_server;
proxy_timeout10m;
proxy_connect_timeout1s;
}
server{
listen0.0.0.0:9443;
proxy_passcontroller_join_api;
proxy_timeout10m;
proxy_connect_timeout1s;
}
}
3.2、搭建 HA 集群
以下為 k0sctl 的 HA + 離線部署樣例配置:
apiVersion:k0sctl.k0sproject.io/v1beta1
kind:Cluster
metadata:
name:k0s-cluster
spec:
hosts:
-ssh:
address:10.0.0.11
user:root
port:22
keyPath:/Users/bleem/.ssh/id_rsa
#role支持的值
#'controller'單Master
#'worker'單Worker
#'controller+worker'Master和Worker都運行
role:controller+worker
#從本地上傳k0sbin文件,不要在目標機器下載
uploadBinary:true
k0sBinaryPath:/Users/bleem/tmp/k0s
#上傳其他文件
files:
#上傳Flannel配置,使用自定的Flannel替換內置的Calico
-name:flannel
src:/Users/bleem/tmp/kube-flannel.yaml
dstDir:/var/lib/k0s/manifests/flannel
perm:0644
#上傳打包好的image鏡像包,k0s會自動導入到containerd
-name:image-bundle
src:/Users/bleem/tmp/bundle_file
dstDir:/var/lib/k0s/images/
perm:0755
#使用Flannel后每個機器要上傳對應的CNI插件
-name:cni-plugins
src:/Users/bleem/tmp/cni-plugins/*
dstDir:/opt/cni/bin/
perm:0755
-ssh:
address:10.0.0.12
user:root
port:22
keyPath:/Users/bleem/.ssh/id_rsa
role:controller+worker
uploadBinary:true
k0sBinaryPath:/Users/bleem/tmp/k0s
files:
-name:image-bundle
src:/Users/bleem/tmp/bundle_file
dstDir:/var/lib/k0s/images/
perm:0755
-name:cni-plugins
src:/Users/bleem/tmp/cni-plugins/*
dstDir:/opt/cni/bin/
perm:0755
-ssh:
address:10.0.0.13
user:root
port:22
keyPath:/Users/bleem/.ssh/id_rsa
role:controller+worker
uploadBinary:true
k0sBinaryPath:/Users/bleem/tmp/k0s
files:
-name:image-bundle
src:/Users/bleem/tmp/bundle_file
dstDir:/var/lib/k0s/images/
perm:0755
-name:cni-plugins
src:/Users/bleem/tmp/cni-plugins/*
dstDir:/opt/cni/bin/
perm:0755
-ssh:
address:10.0.0.14
user:root
port:22
keyPath:/Users/bleem/.ssh/id_rsa
role:worker
uploadBinary:true
k0sBinaryPath:/Users/bleem/tmp/k0s
files:
-name:image-bundle
src:/Users/bleem/tmp/bundle_file
dstDir:/var/lib/k0s/images/
perm:0755
-name:cni-plugins
src:/Users/bleem/tmp/cni-plugins/*
dstDir:/opt/cni/bin/
perm:0755
-ssh:
address:10.0.0.15
user:root
port:22
keyPath:/Users/bleem/.ssh/id_rsa
role:worker
uploadBinary:true
k0sBinaryPath:/Users/bleem/tmp/k0s
files:
-name:image-bundle
src:/Users/bleem/tmp/bundle_file
dstDir:/var/lib/k0s/images/
perm:0755
-name:cni-plugins
src:/Users/bleem/tmp/cni-plugins/*
dstDir:/opt/cni/bin/
perm:0755
k0s:
version:v1.21.2+k0s.1
config:
apiVersion:k0s.k0sproject.io/v1beta1
kind:Cluster
metadata:
name:k0s
spec:
api:
#此處填寫外部的負載均衡器地址,所有kubelet會鏈接這個地址
externalAddress:10.0.0.20
#不要忘了為外部負載均衡器添加API證書的SAN
sans:
-10.0.0.11
-10.0.0.12
-10.0.0.13
-10.0.0.20
#存儲類型使用etcd,etcd集群由k0s自動管理
storage:
type:etcd
network:
podCIDR:10.244.0.0/16
serviceCIDR:10.96.0.0/12
#網絡插件使用custom,然后讓Flannel接管
provider:custom
kubeProxy:
disabled:false
#開啟kubelet的ipvs模式
mode:ipvs
#不發送任何匿名統計信息
telemetry:
enabled:false
images:
default_pull_policy:IfNotPresent
最后只需要執行 k0sctl apply -c k0sctl.yaml 稍等幾分鐘集群就搭建好了,安裝過程中可以看到相關文件的上傳流程:
3.3、證書續簽和管理
kubeadm 集群默認證書有效期是一年,到期要通過 kubeadm 重新簽署;k0s 集群也差不多一樣,但是不同的是 k0s 集群更加暴力;只要 CA(默認 10年)不丟,k0s 每次重啟都強行重新生成一年有效期的證書,所以在 HA 的環境下,快到期時重啟一下 k0s 服務就行。
k0sctl 安裝完的集群默認只有一個 k0scontroller.service 服務,Master、Node 上所有服務都由這個服務啟動,所以到期之前 systemctl restart k0scontroller.service 一下就行。
四、集群備份和恢復
k0sctl 提供了集群備份和恢復功能,默認情況下只需要執行 k0sctl backup 即可完成集群備份,該命令會在當前目錄下生成一個 k0s_backup_TIMESTAMP.tar.gz 備份文件。
需要恢復集群時使用 k0sctl apply --restore-from k0s_backup_TIMESTAMP.tar.gz 命令進行恢復即可;需要注意的是恢復命令等同于在新機器重新安裝集群,所以有一定風險。
經過連續兩天的測試,感覺這個備份恢復功能并不算靠譜,還是推薦使用 Velero 備份集群。
五、其他高級功能
5.1、etcd 替換
在小規模集群場景下可能并不需要特別完善的 etcd 作為存儲,k0s 借助于 kine 庫可以實現使用 SQLite 或 MySQL 等傳統數據庫作為集群存儲;如果想要切換存儲只需要調整 k0sctl.yaml 配置即可:
apiVersion:k0s.k0sproject.io/v1beta1
kind:Cluster
metadata:
name:k0s
spec:
storage:
type:kine
kine:
dataSource:"sqlite:///var/lib/k0s/db/state.db?more=rwc&_journal=WAL&cache=shared"
5.2、集群用戶管理
使用 k0sctl 搭建的集群通過 k0s 命令可以很方便的為集群添加用戶,以下是添加樣例:
k0skubeconfigcreate--groups"system:masters"testUser>k0s.config
5.3、Containerd 配置
在不做配置的情況下 k0s 集群使用默認的 Containerd 配置,如果需要自己定義特殊配置,可以在安裝時通過文件上傳方式將 Containerd 配置文件上傳到 /etc/k0s/containerd.toml 位置,該配置將會被 k0s 啟動的 Containerd 讀取并使用。
六、總結
k0s 是個不錯的項目,對于二進制宿主機部署 Kubernetes 集群很方便,由于其直接采用 Kubernetes 二進制文件啟動,所以基本沒有功能閹割,而 k0sctl 又為自動化安裝提供了良好的擴展性,所以值得一試。不過目前來說 k0s 在細節部分還有一定瑕疵,比如 konnectivity 服務在安裝時無法選擇性關閉等;k0s 綜合來說是個不錯的工具,也推薦看看源碼,里面很多設計很新穎也比較利于了解集群引導過程。
相關鏈接:
https://docs.k0sproject.io/v1.21.2+k0s.1/airgap-install/
https://github.com/containernetworking/plugins/releases
原文鏈接:https://mritd.com/2021/07/29/test-the-k0s-cluster/
-
機器
+關注
關注
0文章
784瀏覽量
40752 -
源碼
+關注
關注
8文章
643瀏覽量
29267 -
負載均衡器
+關注
關注
0文章
18瀏覽量
2607
原文標題:K0S 使用實戰介紹
文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
評論