天天看點

從零開始入門 K8s| 阿裡技術專家詳解 K8s 核心概念

作者| 阿裡巴巴資深技術專家、CNCF 9個 TCO 之一 李響

一、什麼是 Kubernetes

Kubernetes,從官方網站上可以看到,它是一個工業級的容器編排平台。Kubernetes 這個單詞是希臘語,它的中文翻譯是“舵手”或者“飛行員”。在一些常見的資料中也會看到“ks”這個詞,也就是“K8s”,它是通過将 8 個字母“ubernete ”替換為“8”而導緻的一個縮寫。

Kubernetes 為什麼要用“舵手”來命名呢?大家可以看一下這張圖:

從零開始入門 K8s| 阿裡技術專家詳解 K8s 核心概念

這是一艘載着一堆集裝箱的輪船,輪船在大海上運着集裝箱奔波,把集裝箱送到它們該去的地方。我們之前其實介紹過一個概念叫做 container,container 這個英文單詞也有另外的一個意思就是“集裝箱”。Kubernetes 也就借着這個寓意,希望成為運送集裝箱的一個輪船,來幫助我們管理這些集裝箱,也就是管理這些容器。

這個就是為什麼會選用 Kubernetes 這個詞來代表這個項目的原因。更具體一點地來說:Kubernetes 是一個自動化的容器編排平台,它負責應用的部署、應用的彈性以及應用的管理,這些都是基于容器的。

二、Kubernetes 有如下幾個核心的功能:

  • 服務的發現與負載的均衡;
  • 容器的自動裝箱,我們也會把它叫做 scheduling,就是“排程”,把一個容器放到一個叢集的某一個機器上,Kubernetes 會幫助我們去做存儲的編排,讓存儲的聲明周期與容器的生命周期能有一個連接配接;
  • Kubernetes 會幫助我們去做自動化的容器的恢複。在一個叢集中,經常會出現主控端的問題或者說是 OS 的問題,導緻容器本身的不可用,Kubernetes 會自動地對這些不可用的容器進行恢複;
  • Kubernetes 會幫助我們去做應用的自動釋出與應用的復原,以及與應用相關的配置密文的管理;
  • 對于 job 類型任務,Kubernetes 可以去做批量的執行;
  • 為了讓這個叢集、這個應用更富有彈性,Kubernetes 也支援水準的伸縮。

下面,我們希望以三個例子跟大家更切實地介紹一下 Kubernetes 的能力。

1、排程

Kubernetes 可以把使用者送出的容器放到 Kubernetes 管理的叢集的某一台節點上去。Kubernetes 的排程器是執行這項能力的元件,它會觀察正在被排程的這個容器的大小、規格。

比如說它所需要的 CPU以及它所需要的 memory,然後在叢集中找一台相對比較空閑的機器來進行一次 placement,也就是一次放置的操作。在這個例子中,它可能會把紅顔色的這個容器放置到第二個空閑的機器上,來完成一次排程的工作。

從零開始入門 K8s| 阿裡技術專家詳解 K8s 核心概念

2、自動修複

Kubernetes 有一個節點健康檢查的功能,它會監測這個叢集中所有的主控端,當主控端本身出現故障,或者軟體出現故障的時候,這個節點健康檢查會自動對它進行發現。

下面 Kubernetes 會把運作在這些失敗節點上的容器進行自動遷移,遷移到一個正在健康運作的主控端上,來完成叢集内容器的一個自動恢複。

從零開始入門 K8s| 阿裡技術專家詳解 K8s 核心概念
從零開始入門 K8s| 阿裡技術專家詳解 K8s 核心概念

3、水準伸縮

Kubernetes 有業務負載檢查的能力,它會監測業務上所承擔的負載,如果這個業務本身的 CPU 使用率過高,或者響應時間過長,它可以對這個業務進行一次擴容。

比如說在下面的例子中,黃顔色的過度忙碌,Kubernetes 就可以把黃顔色負載從一份變為三份。接下來,它就可以通過負載均衡把原來打到第一個黃顔色上的負載平均分到三個黃顔色的負載上去,以此來提高響應的時間。

從零開始入門 K8s| 阿裡技術專家詳解 K8s 核心概念
從零開始入門 K8s| 阿裡技術專家詳解 K8s 核心概念

以上就是 Kubernetes 三個核心能力的簡單介紹。

三、Kubernetes 的架構

Kubernetes 架構是一個比較典型的二層架構和 server-client 架構。Master 作為中央的管控節點,會去與 Node 進行一個連接配接。

所有 UI 的、clients、這些 user 側的元件,隻會和 Master 進行連接配接,把希望的狀态或者想執行的指令下發給 Master,Master 會把這些指令或者狀态下發給相應的節點,進行最終的執行。

從零開始入門 K8s| 阿裡技術專家詳解 K8s 核心概念

Kubernetes 的 Master 包含四個主要的元件:API Server、Controller、Scheduler 以及 etcd。如下圖所示:

從零開始入門 K8s| 阿裡技術專家詳解 K8s 核心概念
  • API Server:顧名思義是用來處理 API 操作的,Kubernetes 中所有的元件都會和 API Server 進行連接配接,元件與元件之間一般不進行獨立的連接配接,都依賴于 API Server 進行消息的傳送;
  • Controller:是控制器,它用來完成對叢集狀态的一些管理。比如剛剛我們提到的兩個例子之中,第一個自動對容器進行修複、第二個自動進行水準擴張,都是由 Kubernetes 中的 Controller 來進行完成的;
  • Scheduler:是排程器,“排程器”顧名思義就是完成排程的操作,就是我們剛才介紹的第一個例子中,把一個使用者送出的 Container,依據它對 CPU、對 memory 請求大小,找一台合适的節點,進行放置;
  • etcd:是一個分布式的一個存儲系統,API Server 中所需要的這些原資訊都被放置在 etcd 中,etcd 本身是一個高可用系統,通過 etcd 保證整個 Kubernetes 的 Master 元件的高可用性。

我們剛剛提到的 API Server,它本身在部署結構上是一個可以水準擴充的一個部署元件;Controller 是一個可以進行熱備的一個部署元件,它隻有一個 active,它的排程器也是相應的,雖然隻有一個 active,但是可以進行熱備。

Kubernetes 的架構:Node

Kubernetes 的 Node 是真正運作業務負載的,每個業務負載會以 Pod 的形式運作。等一下我會介紹一下 Pod 的概念。一個 Pod 中運作的一個或者多個容器,真正去運作這些 Pod 的元件的是叫做 kubelet,也就是 Node 上最為關鍵的元件,它通過 API Server 接收到所需要 Pod 運作的狀态,然後送出到我們下面畫的這個 Container Runtime 元件中。

從零開始入門 K8s| 阿裡技術專家詳解 K8s 核心概念

在 OS 上去建立容器所需要運作的環境,最終把容器或者 Pod 運作起來,也需要對存儲跟網絡進行管理。Kubernetes 并不會直接進行網絡存儲的操作,他們會靠 Storage Plugin 或者是網絡的 Plugin 來進行操作。使用者自己或者雲廠商都會去寫相應的 Storage Plugin 或者 Network Plugin,去完成存儲操作或網絡操作。

在 Kubernetes 自己的環境中,也會有 Kubernetes 的 Network,它是為了提供 Service network 來進行搭網組網的。(等一下我們也會去介紹“service”這個概念。)真正完成 service 組網的元件的是 Kube-proxy,它是利用了 iptable 的能力來進行組建 Kubernetes 的 Network,就是 cluster network,以上就是 Node 上面的四個元件。

Kubernetes 的 Node 并不會直接和 user 進行 interaction,它的 interaction 隻會通過 Master。而 User 是通過 Master 向節點下發這些資訊的。Kubernetes 每個 Node 上,都會運作我們剛才提到的這幾個元件。

下面我們以一個例子再去看一下 Kubernetes 架構中的這些元件,是如何互相進行 interaction 的。

從零開始入門 K8s| 阿裡技術專家詳解 K8s 核心概念

使用者可以通過 UI 或者 CLI 送出一個 Pod 給 Kubernetes 進行部署,這個 Pod 請求首先會通過 CLI 或者 UI 送出給 Kubernetes API Server,下一步 API Server 會把這個資訊寫入到它的存儲系統 etcd,之後 Scheduler 會通過 API Server 的 watch 或者叫做 notification 機制得到這個資訊:有一個 Pod 需要被排程。

這個時候 Scheduler 會根據它的記憶體狀态進行一次排程決策,在完成這次排程之後,它會向 API Server report 說:“OK!這個 Pod 需要被排程到某一個節點上。”

這個時候 API Server 接收到這次操作之後,會把這次的結果再次寫到 etcd 中,然後 API Server 會通知相應的節點進行這次 Pod 真正的執行啟動。相應節點的 kubelet 會得到這個通知,kubelet 就會去調 Container runtime 來真正去啟動配置這個容器和這個容器的運作環境,去排程 Storage Plugin 來去配置存儲,network Plugin 去配置網絡。

這個例子我們可以看到:這些元件之間是如何互相溝通互相通信,協調來完成一次Pod的排程執行操作的。

四、Kubernetes 的核心概念與它的 API

核心概念

第一個概念:Pod

Pod 是 Kubernetes 的一個最小排程以及資源單元。使用者可以通過 Kubernetes 的 Pod API 生産一個 Pod,讓 Kubernetes 對這個 Pod 進行排程,也就是把它放在某一個 Kubernetes 管理的節點上運作起來。一個 Pod 簡單來說是對一組容器的抽象,它裡面會包含一個或多個容器。

比如像下面的這幅圖裡面,它包含了兩個容器,每個容器可以指定它所需要資源大小。比如說,一個核一個 G,或者說 0.5 個核,0.5 個 G。

當然在這個 Pod 中也可以包含一些其他所需要的資源:比如說我們所看到的 Volume 卷這個存儲資源;比如說我們需要 100 個 GB 的存儲或者 20GB 的另外一個存儲。

從零開始入門 K8s| 阿裡技術專家詳解 K8s 核心概念

在 Pod 裡面,我們也可以去定義容器所需要運作的方式。比如說運作容器的 Command,以及運作容器的環境變量等等。Pod 這個抽象也給這些容器提供了一個共享的運作環境,它們會共享同一個網絡環境,這些容器可以用 localhost 來進行直接的連接配接。而 Pod 與 Pod 之間,是互相有 isolation 隔離的。

第二個概念:Volume

Volume 就是卷的概念,它是用來管理 Kubernetes 存儲的,是用來聲明在 Pod 中的容器可以通路檔案目錄的,一個卷可以被挂載在 Pod 中一個或者多個容器的指定路徑下面。

而 Volume 本身是一個抽象的概念,一個 Volume 可以去支援多種的後端的存儲。比如說 Kubernetes 的 Volume 就支援了很多存儲插件,它可以支援本地的存儲,可以支援分布式的存儲,比如說像 ceph,GlusterFS ;它也可以支援雲存儲,比如說阿裡雲上的雲盤、AWS 上的雲盤、Google 上的雲盤等等。

從零開始入門 K8s| 阿裡技術專家詳解 K8s 核心概念

第三個概念:Deployment

Deployment 是在 Pod 這個抽象上更為上層的一個抽象,它可以定義一組 Pod 的副本數目、以及這個 Pod 的版本。一般大家用 Deployment 這個抽象來做應用的真正的管理,而 Pod 是組成 Deployment 最小的單元。

Kubernetes 是通過 Controller,也就是我們剛才提到的控制器去維護 Deployment 中 Pod 的數目,它也會去幫助 Deployment 自動恢複失敗的 Pod。

比如說我可以定義一個 Deployment,這個 Deployment 裡面需要兩個 Pod,當一個 Pod 失敗的時候,控制器就會監測到,它重新把 Deployment 中的 Pod 數目從一個恢複到兩個,通過再去新生成一個 Pod。通過控制器,我們也會幫助完成釋出的政策。比如說進行滾動更新,進行重新生成的更新,或者進行版本的復原。

從零開始入門 K8s| 阿裡技術專家詳解 K8s 核心概念

第四個概念:Service

Service 提供了一個或者多個 Pod 執行個體的穩定通路位址。

比如在上面的例子中,我們看到:一個 Deployment 可能有兩個甚至更多個完全相同的 Pod。對于一個外部的使用者來講,通路哪個 Pod 其實都是一樣的,是以它希望做一次負載均衡,在做負載均衡的同時,我隻想通路某一個固定的 VIP,也就是 Virtual IP 位址,而不希望得知每一個具體的 Pod 的 IP 位址。

我們剛才提到,這個 pod 本身可能 terminal go(終止),如果一個 Pod 失敗了,可能會換成另外一個新的。

對一個外部使用者來講,提供了多個具體的 Pod 位址,這個使用者要不停地去更新 Pod 位址,當這個 Pod 再失敗重新開機之後,我們希望有一個抽象,把所有 Pod 的通路能力抽象成一個第三方的一個 IP 位址,實作這個的 Kubernetes 的抽象就叫 Service。

實作 Service 有多種方式,Kubernetes 支援 Cluster IP,上面我們講過的 kuber-proxy 的組網,它也支援 nodePort、 LoadBalancer 等其他的一些通路的能力。

從零開始入門 K8s| 阿裡技術專家詳解 K8s 核心概念

第五個概念:Namespace

Namespace 是用來做一個叢集内部的邏輯隔離的,它包括鑒權、資源管理等。Kubernetes 的每個資源,比如剛才講的 Pod、Deployment、Service 都屬于一個 Namespace,同一個 Namespace 中的資源需要命名的唯一性,不同的 Namespace 中的資源可以重名。

Namespace 一個用例,比如像在阿裡巴巴,我們内部會有很多個 business units,在每一個 business units 之間,希望有一個視圖上的隔離,并且在鑒權上也不一樣,在 cuda 上面也不一樣,我們就會用 Namespace 來去給每一個 BU 提供一個他所看到的這麼一個看到的隔離的機制。

從零開始入門 K8s| 阿裡技術專家詳解 K8s 核心概念

Kubernetes 的 API

下面我們介紹一下 Kubernetes 的 API 的基礎知識。從 high-level 上看,Kubernetes API 是由 HTTP+JSON 組成的:使用者通路的方式是 HTTP,通路的 API 中 content 的内容是 JSON 格式的。

Kubernetes 的 kubectl 也就是 command tool,Kubernetes UI,或者有時候用 curl,直接與 Kubernetes 進行溝通,都是使用 HTTP + JSON 這種形式。

下面有個例子:比如說,對于這個 Pod 類型的資源,它的 HTTP 通路的路徑,就是 API,然後是 apiVesion: V1, 之後是相應的 Namespaces,以及 Pods 資源,最終是 Podname,也就是 Pod 的名字。

從零開始入門 K8s| 阿裡技術專家詳解 K8s 核心概念

如果我們去送出一個 Pod,或者 get 一個 Pod 的時候,它的 content 内容都是用 JSON 或者是 YAML 表達的。上圖中有個 yaml 的例子,在這個 yaml file 中,對 Pod 資源的描述也分為幾個部分。

第一個部分,一般來講會是 API 的 version。比如在這個例子中是 V1,它也會描述我在操作哪個資源;比如說我的 kind 如果是 pod,在 Metadata 中,就寫上這個 Pod 的名字;比如說 nginx,我們也會給它打一些 label,我們等下會講到 label 的概念。在 Metadata 中,有時候也會去寫 annotation,也就是對資源的額外的一些使用者層次的描述。

比較重要的一個部分叫做 Spec,Spec 也就是我們希望 Pod 達到的一個預期的狀态。比如說它内部需要有哪些 container 被運作;比如說這裡面有一個 nginx 的 container,它的 image 是什麼?它暴露的 port 是什麼?

當我們從 Kubernetes API 中去擷取這個資源的時候,一般來講在 Spec 下面會有一個項目叫 status,它表達了這個資源目前的狀态;比如說一個 Pod 的狀态可能是正在被排程、或者是已經 running、或者是已經被 terminates,就是被執行完畢了。

剛剛在 API 之中,我們講了一個比較有意思的 metadata 叫做“label”,這個 label 可以是一組 KeyValuePair。

比如下圖的第一個 pod 中,label 就可能是一個 color 等于 red,即它的顔色是紅顔色。當然你也可以加其他 label,比如說 size: big 就是大小,定義為大的,它可以是一組 label。

這些 label 是可以被 selector,也就是選擇器所查詢的。這個能力實際上跟我們的 sql 類型的 select 語句是非常相似的,比如下圖中的三個 Pod 資源中,我們就可以進行 select。name color 等于 red,就是它的顔色是紅色的,我們也可以看到,隻有兩個被選中了,因為隻有他們的 label 是紅色的,另外一個 label 中寫的 color 等于 yellow,也就是它的顔色是黃色,是不會被選中的。

從零開始入門 K8s| 阿裡技術專家詳解 K8s 核心概念

通過 label,kubernetes 的 API 層就可以對這些資源進行一個篩選,那這些篩選也是 kubernetes 對資源的集合所表達預設的一種方式。

例如說,我們剛剛介紹的 Deployment,它可能是代表一組的 Pod,它是一組 Pod 的抽象,一組 Pod 就是通過 label selector 來表達的。當然我們剛才講到說 service 對應的一組 Pod,就是一個 service 要對應一個或者多個的 Pod,來對它們進行統一的通路,這個描述也是通過 label selector 來進行 select 選取的一組 Pod。

是以可以看到 label 是一個非常核心的 kubernetes API 的概念,我們在接下來的課程中也會着重地去講解和介紹 label 這個概念,以及如何更好地去使用它。

五、以一個 demo 結尾

最後一部分,我想以一個例子來結束,讓大家跟我一起來嘗試一個 kubernetes,在嘗試 Kubernetes 之前,我希望大家能在本機上安裝一下 Kubernetes,安裝一個 Kubernetes 沙箱環境。

安裝這個沙箱環境,主要有三個步驟:

  • 首先需要安裝一個虛拟機,來在虛拟機中啟動 Kubernetes。我們會推薦大家利用 virtualbox 來作為虛拟機的運作環境;

安裝 VirtualBox:

https://www.virtualbox.org/wiki/Downloads
  • 其次我們需要在虛拟機中啟動 Kubernetes,Kubernetes 有一個非常有意思的項目,叫 minikube,也就是啟動一個最小的 local 的 Kubernetes 的一個環境。

minikube 我們推薦使用下面寫到的阿裡雲的版本,它和官方 minikube 的主要差別就是把 minikube 中所需要的 Google 上的依賴換成國内通路比較快的一些鏡像,這樣就友善了大家的安裝工作;

安裝 MiniKube(中國版):

https://yq.aliyun.com/articles/221687
  • 最後在安裝完 virtualbox 和 minikube 之後,大家可以對 minikube 進行啟動,也就是下面這個指令。

啟動指令:minikube start —vm-driver virtualbox

如果大家不是 Mac 系統,其他作業系統請通路下面這個連結,檢視其它作業系統如何安裝 minikube 沙箱環境。

https://kubernetes.io/docs/tasks/tools/install-minikube/

當大家安裝好之後,我會跟大家一起做一個例子,來做三件事情:

1.送出一個 nginx deployment;

kubectl apply  -f  

https://k8s.io/examples/application/deployment.yaml

2.更新 nginx deployment;

kubectl apply -f  

https://k8s.io/examples/application/deployment-update.yaml

3.擴容 nginx deployment。

第一步,我們送出一個 nginx 的 Deployment,然後對這個 Deployment 進行一次版本更新,也就是改變它中間 Pod 的版本。最後我們也會嘗試對 nginx 進行一次擴容,進行一次水準的伸縮,下面就讓大家一起跟我來嘗試這三個操作吧。

首先,我們先看一下 minikube 的 status,可以看到 kubelet master 和 kubectl 都是配置好的。

從零開始入門 K8s| 阿裡技術專家詳解 K8s 核心概念

下一步我們利用 kubectl 來看一下這個叢集中節選的狀态,可以看到這個master 的節點已經是running狀态:

從零開始入門 K8s| 阿裡技術專家詳解 K8s 核心概念

我們就以這個為節點,下面我們嘗試去看一下現在叢集中 Deployment 這個資源:

從零開始入門 K8s| 阿裡技術專家詳解 K8s 核心概念

可以看到叢集中沒有任何的 Deployment,我們可以利用 watch 這個語義去看叢集中 Deployment 這個資源的變化情況。

下面我們去做剛才想要的三個操作:第一個操作是去建立一個 Deployment。可以看到下面第一個圖,這是一個 API 的 content,它的 kind 是 Deployment,name 是 nginx-deployment, 有圖中它的 replicas 數目是2,它的鏡像版本是 1.7.9。

從零開始入門 K8s| 阿裡技術專家詳解 K8s 核心概念
從零開始入門 K8s| 阿裡技術專家詳解 K8s 核心概念

我們下面還是回到 kubectl 這個 commnd 來執行這次 Deployment 的真正的操作。我們可以看到一個簡單的操作,就會去讓 Deployment 不停地生成副本。

從零開始入門 K8s| 阿裡技術專家詳解 K8s 核心概念

Deployment 副本數目是 2 個,下面也可以 describe 一下現在的 Deployment 的狀态。我們知道之前是沒有這個 Deployment 的,現在我們去 describe 這個 nginx-deployment。

下圖中可以看到:有一個 nginx-deployment 已經被生成了,它的 replicas 數目也是我們想要的、selector 也是我們想要的、它的 image 的版本也是 1.7.9。還可以看到,裡面的 deployment-controller 這種版本控制器也是在管理它的生成。

從零開始入門 K8s| 阿裡技術專家詳解 K8s 核心概念

下面我們去更新這個 Deployment 版本,首先下載下傳另外一個 yaml 檔案 deployment-update.yaml,可以看到這裡面的 image 本身的版本号從 1.7.9 更新到 1.8。

從零開始入門 K8s| 阿裡技術專家詳解 K8s 核心概念

接下來我們重新 apply 新的 deployment-update 這個 yaml 檔案。

可以看到,在另一邊的螢幕上顯示出了這個 Deployment 更新的一些操作,最終它的 up-to-date 值從 0 變成了 2,也就是說所有的容器都是最新版本的,所有的 Pod 都是最新版本的。我們也可以 discribe 具體去看一下是不是所有 Pod 的版本都被更新了,可以看到這個 image 的版本由 1.7.9 真正更新到了 1.8。

最後,我們也可以看到  controller 又執行了幾次新的操作,這個控制器維護了整個 Deployment 和 Pod 狀态。

從零開始入門 K8s| 阿裡技術專家詳解 K8s 核心概念

最後我們示範一下給 Deployment 做水準擴張,下載下傳另一個 yaml 檔案 deployment-scale.yaml,這裡面的 replicas 數目已經從 2 改成了 4。

從零開始入門 K8s| 阿裡技術專家詳解 K8s 核心概念

回到最開始的視窗,用 kubectl 去 apply 這個新的 deployment-scale.yaml 檔案,在另外一個視窗上可以看到,當我們執行了 deployment-scale 操作之後,它的容器 Pod 數目從 2 變成了 4。我們可以再一次 describ 一下目前叢集中的 deployment 的情況,可以看到它的 replicas 的數目從 2 變到了 4,同時也可以看到 controller 又做了幾次新的操作,這個 scale up 成功了。

從零開始入門 K8s| 阿裡技術專家詳解 K8s 核心概念

最後,讓我們利用 delete 操作把我們剛才生成的 Deployment 給删除掉。kubectl delete deployment,也是剛才我們本身的 deployment name,當我們把它删除掉之後,我們今天所有的操作就完成了。

我們再去重新 get 這個 Deployment,也會顯示這個資源不再存在,這個叢集又回到了最開始幹淨的狀态。

從零開始入門 K8s| 阿裡技術專家詳解 K8s 核心概念

本文總結

本文我們關注了 Kubernetes 的核心概念以及 Kubernetes 的架構設計,主要有以下内容:

  • Kubernetes 是一個自動化的容器編排平台,它負責應用的部署、應用的彈性以及應用的管理,這些都是基于容器的;
  • Kubernetes 架構是一個比較典型的二層架構和 server-client 架構;
阿裡巴巴雲原生微信公衆号(ID:Alicloudnative)關注微服務、Serverless、容器、Service Mesh等技術領域、聚焦雲原生流行技術趨勢、雲原生大規模的落地實踐,做最懂雲原生開發者的技術公衆号。

繼續閱讀