您好,登錄后才能下訂單哦!
這篇文章給大家分享的是有關如何安裝kubernetes的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
如何用一條命令構建 k8s 高可用集群且不依賴 haproxy 和 keepalived,也無需 ansible。通過內核 ipvs
對 apiserver 進行負載均衡,并且帶 apiserver
健康檢測。架構如下圖所示:
本項目名叫 sealos,旨在做一個簡單干凈輕量級穩定的 kubernetes 安裝工具,能很好的支持高可用安裝。 其實把一個東西做的功能強大并不難,但是做到極簡且靈活可擴展就比較難。 所以在實現時就必須要遵循這些原則。下面介紹一下 sealos 的設計原則:
sealos 特性與優勢:
支持離線安裝,工具與資源包(二進制程序 配置文件 鏡像 yaml文件等)分離,這樣不同版本替換不同離線包即可
證書延期
使用簡單
支持自定義配置
內核負載,極其穩定,因為簡單所以排查問題也極其簡單
1.0 版本確實是用 ansible
實現,但是用戶還是需要先裝 ansile,裝 ansible 又需要裝 python
和一些依賴等,為了不讓用戶那么麻煩把 ansible 放到了容器里供用戶使用。如果不想配置免密鑰使用用戶名密碼時又需要 ssh-pass
等,總之不能讓我滿意,不是我想的極簡。
所以我想就來一個二進制文件工具,沒有任何依賴,文件分發與遠程命令都通過調用 sdk 實現所以不依賴其它任何東西,總算讓我這個有潔癖的人滿意了。
haproxy
用 static pod 跑沒有太大問題,還算好管理,keepalived
現在大部分開源 ansible 腳本都用 yum 或者 apt 等裝,這樣非常的不可控,有如下劣勢:
源不一致可能導致版本不一致,版本不一直連配置文件都不一樣,我曾經檢測腳本不生效一直找不到原因,后來才知道是版本原因。
系統原因安裝不上,依賴庫問題某些環境就直接裝不上了。
看了網上很多安裝腳本,很多檢測腳本與權重調節方式都不對,直接去檢測 haproxy 進程在不在,其實是應該去檢測 apiserver 是不是 healthz 的,如果 apiserver 掛了,即使 haproxy 進程存在,集群也會不正常了,就是偽高可用了。
管理不方便,通過 prometheus 對集群進行監控,是能直接監控到 static pod 的但是用 systemd 跑又需要單獨設置監控,且重啟啥的還需要單獨拉起。不如 kubelet 統一管理來的干凈簡潔。
我們還出現過 keepalived 把 CPU 占滿的情況。
所以為了解決這個問題,我把 keepalived 跑在了容器中(社區提供的鏡像基本是不可用的) 改造中間也是發生過很多問題,最終好在解決了。
總而言之,累覺不愛,所以在想能不能甩開 haproxy 和 keepalived 做出更簡單更可靠的方案出來,還真找到了。。。
我們通過本地負載解決高可用問題。
> 本地負載:在每個 node 節點上都啟動一個負載均衡,上游就是三個 master。
如果使用 envoy
之類的負載均衡器,則需要在每個節點上都跑一個進程,消耗的資源更多,這是我不希望的。ipvs 實際也多跑了一個進程 lvscare
,但是 lvscare
只是負責管理 ipvs 規則,和 kube-proxy
類似,真正的流量還是從很穩定的內核走的,不需要再把包丟到用戶態中去處理。
在架構實現上有個問題會讓使用 envoy
等變得非常尷尬,就是 join
時如果負載均衡沒有建立那是會卡住的,kubelet
就不會起來,所以為此你需要先啟動 envoy,意味著你又不能用 static pod 去管理它,同上面 keepalived 宿主機部署一樣的問題,用 static pod 就會相互依賴,邏輯死鎖,雞說要先有蛋,蛋說要先有雞,最后誰都沒有。
使用 ipvs
就不一樣,我可以在 join 之前先把 ipvs 規則建立好,再去 join 就可以了,然后對規則進行守護即可。一旦 apiserver 不可訪問了,會自動清理掉所有 node 上對應的 ipvs 規則, 等到 master 恢復正常時添加回來。
首先是由于 kubeadm
把證書過期時間寫死了,所以需要定制把它改成 99
年,雖然大部分人可以自己去簽個新證書,但是我們還是不想再依賴個別的工具,就直接改源碼了。
其次就是做本地負載時修改 kubeadm
代碼是最方便的,因為在 join 時我們需要做兩個事,第一是 join 之前先創建好 ipvs 規則,第二是創建 static pod。如果這塊不去定制 kubeadm 就把報靜態 pod 目錄已存在的錯誤,忽略這個錯誤很不優雅。 而且 kubeadm 中已經提供了一些很好用的 sdk
供我們去實現這個功能。
且這樣做之后最核心的功能都集成到 kubeadm 中了,sealos
就單單變成分發和執行上層命令的輕量級工具了,增加節點時我們也就可以直接用 kubeadm 了。
安裝并啟動 docker
下載 kubernetes 離線安裝包
下載最新版本 sealos
支持 kubernetes 1.14.0+
多 master HA 只需執行以下命令:
$ sealos init --master 192.168.0.2 \ --master 192.168.0.3 \ --master 192.168.0.4 \ --node 192.168.0.5 \ --user root \ --passwd your-server-password \ --version v1.14.1 \ --pkg-url /root/kube1.14.1.tar.gz
然后,就沒有然后了。。。沒錯,你的高可用集群已經裝好了,是不是覺得一臉懵逼?就是這么簡單快捷!
單 master 多 node:
$ sealos init --master 192.168.0.2 \ --node 192.168.0.5 \ --user root \ --passwd your-server-password \ --version v1.14.1 \ --pkg-url /root/kube1.14.1.tar.gz
使用免密鑰或者密鑰對:
$ sealos init --master 172.16.198.83 \ --node 172.16.198.84 \ --pkg-url https://sealyun.oss-cn-beijing.aliyuncs.com/free/kube1.15.0.tar.gz \ --pk /root/kubernetes.pem # this is your ssh private key file \ --version v1.15.0
參數解釋:
--master master服務器地址列表 --node node服務器地址列表 --user 服務器ssh用戶名 --passwd 服務器ssh用戶密碼 --pkg-url 離線包位置,可以放在本地目錄,也可以放在一個 http 服務器上,sealos 會 wget 到安裝目標機 --version kubernetes 版本 --pk ssh 私鑰地址,配置免密鑰默認就是 /root/.ssh/id_rsa
其他參數:
--kubeadm-config string kubeadm-config.yaml kubeadm 配置文件,可自定義 kubeadm 配置文件 --vip string virtual ip (default "10.103.97.2") 本地負載時虛擬 ip,不推薦修改,集群外不可訪問
檢查安裝是否正常:
$ kubectl get node NAME STATUS ROLES AGE VERSION izj6cdqfqw4o4o9tc0q44rz Ready master 2m25s v1.14.1 izj6cdqfqw4o4o9tc0q44sz Ready master 119s v1.14.1 izj6cdqfqw4o4o9tc0q44tz Ready master 63s v1.14.1 izj6cdqfqw4o4o9tc0q44uz Ready <none> 38s v1.14.1 $ kubectl get pod --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE kube-system calico-kube-controllers-5cbcccc885-9n2p8 1/1 Running 0 3m1s kube-system calico-node-656zn 1/1 Running 0 93s kube-system calico-node-bv5hn 1/1 Running 0 2m54s kube-system calico-node-f2vmd 1/1 Running 0 3m1s kube-system calico-node-tbd5l 1/1 Running 0 118s kube-system coredns-fb8b8dccf-8bnkv 1/1 Running 0 3m1s kube-system coredns-fb8b8dccf-spq7r 1/1 Running 0 3m1s kube-system etcd-izj6cdqfqw4o4o9tc0q44rz 1/1 Running 0 2m25s kube-system etcd-izj6cdqfqw4o4o9tc0q44sz 1/1 Running 0 2m53s kube-system etcd-izj6cdqfqw4o4o9tc0q44tz 1/1 Running 0 118s kube-system kube-apiserver-izj6cdqfqw4o4o9tc0q44rz 1/1 Running 0 2m15s kube-system kube-apiserver-izj6cdqfqw4o4o9tc0q44sz 1/1 Running 0 2m54s kube-system kube-apiserver-izj6cdqfqw4o4o9tc0q44tz 1/1 Running 1 47s kube-system kube-controller-manager-izj6cdqfqw4o4o9tc0q44rz 1/1 Running 1 2m43s kube-system kube-controller-manager-izj6cdqfqw4o4o9tc0q44sz 1/1 Running 0 2m54s kube-system kube-controller-manager-izj6cdqfqw4o4o9tc0q44tz 1/1 Running 0 63s kube-system kube-proxy-b9b9z 1/1 Running 0 2m54s kube-system kube-proxy-nf66n 1/1 Running 0 3m1s kube-system kube-proxy-q2bqp 1/1 Running 0 118s kube-system kube-proxy-s5g2k 1/1 Running 0 93s kube-system kube-scheduler-izj6cdqfqw4o4o9tc0q44rz 1/1 Running 1 2m43s kube-system kube-scheduler-izj6cdqfqw4o4o9tc0q44sz 1/1 Running 0 2m54s kube-system kube-scheduler-izj6cdqfqw4o4o9tc0q44tz 1/1 Running 0 61s kube-system kube-sealyun-lvscare-izj6cdqfqw4o4o9tc0q44uz 1/1 Running 0 86s
先獲取 join command,在 master 上執行:
$ kubeadm token create --print-join-command
可以使用超級 kubeadm,但是 join 時需要增加一個 --master
參數:
$ cd kube/shell && init.sh $ echo "10.103.97.2 apiserver.cluster.local" >> /etc/hosts # using vip $ kubeadm join 10.103.97.2:6443 --token 9vr73a.a8uxyaju799qwdjv \ --master 10.103.97.100:6443 \ --master 10.103.97.101:6443 \ --master 10.103.97.102:6443 \ --discovery-token-ca-cert-hash sha256:7c2e69131a36ae2a042a339b33381c6d0d43887e2de83720eff5359e26aec866
也可以用 sealos join 命令:
$ sealos join --master 192.168.0.2 \ --master 192.168.0.3 \ --master 192.168.0.4 \ --vip 10.103.97.2 \ --node 192.168.0.5 \ --user root \ --passwd your-server-password \ --pkg-url /root/kube1.15.0.tar.gz
有時你可能需要自定義 kubeadm 的配置文件,比如要在證書里加入域名 sealyun.com
。
首先需要獲取配置文件模板:
$ sealos config -t kubeadm >> kubeadm-config.yaml.tmpl
然后修改 kubeadm-config.yaml.tmpl
即可,將 sealyun.com
添加到配置中:
apiVersion: kubeadm.k8s.io/v1beta1 kind: ClusterConfiguration kubernetesVersion: {{.Version}} controlPlaneEndpoint: "apiserver.cluster.local:6443" networking: podSubnet: 100.64.0.0/10 apiServer: certSANs: - sealyun.com # 這是新增的域名 - 127.0.0.1 - apiserver.cluster.local {{range .Masters -}} - {{.}} {{end -}} - {{.VIP}} --- apiVersion: kubeproxy.config.k8s.io/v1alpha1 kind: KubeProxyConfiguration mode: "ipvs" ipvs: excludeCIDRs: - "{{.VIP}}/32"
注意:其它部分不用修改,sealos 會自動填充模板里面的內容。
最后在部署時使用 --kubeadm-config
指定配置文件模板即可:
$ sealos init --kubeadm-config kubeadm-config.yaml.tmpl \ --master 192.168.0.2 \ --master 192.168.0.3 \ --master 192.168.0.4 \ --node 192.168.0.5 \ --user root \ --passwd your-server-password \ --version v1.14.1 \ --pkg-url /root/kube1.14.1.tar.gz
本教程以 1.14
版本升級到 1.15
為例,其它版本原理類似,懂了這個其它的參考官方教程即可。
升級 kubeadm,所有節點導入鏡像
升級控制節點
升級 master(控制節點)上的 kubelet
升級其它 master(控制節點)
升級 node
驗證集群狀態
把離線包拷貝到所有節點執行 cd kube/shell && sh init.sh
。這里會把 kubeadm、kubectl、kubelet 的二進制文件都更新掉,而且會導入高版本鏡像。
$ kubeadm upgrade plan $ kubeadm upgrade apply v1.15.0
重啟 kubelet:
$ systemctl restart kubelet
其實 kubelet 升級很簡單粗暴,我們只需要把新版本的 kubelet 拷貝到 /usr/bin 下面,重啟 kubelet service 即可,如果程序正在使用不讓覆蓋那么就停一下 kubelet 再進行拷貝,kubelet bin 文件在 conf/bin
目錄下。
$ kubeadm upgrade apply
驅逐節點(要不要驅逐看情況, 喜歡粗暴的直接來也沒啥):
$ kubectl drain $NODE --ignore-daemonsets
更新 kubelet 配置:
$ kubeadm upgrade node config --kubelet-version v1.15.0
然后升級 kubelet。同樣是替換二進制再重啟 kubelet service。
$ systemctl restart kubelet
召回失去的愛情:
$ kubectl uncordon $NODE
$ kubectl get nodes
如果版本信息都對的話基本就升級成功了。
檢查集群是否可升級
執行版本升級策略 哪些版本之間可以升級
確認鏡像是否存在
執行控制組件升級,如果失敗就回滾,其實就是 apiserver、controller manager、scheduler 等這些容器
升級 kube-dns 和 kube-proxy
創建新的證書文件,備份老的如果其超過 180 天
因為使用了 netlink
庫,所以推薦在容器內進行編譯,只需一條命令:
$ docker run --rm -v $GOPATH/src/github.com/fanux/sealos:/go/src/github.com/fanux/sealos -w /go/src/github.com/fanux/sealos -it golang:1.12.7 go build
如果你使用的是 go mod,則需要指定通過 vendor
編譯:
$ go build -mod vendor
$ sealos clean \ --master 192.168.0.2 \ --master 192.168.0.3 \ --master 192.168.0.4 \ --node 192.168.0.5 \ --user root \ --passwd your-server-password
通過 sftp
或者 wget
把離線安裝包拷貝到目標機器上(masters 和 nodes)。
在 master0 上執行 kubeadm init
。
在其它 master 上執行 kubeadm join 并設置控制面,這個過程會在其它 master 上起動 etcd
并與 master0
的 etcd 組成集群,并啟動控制平面的組件(apiserver、controller 等)。
join node 節點,會在 node 上配置 ipvs 規則,配置 /etc/hosts 等。
> 所有對 apiserver 的請求都是通過域名進行訪問,因為 node 需要通過虛擬 ip 連接多個 master,每個節點的 kubelet 與 kube-proxy 訪問 apiserver 的虛擬地址是不一樣的,而 kubeadm 又只能在配置文件中指定一個地址,所以使用一個域名但是每個節點解析的 IP 不同。當 IP 地址發生變化時僅需要修改解析地址即可。
通過這樣的方式實現每個 node 上通過本地內核負載均衡訪問 masters:
+----------+ +---------------+ virturl server: 127.0.0.1:6443 | mater0 |<----------------------| ipvs nodes | real servers: +----------+ |+---------------+ 10.103.97.200:6443 | 10.103.97.201:6443 +----------+ | 10.103.97.202:6443 | mater1 |<---------------------+ +----------+ | | +----------+ | | mater2 |<---------------------+ +----------+
在 node 上起了一個 lvscare
的 static pod 去守護這個 ipvs,一旦 apiserver 不可訪問了,會自動清理掉所有 node 上對應的 ipvs 規則, master 恢復正常時添加回來。
所以在你的 node 上加了三個東西,可以直觀的看到:
$ cat /etc/kubernetes/manifests # 這下面增加了 lvscare 的 static pod $ ipvsadm -Ln # 可以看到創建的ipvs規則 $ cat /etc/hosts # 增加了虛擬IP的地址解析
sealos 對 kubeadm 改動非常少,主要是延長了證書過期時間和擴展了 join 命令。下面主要講講對 join 命令的改造。
首先 join 命令增加 --master
參數用于指定 master 地址列表:
lagSet.StringSliceVar( &locallb.LVScare.Masters, "master", []string{}, "A list of ha masters, --master 192.168.0.2:6443 --master 192.168.0.2:6443 --master 192.168.0.2:6443", )
這樣就可以拿到 master 地址列表去做 ipvs 負載均衡了。
如果不是控制節點且不是單 master,那么就只創建一條 ipvs 規則,控制節點上不需要創建,連自己的 apiserver 即可:
if data.cfg.ControlPlane == nil { fmt.Println("This is not a control plan") if len(locallb.LVScare.Masters) != 0 { locallb.CreateLocalLB(args[0]) } }
然后再去創建 lvscare static pod 來守護 ipvs:
if len(locallb.LVScare.Masters) != 0 { locallb.LVScareStaticPodToDisk("/etc/kubernetes/manifests") }
**所以哪怕你不使用 sealos,也可以直接用定制過的 kubeadm 去部署集群,只是麻煩一些。**下面給出安裝步驟。
kubeadm 配置文件:
apiVersion: kubeadm.k8s.io/v1beta1 kind: ClusterConfiguration kubernetesVersion: v1.14.0 controlPlaneEndpoint: "apiserver.cluster.local:6443" # apiserver DNS name apiServer: certSANs: - 127.0.0.1 - apiserver.cluster.local - 172.20.241.205 - 172.20.241.206 - 172.20.241.207 - 172.20.241.208 - 10.103.97.1 # virturl ip --- apiVersion: kubeproxy.config.k8s.io/v1alpha1 kind: KubeProxyConfiguration mode: "ipvs" ipvs: excludeCIDRs: - "10.103.97.1/32" # 注意:如果不加這個,kube-proxy 就會清理你的規則
在 master0
(假設 vip 地址為 10.103.97.100)上執行以下命令:
$ echo "10.103.97.100 apiserver.cluster.local" >> /etc/hosts # 解析的是 master0 的地址 $ kubeadm init --config=kubeadm-config.yaml --experimental-upload-certs $ mkdir ~/.kube && cp /etc/kubernetes/admin.conf ~/.kube/config $ kubectl apply -f https://docs.projectcalico.org/v3.6/getting-started/kubernetes/installation/hosted/kubernetes-datastore/calico-networking/1.7/calico.yaml
在 master1
(假設 vip 地址為 10.103.97.101)上執行以下命令:
$ echo "10.103.97.100 apiserver.cluster.local" >> /etc/hosts #解析的是 master0 的地址,為了能正常 join 進去 $ kubeadm join 10.103.97.100:6443 --token 9vr73a.a8uxyaju799qwdjv \ --discovery-token-ca-cert-hash sha256:7c2e69131a36ae2a042a339b33381c6d0d43887e2de83720eff5359e26aec866 \ --experimental-control-plane \ --certificate-key f8902e114ef118304e561c3ecd4d0b543adc226b7a07f675f56564185ffe0c07 $ sed "s/10.103.97.100/10.103.97.101/g" -i /etc/hosts # 解析再換成自己的地址,否則就都依賴 master0 的偽高可用了
在 master2
(假設 vip 地址為 10.103.97.102)上執行以下命令:
$ echo "10.103.97.100 apiserver.cluster.local" >> /etc/hosts $ kubeadm join 10.103.97.100:6443 --token 9vr73a.a8uxyaju799qwdjv \ --discovery-token-ca-cert-hash sha256:7c2e69131a36ae2a042a339b33381c6d0d43887e2de83720eff5359e26aec866 \ --experimental-control-plane \ --certificate-key f8902e114ef118304e561c3ecd4d0b543adc226b7a07f675f56564185ffe0c07 $ sed "s/10.103.97.100/10.103.97.102/g" -i /etc/hosts
在 node 上 join 時加上 --master
參數指定 master 地址列表:
$ echo "10.103.97.1 apiserver.cluster.local" >> /etc/hosts # 需要解析成虛擬 ip $ kubeadm join 10.103.97.1:6443 --token 9vr73a.a8uxyaju799qwdjv \ --master 10.103.97.100:6443 \ --master 10.103.97.101:6443 \ --master 10.103.97.102:6443 \ --discovery-token-ca-cert-hash sha256:7c2e69131a36ae2a042a339b33381c6d0d43887e2de83720eff5359e26aec866
. ├── bin # 指定版本的二進制文件,只需要這三個,其它組件跑在容器里 │ ├── kubeadm │ ├── kubectl │ └── kubelet ├── conf │ ├── 10-kubeadm.conf # 這個文件新版本沒用到,我在 shell 里直接生成,這樣可以檢測 cgroup driver │ ├── dashboard │ │ ├── dashboard-admin.yaml │ │ └── kubernetes-dashboard.yaml │ ├── heapster │ │ ├── grafana.yaml │ │ ├── heapster.yaml │ │ ├── influxdb.yaml │ │ └── rbac │ │ └── heapster-rbac.yaml │ ├── kubeadm.yaml # kubeadm 的配置文件 │ ├── kubelet.service # kubelet systemd 配置文件 │ ├── net │ │ └── calico.yaml │ └── promethus ├── images # 所有鏡像包 │ └── images.tar └── shell ├── init.sh # 初始化腳本 └── master.sh # 運行master腳本
init.sh
腳本會將 bin 目錄下的二進制文件拷貝到 $PATH
下面,并配置好 systemd,關閉 swap 和防火墻等等,然后導入集群所需要的鏡像。
master.sh
主要執行了 kubeadm init。
conf 目錄下面包含了 kubeadm 的配置文件,calico yaml 文件等等。
sealos 會調用上面的兩個腳本,所以大部分兼容。不同版本都可以通過微調腳本來保持兼容。
感謝各位的閱讀!關于“如何安裝kubernetes”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。