Kubernetes 入門基礎

我們要學習 Kubernetes,就有首先了解 Kubernetes 的技術範圍、基礎理論知識庫等,要學習 Kubernetes,肯定要有入門過程,在這個過程中,學習要從易到難,先從基礎學習。

接下來筆者將為大家講解 Kubernetes 各方面的知識,讓讀者了解 Kubernetes 是什麼。

本文為作者的 Kubernetes 系列電子書的一部分,電子書已經開源,歡迎關注,電子書瀏覽地址:

//k8s.whuanle.cn【適合中國訪問】

//ek8s.whuanle.cn 【gitbook】

Kubernetes 是什麼

在 2008 年,LXC(Linux containers) 發布第一個版本,這是最初的容器版本;2013 年,Docker 推出了第一個版本;而 Google 則在 2014 年推出了 LMCTFY

為了解決大集群(Cluster)中容器部署、伸縮和管理的各種問題,出現了 Kubernetes、Docker Swarm 等軟體,稱為 容器編排引擎

容器的產生解決了很多開發、部署痛點,但隨著雲原生、微服務的興起,純 Docker 出現了一些管理難題。我們先思考一下,運行一個 Docker 容器,只需要使用 docker run ... 命令即可,這是相當簡單(relatibely simple)的方法。

但是,要實現以下場景,則是困難的:

  • 跨多台主機的容器相互連接(connecting containers across multiple hosts)
  • 拓展容器(scaling containers)
  • 在不停機的情況下配置應用(deploying applications without downtime)
  • 在多個方面進行服務發現(service discovery among several aspects)

Kubernetes 是 Google 基於十多年的生產環境運維經驗,開發出的一個生產級別的容器編排系統。在 Kunernetes 文檔中,這樣描述 Kubernetes:

[Success]

“an open-source system for automating deployment, scaling, and management of containerized applications”.

「一個自動化部署、可拓展和管理容器應用的開源系統」

Google 的基礎設施在虛擬機(Virtual machines)技術普及之前就已經達到了很大的規模,高效地使用集群和管理分散式應用成為 Google 挑戰的核心,而容器技術提供了一種高效打包集群的解決方案。

多年來,Google 一直使用 Borg 來管理集群中的容器,積累了大量的集群管理經驗和運維軟體開發能力,Google 參考 Borg ,開發出了 Kubernetes,即 Borg 是 Kubernetes 的前身。(但是 Google 目前還是主要使用 Borg)。

Kubernetes 從一開始就通過一組基元(primitives)、強大的和可拓展的 API 應對這些挑戰,添加新對象和控制器地能力可以很容易地地址各種各樣的產品需求(production needs)。

編排管理是通過一系列的監控循環控制或操作的;每個控制器都向詢問對象狀態,然後修改它,直至達到條件為止。容器編排是管理容器的最主要的技術。Dockers 也有其官方開發的 swarm 這個編排工具,但是在 2017 年的容器編排大戰中,swarm 敗於 Kubernetes。

Kubernetes 集群的組成

在 Kubernets 中,運行應用程式的環境處於虛擬化當中,因此我們一般不談論硬體。

我們談起 Kubernetes 和應用部署時,往往會涉及到容器、節點、Pods 等概念,它們共同工作來管理容器化(containerized)應用的部署和執行,但是各種各樣的術語,令人眼花繚亂。為了更好地摸清 Kubernetes,下面我們將列舉這些有邊界的對象。

成分 名稱
Cluster 集群
Node 節點
Pod 不翻譯
Container 容器
Containerzed Application 容器化的應用

在 Kubernetes 中,不同的對象其管理的範圍、作用範圍不同,它們的邊界大小也不同。接下來的內容,按將從小到大的粒度介紹這些組成成分。

Pod

在上一章中已經介紹過,Pod 是 Kubernetes 中管理和調度的最小工作單位,Pod 中可以包含多個容器。這些容器會共享 Pod 中的網路等資源。當部署 Pod 時,會把一組關聯性較強的容器部署到同一個節點上。

pod1

而節點則是指一台伺服器、虛擬機等,運行著一個完整的作業系統,提供了 CPU、記憶體等計算資源,一個節點可以部署多個 Pod。

node1

而一個集群(Cluster)之中,運行著 N 台伺服器,即 N 個節點。這些節點有兩種,一種是 master 節點,一種是 worker 節點。master 節點運行著 Kubernetes 系統組件,而 worker 節點負責運行用戶的程式。所有節點都歸 master 管,我們通過命令、API 的方式管理 Kubernetes 集群時,是通過發送命令或請求到 master 節點上的系統組件,然後控制整個集群。

cluster1

另外,kubernetes 中有命名空間(namespace)的概念,這跟在 1.2 章中學習到的 Linux-namespace 類似,在一個集群中使用命名空間將不同的 Pod 隔離開來。但是 Kubernetes 中,不同 namespace 的 Pod 是可以相互訪問的,它們不是完全隔離的。

Kubernetes 結構

用圖來表示體系結構,是闡述 Kubernetes 最快的方式,下面是一張稱為 Kubernetes Architecture graphic 。

Kubernetes_Architecture_graphic

上圖是簡單的 kubernetes 結構,左側虛線方框中,是 master 節點,運行著各種各樣的組件,master 節點負責控制整個集群,當然在很大的集群中也可以有多個 master 節點;而右側是三個工作節點,負責運行我們的容器應用。這種結構一般稱為 master-slave 結構,因為某些原因,在 Kubernetes 中後來改稱為 master-minions。工作節點掛了沒關係,master 節點會將故障節點上的業務自動在另一個節點上部署。

工作節點比較簡單,在工作節點中,我們看到有 kubelet 和 kube-proxy 兩個組件,這兩個組件在上一章中接觸過了,kubelet 和 kube-proxy 都是跟 主節點的 kube-apiserver 進行通訊的。kube-proxy 全稱是 Kubenetes Service Proxy,負責組件之間的負載均衡網路流量。

在上圖中, 主節點由多個組件構成,結構比較複雜, 主節點中記錄了整個集群的工作數據,負責控制整個集群的運行。工作節點掛了沒關係,但是 主節點掛了,整個集群就掛了。因此, 有條件的情況下,也應該 設置多個 主節點。

一個 主節點中包含以下訪問:

  • 一個 API 服務(kube-apiserver)
  • 一個調度器(kube-scheduler)
  • 各種各樣的控制器(上圖有兩個控制器)
  • 一個存儲系統(這個組件稱為etcd),存儲集群的狀態、容器的設置、網路配置等數據。

這張圖片中還有很多東西,這裡暫時不作講解,我們在後面的章節再去學習那些 Kubernetes 中的術語和關鍵字。

組件

一個 kubernetes 集群是由一組被稱為節點的機器或虛擬機組成,節點有 master、worker 兩種類型。一個集群中至少有一個 master 節點,在沒有 worker 節點的情況下, Pod 也可以部署到 master 節點上。如果集群中的節點數量非常多,則可考慮擴展 master 節點,使用多個 master 節點控制集群。

在上一小節中,我們看到 主節點中包含了比較多的組件,工作節點也包含了一些組件,這些組件可以分為兩種,分別是 Control Plane Components(控制平面組件)、Node Components(節點組件)。

Control Plane Components 用於對集群做出全局決策,部署在 master 節點上;

Node Components 在 worker 節點中運行,為 Pod 提供 Kubernetes 環境。

Master 節點

Master 是由一組稱為控制平面組件組成的,如果你已經根據第二章中,通過 minikube 或 kubeadm 部署了 kubernetes,那麼我們可以打開 /etc/kubernetes/manifests/ 目錄,這裡存放了 k8s 默認的控制平面組件的 YAML 文件。

.
├── etcd.yaml
├── kube-apiserver.yaml
├── kube-controller-manager.yaml
└── kube-scheduler.yaml

對於集群來說, 這四個組件都是是必不可少的。

master

在結構圖中,還有一個 cloud-controller 組件,主要由雲平台服務商提供,屬於第三方組件,這裡不再討論。下面我們來了解 master 中的組件。

master 節點中各個組件(控制平面組件)需要使用到的埠:

協議 方向 埠範圍 作用 使用者
TCP 入站 6443 Kubernetes API 伺服器 所有組件
TCP 入站 2379-2380 etcd 伺服器客戶端 API kube-apiserver, etcd
TCP 入站 10250 Kubelet API kubelet 自身、控制平面組件
TCP 入站 10251 kube-scheduler kube-scheduler 自身
TCP 入站 10252 kube-controller-manager kube-controller-manager 自身

普通節點中各個組件需要使用到的埠:

協議 方向 埠範圍 作用 使用者
TCP 入站 10250 Kubelet API kubelet 自身、控制平面組件
TCP 入站 30000-32767 NodePort 服務† 所有組件

kube-apiserver

kube-apiserver 是 k8s 主要進程之一,apiserver 組件公開了 Kubernetes API (HTTP API),apiserver 是 Kubernetes 控制面的前端,我們可以用 Go、C# 等程式語言寫程式碼,遠程調用 Kubernetes,控制集群的運行。apiserver 暴露的 endiont 埠是 6443。

為了控制集群的運行,Kubernetes 官方提供了一個名為 kubectl 的二進位命令行工具,正是 apiserver 提供了介面服務,kubectl 解析用戶輸入的指令後,向 apiserver 發起 HTTP 請求,再將結果回饋給用戶。

[Info] kubectl

kubectl 是 Kubernetes 自帶的一個非常強大的控制集群的工具,通過命令行操作去管理整個集群。

Kubernetes 有很多可視化面板,例如 Dashboard,其背後也是調用 apiserver 的 API,相當於前端調後端。

總之,我們使用的各種管理集群的工具,其後端都是 apiserver,通過 apiserver,我們還可以訂製各種各樣的管理集群的工具,例如網格管理工具 istio。騰訊雲、阿里雲等雲平台都提供了在線的 kubernetes 服務,還有控制台可視化操作,也是利用了 apiserver。

etcd

etcd 是兼具一致性和高可用性的鍵值資料庫,作為保存 Kubernetes 所有集群數據的後台資料庫。apiserver 的所有操作結果都會存儲到 etcd 資料庫中,etcd 主要存儲 k8s 的狀態、網路配置以及其它持久化數據,etcd 是使用 B+ 樹實現的,etcd 是非常重要的組件,需要及時備份數據。

kube-scheduler

scheduler 負責監視新創建的 pod,並把 pod 分配到節點上。當要運行容器時,發送的請求會被調度器轉發到 API;調度器還可以尋找一個合適的節點運行這個容器。

kube-controller-manager

kube-controller-manager 中包含了多個控制器,它們都被編譯到一個二進位文件中,但是啟動後會產生不同的進程。這些控制器有:

  • 節點控制器(Node Controller)

    負責在節點出現故障時進行通知和響應

  • 任務控制器(Job controller)

    監測代表一次性任務的 Job 對象,然後創建 Pods 來運行這些任務直至完成

  • 端點控制器(Endpoints Controller)

    填充端點(Endpoints)對象(即加入 Service 與 Pod)

  • 服務帳戶和令牌控制器(Service Account & Token Controllers)

    為新的命名空間創建默認帳戶和 API 訪問令牌

控制器控制的 Pod、Job、Endpoints、Service 等,都是後面要深入學習的。