(一)Kubernetes學習介紹

一、Kubernetes簡介

Kubernetes是Google於2014年開源的一個容器編排工具,使用Google自己的go語言編寫,由Borg衍生而來。Borg是Google內部已經運行近十年的容器編排工具,由於docker的橫空出世,導致Google原本準備作爲祕密武器的容器技術胎死腹中。計劃被打亂,容器層面已經痛失良機,慢人一步,只有在編排工具層面下手了,Google當機立斷,基於Brog的邏輯編寫了Kubernetes,開源並捐給了CNCF(雲遠程計算基金會),由於Google近十年的使用經驗,所以Kubernetes一出世就橫掃了其它編排工具,時至今日,地位依然穩固。

Kubernetes源於希臘語,有“舵”或“飛行員”的意思。k8s,是由Kubernetes中間的八個字母縮寫爲數字8得來的。Google採用這個名字的深意就是:既然你docker把自己定位成馱着集裝箱在大海上遨遊的鯨魚,那麼我就以Kubernetes掌舵大航海時代的話語權,鯨魚必須按照我設定的路線巡遊。

Kubernetes的一大亮點就是自動化,在Kubernetes的解決方案中,一個服務可以自我擴展、自我診斷,並且容易升級,在收到服務擴容的請求後,Kubernetes會觸發調度流程,最終在選定的目標節點上啓動相應數量的服務實例副本,這些實例在啓動成功後會自動加入負載均衡器中並生效,Kubernetes會定時巡查每個服務的所有實例的可用性,確保服務實例的數量與預期的數量一致,當它發現某個實例不可用時,會自動重啓或在其它節點上重建該實例,整個過程無需額外的人工操作。
——來自《Kubernetes權威指南》

在這裏插入圖片描述

二、Kubernetes對象

在這裏插入圖片描述
k8s的api是一種RESTful風格的API,在這種設計風格下,數據也好、服務也罷,一切都可以稱之爲資源(resources)。在k8s中將這些資源實例化後稱之爲對象。比如Pod在沒有使用之前就是一個抽象的概念,可以稱之爲資源,你指定爲Pod創建了容器之後,就可以稱之爲對象。

1、基礎對象

Pod

k8s最小部署單元是Pod,一個Pod可以包含一個或多個容器。

每一個Pod中默認有一個基礎設施容器infrastructure container,後續加進來的容器都會共享此基礎容器的Network、IPC、UTS名稱空間(共享網絡設備、網絡協議、主機名、域名等),因此同一個Pod中的容器可以通過lo互相通信。還可以選擇共享基礎容器的存儲卷。

每個Pod都會被分配一個單獨的IP地址,且每個Pod都提供了Endpoint(Pod IP+Container Port)以被客戶端訪問。

Pod分爲普通Pod和靜態Pod。

普通Pod一旦被創建,就會被放入etcd中存儲,隨後會被Master調度到某個Node上並進行綁定,隨後會被對應Node上的kubelet實例化成一組容器並啓動起來。如果Pod所在的Node宕機了,Master會將這個Node上的所有Pod重新調度到其它Node節點上。
靜態Pod不會存儲到etcd中,而是存放在某個Node節點上的一個具體文件中,並且只在此Node上啓動運行。

Service

在這裏插入圖片描述
Service是一組Pod的抽象,每個Service都擁有一個唯一指定的名字,並被分配一個虛擬IP(Cluster IP、Service IP或VIP)。Service通過代理後端Pod對外或者對內提供訪問,就好比nginx和後端服務的關係。來自這個IP的請求都會經過調度後轉發給後端Pod中的容器。Service通過LabelSelector去選擇一組Pod提供服務。下面會舉例Service和Pod如何關聯。

Label

label標籤用於區分對象,使用標籤引用對象而不再是IP地址。Label以鍵值對的形式存在,每個對象可以有多個標籤,通過標籤可以關聯對象。

假設Service代理一個或者多個Pod,但是某一個Pod因故障被刪重新調度出一個新Pod,那麼這個Pod的IP可能會發生改變,因爲容器的IP是隨機的。那Service怎麼能知道這個新Pod的IP呢。這時使用標籤就可以完美的解決問題。k8s中的Pod,所謂一個蘿蔔一個坑,只要不是手動刪除Pod,那麼這個Pod一定會一直存在,down掉會重啓,故障會重建。在最初創建Pod時,它的Label就已經寫死了,當然後面是可以手動改的。比如app:nginx。所以即便重建了Pod,IP變了,Label不會變。Service通過LabelSelector去找Label爲app:nginx的服務依然能夠找到。

Ingress

給Service提供外部訪問功能。

Namespace

可以抽象理解爲對象的集合。比如將集羣內部的對象劃分到不同得到項目組或用戶組。比如Pods、Services都是屬於某一個Namespace的(默認是default)。

Volume

數據卷,共享Pod中使用的數據。

2、高級對象

ReplicationController

簡稱RC。在舊版的k8s中,只有RC對象,使用它來確保Pod以用戶指定的副本數量運行。容器異常或者缺少都會自動處理。

ReplicaSet

ReplicaSet 是 ReplicationController 的替代物。因此作用基本相同,RC與RS唯一區別就是支持LableSelector不同,RS支持基於集合的標籤。官方建議使用Deployment來自動管理RS,因爲有些功能RS不支持,Deployment支持。

Deployment

Pod控制器,它支持版本記錄、回滾、暫停升級等高級特性。Pod是不可以被直接創建的,需要先創建控制器,然後由控制器去創建Pod。每個Pod都對應一個deployment控制器。
StatefulSet:爲了解決有狀態服務的問題(對應 Deployments 和 ReplicaSets是爲無狀態服務而設計)。

DaemonSet

保證在每個Node節點上都運行一個Pod,常用來部署一些集羣的日誌、監控等應用。比如fluentd、logstash、prometheus等。

Job

一次性任務,運行完後Pod銷燬,不再自動重建。

CronJob

定時任務

三、Kubernetes組件

Kubernetes的結構略微複雜,我會從大的層面一點點往下拆分敘述。整個Kubernetes集羣大致劃分爲四部分:Clients,Master,Node,Registry。k8s本身其實就Master和Node兩部分。

  • Master:是Kubernetes集羣的管理節點,是提供集羣資源訪問與管理的唯一入口。
  • Node:是Kubernetes集羣運行Pod的服務節點,實質上也就是運行容器。
  • Registry:容器的運行需要依賴於鏡像。
  • Clients:編程接口,圖形化接口,命令行接口。我們通過這些接口向Master發請求來管理容器,比如創建、刪除等操作,我們稱發起請求者爲管理客戶端(Clients)。

1、Master的組件

Master節點有四個核心組件,每一個組件都是單獨的服務,下面組件中只有etcd不是k8s自己提供,它只是k8s的主要組成部分,etcd也是CNCF的成員。

  • kube-apiserver:是整個k8s集羣對外提供服務的唯一接口,它提供請求過濾、訪問控制等機制,是各組件的協調者,此API是聲明式的(簡單說就是用戶想要什麼規格的容器直接跟kube-apiserver說就行了,過程不用你管)。用戶的合法請求會被API放行,然後存入etcd中。

是否合法指的是:etcd就好像公司領導,kuber-apiserver就是門口保安,領導規定,必須什麼樣的人你能放進來。k8s將etcd所能接受的數據規格範式加以封裝定義在了kube-apiserver中,符合規格才能放行。
程序的編程範式包括聲明式和命令式。聲明式強調結果;命令式強調過程。

  • kube-scheduler:資源調度器。kube-apiserver收到新建Pod的請求,識別其合法並存入etcd,然後kube-scheduler去watch kube-apiserver知道此需求,根據預定的調度策略評估出一個最合適Node節點來運行Pod,如果沒有最合適,那就隨機,最後會把調度的結果記錄在etcd中。

  • kube-controller:控制器。就好比人類的大腦一樣,負責維護集羣的狀態、故障檢測與恢復、自動擴展、節點狀態等等。kube-controller有一個control loop的機制,它會循環檢測集羣中Pod的狀態,假如Nginx啓的不是預期的80端口,那就由kube-controller來控制容器重啓、重建,直到達到預期效果爲止。

  • replication-controller:管理維護Replication Controller,關聯Replication Controller和Pod,保證Replication Controller定義的Pod副本數量與實際運行Pod數量一致。

  • etcd:是一個鍵值(key:value)格式的存儲系統,保存應用程序配置信息。

舉例:
用戶發送新建Nginx容器的請求給kube-apiserver,kube-apiserver識別其合法後以鍵值對的方式存入etcd,kube-scheduler和kube-controller通過watch
kube-apiserver知道此需求,然後kube-scheduler負責資源分配並決定容器運行在哪個Node上,至於運行時所需的鏡像及運行的健康狀態的維護都由kube-controller來負責,kube-controller會循環將當前容器的狀態與watch到的用戶預期的需求做對比,看是否匹配。

  • k8s watch功能:k8s提供的watch功能是建立在etcd之上的。早期的k8s架構中kube-apiserver、kube-controller、kube-scheduler、Kubelet等都是直接去watch
    etcd的,但是隨着實例的增多,對etcd造成的壓力也越來越大,因此,現在是當etcd中的鍵值發生變化時,通知kube-apiserver,其它的組件需要watch時去直接找kube-apiserver,這樣大大減小了etcd的壓力。

2、Node的組件

Node節點負責運行容器。下面的組件中docker並不是k8s的自己的組件。k8s支持多種容器引擎,比如Core OS的rkt,只不過k8s標準支持的容器是docker,其它容器引擎想要與k8s配合使用,需要接入到k8s的cri接口 。因爲不同容器技術的變動速度是不一樣,k8s只能以一個相對比較權威的容器技術來作爲標準,與之完美兼容。

  • kubelet:kubelet也會去watch kube-apiserver,如果發現有新任務的調度結果分到了自己這個Node節點上,便會接過來執行此任務。完成後將結果彙報給kube-apiserver。
  • docker:假如kubelet接過來的任務中是創建容器,那kubelet就會調docker組件在本節點上執行創建。
  • container runtime:負責pod和容器的運行,就是上面說的cri。
  • kubeletes-proxy:是用來維護Service網絡。根據Service的信息創建代理服務,實現Service到Pod的請求路由和轉發,本身也有負載均衡功能。支持 iptables 和 ipvs 兩種模式。

3、Addons

除了上面Master和Node的幾個核心組件,還有下面一些擴展插件,其中有些插件是非必須的。

  • Coredns:維護Service與cluster ip之間的對應關係
  • CNI:容器網絡接口。k8s的網絡模型需要藉助插件才能實現,比如flannel,calico等,flannel插件就是用來維護Pod網絡的。
  • Web UI(Dashboard):圖形界面,並非必須。
  • Fluentd:爲集羣提供日誌採集、存儲和查詢。
  • Traefik:Ingress Controller的軟件實現,爲pod中服務提供外網訪問。
  • Dashboard:管理k8s的圖形化界面。

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章