Introduction basic of kubernetes
我們要學習 Kubernetes Kubernetes ,就有首先了解 Kubernetes 的技術範圍、基礎理論知識庫等,要學習 Kubernetes,肯定要有入門過程,在這個過程中,學習要從易到難,先從基礎學習。
那麼 Kubernetes 的入門基礎內容(表示學習一門技術前先了解這門技術)包括哪些?
根據 Linux 開源基金會的認證考試,可以確認要了解 Kubernetes ,需要達成以下學習目標:
- Discuss Kubernetes.
- Learn the basic Kubernetes terminology.
- Discuss the configuration tools.
- Learn what community resources are available.
接下來筆者將一一介紹 Kubernetes 的一些概念(Discuss)、技術術語(Terminology)、相關配置工具以及社群開源資源(Community resources)。
本系列教程將會混雜一些英文,因為研究和使用 Kubernetes 的過程中,會接觸到大量英文,並且 Kubernetes 的國際認證考試,都是英文考試,多接觸一些英文單詞,慢慢積累吧。。。
本系列教程主要參考 Linux 開源基金會的課程內容及 Kubernetes 文件,課程內容按照 Attribution 3.0 Unported (CC BY 3.0) 協議,在寫作時參考、複製網站內容、共享知識庫等。關於 CC BY 3.0 協議,其說明如下:
- 共享—以任何媒介或格式複製和重新分發材料
- 適應-重新混合,變換並在材料上構建
- 出於任何目的,甚至出於商業目的。
Linux 開源基金會認證考試與課程學習網址:
https://training.linuxfoundation.org/#
使用條款:
https://www.linuxfoundation.org/terms/
學習 Kubernetes 後,可以進一步考取以下認證證書:
Kubernetes 管理員認證 (CKA)、Kubernetes 應用程式開發者認證 (CKAD)、Kubernetes安全專家認證 (CKS)。
What Is Kubernetes?
我們先思考一下,執行一個 Docker 容器,只需要使用 docker run ...
命令即可,這是相當簡單(relatibely simple)的方法。
但是,要實現以下場景,則是困難的:
- 跨多臺主機的容器相互連線(connecting containers across multiple hosts)
- 擴充容器(scaling containers)
- 在不停機的情況下配置應用(deploying applications without downtime)
- 在多個方面進行服務發現(service discovery among several aspects)
在 2008年,LXC(Linux containers) 釋出第一個版本,這是最初的容器版本;2013 年,Docker 推出了第一個版本;而 Google 則在 2014 年推出了 LMCTFY。
為了解決大叢集(Cluster)中容器部署、伸縮和管理的各種問題,出現了 Kubernetes、Docker Swarm 等軟體,稱為 容器編排引擎。
Kubernetes 是什麼?
"an open-source system for automating deployment, scaling, and management of containerized applications".
“一個自動化部署、可擴充和管理容器應用的開源系統”
Google 的基礎設施在虛擬機器(Virtual machines)技術普及之前就已經達到了很大的規模,高效地(Efficiency)使用叢集和管理分散式應用成為 Google 挑戰的核心。而容器技術提供了一種高效打包叢集的解決方案。
多年來,Google 一直使用 Borg 來管理叢集中的容器,積累了大量的叢集管理經驗和運維軟體開發能力,Google 參考 Borg ,開發出了 Kubernetes,即 Borg 是 Kubernetes 的前身。(但是 Google 目前還是主要使用 Borg)。
Kubernetes 從一開始就通過一組基元(primitives)、強大的和可擴充的 API 應對這些挑戰,新增新物件和控制器地能力可以很容易地地址各種各樣的產品需求(production needs)。
因為 Kubernetes 這個單詞不好發音,而 k 和 s 之間有 8 個單詞,因此一般大家都讀 k 8 s。而專為小型嵌入式裝置開發的 K3S 的原單詞是?我不知道???
Kubernetes 是使用 Go 語言編寫的。
當然,除了 Kubernetes ,還有 Docker Swarm、Apache Mesos、Nomad、Rancher 等軟體可以監控容器狀態、動態伸縮等。
Components of Kubernetes
Kubernetes 的元件分為兩種,分別是 Control Plane Components(控制平面元件)、Node Components(節點元件)。
Control Plane Components 用於對叢集做出全域性決策;
Node Components 在節點中執行,為 Pod 提供 Kubernetes 環境。
Docker 和 Kubernetes 並不是想上就上的,這可能需要改變開發模式和系統管理方法(system administration approach)。在傳統環境中,會在一臺專用伺服器(dedicated server)部署(Deploy)單一的應用(a monolithic application),當業務發展後,需要更大的流量頻寬、CPU和記憶體,這時可能對程式進行大量的定製(提高效能、快取優化等),同時也需要更換更大的硬體(hardware)。
而在使用 Kubernetes 的解決方案中,是使用更多的小型伺服器或者使用微服務的方式,去替代單一的、大型的一臺伺服器模式。
例如,為了保證服務可靠性,當一臺主機的服務程式掛掉後,會啟用另一臺伺服器去替代服務;如果單臺伺服器配置非常高,那麼成本必定也會很高,這種方案的實現成本會比較高。而使用 Kubernetes 的方案中,當一臺伺服器或程式掛掉後,啟動另一臺伺服器,可能只需要不到 1GB 的記憶體,更何況微服務可以實現應用模組解耦(decoupling)。
PS:現在大家使用的 Web 伺服器應該大多數是 Nginx,Nginx 正是支援負載均衡、反向代理、多伺服器配置等,非常適合微服務和多主機部署。而 Apache 的模式是使用許多 httpd 的守護程式(daemons) 去響應頁面請求。
將一個單一應用拆分為多個 microservice;將一臺高配置的伺服器改完多型小型伺服器,即 agent。接著便可以使用 Kubnentes 管理叢集。而為了管理多臺伺服器、多個服務例項,Kubernentes 提供了各種各樣的元件。
在 Kubernetes 中,在每臺小型伺服器上的部署的應用,我們稱 microservice(邏輯上) 或 agent(等同於一臺伺服器),應用的生命週期都是短暫(transient),因為一旦出現異常,都可能被替換掉。為了使用叢集中的多個 microservice,我們需要服務和 API 呼叫。一個服務需要連線到另一個服務,則需要 agent 跟 agent 之間通訊,例如 Web 需要連線到 資料庫。 Kubernetes 和 Consul 都有服務發現和網路代理或組網的功能,Kubernetes 提供了 kube-proxy ,Consul 提供了 Consul connect ,讀者可以單獨查閱資料瞭解。
讀者可以點選下面的連結瞭解更多 Components of Kubernetes 的知識:
https://www.vmware.com/topics/glossary/content/components-kubernetes
Kubernetes Architecture
上圖是簡單的 kubernetes 結構,左側虛線方框中,稱為 central manager (也叫master) ,意思是中心(central)管理器;而右側是三個工作節點(worker node),這些節點被稱為 minions 。這兩部分對應為 Master-Minions。
在 上圖中, Master 由多個元件構成:
- 一個 API 服務(kube-apiserver)
- 一個排程器(kube-scheduler)
- 各種各樣的控制器(上圖有兩個控制器)
- 一個儲存系統(這個元件稱為etcd),儲存叢集的狀態、容器的設定、網路配置等書籍
接下來我們將圍繞這張圖片,去學習那些 Kubernetes 中的術語和關鍵字。
Docker cgroup And namespace
我們知道,作業系統是以一個程式為單位進行資源排程的,現代作業系統為程式設定了資源邊界,每個程式使用自己的記憶體區域等,程式之間不會出現記憶體混用。Linux 核心中,有 cgroups 和 namespaces 可以為程式定義邊界,使得程式彼此隔離。
namespace
在容器中,當我們使用 top 命令或 ps 命令檢視機器的程式時,可以看到程式的 Pid,每個程式一個 Pid,而機器的所有容器都具有一個 Pid = 1 的基礎,但是為什麼不會發生衝突?容器中的程式可以任意使用所有埠,而不同容器可以使用相同的埠,為什麼不會發生衝突?這些都是名稱空間可以設定邊界的表現。
Linux 中,unshare 可以建立一個名稱空間(實際上是一個程式,名稱空間中的其它程式是這個程式的子程式),並且建立一些資源(子程式)。為了深刻理解 Docker 中的 namespace,我們可以在 Linux 中執行:
sudo unshare --fork --pid --mount-proc bash
然後執行 ps aux
檢視程式:
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 23612 3556 pts/1 S 21:14 0:00 bash
root 13 0.0 0.1 37624 3056 pts/1 R+ 21:14 0:00 ps aux
是不是跟 Docker 容器執行命令的結果相似?我們還可以使用 nsenter 命令進入另一個程式的名稱空間。
上面的程式碼中,--pid
引數程式碼建立 pid 名稱空間,但是因為並沒有隔離網路,因此當我們執行 netstat --tlap
命令時,這個名稱空間的網路跟其它名稱空間的網路還不是隔離的。
Linux 中的 namespace 型別有:
- mount :名稱空間具有獨立的掛載檔案系統;
- ipc:Inter-Process Communication (程式間通訊)名稱空間,具有獨立的訊號量、共享記憶體等;
- uts:名稱空間具有獨立的 hostname 、domainname;
- net:獨立的網路,例如每個 docker 容器都有一個虛擬網路卡;
- pid:獨立的程式空間,空間中的程式 Pid 都從 1 開始;
- user:名稱空間中有獨立的使用者體系,例如 Docker 中的 root 跟主機的使用者不一樣;
- cgroup:獨立的使用者分組;
Docker 中的名稱空間正是依賴 Linux 核心實現的。
cgroups
cgroups 可以限制程式可使用的記憶體、CPU大小。cgroups 全稱是 Control Groups,是 Linux 核心中的物理資源隔離機制。
為了避免篇幅過大,讀者只需要知道 Docker 限制容器資源使用量、CPU 核數等操作,其原理是 Linux 核心中的 cgroups 即可,筆者這裡不再贅述。
kube-apiserver
Kubernetes 通過 kube-apiserver 暴露一組 API,我們可以通過這些 API 控制 Kubernetes 的行為,而 kubernetes 有一個呼叫了這些 API 的本地客戶端,名為 kubectl。當然,我們也可以利用這些 API 開發出跟 kubectl 一樣強大的工具,例如網格管理工具 istio。
kube-scheduler
當要執行容器時,傳送的請求會被排程器(kube-scheduler)轉發到 API;排程器還可以尋找一個合適的節點執行這個容器。
node
叢集中的每個節點都會執行著兩個程式,分別是 kubelet,kube-proxy。(可以留意上圖的 Kubernetes Mimons 裡面)
在前面,我們知道當要執行一個容器時,需要排程器轉發 API,這個請求最終會傳送到 node 上的 kubelet,kubelet 可以接收 ”執行容器“ 的請求;kubelet 還可以管理那些必需的資源以及在本地節點上監控它們。
kube-proxy 可以建立和管理網路規則,以便在網路上公開容器。
Kubernetes Master 只能是 Linux,而 node 則可以是 Linux 和 Windows 等。
Terminology
本章將介紹一些 Kubenetes 的術語,以便提前瞭解 kubernetes 中的一些概念。本小節的內容並不會有太多解釋,因為每部分要講起來會很複雜,而這些在後面的 Kubernetes 技術中,都會單獨講解到,因此這裡只是介紹一些簡明的概念。讀者不需要仔細看,只需要概覽一遍即可。
Orchestration is managed
編排管理(Orchestration is managed) 是通過一系列的 監控迴圈(watch-loops)去控制或操作的;每個控制器(controller interogates) 都向 kube-apiserver 詢問物件狀態,然後修改它,直至達到條件。
容器編排是管理容器的最主要的技術。Dockers 也有其官方開發的 swarm 這個編排工具,但是在 2017 年的容器編排大戰中,swarm 敗於 Kubernetes。
namespace
Kubernetes 文件說,對於只有幾到幾十個使用者的叢集,根本不需要建立或考慮名字空間。這裡我們只需要知道,叢集資源被使用名字劃出來,資源之間可以隔離開,這種名字稱為名稱空間。當然這個名稱空間跟前面提到的 Linux 核心的名稱空間技術不同,讀者只需要瞭解到兩者的理念相通就行。
Pod
Pod 是 Kubernetes 中建立和管理的、最小的可部署的計算單元。
在前面的學習中,我們已經瞭解到 Kubernetes 是一個編排系統(orchestration system),用於部署(deploy)和管理容器。而容器,在 一個 Pod 上執行,一個 Pod 執行著多個 容器,並且這些容器共享著 IP 地址、訪問儲存系統和名稱空間。Kubernetes 通過名稱空間讓叢集中的物件相互隔離開,實現資源控制和多租戶(multi-tenant)連線。
Replication Controller
Replication Controller 簡稱 RC,應答控制器(Replication Controller) 用來部署和升級 Pod。
ReplicaSet
ReplicaSet 的目的是維護一組在任何時候都處於執行狀態的 Pod 副本的穩定集合。
如果 Pod 掛了,我們可以手工重啟 Pod,但是這種操作方法肯定不靠譜,不可能人力 24 小時以及瞬時執行完一系列命令。
Deployments
Deployment 提供了一種對 Pod 和 ReplicaSet 的管理方式。這裡不贅述,以後需要時再提及。
Kubernetes 物件
kubernetes 物件是持久化的實體,通過這些實體,可以雕塑整個叢集的狀態。這裡介紹一些物件資訊的表示。
- 物件名稱和 IDs:使用名稱、UID來表示其在同類資源中的唯一性;
- 名稱空間:即之前提到的 namespace;
- 標籤和選擇算符:標籤(Labels) 是附加到 Kubernetes 物件(比如 Pods)上的鍵值對;
- 註解:為物件附加的非標識的後設資料;
- 欄位選擇器:根據一個或多個資源欄位的值 篩選 Kubernetes 資源;