??前面的文章已經(jīng)介紹了用kubeadm搭建一套簡(jiǎn)單的k8s集群偿衰,并在上面運(yùn)行了一個(gè)簡(jiǎn)單的服務(wù)示例统刮。下面介紹一下k8s中比較重要的資源對(duì)象:
1. Master
??Master是k8s的控制節(jié)點(diǎn)誉结,在每個(gè)k8s中,都必須有一個(gè)Master負(fù)責(zé)整個(gè)集群的管理和控制圣贸,基本上k8s所有的控制命令都發(fā)給它限次。如果Master節(jié)點(diǎn)宕機(jī),整個(gè)集群都將不能使用摩梧。Master節(jié)點(diǎn)是k8s的“大腦”物延。Master節(jié)點(diǎn)上運(yùn)行著以下關(guān)鍵進(jìn)程:
- Kubernetes API Server(kube-apiserver):提供了http REST接口的關(guān)鍵服務(wù)進(jìn)程,是k8s里所有資源的增刪改查等操作的唯一入口仅父,也是集群控制入口進(jìn)程叛薯。
- Kubernetes Controller Manager(Kube-controller-manager):k8s里所有對(duì)象的自動(dòng)化控制中心,可以把它理解成資源對(duì)象的“大總管”笙纤。
- Kubernetes Scheduler(kube-scheduler):負(fù)責(zé)資源調(diào)度(pod調(diào)度)的進(jìn)程耗溜,相當(dāng)于公交公司的調(diào)度室。
??同時(shí)省容,在Master上通常還需要部署etcd服務(wù)抖拴,因?yàn)镵ubernetes里的所有資源對(duì)象的數(shù)據(jù)都被保存在etcd中。
2. Node
??除了Master節(jié)點(diǎn)蓉冈,k8s集群中的其他機(jī)器城舞,無(wú)論是虛擬機(jī)還是物理機(jī)轩触,都是Node節(jié)點(diǎn)。每個(gè)Node都會(huì)被Master分配一些工作負(fù)載家夺。Node上運(yùn)行著以下關(guān)鍵進(jìn)程:
- kubelet:負(fù)責(zé)Pod對(duì)應(yīng)的容器的創(chuàng)建脱柱、啟停等任務(wù),同時(shí)于Master密切協(xié)作拉馋,實(shí)現(xiàn)集群管理的基本功能榨为。
- kube-proxy:實(shí)現(xiàn)Kubernetes Service的通信和負(fù)載均衡的重要組件。
- Docker Engine(docker):Docker引擎煌茴,負(fù)責(zé)本機(jī)的容器創(chuàng)建和管理工作随闺。
??Node可以在運(yùn)行期間動(dòng)態(tài)增加到kubernetes集群中,前提是在這個(gè)節(jié)點(diǎn)上正確安裝蔓腐、配置和啟動(dòng)了上述關(guān)鍵進(jìn)程矩乐,默認(rèn)情況下是己,kubelet會(huì)向Master注冊(cè)自己谎倔,這也是Kubernetes推薦的ode管理方式台诗。一旦Node被納入集群管理范圍荞怒,kubelet進(jìn)程就會(huì)定時(shí)向Master匯報(bào)自身的情報(bào)电谣,例如操作系統(tǒng)赶么、Docker版本库继,機(jī)器的CPU和內(nèi)存等情況膏孟;以及哪些Pod在運(yùn)行等葬燎。這樣Master就可以獲知每個(gè)Node的資源使用情況误甚。若某個(gè)Node在超過(guò)指定時(shí)間范圍內(nèi)不上報(bào)信息時(shí),會(huì)被Master判定為“失聯(lián)”谱净,Node的狀態(tài)被標(biāo)記為不可用(Not Ready)窑邦,隨后Master會(huì)觸發(fā)“工作負(fù)載大轉(zhuǎn)移”的自動(dòng)流程。
??執(zhí)行下列命令查看在集群中有多少個(gè)Node:
kubectl get nodes
??然后岳遥,通過(guò)以下命令查看某個(gè)Node的詳細(xì)信息:
kubectl describe node host-10-5-3-206
??上述命令展示Node的基本關(guān)鍵信息奕翔,如下:
- Node的基本信息:名稱、標(biāo)簽浩蓉、創(chuàng)建時(shí)間等派继。
- Node當(dāng)前的運(yùn)行狀態(tài):Node啟動(dòng)后會(huì)做一系列的自檢工作。
- Node的主機(jī)地址和主機(jī)名捻艳。
- Node上的資源數(shù)量驾窟。
- Node的可分配的資源量。
- 主機(jī)系統(tǒng)信息认轨。
- 當(dāng)前運(yùn)行的Pod列表的該要信息绅络。
- 已分配的資源使用該要信息,例如資源申請(qǐng)的最低、最大允許使用量等恩急。
- Node相關(guān)的Event信息杉畜。
3. pod
pod是k8s最基礎(chǔ)重要的基本概念,每個(gè)pod都有一個(gè)特殊的被稱為“跟容器”pause容器衷恭。pause容器對(duì)應(yīng)的鏡像屬于k8s平臺(tái)的一部分此叠,除了Pause容器,每個(gè)Pod還包含一個(gè)或多個(gè)緊密相關(guān)的業(yè)務(wù)容器随珠。??k8s設(shè)計(jì)pod的原因如下:
- 在一組容器作為一個(gè)單元的情況下灭袁,很難簡(jiǎn)單地對(duì)“整體”進(jìn)行有效的判斷和行動(dòng)。引入業(yè)務(wù)無(wú)關(guān)并且不易死亡的Pause容器作為pod的跟容器窗看,以它的狀態(tài)代表整個(gè)容器的狀態(tài)茸歧,就很巧妙的解決了問(wèn)題。
-
Pod里的多個(gè)業(yè)務(wù)容器共享Pause容器的IP显沈,共享Pause容掛接的Volume软瞎。這樣不僅簡(jiǎn)化了業(yè)務(wù)容器之間的通信問(wèn)題,也很好的解決了這一組容器的文件共享問(wèn)題拉讯。
??在k8s中铜涉,一個(gè)pod容器能直接和另一個(gè)主機(jī)上的容器進(jìn)行通信。Pod有兩種類(lèi)型遂唧,分別是普通額Pod和靜態(tài)的 Pod。后者是一種特殊的Pod吊奢,它并不存放在k8s的etcd上盖彭,而是被存在某個(gè)具體的Node的一個(gè)主機(jī)文件中,并且只在此Node上啟動(dòng)页滚、運(yùn)行召边。普通的pod一旦被創(chuàng)建,就會(huì)被放在etcd中存儲(chǔ)裹驰,隨后會(huì)被Kubernetes Master調(diào)度到某個(gè)Node上并進(jìn)行綁定(binding)隧熙,隨后該pod被對(duì)應(yīng)的Node上的kubelet進(jìn)程示例化成一組相關(guān)的Docker容器并啟動(dòng)。在默認(rèn)情況下幻林,當(dāng)Pod里面的某個(gè)容器停止時(shí)贞盯,k8s會(huì)自動(dòng)檢測(cè)這個(gè)問(wèn)題摒棄重新啟動(dòng)這個(gè)pod-->實(shí)際上就是重啟pod中的所有容器,如果pod所在的Node宕機(jī)沪饺,就回將這個(gè)Node上的所有Pod重新調(diào)度到其他節(jié)點(diǎn)上躏敢。pod、node和Master的關(guān)系如下圖所示:
??每個(gè)Pod都可以對(duì)其能使用的資源設(shè)置限額件余,當(dāng)前可以設(shè)置限額的計(jì)算資源有CPU和Memory兩種,其中CPU的資源單位為CPU(code)的數(shù)量,是一個(gè)絕對(duì)值而非相對(duì)值啼器。
??對(duì)于絕大多數(shù)的容器而言旬渠,一個(gè)CPU是相當(dāng)大的,k8s中以千分之一的CPU為最小資源單位端壳,用m表示告丢。通常一個(gè)容器的CPU的配額是100m~300m。在k8s中更哄,一個(gè)計(jì)算資源進(jìn)行配額限定時(shí)需要設(shè)以下兩個(gè)參數(shù): - Request:該資源的最小申請(qǐng)量芋齿,系統(tǒng)必須滿足要求;
- Limits:該資源允許使用的最大量成翩,不能被突破觅捆。下面的示例定義mysql容器能使用的資源配額為0.5個(gè)CPU及128MiB內(nèi)存:
spec:
containers:
- name: db
image: mysql
resources:
requests: #一般情況下
memory: "64Mi"
cpu: "250m"
limits: #最大值
memory: "128Mi"
cpu: "500m"
4. Labels
??Lables是k8s系統(tǒng)中另一個(gè)核心的概念,一個(gè)Label是一個(gè)key=value形式的鍵值對(duì)麻敌,其中key和value由用戶自己指定栅炒。Label相當(dāng)于我們熟悉的標(biāo)簽,通過(guò)Label Selector進(jìn)行選擇术羔。Label Selector可以理解成是SQL語(yǔ)句中的where語(yǔ)句赢赊。目前有兩種Label Selector表達(dá)式,分別是分別是:
- Equality-based:eg:name=redis-slave匹配所有具有redis-slave標(biāo)簽的資源
- Set-based:eg:name in (redis-slave, redis-master) 匹配具有redis-slave和redis-master的對(duì)象
可以通過(guò)多個(gè)label Selector語(yǔ)句的組合實(shí)現(xiàn)復(fù)雜的條件篩選级历,多個(gè)表達(dá)式之間用“,”連接释移。matchLabels用于定義一組Label,和直接在Selector中的作用相同寥殖。Label Selector在k8s中的重要使用場(chǎng)景如下: - kube-controller進(jìn)程通過(guò)在資源對(duì)象RC上定義的Label Selector來(lái)篩選要監(jiān)控的pod副本的數(shù)量玩讳。
- kube-proxy進(jìn)程通過(guò)Service的Label Selector來(lái)選擇對(duì)應(yīng)的pod,自動(dòng)建立每個(gè)service到對(duì)應(yīng)pod的請(qǐng)求轉(zhuǎn)發(fā)路由表嚼贡,從而實(shí)現(xiàn)service智能負(fù)載均衡機(jī)制熏纯。
- 通過(guò)對(duì)某些Node定義特定的Label,并且在Pod定義中使用NodeSelector這種標(biāo)簽粤策,kube-scheduler進(jìn)程可以實(shí)現(xiàn)pod定向調(diào)度的特性樟澜。
??總之,使用Label可以給對(duì)象創(chuàng)建多組標(biāo)簽叮盘,Label和LabelSelector共同構(gòu)成來(lái)k8s系統(tǒng)中核心的應(yīng)用模型秩贰,使得被管理對(duì)象能夠被精細(xì)地分組管理,同時(shí)實(shí)現(xiàn)來(lái)整個(gè)集群的高可用性熊户。
5. Replication Controller
??RC是k8s系統(tǒng)中的核心概念之一萍膛,簡(jiǎn)單來(lái)說(shuō),它其實(shí)定義了一個(gè)期望的場(chǎng)景嚷堡,即聲明某種Pod的副本的數(shù)量在任意時(shí)刻都符合某個(gè)預(yù)期值蝗罗,所以RC定義包括如下幾個(gè)部分艇棕。
- Pod期待的副本的數(shù)量
- 用于篩選目標(biāo)Pod的Label Selector
- 當(dāng)Pod的副本數(shù)量小于預(yù)期數(shù)量時(shí),用于創(chuàng)建新Pod的Pod模版(template)
??下面是一個(gè)完整的RC定義的例子串塑,作用是確保擁有tier=frontend標(biāo)簽的這個(gè)Pod(運(yùn)行Tomcat容器)在整個(gè)k8s集群中始終只有一個(gè)副本:
apiVersion: v1
kind: ReplocationController
metadata: frontend
spec:
replicas: 1
selector:
tier: frontend
template:
metadata:
labels:
app: app-demo
tier: frontend
spec:
container:
- name: tomcat-demo
image: tomcat
imagePullPolicy: IfNotPresent
env:
- name: GET_HOSTS_FROM
value: dns
ports:
- containerPort: 80
??在定義了一個(gè)RC并將其提交到k8s集群中后沼琉,Master上的Controller Manager組件就得到通知,定期巡檢系統(tǒng)中當(dāng)前存活的目標(biāo)Pod桩匪,并確保Pod示例的數(shù)量剛好等于此RC的期望值打瘪,如果有過(guò)多的Pod副本的存在運(yùn)行,系統(tǒng)就會(huì)停掉一些Pod傻昙,否則系統(tǒng)會(huì)自動(dòng)創(chuàng)建一些Pod闺骚。可以說(shuō)妆档,通過(guò)RC僻爽,k8s實(shí)現(xiàn)了用戶應(yīng)用集群的高可用性,并且大大減少了系統(tǒng)管理員在傳統(tǒng)IT環(huán)境中需要完成的許多手工運(yùn)維工作贾惦。在運(yùn)行時(shí)胸梆,可以通過(guò)修改RC的副本數(shù)量,來(lái)實(shí)現(xiàn)Pod的動(dòng)態(tài)縮放(Scaling)须板,這可以通過(guò)執(zhí)行kubectl scale命令來(lái)一鍵完成碰镜。
kubectl scale rc redis-slave --replicas=3
??需要注意的是,刪除RC并不會(huì)影戲那個(gè)通過(guò)該RC已經(jīng)創(chuàng)建好的Pod习瑰。為了刪除所有Pod绪颖,可以設(shè)置replicas的值為0,然后更新該RC甜奄。同時(shí)菠发,kubectl提供了stop和delete命令來(lái)一次性刪除RC和RC控制的全部Pod。RC支持滾動(dòng)升級(jí)贺嫂。Replication Controller由于與k8s中的Replication Controller同名,k8s在1.2之后雁乡,升級(jí)為另一個(gè)新的概念第喳,Replica Set。官方解釋是“新一代的RC”踱稍,當(dāng)前的唯一區(qū)別是曲饱,Replica Sets支持基于Label selector(Set-based selector),而RC只支持基于等式的Label Selector(equality-based selector)珠月,這使得Replica Set的功能更強(qiáng)扩淀。下面等價(jià)于之前RC例子的Replica Set的定義(省去來(lái)Pod模版部分的內(nèi)容):
apiVersion: extensions/v1beta1
kind: ReplicaSet
metadata:
name: frontend
spec:
selector:
matchlabels:
tier: frontend
matchExpressions:
- {key: tier, operator: in, values: [frontend]}
template:
.....
??當(dāng)前,我們很少使用Replica Set啤挎,它主要被Deployment這個(gè)更高級(jí)的資源對(duì)象所使用驻谆,從而形成一整套Pod創(chuàng)建建設(shè)卵凑、刪除、更新的編排機(jī)制胜臊。Replica Set和Deplotment這兩個(gè)重要的資源對(duì)象逐漸替代了之前的RC勺卢,是k8s 1.3里Pod自動(dòng)彈縮這個(gè)告警功能實(shí)現(xiàn)的基礎(chǔ)。
綜上:
- 在大多數(shù)情況下象对,我們定義一個(gè)RC實(shí)現(xiàn)Pod的創(chuàng)建及副本數(shù)量的自動(dòng)控制
- 在RC里包括完整的Pod的定義模版
- RC通過(guò)label Selector機(jī)制實(shí)現(xiàn)對(duì)Pod副本的自動(dòng)控制
- 通過(guò)改變RC里的Pod副本數(shù)量黑忱,可以實(shí)現(xiàn)Pod的擴(kuò)容和縮容
- 通過(guò)改變RC里Pod模版中的鏡像版本,可以實(shí)現(xiàn)Pod的滾動(dòng)升級(jí)
6. Deployment
??Deployment是k8s在1.2版本中引入的概念勒魔,用于更好地解決Pod的編排問(wèn)題甫煞。從各種角度來(lái)看,Deployment和RC的相似度超過(guò)90%冠绢。Deployment相對(duì)于RC的一個(gè)最大升級(jí)就是我們可以隨時(shí)知道Pod“部署”的進(jìn)度抚吠。實(shí)際上由于一個(gè)Pod的創(chuàng)建、調(diào)度唐全、綁定節(jié)點(diǎn)及在目標(biāo)Node上啟動(dòng)對(duì)應(yīng)的容器這一完整過(guò)程需要一定的時(shí)間埃跷,所以 我們期待系統(tǒng)啟動(dòng)N個(gè)Pod副本的目標(biāo)狀態(tài),實(shí)際上是一個(gè)連續(xù)變化的“部署過(guò)程”導(dǎo)致的最終狀態(tài)邮利。
7. Horizontal Pod Autoscaler
??有的場(chǎng)景下弥雹,需要頻繁的觸發(fā)水平擴(kuò)容和縮容。1.1版本發(fā)布了Horizontal Pod Autoscale(HPA)延届,HPA有以下兩種方式作為Pod負(fù)載的度量指標(biāo)剪勿。
- CPUUtilozationPercentage
- 應(yīng)用程序自定義的度量指標(biāo),比如服務(wù)在每秒內(nèi)的相應(yīng)請(qǐng)求數(shù)量(TPS或QPS)
??前者是一個(gè)算數(shù)平均值方庭,即目標(biāo)副本自身的CPU利用率的平均值厕吉。一個(gè)HPA定義的具體例子如下:
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
name: php-apache
namespace: default
spec:
maxReplicas: 10
minReplicas:1
scaleTargetRef:
kind: Deplotment
name: php-apache
targetCPUUtilizationPercentage: 90
??和上面等價(jià)的命令行行為:
kubectl autoscale deployment php-apache --cpu-percent=90 --min=1 --max=10
8. StatefulSet
??k8s系統(tǒng)中,Pod的管理對(duì)象RC械念、Deployment头朱、DeamonSet和Job都面向無(wú)狀態(tài)的服務(wù)。但是有時(shí)候是很多的服務(wù)是有狀態(tài)的龄减,特別是一些有著以下特點(diǎn)的集群:
- 每個(gè)節(jié)點(diǎn)都有都有固定的身份ID项钮,通過(guò)這個(gè)ID,集群中的成員可以相互發(fā)現(xiàn)并進(jìn)行通信希停。
- 集群的規(guī)模是比較固定的烁巫,集群規(guī)模不能隨意變動(dòng)。
- 集群中的每個(gè)環(huán)節(jié)都是有狀態(tài)的宠能,通常會(huì)持久化到永久存儲(chǔ)中亚隙。
- 如果磁盤(pán)損壞,則集群中的某個(gè)節(jié)點(diǎn)無(wú)法正常運(yùn)行违崇,集群功能受損阿弃。
??為了解決服務(wù)有狀態(tài)的問(wèn)題诊霹,k8s引入了StatefulSet,可以將這個(gè)對(duì)象看成是RC/Deployment的一個(gè)變種恤浪,它有以下的特性: - StatefulSet里的每個(gè)Pod都有穩(wěn)定畅哑、唯一的網(wǎng)絡(luò)標(biāo)識(shí),可以用來(lái)發(fā)現(xiàn)集群內(nèi)的其他的成員水由。假設(shè)StatefulSet的名稱為kafka荠呐,那么第一個(gè)Pod叫kafka-0,第2個(gè)叫做kafka-1砂客,以此類(lèi)推泥张。
- Stateful控制的Pod副本的啟停順序是受控的,操作第n個(gè)Pod時(shí)鞠值,前n-1個(gè)Pod已經(jīng)是運(yùn)行且準(zhǔn)備好的狀態(tài)媚创。
- StatefulSet里的pod采用穩(wěn)定的持久化存儲(chǔ)卷,通過(guò)PV或PVC來(lái)實(shí)現(xiàn)彤恶,刪除 Pod時(shí)默認(rèn)不會(huì)刪除于StatefulSet相關(guān)的存儲(chǔ)卷钞钙。
??StatefulSet除了要于PV卷捆綁使用以存儲(chǔ)Pod的狀態(tài)數(shù)據(jù),還要于Headless Service配合使用声离,即在每個(gè)StatefulSet定義中都要聲明它屬于那個(gè)Headless Service芒炼。
9. Service
9.1 概述
??Service服務(wù)是k8s的核心資源對(duì)象之一,k8s里的每個(gè)Service其實(shí)就是我們經(jīng)常提起的微服務(wù)架構(gòu)中的一個(gè)微服務(wù)术徊,之前講解Pod本刽、RC等資源對(duì)象其實(shí)都是為講解k8s Service做鋪墊的。K8s的Service定義了一個(gè)服務(wù)的訪問(wèn)入口地址赠涮,前端的應(yīng)用(Pod)通過(guò)這個(gè)入口地址訪問(wèn)其背后的一組由Pod副本組成的集群實(shí)例子寓,Service和其后端Pod副本集群之間則是通過(guò)Label Selector來(lái)實(shí)現(xiàn)無(wú)縫對(duì)接的。RC的作用實(shí)際上是保證Service的服務(wù)能力和服務(wù)數(shù)量始終符合預(yù)期標(biāo)準(zhǔn)笋除。K8s的服務(wù)之間通過(guò)TCP/IP進(jìn)行通信斜友。k8s發(fā)明了一種很巧妙的服務(wù)發(fā)現(xiàn)和負(fù)載均衡機(jī)制。Service不是公用一個(gè)負(fù)載均衡的IP地址垃它,每個(gè)Service都被分配了一個(gè)全局唯一的的虛擬IP地址蝙寨,這個(gè)虛擬IP被稱為Cluster IP地址。服務(wù)調(diào)用就變成了最基礎(chǔ)的TCP網(wǎng)絡(luò)通信問(wèn)題嗤瞎。下面是一個(gè)tomcat-service的yaml文件:
apiVersion: v1
kind: Service
metadata:
name: tomcat-service
spec:
ports:
-port: 8000
selector:
tier: frontend
??運(yùn)行下面的內(nèi)容進(jìn)行創(chuàng)建:
kubectl create -f tomcat-server.yaml
??運(yùn)行下面的命令分查看端口和Cluster IP:
kubectl get endpoints
kubectl get svc tomcat-service -o yaml
??在很多服務(wù)中,都存在多端口問(wèn)題听系,通常一個(gè)端口提供業(yè)務(wù)服務(wù)贝奇,另一個(gè)端口提供管理功能。k8s支持多個(gè)Endpoint靠胜,但是要求每一個(gè)Endpoint都定義一個(gè)名稱來(lái)區(qū)分掉瞳。下面的 例子是Tomcat多端口service的定義示例:
apVersion: v1
kind: Service
metadata:
name: tomcat-service
spec:
ports:
- port: 8080
name: service-port
- port: 8005
name: shutdown-port
selector:
tier: frontend
9.2 k8s的服務(wù)發(fā)現(xiàn)機(jī)制
?&emps;任何分布式系統(tǒng)都會(huì)涉及“服務(wù)發(fā)現(xiàn)”這個(gè)基礎(chǔ)問(wèn)題毕源,大部分分布式系統(tǒng)都通過(guò)提供特定的API接口來(lái)實(shí)現(xiàn)服務(wù)發(fā)現(xiàn)功能,但是這樣會(huì)導(dǎo)致平臺(tái)的侵入性比較強(qiáng)陕习,也增加了開(kāi)發(fā)霎褐、測(cè)試的難度。k8s則采用了直觀樸素的思路去解決這個(gè)棘手的問(wèn)題该镣。
??首先冻璃,每個(gè)k8s中的Service都有唯一的Cluster IP及唯一的名稱,而名稱是由開(kāi)發(fā)者自己定義的损合,部署時(shí)也沒(méi)有必要改變省艳,所以完全可以固定到配置中,接下來(lái)的問(wèn)題就是如何通過(guò)Service的名稱找到對(duì)應(yīng)的Cluster IP嫁审。
??k8s通過(guò)Add-on增值包引入了DNS系統(tǒng)跋炕,將服務(wù)名作為域名,這樣程序就可以直接使用服務(wù)名來(lái)建立通信了律适。后續(xù)將會(huì)介紹如何部署DNS系統(tǒng)辐烂。
9.3 外部系統(tǒng)訪問(wèn)Service的問(wèn)題
??k8s中有三種IP,弄清他們的區(qū)別對(duì)于 理解k8s很有必要捂贿。
- Node IP:Node的IP地址
- Pod IP:Pod的IP地址
- Cluster IP:Service的IP地址
??Node IP是真實(shí)在的IP地址纠修。集群外的節(jié)點(diǎn)訪問(wèn)k8s集群中的某個(gè)節(jié)點(diǎn)或者是服務(wù)時(shí),都必須通過(guò)Node IP通信眷蜓。Pod IP是每個(gè)Pod的IP地址分瘾,它是Docker Engine根據(jù)docker0網(wǎng)橋的IP地址段進(jìn)行分配的,通常是一個(gè)虛擬的二層網(wǎng)絡(luò)吁系,前面說(shuō)過(guò)德召,k8s要求位于不同Node上的Pod能夠彼此直接通信你,所以Pod都能夠彼此直接通信汽纤,所以k8s里一個(gè)Pod容器訪問(wèn)另一個(gè)Pod里的容器時(shí)上岗,就是通過(guò)Pod IP所在 的虛擬二層網(wǎng)絡(luò)進(jìn)行通信的,而真實(shí)的流量是通過(guò)Node IP所在的物理網(wǎng)卡流出的蕴坪。cluster IP更像是一個(gè)“偽造”的IP網(wǎng)絡(luò)肴掷,因?yàn)椋?/li> - Cluster IP僅僅作用于k8s Service這個(gè)對(duì)象,并由k8s管理和分配的IP地址背传,來(lái)源于Cluster IP池呆瞻。
- Cluster IP無(wú)法被ping,因?yàn)闆](méi)有一個(gè)實(shí)體網(wǎng)絡(luò)來(lái)相應(yīng)径玖。
- Cluster IP只能結(jié)合Service Port組成一個(gè)具體的通信端口痴脾,單獨(dú)的IP不具有TCP/IP通信的基礎(chǔ),并且他們屬于k8s集群中這樣一個(gè)封閉的空間梳星,集群外的節(jié)點(diǎn)如果要訪問(wèn)這個(gè)通信地址赞赖,則需要一些額外的工作滚朵。
- 在k8s集群內(nèi),Node IP網(wǎng)絡(luò)前域、Pod IP網(wǎng)絡(luò)和Cluster IP網(wǎng)之間的通信辕近,采用的是k8s自己設(shè)計(jì)的一種編程方式的特殊的路由規(guī)則,和我們熟悉的IP路由有很大的不同匿垄。
10. Job
??批處理任務(wù)通常并行啟動(dòng)多個(gè)計(jì)算機(jī)進(jìn)程去處理一批工作項(xiàng)移宅,在處理完成后,整個(gè)批處理任務(wù)結(jié)束年堆。從1.2開(kāi)始吞杭,k8s支持批處理類(lèi)型的應(yīng)用,可以通過(guò)Job這種資源對(duì)象定義并啟動(dòng)一個(gè)批處理任務(wù)的Job变丧。Job控制一組Pod容器芽狗,可以將Job看作是一個(gè)特殊的Pod副本控制器,同時(shí)Job控制Pod副本和RC等控制器的工作機(jī)制有以下的區(qū)別:
- Job所控制的Pod副本是短暫運(yùn)行的痒蓬,可以將其視為一組Docker容器童擎,起哄的每個(gè)Docker容器都僅僅運(yùn)行一次,當(dāng)Job控制的所有Pod的副本都運(yùn)行結(jié)束時(shí)攻晒,對(duì)應(yīng)的Job也就結(jié)來(lái)顾复。Job生成的副本是不能自動(dòng)重啟的,對(duì)應(yīng)的Pod副本的RestartPolicy都被設(shè)置為Never鲁捏。
- Job所控制的Pod副本的工作模式能夠多實(shí)例并行計(jì)算芯砸。
11. Volume
??Volume是Pod中能夠被多個(gè)容器訪問(wèn)的共享目錄。k8s的Volume概念给梅、用途和目的和Docker的Volume比較類(lèi)似假丧,但是兩者不能等價(jià)。首先动羽,k8s的volume被定義在Pod上包帚,然后被一個(gè)Pod里的多個(gè)容器掛載到具體的文件目錄下;其次运吓,k8s的Volume和Pod的生命周期相同渴邦,但是與容器的生命周期不相關(guān),當(dāng)容器終止或者重啟時(shí)拘哨,Volume中的數(shù)據(jù)并不會(huì)丟失谋梭,最后,k8s支持多種類(lèi)型的Volume倦青。使用Volume瓮床,必須要現(xiàn)在Pod聲明一個(gè)Volume,然后在容器中引用該Volume并掛載(Mount)到容器里的某個(gè)目錄上。定義一個(gè)Volume如下:
# Pod的部分內(nèi)容
template:
metadata:
labels:
app: app-demo
tier: frontend
spec:
volumes:
- name: detavol
emptydir: {}
containers:
- name: tomcat-demo
image: tomcat
volumeMounts:
- mountPath: /mydata-data
name: datavol
imagePullpolicy: IfNotPresent
??除了可以讓Pod里的多個(gè)容器共享文件纤垂、讓容器的數(shù)據(jù)可以寫(xiě)到宿主機(jī)的磁盤(pán)上或者寫(xiě)文件到網(wǎng)絡(luò)存儲(chǔ)中,k8s的Volume還擴(kuò)展了一種非常有使用價(jià)值的功能磷账,就是容器配置文件的集中化定義與 管理峭沦,這是通過(guò)ConfigMap這種新的資源對(duì)象來(lái)實(shí)現(xiàn)的。k8s實(shí)現(xiàn)了豐富的Volume類(lèi)型的逃糟,如下:
- emptydir:一個(gè)emptydir Volume實(shí)在Pod分配到Node時(shí)創(chuàng)建的吼鱼。它的初始內(nèi)容為空,并且無(wú)需指定宿主機(jī)上對(duì)應(yīng)的目錄文件绰咽,因?yàn)檫@是k8s自動(dòng)分配的一個(gè)目錄菇肃,當(dāng)pod從Node上移除時(shí),它里面的數(shù)據(jù)會(huì)被永久刪除取募,emptydir有下面的一些用途琐谤。
??1.臨時(shí)空間,例如對(duì)于某些應(yīng)用程序運(yùn)行時(shí)所需的臨時(shí)目錄玩敏,且無(wú)需永久保留
??2.長(zhǎng)時(shí)間任務(wù)中的中間過(guò)程CheckPoint的臨時(shí)保存目錄
??3.一個(gè)容器需要從另一個(gè)容器中獲取數(shù)據(jù)的目錄(多容器數(shù)據(jù)共享) - hostPath:hostPath是在Pod容器上掛載宿主機(jī)上的文件或者目錄斗忌,它通常可以用于以下幾個(gè)方面
??1.容器應(yīng)用程序生成的日志文件需要永久保存時(shí)旺聚,可以使用宿主機(jī)的高速文件系統(tǒng)進(jìn)行存儲(chǔ)织阳。
??2.需要訪問(wèn)宿主機(jī)上Docker引擎內(nèi)部數(shù)據(jù)結(jié)構(gòu)的容器應(yīng)用時(shí),可以通過(guò)定義hostsPath為宿主機(jī)/var/lib/docker目錄砰粹,使容器內(nèi)部應(yīng)用可以直接訪問(wèn)Docker的文件系統(tǒng)唧躲。
??在使用這種類(lèi)型的Volume時(shí),需要注意以下幾點(diǎn):
??1.在不同的Node上具有相同配置的Pod碱璃,可能會(huì)因?yàn)樗拗鳈C(jī)上的目錄和文件不同而導(dǎo)致對(duì)Volume上目錄和文件的訪問(wèn)結(jié)果不一致弄痹,
??2.如果使用了資源配額管理,則k8s無(wú)法將hostPath在宿主機(jī)上使用的資源納入管理厘贼。
??定義一個(gè)hostPath類(lèi)型的Volume的文件如下:
volumes:
-name: "Persistent-storage"
hostPath:
path: "/data"
- gcePersistentDisk:使用這種Volume表示使用谷歌公有云提供的永久磁盤(pán)界酒。此處不做過(guò)多解釋。
- awsElasticBlockStore:使用亞馬遜公有云提供的EBS Volume存儲(chǔ)數(shù)據(jù)嘴秸,此處不做過(guò)多解釋毁欣。
- iscsi:使用iSCSI存儲(chǔ)設(shè)備上的目錄掛載到Pod中
-gitRepo:通過(guò)掛載一個(gè)空目錄,并從Git庫(kù)中clone一個(gè)git repository以供Pod使用岳掐。
12. Persistent Volume
??網(wǎng)絡(luò)存儲(chǔ)是相對(duì)獨(dú)立于計(jì)算資源而存在的一種實(shí)體資源凭疮。比如在使用虛擬機(jī)的情況下,我們通常會(huì)定義一個(gè)網(wǎng)絡(luò)存儲(chǔ)串述,然后從中劃出一個(gè)“網(wǎng)盤(pán)”并掛載到虛擬機(jī)上执解。Persistent Volume(PV)和與之相關(guān)聯(lián)的Persistent Volume chaim(PVC)也起到了類(lèi)似的作用。PV可以理解成是k8s集群中的某個(gè)網(wǎng)絡(luò)存儲(chǔ)對(duì)應(yīng)的一塊存儲(chǔ),它與Volume類(lèi)似衰腌,但是有以下區(qū)別:
??1.PV只能是網(wǎng)絡(luò)存儲(chǔ)新蟆,不屬于任何Node,但是可以被任何Node訪問(wèn)
??2.PV并不是被定義 在Pod上的右蕊,而是獨(dú)立于Pod之外定義的
??下面給出一個(gè)NFS類(lèi)型的PV的yaml定義問(wèn)價(jià)琼稻,聲明需要 5G的空間:
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv0003
spec:
capacity:
storage: 5Gi
accessModes:
nfs:
path: /somepath
server: 172.17.0.2
  如果某個(gè)Pod想要申請(qǐng)某種類(lèi)型的PV,則首先需要定義一個(gè)Persistent VolumeClaim對(duì)象:
```yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: myclaim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
stoorage: 8Gi
??然后在Pod的Volume定義中引用上述PVC即可
volume:
- name: mypod
persistent:VolumeVlaim:
claimName: myclaim
??最后說(shuō)下PV的狀態(tài)饶囚。PV是有狀態(tài)的對(duì)象帕翻,它的狀態(tài)有以下集中
??1.Available:空閑狀態(tài)
??2.Bound:已經(jīng)綁定到某個(gè)PVC上
??3.Released:對(duì)應(yīng)的PVC已經(jīng)被刪除,但是資源還沒(méi)有被集群回收
??4.Failed:PV自動(dòng)回收失敗
13. Namespace
??Namespace是k8s系統(tǒng)中另一個(gè)非常重要的概念萝风,Namespace在很多情況下用于實(shí)現(xiàn)用戶的資源隔離嘀掸。Namespace通過(guò)將集群內(nèi)部的資源對(duì)象“分配”到不同的Namespace中,形成邏輯上分組的不同項(xiàng)目规惰、小組或用戶組睬塌,便于不同的分組在共享整個(gè)集群資源的同時(shí)還能被分別管理。Namespace的定義很簡(jiǎn)單:
apiVersion: v1
kind: Namespace
metadata:
name: development
??一旦創(chuàng)建了Namespace卿拴,在創(chuàng)建資源的時(shí)候衫仑,就可以指定資源對(duì)象屬于哪個(gè)Namespace
apiVersion: v1
kind: Pod
metadata:
name: busybox
namespace: development
spec:
containers:
- image: busybox
command:
- sleep
- "3600"
14. ConfigMap
??為了解決Docker容器運(yùn)行時(shí)修改配置文件的問(wèn)題,k8s提供了如下巧妙的實(shí)現(xiàn):
??首先堕花,把所有的配置項(xiàng)當(dāng)作是key-value字符串文狱。value可以來(lái)自某個(gè)文本文件。配置參數(shù)可以作為Map表中的一個(gè)項(xiàng)缘挽,整個(gè)Map的數(shù)據(jù)可以被持久化存儲(chǔ)在etcd數(shù)據(jù)庫(kù)中瞄崇,然后提供API以方便k8s相關(guān)組件或者客戶應(yīng)用CRUD操作這些數(shù)據(jù),上述專(zhuān)門(mén)用來(lái)保存配置參數(shù)的Map就是K8s的ConfigMap對(duì)象壕曼。然后k8s提供一種內(nèi)建機(jī)制苏研,將存儲(chǔ)在etcd中的ConfigMap通過(guò)Volume映射的方式變成目標(biāo)Pod內(nèi)的配置文件,不管目標(biāo)Pod被調(diào)度到哪個(gè)服務(wù)器上腮郊,都會(huì)自動(dòng)映射摹蘑。
以上是k8s中資源的一個(gè)概述,后續(xù)將會(huì)繼續(xù)根據(jù)資源轧飞,逐漸進(jìn)行深入研究衅鹿。你 ,學(xué)廢了嗎过咬?