Kubernetes 架構(gòu)介紹
上圖可見(jiàn)拯刁,kubernetes的節(jié)點(diǎn)角色分為 master 和 node, node 節(jié)點(diǎn)是真正工作的節(jié)點(diǎn),master 負(fù)責(zé)資源調(diào)度,所有的操作均通過(guò) master 端的 kube-apiserver 實(shí)現(xiàn),kube-apiserver 就是Kubernetes的牛鼻子。
1. Kubernetes 組件簡(jiǎn)介
1.1 Master 端
The Kubernetes Master is a collection of three processes that run on a single node in your cluster, which is designated as the master node. Those processes are: kube-apiserver, kube-controller-manager and kube-scheduler.
1.1.1 kube-apiserver
集群內(nèi)的各個(gè)功能模塊通過(guò)API Server將信息存入etcd沮峡,當(dāng)需要獲取和操作這些數(shù)據(jù)的時(shí)候,則通過(guò)API Server提供的REST接口來(lái)實(shí)現(xiàn)亿柑,從而實(shí)現(xiàn)各模塊這之間的信息交互邢疙。
-
與 kubelet 的交互
每個(gè)Node上的kubelet每隔一個(gè)時(shí)間周期,就會(huì)調(diào)用一次API Server的REST接口報(bào)告自身的狀態(tài)望薄,API Server將收到的信息放入etcd中疟游。此外,kubelet也通過(guò)API Server的Watch接口監(jiān)聽(tīng)Pod的信息痕支,根據(jù)監(jiān)聽(tīng)的變化颁虐,會(huì)相應(yīng)地修改本節(jié)點(diǎn)Pod容器。
-
與 kube-controller-manager 交互
kube-controller-manager 中的 Node Controller 模塊通過(guò)API Server提供的 watch 接口卧须,實(shí)時(shí)監(jiān)控 Node 信息另绩,并做相應(yīng)處理儒陨。
-
與 kube-scheduler 交互
通過(guò) watch 接口監(jiān)聽(tīng)到新建 Pod 副本信息后,它會(huì)檢索所有符合該 Pod 要求的 Node 列表笋籽,開(kāi)始執(zhí)行 Pod 調(diào)度邏輯蹦漠,調(diào)度到相應(yīng)的 Node 上。
1.1.2 kube-controller-manager
Controller Manager 作為集群內(nèi)的管理控制中心干签,負(fù)責(zé)集群內(nèi)的 Node津辩,Pod 副本,服務(wù)斷點(diǎn)(Endpoint), 命名空間容劳,服務(wù)賬號(hào),資源定額等的管理闸度,當(dāng)某個(gè) Node 意外宕機(jī)時(shí)竭贩,Controller Manager 會(huì)及時(shí)發(fā)現(xiàn)此故障并執(zhí)行自動(dòng)修復(fù)流程。
1.1.3 kube-scheduler
簡(jiǎn)單來(lái)說(shuō)莺禁, 就是通過(guò)調(diào)度算法調(diào)度為待調(diào)度 Pod 列表的每個(gè) Pod 從 Node列表中選擇一個(gè)最合適的 Node留量。隨后,kubelet 通過(guò) API Server監(jiān)聽(tīng)到 scheduler 產(chǎn)生的 Pod事件哟冬,然后獲取相應(yīng)的 Pod 清單楼熄,下載 image 鏡像,并啟動(dòng)容器浩峡。
1.2 Node 端
Each individual non-master node in your cluster runs two processes: kubelet, which communicates with the Kubernetes Master. kube-proxy, a network proxy which reflects Kubernetes networking services on each node.
1.2.1 kubelet
該進(jìn)程用于處理 Master 下發(fā)到本節(jié)點(diǎn)的任務(wù)可岂,管理 Pod 及 Pod 中的容器并堅(jiān)持容器的健康狀況。每個(gè) kubelet 進(jìn)程會(huì)在 API Server 上注冊(cè)節(jié)點(diǎn)信息翰灾,定期向 Master 節(jié)點(diǎn)匯報(bào)節(jié)點(diǎn)資源使用情況缕粹,并通過(guò) cAdvisor 監(jiān)控容器和節(jié)點(diǎn)資源。
1.2.2 kube-proxy
用來(lái)轉(zhuǎn)發(fā) service 中定義的服務(wù)纸淮,默認(rèn)采用 iptables 來(lái)實(shí)習(xí)轉(zhuǎn)發(fā)平斩,為了更好的性能,在 kubernetes 1.9 版本支持了 ipvs 的模式(目前還是beat版本), 轉(zhuǎn)發(fā)的流程大致如下:
client -> [service cluster_ip] -> kube-proxy -> [get pod_ip:pod_port from kube-api] -> pod
2. Kubernetes 中管理的資源
Kubernetes 作為目前最流行的一個(gè)容器調(diào)度管理平臺(tái)咽块, 它所管理的資源對(duì)象均是通過(guò) kube-apiserver 所創(chuàng)建管理绘面,下面我們就來(lái)看一看里面所管理的資源。
2.1 Pod
Pod是Kubernetes創(chuàng)建或部署的最小單位侈沪,一個(gè)Pod中可以包含一個(gè)或多個(gè)容器揭璃,如果是多個(gè)容器,這些容器是共享Pod中的一個(gè)網(wǎng)絡(luò)和存儲(chǔ)資源的峭竣。比方說(shuō)塘辅,我將一個(gè)front
應(yīng)用容器與一個(gè)backend
應(yīng)用容器部署在同一個(gè)Pod中,front
應(yīng)用可以直接通過(guò)localhost:backend_port
的形式調(diào)用backend
服務(wù)皆撩,因?yàn)樗鼈児灿靡粋€(gè)網(wǎng)絡(luò)扣墩,外部訪問(wèn)就通過(guò)pod_ip:front_port
哲银。
正常情況下,我們不會(huì)通過(guò)API來(lái)直接創(chuàng)建Pod呻惕,而是通過(guò)后面介紹的 Deployment
來(lái)創(chuàng)建管理Pod荆责,Deployment
是一種聲明式的,它可以聲明這個(gè)Pod的狀態(tài)亚脆,比如我希望這個(gè)Pod的個(gè)數(shù)是多少做院,kube-scheduler就會(huì)根據(jù)聲明的個(gè)數(shù)盡可能地調(diào)度和實(shí)現(xiàn),如果其中有Pod異常退出濒持,它馬上又會(huì)啟動(dòng)了一個(gè)新的键耕。
2.2 Static Pod
Static Pod
稱為靜態(tài)Pod, 與 Pod
的主要區(qū)別是 Static Pod
是由 Worker Node
節(jié)點(diǎn)上的 kubelet 進(jìn)行創(chuàng)建和管理的柑营,不能通過(guò)API Server進(jìn)行管理屈雄。
2.3 Replication Controller(RC)
RC是Kubernetes中的核心概念之一,簡(jiǎn)單來(lái)說(shuō)官套,它其實(shí)是定義了一個(gè)期望的場(chǎng)景酒奶,即聲明某種Pod的副本數(shù)量在任意時(shí)刻都符合某個(gè)預(yù)設(shè)值,所以RC的定義包括如下部分:
- Pod期待的副本數(shù)(replicas)
- 用語(yǔ)選擇目標(biāo)Pod的Label Selector
- 當(dāng)Pod的副本數(shù)量小于預(yù)設(shè)值奶赔,用于創(chuàng)建新Pod的Pod模版(template)
需要注意的是, 刪除RC并不會(huì)影響通過(guò)該RC創(chuàng)建好的Pod惋嚎,為了刪除所有的Pod,可以設(shè)置replicas=0, 然后更新該RC站刑。另外另伍,kubectl提供了stop和delete命令來(lái)一次性刪除RC和RC控制的全部Pod。
2.4 ReplicaSet
RS是上面RC的升級(jí)版本笛钝,质况,區(qū)別主要在于它可以使用更多的selector匹配模式,如正則玻靡,不等于等來(lái)實(shí)現(xiàn)目的结榄。
2.5 Deployment
A Deployment controller provides declarative updates for Pods and ReplicaSets.
Deployment是Kubernetes1.2引入的新概念,是ReplicaSet的一個(gè)更高級(jí)的接口囤捻,它是聲明式的臼朗,引入的目的是為了更好地解決Pod的編排問(wèn)題。Deployment相對(duì)RC的一個(gè)最大升級(jí)是我們可以隨時(shí)知道當(dāng)前Pod"部署"的進(jìn)度蝎土,也是官方推薦的管理Pod的方式视哑,下面我們就通過(guò) Deployment 來(lái)創(chuàng)建一個(gè) nginx Pod。
-
創(chuàng)建資源文件nginx-deployment.yaml
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80
-
通過(guò) kubectl 調(diào)用API創(chuàng)建資源
kubectl create -f nginx-deployment.yaml
-
查看運(yùn)行情況
kubectl get deployments # 查看Deployment rollout status kubectl rollout status deployment/nginx-deployment # 查看 ReplicaSet kubectl get rs # 查看 Pod kubectl get pods --show-labels
滾動(dòng)更新
比如誊涯,我們需要更新Pod中容器的 image tag
方法1:
kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
方法2 (交互式):
kubectl edit deployment/nginx-deployment
通過(guò) kubectl describe deployments
可以查看 rollout 日志
通過(guò) kubectl get rs
可以查看到新建的 rs
回滾 Deployment revision
-
查看 deployment 歷史
kubectl rollout history deployment/nginx-deployment # 查看具體某個(gè)版本的詳情 kubectl rollout history deployment/nginx-deployment --revision=2
-
回滾
kubectl rollout undo deployment/nginx-deployment --to-revision=2
擴(kuò)容 Pod
kubectl scale deployment nginx-deployment --replicas=10
2.6 DaemonSet
能夠讓所有(或者一些特定)的Node節(jié)點(diǎn)運(yùn)行同一個(gè)Pod挡毅。如果刪除DaemonSet,與之對(duì)應(yīng)的Pod也會(huì)刪除暴构。每個(gè)Node上僅運(yùn)行一次Pod副本實(shí)例跪呈。比如段磨,日志收集agent, 監(jiān)控agent等可以采用此方式運(yùn)行。
2.7 Service
Kubernetes里的每個(gè)Service其實(shí)就是我們經(jīng)常提起的微服務(wù)架構(gòu)中的一個(gè)"微服務(wù)", 定義了一個(gè)服務(wù)的訪問(wèn)入口耗绿。Service 通過(guò) labels
與指定的 Pod 綁定苹支,Service 會(huì)生成一個(gè) Cluster IP, 我們通過(guò)這個(gè) Cluster IP 就可以訪問(wèn)到Pod的資源了误阻。
Node 節(jié)點(diǎn)上的 kube-proxy
進(jìn)程通過(guò) watch
apiserver 中的 Pod 的變更债蜜,將與 Cluster IP 與 Pod 的規(guī)則放入 iptables 中,實(shí)現(xiàn)請(qǐng)求轉(zhuǎn)發(fā)究反,當(dāng) Client 請(qǐng)求的地址是 Cluster IP就會(huì)被 iptables 中的規(guī)則匹配寻定,根據(jù)指定的負(fù)載均衡算法,將請(qǐng)求轉(zhuǎn)發(fā)至Pod奴紧。
2.8 Volume
Kubernetes的Volume的概念特姐,用途和目的與Docker Volume比較類似,但兩者不等價(jià)黍氮。
首先,Kubernetes中的Volume定義在Pod上浅浮,然后一個(gè)Pod里的多個(gè)容器掛載到具體的文件目錄下沫浆;
其次,Kubernetes中的Volume與Pod的生命周期相同滚秩,但與容器的生命周期不相關(guān)专执,當(dāng)容器終止或重啟,Volume中的數(shù)據(jù)也不會(huì)丟失郁油;
要使用卷本股,需要為 pod 指定為卷( spec.volumes
字段) 以及將它掛載到容器的位置( spec.containeres.volumeMounts
字段)。
Kubernetes支持多中類型的Volume桐腌,有本地的拄显,有遠(yuǎn)程共享的,下面就例舉幾個(gè)常用的:
- emptyDir
當(dāng) Pod 被分配給節(jié)點(diǎn)時(shí)案站,首先創(chuàng)建 emptyDi
r 卷躬审,并且只要該 Pod 在該節(jié)點(diǎn)上運(yùn)行,該卷就會(huì)存在蟆盐。正如卷的名字所述承边,它最初是空的。Pod 中的容器可以讀取和寫入 emptyDir
卷中的相同文件石挂,盡管該卷可以掛載到每個(gè)容器中的相同或不同路徑上博助。當(dāng)出于任何原因從節(jié)點(diǎn)中刪除 Pod 時(shí),emptyDir
中的數(shù)據(jù)將被永久刪除痹愚。
注意:容器崩潰不會(huì)從節(jié)點(diǎn)中移除 pod富岳,因此 emptyDir
卷中的數(shù)據(jù)在容器崩潰時(shí)是安全的蛔糯。
emptyDir 的用法有:
- 暫存空間,例如用于基于磁盤的合并排序
- 用作長(zhǎng)時(shí)間計(jì)算崩潰恢復(fù)時(shí)的檢查點(diǎn)
- Web服務(wù)器容器提供數(shù)據(jù)時(shí)城瞎,保存內(nèi)容管理器容器提取的文件
示例:
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {}
- hostPath
hostPath
卷將主機(jī)節(jié)點(diǎn)的文件系統(tǒng)中的文件或目錄掛載到集群中渤闷。該功能大多數(shù) Pod 都用不到,但它為某些應(yīng)用程序提供了一個(gè)強(qiáng)大的解決方法脖镀。
例如飒箭,hostPath
的用途如下:
運(yùn)行需要訪問(wèn) Docker 內(nèi)部的容器;使用 /var/lib/docker
的 hostPath
在容器中運(yùn)行 cAdvisor蜒灰;使用 /dev/cgroups
的 hostPath
允許 pod 指定給定的 hostPath 是否應(yīng)該在 pod 運(yùn)行之前存在弦蹂,是否應(yīng)該創(chuàng)建,以及它應(yīng)該以什么形式存在
示例:
apiVersion: v1
kind: Pod
metadata:
name: test-pd
spec:
containers:
- image: k8s.gcr.io/test-webserver
name: test-container
volumeMounts:
- mountPath: /test-pd
name: test-volume
volumes:
- name: test-volume
hostPath:
# directory location on host
path: /data
# this field is optional
type: Directory