k8s介紹

1. 介紹

Kubernetes(k8s)是自動(dòng)化容器操作的開(kāi)源平臺(tái),這些操作包括部署,調(diào)度和節(jié)點(diǎn)集群間擴(kuò)展。

Kubernetes組件組成:

1 Kubectl

客戶端命令行工具,將接受的命令格式化后發(fā)送給kube-apiserver,作為整個(gè)系統(tǒng)的操作入口。

2 kube-apiserver

作為整個(gè)系統(tǒng)的控制入口,以REST API服務(wù)提供接口,提供了資源操作的唯一入口,并提供認(rèn)證、授權(quán)、訪問(wèn)控制、API注冊(cè)和發(fā)現(xiàn)等機(jī)制。

3 kube-controller-manager

用來(lái)執(zhí)行整個(gè)系統(tǒng)中的后臺(tái)任務(wù),包括節(jié)點(diǎn)狀態(tài)狀況、Pod個(gè)數(shù)、Pods和Service的關(guān)聯(lián)等。負(fù)責(zé)維護(hù)集群的狀態(tài),比如故障檢測(cè)、自動(dòng)擴(kuò)展、滾動(dòng)更新等。

4 kube-scheduler

負(fù)責(zé)節(jié)點(diǎn)資源管理,接受來(lái)自kube-apiserver創(chuàng)建Pods任務(wù),并分配到某個(gè)節(jié)點(diǎn)。

5 etcd

etcd 集群的主數(shù)據(jù)庫(kù),保存了整個(gè)集群的狀態(tài),負(fù)責(zé)節(jié)點(diǎn)間的服務(wù)發(fā)現(xiàn)和配置共享。

6 kube-proxy

運(yùn)行在每個(gè)計(jì)算節(jié)點(diǎn)上,負(fù)責(zé)Pod網(wǎng)絡(luò)代理。定時(shí)從etcd獲取到service信息來(lái)做相應(yīng)的策略。負(fù)責(zé)為Service提供cluster內(nèi)部的服務(wù)發(fā)現(xiàn)和負(fù)載均衡。

7 kubelet

運(yùn)行在每個(gè)計(jì)算節(jié)點(diǎn)上,作為agent,接受分配該節(jié)點(diǎn)的Pods任務(wù)及管理容器,周期性獲取容器狀態(tài),反饋給kube-apiserver。負(fù)責(zé)維護(hù)容器的生命周期,負(fù)責(zé)管理pods和它們上面的容器,images鏡像、volumes、etc。同時(shí)也負(fù)責(zé)Volume(CVI)和網(wǎng)絡(luò)(CNI)的管理。

8 DNS

一個(gè)可選的DNS服務(wù),用于為每個(gè)Service對(duì)象創(chuàng)建DNS記錄,這樣所有的Pod就可以通過(guò)DNS訪問(wèn)服務(wù)了。

2 相關(guān)概念

2.1 Pod

Pod是在K8s集群中運(yùn)行部署應(yīng)用或服務(wù)的最小單元,它是可以支持多容器的。Pod的設(shè)計(jì)理念是支持多個(gè)容器在一個(gè)Pod中共享網(wǎng)絡(luò)地址和文件系統(tǒng),可以通過(guò)進(jìn)程間通信和文件共享這種簡(jiǎn)單高效的方式組合完成服務(wù).比如你運(yùn)行一個(gè)操作系統(tǒng)發(fā)行版的軟件倉(cāng)庫(kù),一個(gè)Nginx容器用來(lái)發(fā)布軟件,另一個(gè)容器專(zhuān)門(mén)用來(lái)從源倉(cāng)庫(kù)做同步,這兩個(gè)容器的鏡像不太可能是一個(gè)團(tuán)隊(duì)開(kāi)發(fā)的,但是他們一塊兒工作才能提供一個(gè)微服務(wù);這種情況下,不同的團(tuán)隊(duì)各自開(kāi)發(fā)構(gòu)建自己的容器鏡像,在部署的時(shí)候組合成一個(gè)微服務(wù)對(duì)外提供服務(wù)

2.2副本復(fù)制器(RC)

通過(guò)監(jiān)控運(yùn)行中的Pod來(lái)保證集群中運(yùn)行指定數(shù)目的Pod副本。少于指定數(shù)目,RC就會(huì)啟動(dòng)運(yùn)行新的Pod副本;多于指定數(shù)目,RC就會(huì)殺死多余的Pod副本

2.3副本集(Replica Set,RS)

RS是新一代RC,提供同樣的高可用能力,區(qū)別主要在于RS后來(lái)居上,能支持更多種類(lèi)的匹配模式。副本集對(duì)象一般不單獨(dú)使用,而是作為Deployment的理想狀態(tài)參數(shù)使用

2.4部署(Deployment)

部署是一個(gè)比RS應(yīng)用模式更廣的API對(duì)象,支持動(dòng)態(tài)擴(kuò)展??梢詣?chuàng)建一個(gè)新的服務(wù),更新一個(gè)新的服務(wù),也可以是滾動(dòng)升級(jí)一個(gè)服務(wù)。滾動(dòng)升級(jí)一個(gè)服務(wù),實(shí)際是創(chuàng)建一個(gè)新的RS,然后逐漸將新RS中副本數(shù)增加到理想狀態(tài),將舊RS中的副本數(shù)減小到0的復(fù)合操作【逐步升級(jí)新得副本,剔除舊的副本】;

總結(jié):RC、RS和Deployment只是保證了支撐服務(wù)的微服務(wù)Pod的數(shù)量

2.5服務(wù)(Service)

RC、RS和Deployment只是保證了支撐服務(wù)的微服務(wù)Pod的數(shù)量,但是沒(méi)有解決如何訪問(wèn)這些服務(wù)的問(wèn)題。一個(gè)Pod只是一個(gè)運(yùn)行服務(wù)的實(shí)例,隨時(shí)可能在一個(gè)節(jié)點(diǎn)上停止,在另一個(gè)節(jié)點(diǎn)以一個(gè)新的IP啟動(dòng)一個(gè)新的Pod,因此不能以確定的IP和端口號(hào)提供服務(wù)。要穩(wěn)定地提供服務(wù)需要服務(wù)發(fā)現(xiàn)和負(fù)載均衡能力。服務(wù)發(fā)現(xiàn)完成的工作,是針對(duì)客戶端訪問(wèn)的服務(wù),找到對(duì)應(yīng)的的后端服務(wù)實(shí)例。在K8s集群中,客戶端需要訪問(wèn)的服務(wù)就是Service對(duì)象。

每個(gè)Service會(huì)對(duì)應(yīng)一個(gè)集群內(nèi)部有效的虛擬IP,集群內(nèi)部通過(guò)虛擬IP訪問(wèn)一個(gè)服務(wù)。在K8s集群中微服務(wù)的負(fù)載均衡是由Kube-proxy實(shí)現(xiàn)的。Kube-proxy是K8s集群內(nèi)部的負(fù)載均衡器。它是一個(gè)分布式代理服務(wù)器,在K8s的每個(gè)節(jié)點(diǎn)上都有一個(gè);這一設(shè)計(jì)體現(xiàn)了它的伸縮性優(yōu)勢(shì),需要訪問(wèn)服務(wù)的節(jié)點(diǎn)越多,提供負(fù)載均衡能力的Kube-proxy就越多,高可用節(jié)點(diǎn)也隨之增多。與之相比,我們平時(shí)在服務(wù)器端做個(gè)反向代理做負(fù)載均衡,還要進(jìn)一步解決反向代理的負(fù)載均衡和高可用問(wèn)題。

3 PodIP、ClusterIP和外部IP

3.1 Pod IP

Kubernetes的最小部署單元是Pod。利用Flannel作為不同HOST之間容器互通技術(shù)時(shí),由Flannel和etcd維護(hù)了一張節(jié)點(diǎn)間的路由表。Flannel的設(shè)計(jì)目的就是為集群中的所有節(jié)點(diǎn)重新規(guī)劃IP地址的使用規(guī)則,從而使得不同節(jié)點(diǎn)上的容器能夠獲得“同屬一個(gè)內(nèi)網(wǎng)”且”不重復(fù)的”IP地址,并讓屬于不同節(jié)點(diǎn)上的容器能夠直接通過(guò)內(nèi)網(wǎng)IP通信。

每個(gè)Pod啟動(dòng)時(shí),會(huì)自動(dòng)創(chuàng)建一個(gè)鏡像為gcr.io/google_containers/pause:0.8.0的容器,容器內(nèi)部與外部的通信經(jīng)由此容器代理,該容器的IP也可以稱(chēng)為Pod IP。

3.2 Cluster IP

Pod IP 地址是實(shí)際存在于某個(gè)網(wǎng)卡(可以是虛擬設(shè)備)上的,但Service Cluster IP就不一樣了,沒(méi)有網(wǎng)絡(luò)設(shè)備為這個(gè)地址負(fù)責(zé)。它是由kube-proxy使用Iptables規(guī)則重新定向到其本地端口,再均衡到后端Pod的。

就拿上面我們提到的圖像處理程序?yàn)槔?。?dāng)我們的Service被創(chuàng)建時(shí),Kubernetes給它分配一個(gè)地址10.0.0.1。這個(gè)地址從我們啟動(dòng)API的service-cluster-ip-range參數(shù)(舊版本為portal_net參數(shù))指定的地址池中分配,比如–service-cluster-ip-range=10.0.0.0/16。假設(shè)這個(gè)Service的端口是1234。集群內(nèi)的所有kube-proxy都會(huì)注意到這個(gè)Service。當(dāng)proxy發(fā)現(xiàn)一個(gè)新的service后,它會(huì)在本地節(jié)點(diǎn)打開(kāi)一個(gè)任意端口,建相應(yīng)的iptables規(guī)則,重定向服務(wù)的IP和port到這個(gè)新建的端口,開(kāi)始接受到達(dá)這個(gè)服務(wù)的連接。

當(dāng)一個(gè)客戶端訪問(wèn)這個(gè)service時(shí),這些iptable規(guī)則就開(kāi)始起作用,客戶端的流量被重定向到kube-proxy為這個(gè)service打開(kāi)的端口上,kube-proxy隨機(jī)選擇一個(gè)后端pod來(lái)服務(wù)客戶。這個(gè)流程如下圖所示:

根據(jù)Kubernetes的網(wǎng)絡(luò)模型,使用Service Cluster IP和Port訪問(wèn)Service的客戶端可以坐落在任意代理節(jié)點(diǎn)上。外部要訪問(wèn)Service,我們就需要給Service外部訪問(wèn)IP。

3.3外部IP

Service對(duì)象在Cluster IP range池中分配到的IP只能在內(nèi)部訪問(wèn),如果服務(wù)作為一個(gè)應(yīng)用程序內(nèi)部的層次,還是很合適的。如果這個(gè)Service作為前端服務(wù),準(zhǔn)備為集群外的客戶提供業(yè)務(wù),我們就需要給這個(gè)服務(wù)提供公共IP了。

外部訪問(wèn)者是訪問(wèn)集群代理節(jié)點(diǎn)的訪問(wèn)者。為這些訪問(wèn)者提供服務(wù),我們可以在定義Service時(shí)指定其spec.publicIPs,一般情況下publicIP 是代理節(jié)點(diǎn)的物理IP地址。和先前的Cluster IP range上分配到的虛擬的IP一樣,kube-proxy同樣會(huì)為這些publicIP提供Iptables 重定向規(guī)則,把流量轉(zhuǎn)發(fā)到后端的Pod上。有了publicIP,我們就可以使用load balancer等常用的互聯(lián)網(wǎng)技術(shù)來(lái)組織外部對(duì)服務(wù)的訪問(wèn)了。

spec.publicIPs在新的版本中標(biāo)記為過(guò)時(shí)了,代替它的是spec.type=NodePort,這個(gè)類(lèi)型的service,系統(tǒng)會(huì)給它在集群的各個(gè)代理節(jié)點(diǎn)上分配一個(gè)節(jié)點(diǎn)級(jí)別的端口,能訪問(wèn)到代理節(jié)點(diǎn)的客戶端都能訪問(wèn)這個(gè)端口,從而訪問(wèn)到服務(wù)。

3.4 Endpoint地址保持

Pod的endpointd地址會(huì)隨著pod的銷(xiāo)毀和重新創(chuàng)建而發(fā)生改變,因?yàn)樾碌膒od的ip地址和舊的pod的地址不同,service一旦創(chuàng)建,kubernetes會(huì)自動(dòng)為它分配一個(gè)可用cluster ip,而且在service的整個(gè)生命周期內(nèi),它的cluster ip不會(huì)發(fā)生改變。解決endpoint地址不發(fā)生改變的方法:只需要service的name與service的cluster ip地址做一個(gè)dns域名映射就可以解決。

3.5 namespace(命名空間)

Namespace(命名空間)是kubernetes系統(tǒng)中的一個(gè)重要概念,namespace在很多情況下用于實(shí)現(xiàn)多租戶的資源隔離。Namespace通過(guò)將集群內(nèi)部的資源對(duì)象“分配”到不同的namespace中,形成邏輯上分組的不同項(xiàng)目、小組或用戶組,便于不同的分組在共享使用整個(gè)集群的資源的同時(shí)還能被分別管理。如果不特別指明namespace,用戶創(chuàng)建的pod、rc、service都將被系統(tǒng)創(chuàng)建到這個(gè)默認(rèn)名為default的namespace中。當(dāng)我們給每個(gè)租戶創(chuàng)建一個(gè)namespace來(lái)實(shí)現(xiàn)多租戶的資源隔離,還能結(jié)合kubernetes的資源配額管理,限定不同租戶能占用的資源,例如cpu使用量,內(nèi)存使用量等。

3.6 mysql-rc.yaml詳解

apiVersion: V1

king: ReplicationController????? ---副本控制器rc

metadata:

?? name: mysql?????????????????? --- rc的名稱(chēng),全局唯一

spec:

?? replics :1??????????????????? --- pod副本期待數(shù)量

?? selector:

????? app: mysql?????????????? --- 符合目標(biāo)的pod擁有此標(biāo)簽

template:??????????????? ---根據(jù)此模板創(chuàng)建pod的副本(實(shí)例)

?? metadata:

????? labels:

??????? app: mysql?? --pod副本擁有的標(biāo)簽,對(duì)應(yīng)rc的selector

?? spec:

????? containers:???? -- pod內(nèi)容器的定義部分

name: mysql?? -- 容器的名稱(chēng)

image: mysql? -- 容器對(duì)應(yīng)的docker image

ports:

- containerPort: 3306? -- 容器暴露的端口號(hào)

env:??? -- 注入到容器內(nèi)的環(huán)境變量

- name: MYSQL_ROOT_PASSWORD

? Value: “123456”

Kind屬性:用來(lái)表示此資源對(duì)象的類(lèi)型,比如這里是replication,表示這是一個(gè)rc,Spec一節(jié)中是rc的相關(guān)屬性定義,比如spec.selector是rc的pod標(biāo)簽(label)選擇器,即監(jiān)控和管理?yè)碛羞@些標(biāo)簽的pod實(shí)例,確保當(dāng)前集群上始終有且僅有replicas哥pod實(shí)例在運(yùn)行,這里我們?cè)O(shè)置replicas=1表示只能運(yùn)行一個(gè)mysql pod實(shí)例。

3.7 mysql-svc.yaml

apiVersion: v1

kind: Service? --表明是kubernetes service

metadata:

?? name: mysql? -- service的全局唯一名稱(chēng)

spec:

? ports:

- port: 3306?? --service提供服務(wù)的端口號(hào)

? selector:

??? app: mysql???? -- services對(duì)應(yīng)的pod擁有這里定義的標(biāo)簽

metadata.name是service的服務(wù)名(servicename)

port屬性定義了service的端口

spec.selector確定了哪些pod副本(實(shí)例)對(duì)應(yīng)到本地服務(wù)

3.8 myweb-rc.yaml

king: ReplicationController

metadata:

?? name: myweb

spec:

?? replicas: 5

?? selector:

????? app: myweb

?? template:

?? ? metadata:

????? ? labels:

????????? app:myweb

?? spec:

???? containers:

?????? - name: myweb

???????? image:kubeguide/tomcat-app:v1

???????? ports:

???????? - containerPort: 8080

???????? env:

???????? - name: MYSQL_SERVICE_HOST

?????????? value: ‘mysql’

???????? - name: MYSQL_SERVICE_PORT

?????????? Value:? ‘3306’

該配置文件中的rc對(duì)應(yīng)的tomcat容器里引用了MYSQL_SERVICE_HOST=mysql這個(gè)環(huán)境變量,而mysql是我們之前定義的mysql服務(wù)的服務(wù)名

3.9 myweb-svc.yaml

apiVersion: V1

kind: Service

metadata:

?? name: myweb

spec:

?? type: NodePort

ports:

? - port: 8080

??? nodePort: 30001

?selector:

??? app: myweb

該配置文件中的type=nodeport和nodeport=30001這兩個(gè)屬性表示,表明此service開(kāi)啟了nodeport方式的外網(wǎng)訪問(wèn)模式

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容