Kubernetes是Google開(kāi)源的容?集群管理系統(tǒng),,是Google多年?規(guī)模容?管理技術(shù)Borg的開(kāi)源版本,,主要功能包括:- 基于容器的應(yīng)用部署、維護(hù)和滾動(dòng)升級(jí)
- 負(fù)載均衡和服務(wù)發(fā)現(xiàn)
- 跨機(jī)器和跨地區(qū)的集群調(diào)度
- 無(wú)狀態(tài)服務(wù)和有狀態(tài)服務(wù)
Kubernetes發(fā)展非常迅速,,已經(jīng)成為容器編排領(lǐng)域的領(lǐng)導(dǎo)者,,接下來(lái)我們將講解Kubernetes中涉及到的一些主要概念。
1,、PodPod是一組緊密關(guān)聯(lián)的容器集合,,支持多個(gè)容器在一個(gè)Pod中共享網(wǎng)絡(luò)和文件系統(tǒng),可以通過(guò)進(jìn)程間通信和文件共享這種簡(jiǎn)單高效的方式完成服務(wù),,是Kubernetes調(diào)度的基本單位,。Pod的設(shè)計(jì)理念是每個(gè)Pod都有一個(gè)唯一的IP,。- 包含多個(gè)共享IPC、Network和UTC namespace的容器,,可直接通過(guò)localhost通信
- 所有Pod內(nèi)容器都可以訪問(wèn)共享的Volume,,可以訪問(wèn)共享數(shù)據(jù)
- 優(yōu)雅終止:Pod刪除的時(shí)候先給其內(nèi)的進(jìn)程發(fā)送SIGTERM,等待一段時(shí)間(grace period)后才強(qiáng)制停止依然還在運(yùn)行的進(jìn)程
- 特權(quán)容器(通過(guò)SecurityContext配置)具有改變系統(tǒng)配置的權(quán)限(在網(wǎng)絡(luò)插件中大量應(yīng)用)
- 支持三種重啟策略(restartPolicy),,分別是:Always,、OnFailure、Never
- 支持三種鏡像拉取策略(imagePullPolicy),,分別是:Always,、Never、IfNotPresent
- 資源限制,,Kubernetes通過(guò)CGroup限制容器的CPU以及內(nèi)存等資源,,可以設(shè)置request以及l(fā)imit值
- 健康檢查,提供兩種健康檢查探針,,分別是livenessProbe和redinessProbe,,前者用于探測(cè)容器是否存活,如果探測(cè)失敗,,則根據(jù)重啟策略進(jìn)行重啟操作,,后者用于檢查容器狀態(tài)是否正常,如果檢查容器狀態(tài)不正常,,則請(qǐng)求不會(huì)到達(dá)該P(yáng)od
- Init container在所有容器運(yùn)行之前執(zhí)行,,常用來(lái)初始化配置
- 容器生命周期鉤子函數(shù),用于監(jiān)聽(tīng)容器生命周期的特定事件,,并在事件發(fā)生時(shí)執(zhí)行已注冊(cè)的回調(diào)函數(shù),,支持兩種鉤子函數(shù):postStart和preStop,前者是在容器啟動(dòng)后執(zhí)行,,后者是在容器停止前執(zhí)行
2、NamespaceNamespace(命名空間)是對(duì)一組資源和對(duì)象的抽象集合,,比如可以用來(lái)將系統(tǒng)內(nèi)部的對(duì)象劃分為不同的項(xiàng)目組或者用戶(hù)組,。常見(jiàn)的pod、service,、replicaSet和deployment等都是屬于某一個(gè)namespace的(默認(rèn)是default),,而node, persistentVolumes等則不屬于任何namespace。- kubectlgetnamespace, 查詢(xún)所有namespace
- kubectl createnamespacens-name,,創(chuàng)建namespace
- kubectldeletenamespacens-name, 刪除namespace
刪除命名空間時(shí),,需注意以下幾點(diǎn):- 刪除一個(gè)namespace會(huì)自動(dòng)刪除所有屬于該namespace的資源。
- default 和 kube-system 命名空間不可刪除,。
- PersistentVolumes是不屬于任何namespace的,,但PersistentVolumeClaim是屬于某個(gè)特定namespace的,。
- Events是否屬于namespace取決于產(chǎn)生events的對(duì)象。
3,、NodeNode是Pod真正運(yùn)行的主機(jī),,可以是物理機(jī)也可以是虛擬機(jī)。Node本質(zhì)上不是Kubernetes來(lái)創(chuàng)建的,, Kubernetes只是管理Node上的資源,。為了管理Pod,每個(gè)Node節(jié)點(diǎn)上至少需要運(yùn)行container runtime(Docker),、kubelet和kube-proxy服務(wù),。- kubectlgetnodes,查詢(xún)所有node
- kubectl cordon $nodename, 將node標(biāo)志為不可調(diào)度
- kubectl uncordon $nodename, 將node標(biāo)志為可調(diào)度
使用kubectl taint命令可以給某個(gè)Node節(jié)點(diǎn)設(shè)置污點(diǎn),,Node被設(shè)置上污點(diǎn)之后就和Pod之間存在了一種相斥的關(guān)系,,可以讓Node拒絕Pod的調(diào)度執(zhí)行,甚至將Node已經(jīng)存在的Pod驅(qū)逐出去,。每個(gè)污點(diǎn)的組成:key=value:effect,,當(dāng)前taint effect支持如下三個(gè)選項(xiàng):- NoSchedule:表示k8s將不會(huì)將Pod調(diào)度到具有該污點(diǎn)的Node上
- PreferNoSchedule:表示k8s將盡量避免將Pod調(diào)度到具有該污點(diǎn)的Node上
- NoExecute:表示k8s將不會(huì)將Pod調(diào)度到具有該污點(diǎn)的Node上,同時(shí)會(huì)將Node上已經(jīng)存在的Pod驅(qū)逐出去
- kubectl taint node node0 key1=value1:NoShedule,,為node0設(shè)置不可調(diào)度污點(diǎn)
- kubectl taint node node0 key-,,將node0上key值為key1的污點(diǎn)移除
- kubectl taint node node1 node-role.kubernetes.io/master=:NoSchedule,為kube-master節(jié)點(diǎn)設(shè)置不可調(diào)度污點(diǎn)
- kubectl taint node node1 node-role.kubernetes.io/master=PreferNoSchedule,,為kube-master節(jié)點(diǎn)設(shè)置盡量不可調(diào)度污點(diǎn)
設(shè)置了污點(diǎn)的Node將根據(jù)taint的effect:NoSchedule,、PreferNoSchedule、NoExecute和Pod之間產(chǎn)生互斥的關(guān)系,,Pod將在一定程度上不會(huì)被調(diào)度到Node上,。 但我們可以在Pod上設(shè)置容忍(Toleration),意思是設(shè)置了容忍的Pod將可以容忍污點(diǎn)的存在,,可以被調(diào)度到存在污點(diǎn)的Node上,。
4、ServiceService是對(duì)一組提供相同功能的Pods的抽象,,并為他們提供一個(gè)統(tǒng)一的入口,,借助 Service 應(yīng)用可以方便的實(shí)現(xiàn)服務(wù)發(fā)現(xiàn)與負(fù)載均衡,并實(shí)現(xiàn)應(yīng)用的零宕機(jī)升級(jí),。Service通過(guò)標(biāo)簽(label)來(lái)選取后端Pod,,一般配合ReplicaSet或者Deployment來(lái)保證后端容器的正常運(yùn)行。service 有如下四種類(lèi)型,,默認(rèn)是ClusterIP:- ClusterIP: 默認(rèn)類(lèi)型,,自動(dòng)分配一個(gè)僅集群內(nèi)部可以訪問(wèn)的虛擬IP
- NodePort: 在ClusterIP基礎(chǔ)上為Service在每臺(tái)機(jī)器上綁定一個(gè)端口,這樣就可以通過(guò) NodeIP:NodePort 來(lái)訪問(wèn)該服務(wù)
- LoadBalancer: 在NodePort的基礎(chǔ)上,,借助cloud provider創(chuàng)建一個(gè)外部的負(fù)載均衡器,,并將請(qǐng)求轉(zhuǎn)發(fā)到 NodeIP:NodePort
- ExternalName: 將服務(wù)通過(guò)DNS CNAME記錄方式轉(zhuǎn)發(fā)到指定的域名
另外,,也可以將已有的服務(wù)以Service的形式加入到Kubernetes集群中來(lái),只需要在創(chuàng)建 Service 的時(shí)候不指定Label selector,,而是在Service創(chuàng)建好后手動(dòng)為其添加endpoint,。
5、Volume 存儲(chǔ)卷默認(rèn)情況下容器的數(shù)據(jù)是非持久化的,,容器消亡以后數(shù)據(jù)也會(huì)跟著丟失,,所以Docker提供了Volume機(jī)制以便將數(shù)據(jù)持久化存儲(chǔ)。Kubernetes提供了更強(qiáng)大的Volume機(jī)制和插件,,解決了容器數(shù)據(jù)持久化以及容器間共享數(shù)據(jù)的問(wèn)題,。Kubernetes存儲(chǔ)卷的生命周期與Pod綁定- 容器掛掉后Kubelet再次重啟容器時(shí),Volume的數(shù)據(jù)依然還在
- Pod刪除時(shí),,Volume才會(huì)清理,。數(shù)據(jù)是否丟失取決于具體的Volume類(lèi)型,比如emptyDir的數(shù)據(jù)會(huì)丟失,,而PV的數(shù)據(jù)則不會(huì)丟
目前Kubernetes主要支持以下Volume類(lèi)型:- emptyDir:Pod存在,,emptyDir就會(huì)存在,容器掛掉不會(huì)引起emptyDir目錄下的數(shù)據(jù)丟失,,但是pod被刪除或者遷移,,emptyDir也會(huì)被刪除
- hostPath:hostPath允許掛載Node上的文件系統(tǒng)到Pod里面去
- NFS(Network File System):網(wǎng)絡(luò)文件系統(tǒng),Kubernetes中通過(guò)簡(jiǎn)單地配置就可以掛載NFS到Pod中,,而NFS中的數(shù)據(jù)是可以永久保存的,,同時(shí)NFS支持同時(shí)寫(xiě)操作。
- glusterfs:同NFS一樣是一種網(wǎng)絡(luò)文件系統(tǒng),,Kubernetes可以將glusterfs掛載到Pod中,,并進(jìn)行永久保存
- cephfs:一種分布式網(wǎng)絡(luò)文件系統(tǒng),可以掛載到Pod中,,并進(jìn)行永久保存
- subpath:Pod的多個(gè)容器使用同一個(gè)Volume時(shí),,會(huì)經(jīng)常用到
- secret:密鑰管理,可以將敏感信息進(jìn)行加密之后保存并掛載到Pod中
- persistentVolumeClaim:用于將持久化存儲(chǔ)(PersistentVolume)掛載到Pod中
6,、PersistentVolume(PV) 持久化存儲(chǔ)卷PersistentVolume(PV)是集群之中的一塊網(wǎng)絡(luò)存儲(chǔ),。跟 Node 一樣,,也是集群的資源,。PersistentVolume (PV)和PersistentVolumeClaim (PVC)提供了方便的持久化卷: PV提供網(wǎng)絡(luò)存儲(chǔ)資源,,而PVC請(qǐng)求存儲(chǔ)資源并將其掛載到Pod中,。PV的訪問(wèn)模式(accessModes)有三種:- ReadWriteOnce(RWO):是最基本的方式,,可讀可寫(xiě),但只支持被單個(gè)Pod掛載,。
- ReadOnlyMany(ROX):可以以只讀的方式被多個(gè)Pod掛載,。
- ReadWriteMany(RWX):這種存儲(chǔ)可以以讀寫(xiě)的方式被多個(gè)Pod共享,。
不是每一種存儲(chǔ)都支持這三種方式,像共享方式,,目前支持的還比較少,,比較常用的是 NFS。在PVC綁定PV時(shí)通常根據(jù)兩個(gè)條件來(lái)綁定,,一個(gè)是存儲(chǔ)的大小,,另一個(gè)就是 訪問(wèn)模式。PV的回收策略(persistentVolumeReclaimPolicy)也有三種- Retain,,不清理保留Volume(需要手動(dòng)清理)
- Recycle,,刪除數(shù)據(jù),即 rm -rf /thevolume/* (只有NFS和HostPath支持)
7,、Deployment 無(wú)狀態(tài)應(yīng)用一般情況下我們不需要手動(dòng)創(chuàng)建Pod實(shí)例,而是采用更高一層的抽象或定義來(lái)管理Pod,,針對(duì)無(wú)狀態(tài)類(lèi)型的應(yīng)用,,Kubernetes使用Deloyment的Controller對(duì)象與之對(duì)應(yīng)。其典型的應(yīng)用場(chǎng)景包括:- 定義Deployment來(lái)創(chuàng)建Pod和ReplicaSet
- 滾動(dòng)升級(jí)和回滾應(yīng)用
- kubectl run www--image=10.0.0.183:5000/hanker/www:0.0.1--port=8080 生成一個(gè)Deployment對(duì)象
- kubectlgetdeployment--all-namespaces 查找Deployment
- kubectl describe deployment www 查看某個(gè)Deployment
- kubectl edit deployment www 編輯Deployment定義
- kubectldeletedeployment www 刪除某Deployment
- kubectl scale deployment/www--replicas=2 擴(kuò)縮容操作,,即修改Deployment下的Pod實(shí)例個(gè)數(shù)
- kubectlsetimage deployment/nginx-deployment nginx=nginx:1.9.1更新鏡像
- kubectl rollout undo deployment/nginx-deployment 回滾操作
- kubectl rollout status deployment/nginx-deployment 查看回滾進(jìn)度
- kubectl autoscale deployment nginx-deployment--min=10--max=15--cpu-percent=80 啟用水平伸縮(HPA - horizontal pod autoscaling),,設(shè)置最小、最大實(shí)例數(shù)量以及目標(biāo)cpu使用率
- kubectl rollout pause deployment/nginx-deployment 暫停更新Deployment
- kubectl rollout resume deploy nginx 恢復(fù)更新Deployment
.spec.strategy 指新的Pod替換舊的Pod的策略,,有以下兩種類(lèi)型- RollingUpdate 滾動(dòng)升級(jí),,可以保證應(yīng)用在升級(jí)期間,對(duì)外正常提供服務(wù),。
- Recreate 重建策略,,在創(chuàng)建出新的Pod之前會(huì)先殺掉所有已存在的Pod。
Deployment和ReplicaSet兩者之間的關(guān)系- 使用Deployment來(lái)創(chuàng)建ReplicaSet,。ReplicaSet在后臺(tái)創(chuàng)建pod,,檢查啟動(dòng)狀態(tài),看它是成功還是失敗,。
- 當(dāng)執(zhí)行更新操作時(shí),,會(huì)創(chuàng)建一個(gè)新的ReplicaSet,Deployment會(huì)按照控制的速率將pod從舊的ReplicaSet移 動(dòng)到新的ReplicaSet中
8,、StatefulSet 有狀態(tài)應(yīng)用Deployments和ReplicaSets是為無(wú)狀態(tài)服務(wù)設(shè)計(jì)的,,那么StatefulSet則是為了有狀態(tài)服務(wù)而設(shè)計(jì),其應(yīng)用場(chǎng)景包括:- 穩(wěn)定的持久化存儲(chǔ),,即Pod重新調(diào)度后還是能訪問(wèn)到相同的持久化數(shù)據(jù),,基于PVC來(lái)實(shí)現(xiàn)
- 穩(wěn)定的網(wǎng)絡(luò)標(biāo)志,即Pod重新調(diào)度后其PodName和HostName不變,基于Headless Service(即沒(méi)有Cluster IP的Service)來(lái)實(shí)現(xiàn)
- 有序部署,,有序擴(kuò)展,,即Pod是有順序的,在部署或者擴(kuò)展的時(shí)候要依據(jù)定義的順序依次進(jìn)行操作(即從0到N-1,,在下一個(gè)Pod運(yùn)行之前所有之前的Pod必須都是Running和Ready狀態(tài)),,基于init containers來(lái)實(shí)現(xiàn)
- OnDelete:當(dāng) .spec.template更新時(shí),,并不立即刪除舊的Pod,,而是等待用戶(hù)手動(dòng)刪除這些舊Pod后自動(dòng)創(chuàng)建新Pod。這是默認(rèn)的更新策略,,兼容v1.6版本的行為
- RollingUpdate:當(dāng) .spec.template 更新時(shí),,自動(dòng)刪除舊的Pod并創(chuàng)建新Pod替換。在更新時(shí)這些Pod是按逆序的方式進(jìn)行,,依次刪除,、創(chuàng)建并等待Pod變成Ready狀態(tài)才進(jìn)行下一個(gè)Pod的更新。
9,、DaemonSet 守護(hù)進(jìn)程集DaemonSet保證在特定或所有Node節(jié)點(diǎn)上都運(yùn)行一個(gè)Pod實(shí)例,,常用來(lái)部署一些集群的日志采集、監(jiān)控或者其他系統(tǒng)管理應(yīng)用,。典型的應(yīng)用包括:- 日志收集,,比如fluentd,logstash等
- 系統(tǒng)監(jiān)控,,比如Prometheus Node Exporter,,collectd等
- 系統(tǒng)程序,比如kube-proxy, kube-dns, glusterd, ceph,,ingress-controller等
DaemonSet會(huì)忽略Node的unschedulable狀態(tài),,有兩種方式來(lái)指定Pod只運(yùn)行在指定的Node節(jié)點(diǎn)上:- nodeSelector:只調(diào)度到匹配指定label的Node上
- nodeAffinity:功能更豐富的Node選擇器,比如支持集合操作
- podAffinity:調(diào)度到滿足條件的Pod所在的Node上
- OnDelete: 默認(rèn)策略,,更新模板后,,只有手動(dòng)刪除了舊的Pod后才會(huì)創(chuàng)建新的Pod
- RollingUpdate: 更新DaemonSet模版后,自動(dòng)刪除舊的Pod并創(chuàng)建新的Pod
10,、IngressKubernetes中的負(fù)載均衡我們主要用到了以下兩種機(jī)制:- Service:使用Service提供集群內(nèi)部的負(fù)載均衡,,Kube-proxy負(fù)責(zé)將service請(qǐng)求負(fù)載均衡到后端的Pod中
- Ingress Controller:使用Ingress提供集群外部的負(fù)載均衡
Service和Pod的IP僅可在集群內(nèi)部訪問(wèn)。集群外部的請(qǐng)求需要通過(guò)負(fù)載均衡轉(zhuǎn)發(fā)到service所在節(jié)點(diǎn)暴露的端口上,,然后再由kube-proxy通過(guò)邊緣路由器將其轉(zhuǎn)發(fā)到相關(guān)的Pod,,Ingress可以給service提供集群外部訪問(wèn)的URL、負(fù)載均衡,、HTTP路由等,,為了配置這些Ingress規(guī)則,,集群管理員需要部署一個(gè)Ingress Controller,它監(jiān)聽(tīng)I(yíng)ngress和service的變化,,并根據(jù)規(guī)則配置負(fù)載均衡并提供訪問(wèn)入口。
11,、Job & CronJob 任務(wù)和定時(shí)任務(wù)Job負(fù)責(zé)批量處理短暫的一次性任務(wù) (short lived>CronJob即定時(shí)任務(wù),,就類(lèi)似于Linux系統(tǒng)的crontab,在指定的時(shí)間周期運(yùn)行指定的任務(wù),。
12,、HPA(Horizontal Pod Autoscaling) 水平伸縮Horizontal Pod Autoscaling可以根據(jù)CPU、內(nèi)存使用率或應(yīng)用自定義metrics自動(dòng)擴(kuò)展Pod數(shù)量 (支持replication controller,、deployment和replica set),。- 控制管理器默認(rèn)每隔30s查詢(xún)metrics的資源使用情況(可以通過(guò) --horizontal-pod-autoscaler-sync-period 修改)
- 預(yù)定義metrics(比如Pod的CPU)以利用率的方式計(jì)算
- 自定義的Pod metrics,以原始值(raw value)的方式計(jì)算
- 支持兩種metrics查詢(xún)方式:Heapster和自定義的REST API
可以通過(guò)如下命令創(chuàng)建HPA:kubectl autoscale deployment php-apache--cpu-percent=50--min=1--max=10
13,、Service AccountService account是為了方便Pod里面的進(jìn)程調(diào)用Kubernetes API或其他外部服務(wù)而設(shè)計(jì)的Service Account為服務(wù)提供了一種方便的認(rèn)證機(jī)制,,但它不關(guān)心授權(quán)的問(wèn)題??梢耘浜蟁BAC(Role Based Access Control)來(lái)為Service Account鑒權(quán),,通過(guò)定義Role、RoleBinding,、ClusterRole,、ClusterRoleBinding來(lái)對(duì)sa進(jìn)行授權(quán)。
14,、Secret 密鑰Sercert-密鑰解決了密碼,、token、密鑰等敏感數(shù)據(jù)的配置問(wèn)題,,而不需要把這些敏感數(shù)據(jù)暴露到鏡像或者Pod Spec中,。Secret可以以Volume或者環(huán)境變量的方式使用。有如下三種類(lèi)型:- Service Account:用來(lái)訪問(wèn)Kubernetes API,,由Kubernetes自動(dòng)創(chuàng)建,,并且會(huì)自動(dòng)掛載到Pod的 /run/secrets/kubernetes.io/serviceaccount 目錄中;
- Opaque:base64編碼格式的Secret,用來(lái)存儲(chǔ)密碼,、密鑰等;
- kubernetes.io/dockerconfigjson: 用來(lái)存儲(chǔ)私有docker registry的認(rèn)證信息,。
15、ConfigMap 配置中心ConfigMap用于保存配置數(shù)據(jù)的鍵值對(duì),,可以用來(lái)保存單個(gè)屬性,,也可以用來(lái)保存配置文件。ConfigMap跟secret很類(lèi)似,,但它可以更方便地處理不包含敏感信息的字符串,。ConfigMap可以通過(guò)三種方式在Pod中使用,,三種分別方式為:設(shè)置環(huán)境變量、設(shè)置容器命令行參數(shù)以及在Volume中直接掛載文件或目錄,。可以使用 kubectl create configmap從文件,、目錄或者key-value字符串創(chuàng)建等創(chuàng)建 ConfigMap。也可以通過(guò) kubectl create-f value.yaml 創(chuàng)建,。
16,、Resource Quotas 資源配額資源配額(Resource Quotas)是用來(lái)限制用戶(hù)資源用量的一種機(jī)制。- cpu, limits.cpu, requests.cpu
- memory, limits.memory, requests.memory
- 存儲(chǔ)資源,,包括存儲(chǔ)資源的總量以及指定storage class的總量
- requests.storage:存儲(chǔ)資源總量,如500Gi
- persistentvolumeclaims:pvc的個(gè)數(shù)
- storageclass.storage.k8s.io/requests.storage
- storageclass.storage.k8s.io/persistentvolumeclaims
- 對(duì)象數(shù),,即可創(chuàng)建的對(duì)象的個(gè)數(shù)
- pods, replicationcontrollers, configmaps, secrets
- resourcequotas, persistentvolumeclaims
- services, services.loadbalancers, services.nodeports
- 資源配額應(yīng)用在Namespace上,,并且每個(gè)Namespace最多只能有一個(gè) ResourceQuota 對(duì)象
- 開(kāi)啟計(jì)算資源配額后,創(chuàng)建容器時(shí)必須配置計(jì)算資源請(qǐng)求或限制(也可以 用LimitRange設(shè)置默認(rèn)值)
- 用戶(hù)超額后禁止創(chuàng)建新的資源
|