[toc]
一、HPA與彈性伸縮
1.1 scale
- scale命令可以使用命令行通過控制器調(diào)整副本數(shù)
kubectl scale --replicas=3 deployment/mysql -n default
1.2 HPA
1.2.1 HPA簡介
HPA(Horizontal Pod Autoscaler)控制器,通過autoscale自動控制在k8s集群中運行的pod數(shù)量(水平自動伸縮),需要提前設置pod范圍及觸發(fā)條件邮旷;k8從1.1版本開始增加了HPA控制器,用于實現(xiàn)基于pod中資源(CPU)利用率進行對pod的自動擴縮容功能的實現(xiàn),開始版本只能基于Heapster組件實現(xiàn)對CPU利用率作為觸發(fā)條件傲霸,但是在k8s 1.11版本開始使用Metric Server完成數(shù)據(jù)采集,然后將采集到的數(shù)據(jù)通過API(Aggregated API眉反,匯總API)昙啄,例如metrics.k8s.io、custom.Metrics.k8s.io寸五、external.metric.k8s.io梳凛,然后再把數(shù)據(jù)提供給HPA控制器進行查詢,實現(xiàn)基于某個資源利用率對pod進行擴縮容的目的梳杏。
控制管理器默認每隔15s(可以通過 horizontal-pod-autoscaler-sync-period修改)
kube-controller-manager --help | grep horizontal-pod-autoscaler-sync-period 進行查看
HPA控制器訪問metrics-server查到的韧拒;kubelet將pod的資源利用率數(shù)據(jù)收集后,匯報給api-server十性,api-server將數(shù)據(jù)寫入etcd中叛溢,然后metrics-server通過api-server拿到數(shù)據(jù)
1.2.2 計算公式
從最基本的角度來看,Pod 水平自動擴縮控制器根據(jù)當前指標和期望指標來計算擴縮比例劲适。
期望副本數(shù) = ceil[當前副本數(shù) * (當前指標/期望指標)]
例如楷掉,當前度量值為
200m
,目標設定值為100m
霞势,那么由于200.0/100.0 == 2.0
烹植, 副本數(shù)量將會翻倍斑鸦。 如果當前指標為50m
,副本數(shù)量將會減半草雕,因為50.0/100.0 == 0.5
鄙才。 如果計算出的擴縮比例接近 1.0 (根據(jù)--horizontal-pod-autoscaler-tolerance
參數(shù)全局配置的容忍值,默認為 0.1)促绵, 將會放棄本次擴縮攒庵。
1.2.3 伸縮命令
- 命令行
kubectl autoscale rc foo --max=5 --cpu-percent=80
- yaml
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
namespace: linux
name: tomcat-app1-podautoscaler
labels:
app: tomcat-app1
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: tomcat-app1-deployment
minReplicas: 2
maxReplicas: 5
targetCPUUtilizationPercentage: 50
1.2.4 部署hpa
- 通過yaml部署
kubectl apply -f hpa.yaml
首次啟動,默認是等5分鐘败晴,開始伸縮浓冒;可以設置冷卻期,防止pod剛擴縮容后尖坤,又馬上恢復
二稳懒、CI/CD
2.1 CI
CI(Continuous Integration)持續(xù)集成
2.1.1 gitlab簡介
GitLab是一個用于倉庫管理系統(tǒng)的開源項目,使用Git作為代碼管理工具慢味,并在此基礎上搭建起來的web服務
GitLab和GitHub一樣屬于第三方基于Git開發(fā)的產(chǎn)品场梆,免費且開源(基于MIT協(xié)議),與GitHub類似纯路,可以注冊用戶或油,任意提交你的代碼,添加SSHKey等驰唬;不同的是顶岸,GitLab是可以部署到自己的服務器上,數(shù)據(jù)庫等一切信息都掌握在自己手上叫编,適合團隊內(nèi)部寫作開發(fā)
簡單來說可以把GitLab看作個人版的GitHub
2.1.2 安裝gitlab
- 安裝相關依賴
yum install -y policycoreutils openssh-server opssh-clients postfix
- 關閉防火墻并設置開機不啟動
systemctl disable firewalld
systemctl stop firewalld
- 啟動ssh服務并設置為開機自啟動
systemctl enable sshd
systemctl start sshd
- 啟動postfix服務并設置為開機自動
systemctl enable postfix
systemctl start postfix
- 下載gitlab包辖佣,并安裝
wget https://mirrors.tuna.tsinghua.edu.cn/gitlab-ce/yum/el7/gitlab-ce-12.4.2-ce.0.el7.x86_64.rpm
rpm -ivh gitlab-ce-12.4.2-ce.0.el7.x86_64.rpm
- 修改gitlab配置
vim /etc/gitlab/gitlab.rb
修改gitlab訪問地址和端口,默認為80
external_url 'http://IP:PORT'
nginx['listen_port'] = PORT
- 重載配置及啟動gitlab
gitlab-ctl reconfigure
gitlab-ctl restart
2.1.3 組搓逾、項目和用戶
- 創(chuàng)建組
使用管理員root創(chuàng)建組卷谈,一個組里面可以有多個項目分支,可以將開發(fā)添加到組里面進行權限設置霞篡,不通的組就是公司里不通的開發(fā)項目或者服務模塊世蔗,不通的組添加不通的角色即可實現(xiàn)對開發(fā)成員權限的管理
私有組,只有組里的用戶才可以訪問寇损;公開的組所有人都可以訪問凸郑;通常設置為私有
- 創(chuàng)建項目
在上步創(chuàng)建的組中創(chuàng)建項目裳食,圖中標紅方框位置矛市,選擇剛才創(chuàng)建的組,創(chuàng)建私有項目
- 創(chuàng)建用戶
點擊導航欄扳手圖標(Admin Area)诲祸,點擊Users
點擊New user
密碼會在用戶第一次登陸時重置
項目限制浊吏,默認是十萬個而昨,可以自己修改;訪問級別默認是Regular找田,可以訪問歸屬組和項目歌憨,Admin可以訪問所有組、項目和用戶
創(chuàng)建用戶后點擊Edit設置用戶密碼
- 添加用戶到組
點擊導航欄Groups墩衙,Explore groups
點擊進去要管理的項目务嫡,點擊Members
選擇用戶和相應的權限添加到組
GitLab用戶在組里面有五種不同權限:
Guest:可以創(chuàng)建issue、發(fā)表評論漆改、不能讀寫版本庫
Reporter:可以克隆代碼心铃,不能提交;QA挫剑、PM可以賦予這個權限
Developer:可以克隆代碼去扣、開發(fā)、提交樊破、push愉棱;普通開發(fā)可以賦予這個權限
Maintainer:可以創(chuàng)建項目、添加tag哲戚、保護分支奔滑、添加項目成員、編輯項目顺少;核心開發(fā)可以賦予這個權限
Owner:可以設置訪問權限(Visibility Level)档押、刪除項目、遷移項目祈纯、管理組成員令宿;開發(fā)組組長可以賦予這個權限
2.2 CD
CD(Continuous Delivery)持續(xù)交付
2.2.1 jenkins簡介
Jenkins是一個開源軟件項目,是基于java開發(fā)的一種持續(xù)集成工具腕窥,用于監(jiān)控持續(xù)重復的工作粒没,旨在提供一個開發(fā)易用的軟件平臺,是軟件項目可以進行持續(xù)集成簇爆。
功能包括:
持續(xù)的軟件版本發(fā)布/測試項目
監(jiān)控外部調(diào)用執(zhí)行的工作
2.2.2 安裝jenkins
- 安裝jdk依賴
yum install -y java-1.8.0-openjdk*
安裝后目錄為/usr/lib/jvm
- 關閉防火墻并設置開機不啟動
systemctl disable firewalld
systemctl stop firewalld
- 安裝jenkins
wget https://mirrors.tuna.tsinghua.edu.cn/jenkins/redhat/jenkins-2.300-1.1.noarch.rpm
rmp -ivh jenkins-2.300-1.1.noarch.rpm
- 修改jenkins配置
vim /etc/sysconfig/jenkins
JENKINS_USER="root"
默認是jenkins用戶癞松,需要創(chuàng)建一個jenkins用戶,用root也可以
JENKINS_PORT="PORT"
- 啟動jenkins并設置為開機自啟動
systemctl start jenkins
systemctl enable jenkins
2.2.3 創(chuàng)建憑證
創(chuàng)建向gitlab拉取代碼時的憑證
可以選擇用戶名密碼入蛆,就是gitlab的用戶名密碼响蓉,需要用戶有對項目管理的權限,填寫的描述是在選擇認證方式時的提示
2.2.4 創(chuàng)建任務
- 點擊新建任務哨毁,創(chuàng)建一個任務
新建任務一般是自由風格(freestyle)枫甲、maven、流水線(pipeline)較多,每種類型的構建其實都可以完成一樣的構建過程與結果想幻,只是在操作方式粱栖、靈活度等方面有所區(qū)別,在實際開發(fā)中可以根據(jù)自己的需求和習慣來選擇(流水線類型靈活度較高)
點擊新創(chuàng)建的項目
點擊配置脏毯,源碼管理選擇Git
填寫git代碼url闹究,選擇相應認證方式;http選擇用戶名密碼認證食店,ssh選擇密鑰認證渣淤;選擇分支
選擇構建方式
點擊立即構建
點擊控制臺輸出,查看構建日志
2.2.5 免密登陸
- 在任意一臺服務器生成密鑰對
ssh-keygen -t rsa
在/root/.ssh目錄下吉嫩,找到公私鑰對砂代,.pub結尾的是公鑰
- 在gitlab配置公鑰
點擊SSH Keys,填寫公鑰率挣,點擊Add key
- 在jenkins添加私鑰
在添加憑據(jù)的位置刻伊,類型選擇SSH Username with private key,填寫的描述是選擇憑據(jù)時的提示椒功,用戶名是生成公私鑰的用戶捶箱,點擊Add,將私鑰粘貼進去
2.2.6 配置mvn
- 在系統(tǒng)配置动漾,全局配置中配置環(huán)境變量
添加這幾個環(huán)境變量丁屎;注意添加主機PATH環(huán)境變量,不然在編譯的時候會報錯不能執(zhí)行命令旱眯;"PATH+EXTRA"是固定名字
2.2.7 pipeline
pipeline是一套運行在jenkins上的工作流框架晨川,將原來獨立運行與單個或者多個節(jié)點的任務連接起來,實現(xiàn)單個任務難以完成的復雜流程編排和可視化的工作
pipeline優(yōu)點:
代碼:pipeline以代碼的形式實現(xiàn)删豺,通常被檢入源代碼控制共虑,使團隊能夠編輯,審查和迭代其傳送流程
持久:無論是計劃內(nèi)的還是計劃外的服務器重啟呀页,pipeline都是可恢復的
可停止:pipeline可接收交互式輸入妈拌,以確定是否繼續(xù)執(zhí)行pipeline
多功能:pipeline支持實現(xiàn)世界中復雜的持續(xù)交付要求,支持fork/join蓬蝶、循環(huán)執(zhí)行尘分,并行執(zhí)行任務的功能
可擴展:pipeline插件支持其DSL的自定義擴展,以及與其他插件集成的多個選項
特點:
pipeline腳本是由Groovy語言實現(xiàn)的丸氛,支持兩種語法培愁,Declaration(聲明式)和Scripted Pipeline(腳本式)語法
pipeline有兩種創(chuàng)建方法:可在jenkins的Web UI界面中輸入腳本,也可以通過一個jenkinsfile腳本文件放入項目源碼庫中(推薦在jenkins中直接從源代碼控制(SCM)中直接載入jenkinsfile pipeline的方法)
2.3 鏡像升級與回滾
2.3.1 deployment控制器
deployment控制器支持兩種更新策略缓窜,默認為滾動更新
- 滾動更新
滾動更新(rollingUpdate)是默認的更新策略定续,基于新版本鏡像創(chuàng)建新版本pod谍咆,然后刪除一部分舊版本pod,然后再創(chuàng)建新版本pod香罐,再刪除一部分舊版本pod卧波,知道舊版本pod刪除完成时肿;滾動更新優(yōu)勢在于升級過程中不會導致服務不可用庇茫,缺點是升級過程中會導致兩個版本在短時間內(nèi)并存
升級過程是在執(zhí)行更新操作后k8s會再創(chuàng)建一個新版本的ReplicaSet控制器,在刪除舊版本的ReplicaSet控制器下的pod時螃成,也會在新版本的ReplicaSet控制器下創(chuàng)建新的pod旦签,知道舊版本的pod更新完,再把舊版本的ReplicaSet控制器也回收
在執(zhí)行滾動更新的同時寸宏,為了保證服務的可用性(pod拉取鏡像進行創(chuàng)建并且執(zhí)行探針探測期間是不可用的)宁炫,當前控制器內(nèi)不可用的pod不能超出一定范圍,需要保留一定數(shù)量的pod以保證服務可以被客戶端正常訪問
pod可用比例可以通過命令設置
kubectl explain deployment.spec.strategy
deployment.spec.strategy.rollingUpdate.maxSurge:指定在升級期間pod總數(shù)可以超出期望的pod數(shù)量或者百分比氮凝,默認為25%羔巢,如果設置10%,就是當前有100個pod罩阵,那么升級時最多可以共存110個pod竿秆,也就是額外有10%的pod臨時超出ReplicaSet指定的副本數(shù)
deployment.spec.strategy.rollingUpdate.maxUnavailable:指定在升級期間最大不可用的pod數(shù)量,可以是數(shù)值或者百分比稿壁,默認是25%幽钢,就是當前有100個pod,那么升級時最多可以有25個(25%)pod不可用傅是,即還有75個(75%)pod是可用的
注意:以上兩個值不能同時為0匪燕,如果maxUnavailable最大不可用pod為0,maxSurage超出pod數(shù)也為0喧笔,那么將會導致pod無法進行滾動更新
- 重建更新
重建(recreate)更新是先刪除現(xiàn)有的pod帽驯,然后基于新版本的鏡像重建,優(yōu)勢是同時只有一個版本提供服務书闸,不會產(chǎn)生多版本在線問題界拦,缺點是pod刪除后到pod重建成功之間的時間,服務無法訪問梗劫,因此使用較少
- 版本升級
更新鏡像
kubectl -n NAMESPACE set image deployment/DEPLOYMENT CONTAINER_NAME=IMAGE:VERSION --record=true
--record=true可以記錄變更命令享甸,在查看歷史信息命令的CHANGE-CAUSE里顯示
查看歷史信息
kubectl -n NAMESPACE rollout history deployment DEPLOYMENT
rollout有效資源種類包括:deployments、daemonsets梳侨、statefulsets
回滾版本
kubectl -n NAMESPACE rollout undo deployment DEPLOYMENT
回滾到上一個版本蛉威;再次執(zhí)行命令的時候,是回滾到當前版本
比如deployment現(xiàn)在三個版本走哺,nging的1.19蚯嫌、1.20、1.21;當前版本是nginx:1.21择示,上一個版本是nginx:1.20束凑,執(zhí)行回滾命令會回滾到nginx:1.20,現(xiàn)在對于更新后的版本來說栅盲,nginx:1.20是當前版本汪诉,上一個版本是nginx:1.21,所以再次執(zhí)行回滾命令是回滾到nginx:1.21谈秫,而不會回滾到nginx:1.19
每次執(zhí)行回滾命令扒寄,當前版本號為現(xiàn)有最大版本號(REVISION)加一,也就是最新版本號
回滾到指定版本
kubectl -n NAMESPACE rollout undo deployment DEPLOYMENT --to-revision=1
回滾到版本號為1的版本拟烫,現(xiàn)有最新版本號加1该编,成為最新的版本(回滾指定的歷史版本號會消失,變成最新版本號)
2.3.2 自動化
gitlab硕淑,jenkins课竣,和set images命令,可以實現(xiàn)業(yè)務的自動化更新功能(結合shell腳本)置媳,如果需要業(yè)務回滾于樟,可以使用rollout undo命令
三、親和與污點
3.1 pod創(chuàng)建流程
- 用戶通過kubectl命令行或者dashboard創(chuàng)建pod請求半开,發(fā)給kube-apiserver隔披,kube-apiserver負責鑒權和準入,然后把請求寫入etcd
- 一直監(jiān)聽kube-apiserver的kube-scheduler按照策略進行調(diào)度(nodeSelector寂拆、nodeAffinity等)奢米,如果沒有聲明策略,會執(zhí)行默認策略
- kube-scheduler給pod選定node纠永,第一步先過濾掉不符合條件的node(例如node資源不足鬓长,不符合pod需求),第二步在可用的多個節(jié)點之間進行打分尝江,選擇其中得分最高的節(jié)點進行綁定
- kube-scheduler將綁定關系返回給kube-apiserver涉波,由kube-apiserver再把數(shù)據(jù)寫入etcd
- node節(jié)點上一直監(jiān)聽kube-apiserver的kubelet,如果發(fā)現(xiàn)有本機需要創(chuàng)建pod的事件炭序,kubelet會將事件獲取過來啤覆,然后在本機調(diào)用容器運行時,創(chuàng)建pod
3.2 nodeSelector
基于標簽選擇器惭聂,將pod調(diào)度到目的節(jié)點上
- 打標簽
kubectl label node NODE_IP KEY=VALUE
- 刪除標簽
kubectl label node NODE_IP KEY-
刪除標簽是key后邊加上減號
- depolyment的yaml文件中聲明nodeSelector選擇器
nodeSelector:
KEY: VALUE
層級:deployment.spec.template.spec.nodeSelector
如果有多個標簽時窗声,必須同時滿足,不然pod調(diào)度不成功
3.3 nodeName
選定node名字創(chuàng)建pod
- depolyment的yaml文件中聲明nodeName選擇器
spec:
nodeName: 192.168.204.102
層級:deploy.spec.template.spec.nodeName
使用較少
3.4 nodeaAffinity
3.4.1 nodeaAffinity簡介
affinity是kubernetes 1.2版本后引入的新特性辜纲,類似于nodeSelector笨觅,允許使用者指定一些pod在Node間調(diào)度的約束拦耐,目前支持兩種形式:
- requiredDuringSchedulingIgnoredDuringExecution
必須滿足pod調(diào)度匹配條件,如果不滿足則不進行調(diào)度
- preferredDuringSchedulingIgnoredDuringExecution
傾向滿足pod調(diào)度匹配條件见剩,不滿足的情況下會調(diào)度到不符合條件的node上
IgnoredDuringExecution表示如果在pod運行期間node的標簽發(fā)生變化杀糯,導致親和性策略不能滿足,也會繼續(xù)運行當前pod
- 操作符支持And苍苞、In固翰、NotIn、Exists柒啤、DoesNotExist傻谁、Gt钳榨、Lt
- 可以設置軟匹配和硬匹配,在軟匹配下换棚,如果調(diào)度器無法匹配節(jié)點没炒,仍然將pod調(diào)度調(diào)度到其他不符合條件的節(jié)點
- 可以對pod定義親和性策略涛癌,例如,允許一些pod可以或者不可以調(diào)度到同一臺node
In:標簽的值存在匹配列表中(匹配成功就調(diào)度到目的node送火,實現(xiàn)node親和)
NotIn:標簽的值不存在指定的匹配列表中(不會調(diào)度到目的node拳话,實現(xiàn)反親和)
Gt:標簽的值大于某個值(字符串)
Lt:標簽的值小于某個值(字符串)
Exists:指定的標簽存在
注:如果定義一個nodeSelectorTerms(條件)中通過一個matchExpressions(匹配表達式)基于列表指定了多個條件,則只要滿足其中一個條件种吸,就會被調(diào)度到相應的節(jié)點上弃衍。
如果定義一個nodeSelectorTerms中都通過一個matchExpressions(匹配表達式)指定key匹配多個條件,則所有的條件都必須滿足才會調(diào)度到相應節(jié)點坚俗,即and關系镜盯。
3.4.2 親和性硬策略
requiredDuringSchedulingIgnoredDuringExecution即硬策略
- depolyment的yaml文件中聲明Affinity選擇器硬策略,多個matchExpressions
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions: #匹配條件1,多個values可以調(diào)度
- key: KEY1
operator: In
values:
- VALUE1 # 只有一個value匹配成功也可以調(diào)度
- VALUE2
- matchExpressions: #匹配條件2,多個matchExpressions猖败,任意一個matchExpressions的values中有一個value匹配成功就可以調(diào)度
- key: KEY2
operator: In
values:
- VALUE3 #即使這兩個條件都匹配不上也可以調(diào)度
- VALUE4
層級:deployment.spec.template.spec.affinity
多個matchExpressions速缆,任意一個標簽的任意一個值匹配成功就可以
- depolyment的yaml文件中聲明Affinity選擇器硬策略,多個key
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions: #匹配條件1
- key: KEY1
operator: In
values:
- VALUE1
- VALUE2 #同個key的多個value只有有一個匹配成功就行
- key: KEY2 #條件1和條件2必須同時滿足,否則不調(diào)度
operator: In
values:
- VALUE3
層級:deployment.spec.template.spec.affinity
多個key恩闻,都滿足條件才可以
如果調(diào)度失敗會報錯:
Warning FailedScheduling 45s default-scheduler 0/3 nodes are available: 3 node(s) didn't match Pod's node affinity/selector
3.4.3 親和性軟策略
preferredDuringSchedulingIgnoredDuringExecution即軟策略
- depolyment的yaml文件中聲明Affinity選擇器軟策略
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 80
preference:
matchExpressions:
- key: KEY1
operator: In
values:
- VALUE1
- weight: 60
preference:
matchExpressions:
- key: KEY2
operator: In
values:
- VALUE2
層級:deployment.spec.template.spec.affinity
軟策略中可以設置weight(權重)艺糜,優(yōu)先匹配權重高的key
軟策略即使所有的key匹配都不成功,也會可以成功調(diào)度到node上
3.4.4 親和性結合使用
硬策略和軟策略結合使用
- depolyment的yaml文件中聲明Affinity選擇器硬策略和軟策略結合使用
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution: #硬限制
nodeSelectorTerms:
- matchExpressions: #硬匹配條件1
- key: "kubernetes.io/role"
operator: NotIn
values:
- "master" #硬性匹配key 的值kubernetes.io/role不包含master的節(jié)點,即絕對不會調(diào)度到master節(jié)點(node反親和)
preferredDuringSchedulingIgnoredDuringExecution: #軟限制
- weight: 80
preference:
matchExpressions:
- key: project
operator: In
values:
- magedu
- weight: 100
preference:
matchExpressions:
- key: disktype
operator: In
values:
- ssd
層級:deployment.spec.template.spec.affinity
首先匹配硬策略幢尚,然后根據(jù)權重匹配軟策略
3.4.5 反親和性
operator為NotIn破停,即為反親和性
- depolyment的yaml文件中聲明Affinity選擇器反親和性
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions: #匹配條件1
- key: disktype
operator: NotIn
values:
- hdd #絕對不會調(diào)度到hdd的節(jié)點
層級:deployment.spec.template.spec.affinity
不會調(diào)度到NotIn聲明的鍵值對的node上
3.5 podAffinity
3.5.1 podAffinity簡介
pod親和性與反親和性可以基于已經(jīng)在節(jié)點上運行的pod標簽,約束新創(chuàng)建的pod調(diào)度的目的節(jié)點尉剩,注意不是node標簽真慢,是pod的標簽;pod親和性與反親和性可以通過LabelSelector選擇namespace边涕,是應為pod是命名空間限定的晤碘,而node不屬于任何namespace
目前支持兩種形式:
- requiredDuringSchedulingIgnoredDuringExecution
硬策略
- preferredDuringSchedulingIgnoredDuringExecution
軟策略
Pod親和性與反親和性操作符:In褂微、NotIn、Exists园爷、DoesNotExists
對于pod親和性和反親和性而言宠蚂,硬策略和軟策略中的topoloygKey不允許為空
對于硬策略要求的pod反親和性,準入控制器LimitPodHardAntiAffinityTopology被引入以確保topologyKey只能是kubernetes.io/hostname童社;如果希望topologyKey可以用于其他定制拓撲邏輯求厕,可以更改準入控制器或者禁用。
3.5.2 親和性軟策略
- depolyment的yaml文件中聲明Affinity選擇器軟策略pod親和性
affinity:
podAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: KEY
operator: In
values:
- VALUE
topologyKey: kubernetes.io/hostname
namespaces:
- linux
層級:deployment.spec.template.spec.affinity
匹配鍵為KEY扰楼,值為VALUE的pod標簽呀癣,優(yōu)先調(diào)度到匹配成功的pod所在的節(jié)點上
3.5.3 親和性硬策略
- depolyment的yaml文件中聲明Affinity選擇器硬策略pod親和性
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: KEY
operator: In
values:
- VALUE
topologyKey: "kubernetes.io/hostname"
namespaces:
- linux
層級:deployment.spec.template.spec.affinity
匹配鍵為KEY,值為VALUE的pod標簽弦赖,必須調(diào)度到匹配成功的pod所在的節(jié)點上
3.5.4 反親和硬策略
- depolyment的yaml文件中聲明Affinity選擇器硬策略pod反親和性
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: KEY
operator: In
values:
- VALUE
topologyKey: "kubernetes.io/hostname"
namespaces:
- linux
層級:deployment.spec.template.spec.affinity
關鍵字為podAntiAffinity项栏,node親和沒有這個選項
鍵為KEY,值為VALUE的pod標簽蹬竖,不會調(diào)度到匹配成功的pod所在的節(jié)點上
3.5.5 反親和軟策略
- depolyment的yaml文件中聲明Affinity選擇器軟策略pod反親和性
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: LINUX
operator: In
values:
- VALUE
topologyKey: kubernetes.io/hostname
namespaces:
- linux
層級:deployment.spec.template.spec.affinity
鍵為KEY沼沈,值為VALUE的pod標簽,優(yōu)先不調(diào)度到匹配成功的pod所在的節(jié)點上
3.6 Taints和Tolerations
3.6.1 taints簡介
- 污點(taints)用于node節(jié)點排斥pod調(diào)度币厕,與親和和作用是完全相反的列另,即taint的node和pod是排斥調(diào)度關系
- 容忍(toleration)用于pod容忍node節(jié)點的污點信息,即node有污點信息也會將新的pod調(diào)度到該node
https://kubernetes.io/zh/docs/concepts/scheduling-eviction/taint-and-toleration/
3.6.2 污點設置與取消
- 給nodes設置污點
kubectl taint node NODE_IP key1=value1:NoSchedule
污點類型:
NoSchedule:表示k8s不會把pod調(diào)度到具有污點的node上
PreferNoSchedule:表示k8s優(yōu)先不調(diào)度到具有污點的node上
NoExecute:表示k8s不會把pod調(diào)度到具有污點的node上旦装,同時會把node上已經(jīng)存在的pod強制驅逐出去
- 取消污點
kubectl taint node NODE_IP key1:NoSchedule-
3.6.3 tolerations簡介
- tolerations(容忍)定義pod的容忍度页衙,可以調(diào)度至含有污點的node。
- 容忍基于operator的匹配污點
operator有兩種
Exists:容忍度不需要value二十直接匹配污點類型
Equal:需要指定value并且value值等于tolerations的key
3.6.4 容忍設置
- 設置容忍
tolerations:
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoSchedule"
層級:deployment.spec.template.spec.tolerations
匹配key阴绢、value店乐、effect的值,匹配成功旱函,可以容忍污點(優(yōu)先調(diào)度到?jīng)]有污點的節(jié)點)
3.6 驅逐
3.6.1 驅逐簡介
驅逐(eviction响巢,節(jié)點驅逐),用于當node節(jié)點資源不足的時候自動將pod進行強制驅逐棒妨,以保證當期node節(jié)點的正常運行踪古。k8s基于QoS(服務質量等級)驅逐pod,QoS等級包括:
- Guaranteed:limits和requests相等(最后驅逐)
- Burstable:limits高于requests(次之)
- BestEffort:沒有限制券腔,即resources為空(最先驅逐)
當宿主機資源不足時伏穆,pod還在向宿主機申請資源,宿主機內(nèi)核為了保證正常運行纷纫,會把占用資源較多的進程殺掉枕扫,以保證主機能正常運行,殺掉進程之后辱魁,就會觸發(fā)驅逐(pod狀態(tài)eviction)烟瞧,pod掛了之后诗鸭,kube-controller-manager會在別的主機重建
kubelet有默認值,即使沒配置参滴,也會驅逐强岸;如果resources配置不合理,pod有可能會被反復驅逐
- kube-controller-manager實現(xiàn)eviction:node宕機后驅逐
- kubelet實現(xiàn)eviction:基于node負載砾赔、資源利用率等
3.6.2 驅逐條件
- 軟驅逐
軟驅逐不會立即驅逐pod蝌箍,可以自定義寬限期,在條件持續(xù)到寬限期限還沒有恢復暴心,kubelet再強制殺死pod并觸發(fā)驅逐
eviction-signal:kubelet捕獲node節(jié)點信號妓盲,進行判斷是否驅逐,比如通過cgoupfs獲取memory.available的值
operator:基于預算符比對條件是否匹配資源使用情況
quantity:獲取node節(jié)點資源使用率進行驅逐专普,可以使用百分比或者單位指定悯衬,如內(nèi)存1Gi等
eviction-soft:軟驅逐條件,如memory.available<1.5Gi脆诉,如果驅逐條件持續(xù)時長超過指定的寬限期甚亭,會觸發(fā)pod驅逐
eviction-soft-grace-period:驅逐寬限期贷币,如memory.available=1m30s击胜,定義軟驅逐條件在觸發(fā)pod驅逐之前時長
eviction-max-pod-grace-period:在滿足軟驅逐條件而終止pod時的最大允許寬限期(以秒為單位)
- 硬驅逐
硬驅逐條件沒有寬限期,當達到硬驅逐條件時役纹,kubelet會強制立即殺死pod并驅逐
kubelet具有以下默認硬驅逐條件(可以自行跳轉):
imagefs.available<15%
memory.available<100Mi
nodefs.available<10%
nodefs.inodesFree<5%查看kubelet配置中硬驅逐配置:
cat /etc/systemd/system/kubelet.service cat /var/lib/kubelet/config.yaml
配置如下:
eventBurst: 10
eventRecordQPS: 5
evictionHard:
imagefs.available: 15%
memory.available: 300Mi
nodefs.available: 10%
nodefs.inodesFree: 5%(宿主機節(jié)點)
四偶摔、Prometheus
4.1 監(jiān)控簡介
監(jiān)控的重要性:通過業(yè)務監(jiān)控系統(tǒng),全面掌握業(yè)務環(huán)境的運行狀態(tài)促脉,通過白盒監(jiān)控能夠提前預知業(yè)務瓶頸辰斋,通過黑盒監(jiān)控能夠第一時間發(fā)現(xiàn)業(yè)務故障并通過告警通告運維人員進行緊急恢復,從而將業(yè)務影響降到最低瘸味。
黑盒監(jiān)控:關注實時的狀態(tài)宫仗,一般都是正在發(fā)生的事件,比如nginx web界面打開報錯503等旁仿,即黑盒監(jiān)控重點在于能對正在發(fā)生的故障進行通知告警
白盒監(jiān)控:關注的是原因藕夫,也就是系統(tǒng)內(nèi)部暴露的一些指標數(shù)據(jù),比如nginx后端服務器響應時間長等
監(jiān)控系統(tǒng)需要能夠有效的支持白盒監(jiān)控和黑盒監(jiān)控枯冈,通過白盒監(jiān)控能夠了解內(nèi)部的運行狀態(tài)毅贮,以及對監(jiān)控指標的觀察,能夠預判可能出現(xiàn)的潛在問題尘奏,從而對潛在的不確定因素進行提前優(yōu)化并避免問題的發(fā)生滩褥;通過黑盒監(jiān)控(如HTTP探針、TCP探針)可以在系統(tǒng)或服務發(fā)生故障時快速通知相關人員進行處理
通過完善的監(jiān)控體系炫加,達到以下目的:
長期趨勢分析:通過對監(jiān)控樣本數(shù)據(jù)的持續(xù)收集和統(tǒng)計瑰煎,對監(jiān)控指標進行長期趨勢分析铺然。例如,通過對磁盤空間增長率的判斷酒甸,我們可以提前預測在未來什么時間點需要對資源進行擴容
對照分析:兩個版本的系統(tǒng)運行資源使用情況的差異性探熔,在不同容量情況下系統(tǒng)的并發(fā)和負載對比
告警:當系統(tǒng)出現(xiàn)或者即將出現(xiàn)故障時,監(jiān)控系統(tǒng)迅速通知管理員烘挫,從而針對告警內(nèi)容進行快速的處理
故障分析與定位:當問題發(fā)生后诀艰,需要對問題進行調(diào)查和處理;通過對監(jiān)控和歷史數(shù)據(jù)的分析饮六,找到并解決根源問題
數(shù)據(jù)可視化:通過可視化儀表盤能夠直接獲取系統(tǒng)的運行狀態(tài)其垄、資源使用情況、以及服務運行狀態(tài)等直觀的信息
4.2 常用監(jiān)控軟件
開源軟件監(jiān)控:cacti卤橄、nagios绿满、zabbix、smokeping窟扑、open-falcon喇颁、nightingale、prometheus等
- Cacti
https://github.com/Cacti/cacti
cacti是基于LAMP平臺展現(xiàn)的網(wǎng)絡流量監(jiān)測及分析工具嚎货,通過SNMP技術或自定義腳本從目標設備橘霎、主機獲取監(jiān)控指標信息;其次進行數(shù)據(jù)存儲殖属,調(diào)用模板將數(shù)據(jù)存到數(shù)據(jù)庫姐叁,使用rrdtool存儲和更新數(shù)據(jù),通過rrdtool繪制結果圖形洗显;最后進行數(shù)據(jù)展現(xiàn)外潜,通過web方式將監(jiān)控結果呈現(xiàn)出來,常用于在數(shù)據(jù)中心監(jiān)控網(wǎng)絡設備挠唆。
- Nagios
Nagios是用來監(jiān)視系統(tǒng)和網(wǎng)絡的開源應用軟件处窥,利用其眾多的插件實現(xiàn)對本機和遠端服務的監(jiān)控,當被監(jiān)控對象發(fā)生異常時玄组,會及時向管理員告警滔驾,提供一批預設好的監(jiān)控插件,用戶可以調(diào)用巧勤,也可以自定義shell腳本來監(jiān)控服務嵌灰,適合各企業(yè)的業(yè)務監(jiān)控,可通過web頁面顯示監(jiān)控對象狀態(tài)颅悉、日志沽瞭、告警信息,分層告警機制及自定義監(jiān)控相對薄弱剩瓶。
- SmokePing
https://www.oetiker.ch/home/oss-2/projekte/smokeping/
Somkeping是一款用于網(wǎng)絡性能檢測的開源監(jiān)控軟件驹溃,主要用于對IDC的網(wǎng)絡狀況城丧、網(wǎng)絡質量、穩(wěn)定性等做檢測豌鹤,通過rrdtool制圖亡哄,展示網(wǎng)絡的時延情況。
- open-falcon
https://github.com/XiaoMi/open-falcon
小米公司開源的監(jiān)控軟件布疙,open-falcon(獵鷹)蚊惯,監(jiān)控能力和性能較強
- Nightingale
夜鶯( Nightingale )是一款經(jīng)過大規(guī)模生產(chǎn)環(huán)境驗證的、分布式高性能的運維監(jiān)控系統(tǒng)灵临,由滴滴基于open-falcon二次開發(fā)后開源出來的分布式監(jiān)控系統(tǒng)
- Zabbix
目前使用較多的開源監(jiān)控軟件截型,可橫向擴展,自定義監(jiān)控項儒溉,支持多種監(jiān)控方式宦焦,可監(jiān)控網(wǎng)絡與服務等
zabbix 6.0支持監(jiān)控kubernetes(centos系統(tǒng)只有8以上支持)
- prometheus
https://github.com/prometheus/prometheus
針對容器環(huán)境的開源監(jiān)控軟件
商業(yè)監(jiān)控解決方案
- 監(jiān)控寶
- 聽云
4.3 Prometheus簡介
prometheus是基于go語言開發(fā)的一套開源的監(jiān)控、報警和時間序列數(shù)據(jù)庫的組合顿涣,是有SoundCloud公司開發(fā)的開源監(jiān)控系統(tǒng)波闹,prometheus于2016年加入CNCF(Cloud Native Computing Foundation,云原生計算基金會)涛碑,于2018年8月9日成為繼kubernetes之后畢業(yè)的第二個項目精堕,prometheus在容器和微服務領域得到了廣泛的應用。
特點如下:
使用key-value的多維度(多個角度锌唾、層面)格式保存數(shù)據(jù)
使用時序數(shù)據(jù)庫
支持第三方Dashboard實現(xiàn)更好的圖形界面锄码,如grafana(grafana 2.5.0版本及以上)
組件模塊化
不需要依賴存儲,數(shù)據(jù)可以本地保存晌涕,也可以遠程保存
平均每個采樣點僅占3.5bytes,且一個Prometheus Server可以處理數(shù)百萬級別的metrics指標數(shù)據(jù)
支持服務自動化發(fā)現(xiàn)(基于consul等方式動態(tài)發(fā)現(xiàn)被監(jiān)控的目標服務)
強大的數(shù)據(jù)查詢語句(PoemQL痛悯,Prometheus Query Language)
數(shù)據(jù)可以直接進行算術運算
易于橫向伸縮
眾多官方和第三方的exporter實現(xiàn)不通的指標數(shù)據(jù)收集
容器監(jiān)控的實現(xiàn)方式對比虛擬機或物理機來說余黎,有較大的區(qū)別,比如容器在k8s環(huán)境中可以任意橫向擴容與縮容载萌,那么就需要監(jiān)控服務能夠自動對新創(chuàng)建的容器進行監(jiān)控惧财,當容器刪除后,有能夠及時的從監(jiān)控服務總刪除扭仁,而傳統(tǒng)的zabbix的監(jiān)控方式需要在每個容器中安裝啟動agent垮衷,并且在容器自動發(fā)現(xiàn)注冊及模板關聯(lián)方面并沒有比較好的實現(xiàn)方式。
Prometheus包含以下組件:
prometheus server:主服務乖坠,接受外部http請求搀突,收集、存儲與查詢數(shù)據(jù)等
prometheus targets:靜態(tài)收集的目標服務數(shù)據(jù)
service discovery:動態(tài)發(fā)現(xiàn)服務
prometheus alerting:報警通知
push gateway:數(shù)據(jù)收集代理服務器(類似于zabbix proxy)
data visualization and exporter:數(shù)據(jù)可視化與數(shù)據(jù)導出(訪問客戶端)
4.4 安裝
4.4.1 docker安裝
docker run -p 9090:9090 prom/prometheus
官方示例需要指定配置文件掛載路徑熊泵,也可以不掛載仰迁,直接跑起來
4.4.2 operator安裝
github上對比k8s版本甸昏,找到合適的版本,這里以k8s v1.22.2為例徐许,operator版本為0.9
git clone -b release-0.9 https://github.com/prometheus-operator/kube-prometheus.git
- 首先到kube-prometheus/manifests/setup目錄下執(zhí)行
kubectl apply -f .
- 然后后退一層目錄施蜜,到kube-prometheus/manifests目錄下執(zhí)行
kubectl apply -f .
下載后需要修改k8s.gcr.io/kube-state-metrics/kube-state-metrics:v2.1.1和k8s.gcr.io/prometheus-adapter/prometheus-adapter:v0.9.0的鏡像,這google官方的倉庫雌隅,訪問不了翻默,可以去docker官方鏡像倉庫找到替換下
- 修改prometheus-service.yaml文件,端口類型改成NodePort類型恰起,重新執(zhí)行
kubectl apply -f prometheus-service.yaml
- 修改grafana-service.yaml文件冰蘑,端口類型改成NodePort類型,重新執(zhí)行
kubectl apply -f grafana-service.yaml