kubernetes

kubernetes 簡介

一個迅速過一遍kubernetes 非常不錯的資源:
基于Kubernetes構建Docker集群管理詳解

kubernetes 出現(xiàn)原因

目前企業(yè)級應用出現(xiàn)的問題:

  1. 粗放型的技術團隊中開發(fā)人員直接與機器、操作系統(tǒng)打交道,無運維人員造成了大量的時間開銷,同時運維人員不了解相應的應用,出問題需要多方同時到位,進行解決。
  2. 系統(tǒng)的可用性和穩(wěn)定性很難得到保證
  3. 分布式應用及分布式系統(tǒng)門檻很高,需要長期的技術積累。

kubernetes 的出現(xiàn)即為了解決該問題,為各種各樣的開發(fā)完成的微服務能夠迅速服務千萬用戶的訪問。

解決上述問題即是kubernetes的設計目的:

  1. 隱藏資源管理和錯誤處理,用戶開發(fā)者僅需要關注應用的開發(fā)。
  2. 服務高可用、高可靠。
  3. 可將負載運行在由成千上萬的機器聯(lián)合而成的集群中,同時實現(xiàn)彈性伸縮。

Kubernetes對計算資源進行了更高層次的抽象,通過將容器進行細致的組合,將最終的應用服務交給用戶。

Kubernetes在模型建立之初就考慮了容器跨機連接的要求,支持多種網(wǎng)絡解決方案,同時在Service層次構建集群范圍的SDN網(wǎng)絡。其目的是將服務發(fā)現(xiàn)和負載均衡放置到容器可達的范圍,這種透明的方式便利了各個服務間的通信,并為微服務架構的實踐提供了平臺基礎。而在Pod層次上,作為Kubernetes可操作的最小對象,其特征更是對微服務架構的原生支持。

kubernetes 一次完整的工作流

說工作流之前附上參考鏈接:k8s 工作流參考鏈接

三個維度認識kubernetes

關于上圖需要補充兩點:

  1. 操作對象是基本對象,是k8s及用戶直接操作的對象單元。
  2. apiservver里面包含REST對象,其中REST對象起到了服務注冊的作用。

操作對象

Kubernetes以RESTFul形式開放接口,用戶可操作的REST對象有三個:

  • pod:是Kubernetes最基本的部署調(diào)度單元,可以包含container,邏輯上表示某種應用的一個實例。比如一個web站點應用由前端、后端及數(shù)據(jù)庫構建而成,這三個組件將運行在各自的容器中,那么我們可以創(chuàng)建包含三個container的pod。
  • service:是pod的路由代理抽象,用于解決pod之間的服務發(fā)現(xiàn)問題。因為pod的運行狀態(tài)可動態(tài)變化(比如切換機器了、縮容過程中被終止了等),所以訪問端不能以寫死IP的方式去訪問該pod提供的服務。service的引入旨在保證pod的動態(tài)變化對訪問端透明,訪問端只需要知道service的地址,由service來提供代理。
  • replicationController:是pod的復制抽象,用于解決pod的擴容縮容問題。通常,分布式應用為了性能或高可用性的考慮,需要復制多份資源,并且根據(jù)負載情況動態(tài)伸縮。通過replicationController,我們可以指定一個應用需要幾份復制,Kubernetes將為每份復制創(chuàng)建一個pod,并且保證實際運行pod數(shù)量總是與該復制數(shù)量相等(例如,當前某個pod宕機時,自動創(chuàng)建新的pod來替換)。

可以看到,service和replicationController只是建立在pod之上的抽象,最終是要作用于pod的,那么它們?nèi)绾胃鷓od聯(lián)系起來呢?這就要引入label的概念:label其實很好理解,就是為pod加上可用于搜索或關聯(lián)的一組key/value標簽,而service和replicationController正是通過label來與pod關聯(lián)的。如下圖所示,有三個pod都有l(wèi)abel為"app=backend",創(chuàng)建service和replicationController時可以指定同樣的label:"app=backend",再通過label selector機制,就將它們與這三個pod關聯(lián)起來了。例如,當有其他frontend pod訪問該service時,自動會轉(zhuǎn)發(fā)到其中的一個backend pod。

REST對象會寫入到etcd中

功能組件

如下圖所示是官方文檔里的集群架構圖,一個典型的master/slave(minion)模型。


master運行三個組件:

  • apiserver:作為kubernetes系統(tǒng)的入口,封裝了核心對象的增刪改查操作,以RESTFul接口方式提供給外部客戶和內(nèi)部組件調(diào)用。它維護的REST對象將持久化到etcd(一個分布式強一致性的key/value存儲)。
  • scheduler:負責集群的資源調(diào)度,為新建的pod分配機器。這部分工作分出來變成一個組件,意味著可以很方便地替換成其他的調(diào)度器。
  • controller-manager:負責執(zhí)行各種控制器,目前有兩類:
    • endpoint-controller:定期關聯(lián)service和pod(關聯(lián)信息由endpoint對象維護),保證service到pod的映射總是最新的。
    • replication-controller:定期關聯(lián)replicationController和pod,保證replicationController定義的復制數(shù)量與實際運行pod的數(shù)量總是一致的。
      slave(稱作minion)運行兩個組件:
  • kubelet:負責管控docker容器,如啟動/停止、監(jiān)控運行狀態(tài)等。它會定期從etcd獲取分配到本機的pod,并根據(jù)pod信息啟動或停止相應的容器。同時,它也會接收apiserver的HTTP請求,匯報pod的運行狀態(tài)。
  • proxy:負責為pod提供代理。它會定期從etcd獲取所有的service,并根據(jù)service信息創(chuàng)建代理。當某個客戶pod要訪問其他pod時,訪問請求會經(jīng)過本機proxy做轉(zhuǎn)發(fā)。

更簡單kubernetes架構圖:

工作流

上文已經(jīng)提到了Kubernetes中最基本的三個操作對象:pod, replicationController及service。下面分別從它們的對象創(chuàng)建出發(fā),通過時序圖來描述Kubernetes各個組件之間的交互及其工作流。

簡述createPod的過程:

  1. 客戶端提交創(chuàng)建請求,可以通過API Server的Restful API,也可以使用kubectl命令行工具。支持的數(shù)據(jù)類型包括JSON和YAML。
  2. API Server處理用戶請求,存儲Pod數(shù)據(jù)到etcd。
  3. 調(diào)度器通過API Server查看未綁定的Pod。嘗試為Pod分配主機。
  4. 過濾主機 (調(diào)度預選):調(diào)度器用一組規(guī)則過濾掉不符合要求的主機。比如Pod指定了所需要的資源量,那么可用資源比Pod需要的資源量少的主機會被過濾掉。
  5. 主機打分(調(diào)度優(yōu)選):對第一步篩選出的符合要求的主機進行打分,在主機打分階段,調(diào)度器會考慮一些整體優(yōu)化策略,比如把容一個Replication Controller的副本分布到不同的主機上,使用最低負載的主機等。
  6. 選擇主機:選擇打分最高的主機,進行binding操作,結(jié)果存儲到etcd中。
  7. kubelet根據(jù)調(diào)度結(jié)果執(zhí)行Pod創(chuàng)建操作: 綁定成功后,scheduler會調(diào)用APIServer的API在etcd中創(chuàng)建一個boundpod對象,描述在一個工作節(jié)點上綁定運行的所有pod信息。運行在每個工作節(jié)點上的kubelet也會定期與etcd同步boundpod信息,一旦發(fā)現(xiàn)應該在該工作節(jié)點上運行的boundpod對象沒有更新,則調(diào)用Docker API創(chuàng)建并啟動pod內(nèi)的容器。

kubernetes 相應的組件實現(xiàn)及原理

Kubernetes node有運行應用容器必備的服務,而這些都是受Master的控制。

每次個節(jié)點上當然都要運行Docker。Docker來負責所有具體的映像下載和容器運行。

Kubernetes主要由以下幾個核心組件組成:

etcd保存了整個集群的狀態(tài);

  • apiserver提供了資源操作的唯一入口,并提供認證、授權、訪問控制、API注冊和發(fā)現(xiàn)等機制;
  • controller manager負責維護集群的狀態(tài),比如故障檢測、自動擴展、滾動更新等;
  • scheduler負責資源的調(diào)度,按照預定的調(diào)度策略將Pod調(diào)度到相應的機器上;
  • kubelet負責維護容器的生命周期,同時也負責Volume(CVI)和網(wǎng)絡(CNI)的管理;
  • Container runtime負責鏡像管理以及Pod和容器的真正運行(CRI);
  • kube-proxy負責為Service提供cluster內(nèi)部的服務發(fā)現(xiàn)和負載均衡;

除了核心組件,還有一些推薦的Add-ons:

  • kube-dns負責為整個集群提供DNS服務
  • Ingress Controller為服務提供外網(wǎng)入口
  • Heapster提供資源監(jiān)控
  • Dashboard提供GUI
  • Federation提供跨可用區(qū)的集群
  • Fluentd-elasticsearch提供集群日志采集、存儲與查詢

幾個主要的組件

kubelet

kubelet負責管理pods和它們上面的容器,images鏡像、volumes、etc。

kube-proxy

每一個節(jié)點也運行一個簡單的網(wǎng)絡代理和負載均衡(詳見services FAQ )(PS:官方 英文)。 正如Kubernetes API里面定義的這些服務(詳見the services doc)(PS:官方 英文)也可以在各種終端中以輪詢的方式做一些簡單的TCP和UDP傳輸。

服務端點目前是通過DNS或者環(huán)境變量( Docker-links-compatible 和 Kubernetes{FOO}_SERVICE_HOST 及 {FOO}_SERVICE_PORT 變量都支持)。這些變量由服務代理所管理的端口來解析。

Kubernetes控制面板

Kubernetes控制面板可以分為多個部分。目前它們都運行在一個master 節(jié)點,然而為了達到高可用性,這需要改變。不同部分一起協(xié)作提供一個統(tǒng)一的關于集群的視圖。

etcd

所有master的持續(xù)狀態(tài)都存在etcd的一個實例中。這可以很好地存儲配置數(shù)據(jù)。因為有watch(觀察者)的支持,各部件協(xié)調(diào)中的改變可以很快被察覺。

etcd為了提高可靠性,可以使用多個master節(jié)點:

參考鏈接:搭建含三個master節(jié)點的kubernetes集群

需要注意的地方有:

  • kube-scheduler、kube-controller-manager 和 kube-apiserver 三者的功能緊密相關;
    同時只能有一個 kube-scheduler、kube-controller-manager 進程處于工作狀態(tài),如果運行多個,則需要通過選舉產(chǎn)生一個 leader;(raft算法)

Kubernetes API Server

API服務提供Kubernetes API (PS:官方 英文)的服務。這個服務試圖通過把所有或者大部分的業(yè)務邏輯放到不兩只的部件中從而使其具有CRUD特性。它主要處理REST操作,在etcd中驗證更新這些對象(并最終存儲)。

Scheduler

調(diào)度器把未調(diào)度的pod通過binding api綁定到節(jié)點上。調(diào)度器是可插拔的,并且我們期待支持多集群的調(diào)度,未來甚至希望可以支持用戶自定義的調(diào)度器。

Kubernetes控制管理服務器

所有其它的集群級別的功能目前都是由控制管理器所負責。例如,端點對象是被端點控制器來創(chuàng)建和更新。這些最終可以被分隔成不同的部件來讓它們獨自的可插拔。

replicationcontroller(PS:官方 英文)是一種建立于簡單的 pod API之上的一種機制。一旦實現(xiàn),我們最終計劃把這變成一種通用的插件機制。

kubernetes 常用名詞解釋與在整體架構中的作用

Pod

K8s有很多技術概念,同時對應很多API對象,最重要的也是最基礎的是微服務Pod。Pod是在K8s集群中運行部署應用或服務的最小單元,它是可以支持多容器的。Pod的設計理念是支持多個容器在一個Pod中共享網(wǎng)絡地址和文件系統(tǒng),可以通過進程間通信和文件共享這種簡單高效的方式組合完成服務。Pod對多容器的支持是K8s最基礎的設計理念。比如你運行一個操作系統(tǒng)發(fā)行版的軟件倉庫,一個Nginx容器用來發(fā)布軟件,另一個容器專門用來從源倉庫做同步,這兩個容器的鏡像不太可能是一個團隊開發(fā)的,但是他們一塊兒工作才能提供一個微服務;這種情況下,不同的團隊各自開發(fā)構建自己的容器鏡像,在部署的時候組合成一個微服務對外提供服務。

Pod是K8s集群中所有業(yè)務類型的基礎,可以看作運行在K8s集群中的小機器人,不同類型的業(yè)務就需要不同類型的小機器人去執(zhí)行。目前K8s中的業(yè)務主要可以分為長期伺服型(long-running)、批處理型(batch)、節(jié)點后臺支撐型(node-daemon)和有狀態(tài)應用型(stateful application);分別對應的小機器人控制器為Deployment、Job、DaemonSet和PetSet,本文后面會一一介紹。

復制控制器(Replication Controller,RC)

RC是K8s集群中最早的保證Pod高可用的API對象。通過監(jiān)控運行中的Pod來保證集群中運行指定數(shù)目的Pod副本。指定的數(shù)目可以是多個也可以是1個;少于指定數(shù)目,RC就會啟動運行新的Pod副本;多于指定數(shù)目,RC就會殺死多余的Pod副本。即使在指定數(shù)目為1的情況下,通過RC運行Pod也比直接運行Pod更明智,因為RC也可以發(fā)揮它高可用的能力,保證永遠有1個Pod在運行。RC是K8s較早期的技術概念,只適用于長期伺服型的業(yè)務類型,比如控制小機器人提供高可用的Web服務。

服務(Service)

RC、RS和Deployment只是保證了支撐服務的微服務Pod的數(shù)量,但是沒有解決如何訪問這些服務的問題。一個Pod只是一個運行服務的實例,隨時可能在一個節(jié)點上停止,在另一個節(jié)點以一個新的IP啟動一個新的Pod,因此不能以確定的IP和端口號提供服務。要穩(wěn)定地提供服務需要服務發(fā)現(xiàn)和負載均衡能力。服務發(fā)現(xiàn)完成的工作,是針對客戶端訪問的服務,找到對應的的后端服務實例。在K8s集群中,客戶端需要訪問的服務就是Service對象。每個Service會對應一個集群內(nèi)部有效的虛擬IP,集群內(nèi)部通過虛擬IP訪問一個服務。在K8s集群中微服務的負載均衡是由Kube-proxy實現(xiàn)的。Kube-proxy是K8s集群內(nèi)部的負載均衡器。它是一個分布式代理服務器,在K8s的每個節(jié)點上都有一個;這一設計體現(xiàn)了它的伸縮性優(yōu)勢,需要訪問服務的節(jié)點越多,提供負載均衡能力的Kube-proxy就越多,高可用節(jié)點也隨之增多。與之相比,我們平時在服務器端做個反向代理做負載均衡,還要進一步解決反向代理的負載均衡和高可用問題。

任務(Job)

Job是K8s用來控制批處理型任務的API對象。批處理業(yè)務與長期伺服業(yè)務的主要區(qū)別是批處理業(yè)務的運行有頭有尾,而長期伺服業(yè)務在用戶不停止的情況下永遠運行。Job管理的Pod根據(jù)用戶的設置把任務成功完成就自動退出了。成功完成的標志根據(jù)不同的spec.completions策略而不同:單Pod型任務有一個Pod成功就標志完成;定數(shù)成功型任務保證有N個任務全部成功;工作隊列型任務根據(jù)應用確認的全局成功而標志成功。

kubernetes 配置文件寫法

kubernentes 使用實例

一個非常不錯的kubernentes的例子:
參考鏈接

kubernetes 后面新加入了許多新的特性,但是通常一般來說主要定義三個kind,包括

service,rc,pod

service 用來服務注冊
rc 用來保持一定量的副本
pod 用來指明啟動的docker鏡像。

kubernetes 與fabric結(jié)合

從 fabric 的配置文件說起:

非常不錯的k8s整合fabric文檔

項目的github地址

k8s上面部署kubernentes文章主要分為幾個步驟:

  • 基礎設施:網(wǎng)絡、共享存儲。網(wǎng)絡解決的問題是通過docker.sock創(chuàng)建的容器k8s訪問不到。pv和pvc解決的是共享存儲的問題。
  • 組件劃分 namespace隔離 分為幾個部分,幾個pod。這塊和fabric關系比較緊密,決定了fabric的模板文件如何去寫。
  • 源代碼

附錄

Kubernetes支持2種服務發(fā)現(xiàn)方式,環(huán)境變量DNS。 其中環(huán)境變量是默認支持的,但是環(huán)境變量方式存在限制: Pod必須在Service之后創(chuàng)建,DNS則沒有這個限制。

為什么要使用kube-dns

簡單描述一句話:
創(chuàng)建service.yaml之后,仍需要獲取Service的Cluster-IP,再結(jié)合Port訪問服務。

雖然Service解決了Pod的服務發(fā)現(xiàn)和負載均衡問題,但存在著類似的問題:不提前知道Service的cluster-IP,還是需要改程序或配置啊??吹竭@里有沒有感覺身體被掏空?

service 比pod強了一點是service有個虛擬ip,它是不會改變的,訪問的時候通過serviceIp:port即可完成訪問。

但是service cluster IP還是必須查的。

kube-dns可以解決Service的發(fā)現(xiàn)問題,k8s將Service的名稱當做域名注冊到kube-dns中,通過Service的名稱就可以訪問其提供的服務。

一個service的實例。

{
    "kind": "Service",
    "apiVersion": "v1",
    "metadata": {
        "name": "my-service"
    },
    "spec": {
        "selector": {
            "app": "MyApp"
        },
        "ports": [
            {
                "protocol": "TCP",
                "port": 80,
                "targetPort": 9376
            }
        ]
    }
}

在yaml的配置文件中,Kubernetes 提供了一種新的部署,名為deployment,它繼承了絕大多數(shù)rc的特性,并且提供了更強的功能。

pv和pvc

在kubernentes整合fabric中用到了pv和pvc,它們二者的區(qū)別是:

PersistentVolume(pv)和PersistentVolumeClaim(pvc)是k8s提供的兩種API資源,用于抽象存儲細節(jié)。管理員關注于如何通過pv提供存儲功能而無需
關注用戶如何使用,同樣的用戶只需要掛載pvc到容器中而不需要關注存儲卷采用何種技術實現(xiàn)。

pv和pvc參考鏈接

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

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

  • Kubernetes作為容器應用的管理中心,通過對Pod的數(shù)量進行監(jiān)控,并且根據(jù)主機或容器失效的狀態(tài)將新的Pod調(diào)...
    輝耀輝耀閱讀 4,679評論 0 13
  • docker實現(xiàn)了更便捷的單機容器虛擬化的管理, docker的位置處于操作系統(tǒng)層與應用層之間; 相對傳統(tǒng)虛擬化(...
    Harvey_L閱讀 20,137評論 3 44
  • ?Kubernetes介紹1.背景介紹云計算飛速發(fā)展- IaaS- PaaS- SaaSDocker技術突飛猛進-...
    Zero___閱讀 14,860評論 0 21
  • 什么是泛型 泛型這個術語的概念是"適用于許多的類型" 為什么需要泛型 一般的類和方法,只能使用具體的類型,要么是基...
    宿命99閱讀 1,056評論 0 1
  • 我的第九幅彩鉛作品-愛心拖鞋。請多指教。
    高鑫麗閱讀 445評論 0 3

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