您好,登錄后才能下訂單哦!
Kubernetes高級進階之Node自動擴容/縮容
目錄:
1、Cluster AutoScaler云廠商擴容/縮容
2、Ansible一鍵自動擴容Node
1、Cluster AutoScaler
擴容:Cluster AutoScaler 定期檢測是否有充足的資源來調度新創建的 Pod,當資源不足時會調用 Cloud Provider 創建新的 Node。
工作流程:定期檢查集群中的資源是否充足的,如果發現集群資源不夠pod就會出現pending的狀態,會等待資源的一個就緒,如果沒有新的資源沒有釋放出來,它會一直等待,部署的服務就不會提供服務,此時autoscaler會檢測到一個資源的利用率的情況,是不是存在資源的一個緊缺,存在的話會調用云供應商provider來創建新的node
縮容:Cluster AutoScaler 也會定期監測 Node 的資源使用情況,當一個 Node 長時間資源利用率都很低時(低于 50%)長時間利用率比較低的資源下線,來進行判斷,自動將其所在虛擬機從云服務商中刪除。此時,將原來上面的pod驅逐掉,調度到其他節點上提供服務。
支持的云提供商:
要是使用它們云廠商的就可以使用它們的的組件解決去用,一般他們都對接完成了。
? 阿里云:https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/alicloud/README.md
? AWS: https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/aws/README.md
? Azure: https://github.com/kubernetes/autoscaler/blob/master/cluster-autoscaler/cloudprovider/azure/README.md
小結:
彈性伸縮主要解決的問題是容量規劃與實際負載的矛盾,就是我這批機器中,其中負載高了,能不能讓這批服務器快速的擴容,主要是解決這么一個問題,考驗的就是快速的擴容和縮容。
就是傳統的這種彈性伸縮放到k8s中,仔細想想會遇到兩種問題
1、 機器規格不統一造成機器利用率百分比的碎片化
在k8s集群中不是所有機器都是一樣的,我們也沒必要都是一樣,其實k8s已經幫我們做好資源的管理了,這些cpu,內存都會作為一個整體放在資源池中去調度,對于縮容和擴容的情況下,特別是縮容,機器規格的不統一,縮容時可能縮容一些小規格的機器,那么很有可能你縮容之后其實沒有太多的效果,可能你大機器還沒有去縮容,導致你效果還不是很明顯,如果大規格機器縮容的話,可能會讓你資源的一個爭搶,可能你資源的冗余不是很多了。
2、 機器利用率不單純依靠宿主機計算
當你沒做容器之前,做一個服務器的資源的規劃,內存和CPU去申請就完事了,那么在那種情況下做一些縮容擴容也比較簡單,比如擴容你看你的服務器的資源是不是到達80%,90%,然后申請新的機器就好了,縮容也是如此,看一下資源空閑的整體資源利用率比較低,減少幾臺還是很容易的,但是到k8s的場景中呢,其實我們在上面部署的一些應用,沒必要太注意服務器底層的資源了,不關心我機器的配置利用率多少,它關心的是,我申請的資源,我部署的應用你能不能給足我就行了,在k8s中容量規劃是根據request和limit這兩個值,request其實就是在k8s中的一個配額,你部署一個應用,申請的資源都是通過request去定義的,所以在k8s中就多了一個維度,request與宿主機的資源利用率,所以在做縮容擴容的時候要考慮到這一點,也就是不能根據你當前的節點去分配了,因為你申請部署request的這個配額它即使不用,你也不能說把它去掉,所以要考慮整體request的一個整體資源的利用率,并且在這個資源利用率之上保持一定的冗余。
2.2 Ansible擴容Node
第三種就是我們人工干預的去進行擴容縮容了,這是普遍自建采用的一種手段
1. 觸發新增Node,要知道要不要去增加一個節點。
2. 調用Ansible腳本部署組件,怎么去準備好這個節點,這臺新機器有沒有準備好,有沒有部署這些組件。
3. 檢查服務是否可用,新加入的組件查看是否是正常的
4. 調用API將新Node加入集群或者啟用Node自動加入
5. 觀察新Node狀態,進行監控,對于新節點觀察,運行的日志,資源狀態。
6. 完成Node擴容,接收新Pod
模擬擴容node節點,由于我的資源過多,導致無法分配,出現pending的狀態
[root@k8s-master1 ~]# kubectl run web --image=nginx --replicas=6 --requests="cpu=1,memory=256Mi"
[root@k8s-master1 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
web-944cddf48-6qhcl 1/1 Running 0 15m
web-944cddf48-7ldsv 1/1 Running 0 15m
web-944cddf48-7nv9p 0/1 Pending 0 2s
web-944cddf48-b299n 1/1 Running 0 15m
web-944cddf48-nsxgg 0/1 Pending 0 15m
web-944cddf48-pl4zt 1/1 Running 0 15m
web-944cddf48-t8fqt 1/1 Running 0 15m
現在的狀態就是pod由于資源池不夠,無法分配資源到當前的節點上了,所以現在我們需要對我們的node節點進行擴容
[newnode]
10.4.7.22 node_name=k8s-node3
[root@ansible ansible-install-k8s-master]# ansible-playbook -i hosts add-node.yml -uroot -k
查看已經收到加入node的請求,并運行通過
[root@k8s-master1 ~]# kubectl get csr
NAME AGE REQUESTOR CONDITION
node-csr-0i7BzFaf8NyG_cdx_hqDmWg8nd4FHQOqIxKa45x3BJU 45m kubelet-bootstrap Approved,Issued
查看node節點狀態
[root@k8s-master1 ~]# kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master1 Ready <none> 7d v1.16.0
k8s-node1 Ready <none> 7d v1.16.0
k8s-node2 Ready <none> 7d v1.16.0
k8s-node3 Ready <none> 2m52s v1.16.0
查看資源狀態的分配的總體利用率[root@k8s-master1 ~]# kubectl describe node k8s-node1
縮容Node節點
縮容的話,就是驅逐這個節點上的pod,對業務和集群可能都會受一些影響
如果想從kubernetes集群中刪除節點,正確流程
1、 獲取節點列表
Kubectl get node
2、 設置不可調度
Kubectl cordon $node_name
3、 驅逐節點上額pod
Kubectl drain $node_name –I gnore-daemonsets
4、 移除節點
該節點上已經沒有任何資源了,可以直接移除節點:
Kubectl delete node $node_node
這樣,我們平滑移除了一個k8s節點
首先要了解到整個集群哪個節點要刪除,這個人工干預的話,是要先確定好,哪個值得去縮容刪除的,那肯定是資源利用率低,上面跑的資源最少最有優先縮容的節點。
然后設置不可調度,因為隨時有可能新的pod去調度上面去,防止新的pod調度過來,這個有kubectl –help的相關命令
cordon 標記 node 為 unschedulable
[root@k8s-master1 ~]# kubectl cordon k8s-node3
node/k8s-node3 cordoned
這里會給不可調度的node打個標記
[root@k8s-master1 ~]# kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master1 Ready <none> 7d1h v1.16.0
k8s-node1 Ready <none> 7d1h v1.16.0
k8s-node2 Ready <none> 7d1h v1.16.0
k8s-node3 Ready,SchedulingDisabled <none> 45m v1.16.0
現在這個階段不會對現有的階段的pod不會有任何影響
現在驅逐現在節點上已有的pod,所以現在要對這個node節點設置一定的維護期,這個也有相關命令drain Drain node in preparation for maintenance
設置這個狀態的話,它會將這個節點上的pod進行驅逐,會給你一個提示會告訴你現在的這個節點已經是不可調度狀態了,現在在進行驅逐,這里報了一個錯誤daemonset的一個pod,因為我們部署的flanneld是使用daemonset去啟動的,所以會出現這種情況,這個就可以直接忽略
[root@k8s-master1 ~]# kubectl drain k8s-node3
node/k8s-node3 already cordoned
error: unable to drain node "k8s-node3", aborting command...
There are pending nodes to be drained:
k8s-node3
error: cannot delete DaemonSet-managed Pods (use --ignore-daemonsets to ignore): ingress-nginx/nginx-ingress-controller-qxhj7, kube-system/kube-flannel-ds-amd64-j9w5l
這個加后面的命令
[root@k8s-master1 ~]# kubectl drain k8s-node3 --ignore-daemonsets
node/k8s-node3 already cordoned
WARNING: ignoring DaemonSet-managed Pods: ingress-nginx/nginx-ingress-controller-qxhj7, kube-system/kube-flannel-ds-amd64-j9w5l
evicting pod "web-944cddf48-nsxgg"
evicting pod "web-944cddf48-7nv9p"
pod/web-944cddf48-nsxgg evicted
pod/web-944cddf48-7nv9p evicted
node/k8s-node3 evicted
[root@k8s-master1 ~]# kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master1 Ready <none> 7d1h v1.16.0
k8s-node1 Ready <none> 7d1h v1.16.0
k8s-node2 Ready <none> 7d1h v1.16.0
k8s-node3 Ready,SchedulingDisabled <none> 53m v1.16.0
[root@k8s-master1 ~]# kubectl get pod
NAME READY STATUS RESTARTS AGE
web-944cddf48-6qhcl 1/1 Running 0 127m
web-944cddf48-7ldsv 1/1 Running 0 127m
web-944cddf48-b299n 1/1 Running 0 127m
web-944cddf48-cc6n5 0/1 Pending 0 38s
web-944cddf48-pl4zt 1/1 Running 0 127m
web-944cddf48-t8fqt 1/1 Running 0 127m
web-944cddf48-vl5hg 0/1 Pending 0 38s
[root@k8s-master1 ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
web-944cddf48-6qhcl 1/1 Running 0 127m 10.244.0.6 k8s-node2 <none> <none>
web-944cddf48-7ldsv 1/1 Running 0 127m 10.244.0.5 k8s-node2 <none> <none>
web-944cddf48-b299n 1/1 Running 0 127m 10.244.0.7 k8s-node2 <none> <none>
web-944cddf48-cc6n5 0/1 Pending 0 43s <none> <none> <none> <none>
web-944cddf48-pl4zt 1/1 Running 0 127m 10.244.2.2 k8s-master1 <none> <none>
web-944cddf48-t8fqt 1/1 Running 0 127m 10.244.1.2 k8s-node1 <none> <none>
web-944cddf48-vl5hg 0/1 Pending 0 43s <none> <none> <none> <none>
現在縮容完,由于我的資源比較緊張所以又出現了pending的狀態,所以這就是縮容,當縮容之后,還是由控制器去保證pod的副本數量的,這個當前你要保證一個其他節點的冗余性,這樣縮容才有意義,不然出現pending狀態肯定不行的。
然后刪除k8s-node3節點
[root@k8s-master1 ~]# kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master1 Ready <none> 7d2h v1.16.0
k8s-node1 Ready <none> 7d2h v1.16.0
k8s-node2 Ready <none> 7d2h v1.16.0
k8s-node3 Ready,SchedulingDisabled <none> 71m v1.16.0
移除節點,當驅逐完成之后,也要保證在其他的節點上有預期的副本,還要做好一定的策略,在下線期間不能做pod的調度。
或者將node3關機也可以,首先要保證其他的節點的資源是冗余的,即使在出現其他的狀況下,k8s有一定的機制會在5分鐘之內將出現故障的node節點上的pod飄移到其他正常的node節點上,像微服務我們的服務當我們去驅逐的時候,其實業務也會收到一些影響,畢竟我們需要將這個節點上的node做驅逐,轉移到其他節點上,所以盡量在業務低峰期去做這件事。
[root@k8s-master1 ~]# kubectl delete node k8s-node3
node "k8s-node3" deleted
[root@k8s-master1 ~]# kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master1 Ready <none> 7d2h v1.16.0
k8s-node1 Ready <none> 7d2h v1.16.0
k8s-node2 Ready <none> 7d2h v1.16.0
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。