背景
這是在HWL負責網校雲業務線測試時,給同事分享的基礎概念文件。
目錄:
一. Docker核心概念
二. Kubernetes是什麼及架構
三. Kubernetes核心概念
四. Deployment部署Pod操作
一、Docker核心概念
1、為什麼是Docker
虛擬機器:
基礎設施(Infrastructure)。伺服器,或者是雲主機。
主作業系統(Host Operating System)。伺服器上執行的作業系統
虛擬機器管理系統(Hypervisor)。利用Hypervisor,可以在主作業系統之上執行多個不同的從作業系統。
從作業系統(Guest Operating System)。假設你需要執行3個相互隔離的應用,則需要使用Hypervisor啟動3個從作業系統,也就是3個虛擬機器。這些虛擬機器都非常大,也許有700MB,這就意味著它們將佔用2.1GB的磁碟空間。更糟糕的是,它們還會消耗很多CPU和記憶體。
各種依賴。每一個從作業系統都需要安裝許多依賴。
應用。安裝依賴之後,就可以在各個從作業系統分別執行應用了,這樣各個應用就是相互隔離的。
Docker:
Docker守護程序(Docker Daemon)。Docker守護程序取代了Hypervisor,它是執行在作業系統之上的後臺程序,負責管理Docker容器。
各種依賴。對於Docker,應用的所有依賴都打包在Docker映象中,Docker容器是基於Docker映象建立的。
應用。應用的原始碼與它的依賴都打包在Docker映象中,不同的應用需要不同的Docker映象。不同的應用執行在不同的Docker容器中,它們是相互隔離的。
對比虛擬機器與Docker
Docker守護程序可以直接與主作業系統進行通訊,為各個Docker容器分配資源;它還可以將容器與主作業系統隔離,並將各個容器互相隔離。虛擬機器啟動需要數分鐘,而Docker容器可以在數毫秒內啟動。由於沒有臃腫的從作業系統,Docker可以節省大量的磁碟空間以及其他系統資源。
2、Docker 架構
Docker使用客戶端 - 伺服器(C/S)架構,使用遠端API管理和建立Docker 容器。Docker 客戶端與Docker 守護程序通訊,後者負責構建、執行和分發Docker容器。
Docker客戶端和守護程序可以在同一系統上執行,也可以將Docker客戶端連線到遠端Docker守護程序。Docker客戶端和守護程序使用REST API,透過UNIX套接字或網路介面進行通訊。
Client
客戶端透過命令列或其他工具與守護程序通訊,客戶端會將這些命令傳送給守護程序,然後執行這些命令。命令使用Docker API,Docker客戶端可以與多個守護程序通訊。
Docker daemon
Docker守護程序(docker daemon)監聽Docker API請求並管理Docker物件,如映象,容器,網路和卷。守護程式還可以與其他守護程式通訊以管理Docker服務。
Docker Host
Docker Host是物理機或虛擬機器,用於執行Docker守護程序的倉庫。
Docker Registry
Docker倉庫用於儲存Docker映象,可以是Docker Hub這種公共倉庫,也可以是個人搭建的私有倉庫。使用docker pull或docker run命令時,將從配置的倉庫中提取所需的映象。使用docker push命令時,映象將被推送到配置的倉庫。
Docker Image
Docker 映象可以看作是一個特殊的檔案系統,除了提供容器執行時所需的程式、庫、資源、配置等檔案外,還包含了一些為執行時準備的一些配置引數(如匿名卷、環境變數、使用者等)。
映象可以用來建立 Docker 容器,一個映象可以建立很多容器。Docker 提供了一個很簡單的機制來建立映象或者更新現有的映象,使用者甚至可以直接從其他人那裡下載一個已經做好的映象來直接使用。
Docker Container
Docker 利用容器來執行應用。容器是從映象建立的執行例項。它可以被啟動、開始、停止、刪除。每個容器都是相互隔離的、保證安全的平臺。
可以把容器看做是一個簡易版的 Linux 環境(包括root使用者許可權、程序空間、使用者空間和網路空間等)和執行在其中的應用程式。
3、Docker CLI
4、Dockerfile
5、Docker Compose
Compose 是用於定義和執行多容器 Docker 應用程式的工具。透過 Compose,您可以使用 YML 檔案來配置應用程式需要的所有服務。然後,使用一個命令,就可以從 YML 檔案配置中建立並啟動所有服務。
6、Docker Swarm 叢集管理
Swarm是Docker 引擎內建(原生)的叢集管理和編排工具,它將 Docker 主機池轉變為單個虛擬 Docker 主機。
Docker Swarm 適用於簡單和快速開發至關重要的環境,而 Kubernetes 適合大中型叢集執行復雜應用程式的環境。
兩者不是競爭對手,各有利弊,因需選擇。
二、Kubernetes是什麼及架構
1、k8s是什麼
先來一張Kubernetes官網的截圖,可以看到,官方對Kubernetes的定義:Kubernetes(k8s)是一個自動化部署、擴充套件和管理容器化應用程式的開源系統。
Kubernetes 這個單詞是希臘語,它的中文翻譯是“舵手”或者“飛行員”。在一些常見的資料中也會看到“ks”這個詞,也就是“k8s”,它是透過將8個字母“ubernete ”替換為“8”而導致的一個縮寫。 Kubernetes 為什麼要用“舵手”來命名呢?
這是一艘載著一堆集裝箱的輪船,輪船在大海上運著集裝箱奔波,把集裝箱送到它們該去的地方。Container 這個英文單詞也有另外的一個意思就是“集裝箱”。Kubernetes 也就藉著這個寓意,希望成為運送集裝箱的一個輪船,來幫助我們管理這些集裝箱,也就是管理這些容器。
這個就是為什麼會選用 Kubernetes 這個詞來代表這個專案的原因。更具體一點地來說:Kubernetes 是一個自動化的容器編排平臺,它負責應用的部署、應用的彈性以及應用的管理。
2、k8s能做什麼
- 服務的發現與負載的均衡
- 容器的自動裝箱,也會把它叫做 scheduling,就是“排程”,把一個容器放到一個叢集的某一個機器上,Kubernetes會幫助我們去做儲存的編排,讓儲存的宣告週期與容器的生命週期建立連線
- 容器的自動化恢復。在一個叢集中,經常會出現宿主機的問題,導致容器本身的不可用,Kubernetes會自動地對這些不可用的容器進行恢復
- 應用的自動釋出與應用的回滾,以及與應用相關的配置密文的管理
- 對於 job 型別任務,Kubernetes可以去做批次的執行
- 為了讓這個叢集、這個應用更富有彈性,Kubernetes支援容器的水平伸縮
2.1排程
Kubernetes 可以把使用者提交的容器放到 Kubernetes 管理的叢集的某一臺節點上去。Kubernetes 的排程器是執行這項能力的元件,它會觀察正在被排程的這個容器的大小、規格。
比如,容器所需要的CPU以及它所需要的記憶體,然後在叢集中找一臺相對比較空閒的機器來進行一次放置的操作。
2.2 自動修復
Kubernetes 有節點健康檢查的功能,它會監測這個叢集中所有的宿主機,當宿主機本身出現故障,或者軟體出現故障的時候,這個節點健康檢查會自動對它進行發現。
接下來 Kubernetes 會把執行在這些失敗節點上的容器進行自動遷移,遷移到一個正在健康執行的宿主機上,來完成叢集內容器的自動恢復。
2.3 水平伸縮
Kubernetes有業務負載檢查的能力,它會監測業務上所承擔的負載,如果這個業務本身的CPU利用率或記憶體佔用過高,或者響應時間過長,它可以對這個業務進行一次擴容。
比如,下面的例子中,黃顏色的過度忙碌,Kubernetes就可以把黃顏色負載從一份變為三份。接下來,它就可以透過負載均衡把原來打到第一個黃顏色上的負載平均分到三個黃顏色的負載上去,以此來提高響應速度。
3、k8s的架構
Kubernetes 架構是一個比較典型的二層架構和server-client架構。Master作為中央管控節點,與Node建立連線。
所有 UI 的、clients、user側的元件,只會和Master進行連線,把希望的狀態或者想執行的命令下發給 Master,Master會把這些命令或者狀態下發給相應的節點,進行最終的執行。
- Master
Kubernetes 的Master包含四個主要的元件:API Server、Controller、Scheduler以及etcd。
API Server:提供了資源操作的唯一入口,並提供認證、授權、訪問控制、API註冊和發現等機制。
Kubernetes 中所有的元件都會和API Server進行連線,元件與元件之間一般不進行獨立的連線,都依賴於API Server進行訊息的傳送;
Controller:控制器,它負責維護叢集的狀態,比如故障檢測、自動擴充套件、滾動更新等。上面的2個例子,第1個自動對容器進行修復、第2個自動水平擴張,都是由Controller 完成的;
Scheduler:是排程器,負責資源的排程,按照預定的排程策略將Pod排程到相應的機器上。例如上面的例子,把使用者提交的pod,依據它對CPU、memory請求的大小,找一臺合適的節點,進行放置;
etcd:是一個分散式的儲存系統,儲存了整個叢集的狀態,比如Pod、Service等物件資訊。API Server 中所需要的原資訊都被放置在etcd中,etcd本身是一個高可用系統,透過etcd保證整個Kubernetes的Master元件的高可用性。
- Node
Kubernetes 的 Node 是真正執行業務負載的,每個業務負載會以 Pod 的形式執行。一個 Pod 中執行的一個或者多個容器。
kubelet:Master在Node節點上的Agent,是真正去執行 Pod 的元件,也是Node上最關鍵的元件,負責本Node節點上Pod的建立、修改、監控、刪除等生命週期管理,同時Kubelet定時“上報”本Node的狀態資訊到API Server。
它透過 API Server 接收到所需要 Pod 執行的狀態。然後提交到 Container Runtime 元件中。
Container Runtime:容器執行時。負責映象管理以及Pod和容器的真正執行(CRI),可以理解為類似JVM
Storage Plugin 或者 Network Plugin:對儲存跟網路進行管理
在 OS 上去建立容器所需要執行的環境,最終把容器或者 Pod 執行起來,也需要對儲存跟網路進行管理。Kubernetes 並不會直接進行網路儲存的操作,他們會靠 Storage Plugin 或者Network Plugin 來進行操作。使用者自己或者雲廠商都會去寫相應的 Storage Plugin 或者 Network Plugin,去完成儲存操作或網路操作。
Kube-proxy:負責為Service提供cluster內部的服務發現和負載均衡,完成 service 組網
在 Kubernetes 自己的環境中,也會有 Kubernetes 的 Network,它是為了提供 Service network 來進行搭網組網的。真正完成 service 組網的元件是 Kube-proxy,它是利用了 iptable 的能力來進行組建 Kubernetes 的 Network,就是 cluster network。
元件間的通訊
步驟說明:
1. 透過 UI 或者 CLI 提交1個 Pod 給 Kubernetes 進行部署,這個 Pod 請求首先會提交給API Server,下一步 API Server 會把這個資訊寫入到儲存系統 etcd,之後 Scheduler 會透過 API Server 的 watch機制得到這個資訊:有1個Pod 需要被排程。
2. Scheduler會根據node叢集的記憶體狀態進行1次排程決策,在完成這次排程之後,它會向 API Server 報告:“OK!這個 Pod 需要被排程到XX節點上。”
API Server 接收後,會把這次的操作結果再次寫到 etcd 中。
3. API Server 通知相應的節點進行這個Pod真正的執行啟動。相應節點的 kubelet 會得到通知,然後kubelet 會去調 Container runtime 來真正去啟動配置這個容器和這個容器的執行環境,去排程 Storage Plugin 來去配置儲存,network Plugin 去配置網路。
三、Kubernetes核心概念
第一個概念:Pod
Pod 是 Kubernetes 的最小排程以及資源單元。可以透過 Kubernetes 的 Pod API 生產一個 Pod,讓 Kubernetes 對這個 Pod 進行排程,也就是把它放在某一個 Kubernetes 管理的節點上執行起來。一個 Pod 簡單來說是對一組容器的抽象,它裡面會包含一個或多個容器。
比如下圖,它包含了兩個容器,每個容器可以指定它所需要資源大小
當然,在這個 Pod 中也可以包含一些其他所需要的資源:比如說我們所看到的 Volume 卷這個儲存資源。
第二個概念:Volume
管理 Kubernetes 儲存,用來宣告在 Pod 中的容器可以訪問的檔案目錄,一個卷可以被掛載在 Pod 中一個或者多個容器的指定路徑下面。
而 Volume 本身是一個抽象的概念,一個 Volume 可以去支援多種的後端的儲存。Kubernetes 的 Volume 支援很多儲存外掛,可以支援本地的儲存和分散式的儲存,比如像 ceph,GlusterFS;也可以支援雲端儲存,比如阿里雲上的雲盤、AWS 上的雲盤、Google 上的雲盤等等。
第三個概念:Deployment
Deployment 是在Pod上更為上層的一個抽象,它可以定義一組Pod 的副本數目、以及Pod的版本。一般用Deployment來做應用的真正的管理,而Pod是組成Deployment最小的單元。
Kubernetes透過 Controller(控制器)維護Deployment中Pod 的數目,Controller也會去幫助Deployment自動恢復失敗的Pod。
比如,可以定義一個Deployment,這個Deployment裡面需要2個Pod,當1個Pod失敗的時候,控制器就會監測到,再去新生成1個Pod,把Deployment中的Pod數目從1個恢復到2個。透過控制器,也可以完成釋出策略,比如進行滾動升級、重新生成的升級或者進行版本回滾。
第四個概念:Service
Service:提供1個或者多個 Pod 例項的穩定訪問地址
比如,一個 Deployment 可能有2個甚至更多個完全相同的 Pod。對於外部的使用者來講,訪問哪個 Pod 都是一樣的,所以希望做一次負載均衡,在做負載均衡的同時,只需要訪問某一個固定的 VIP,也就是 Virtual IP 地址,而不需要得知每一個具體的 Pod 的 IP 地址。
如果1個 Pod 失敗了,可能會換成另外一個新的。提供了多個具體的 Pod 地址,對外部使用者來說,要不停地去更新 Pod 地址。當這個 Pod 再失敗重啟之後,如果有一個抽象,把所有 Pod 的訪問能力抽象成1個第三方的 IP 地址,實現這個的 Kubernetes 的抽象就叫 Service。
實現 Service 有多種入口方式:
- ClusterIP:Service 在叢集內的唯一 ip 地址,我們可以透過這個 ip,均衡的訪問到後端的 Pod,而無須關心具體的 Pod。
- NodePort:Service 會在叢集的每個 Node 上都啟動一個埠,我們可以透過任意Node 的這個埠來訪問到 Pod。
- LoadBalancer:在 NodePort 的基礎上,藉助公有云環境建立一個外部的負載均衡器,並將請求轉發到 NodeIP:NodePort。
- ExternalName:將服務透過 DNS CNAME 記錄方式轉發到指定的域名(透過 spec.externlName 設定)。
第五個概念:Namespace
Namespace:用來做一個叢集內部的邏輯隔離,包括鑑權、資源管理等。Kubernetes 的每個資源,比如Pod、Deployment、Service 都屬於一個 Namespace,同一個 Namespace 中的資源需要命名的唯一性,不同的 Namespace 中的資源可以重名。
K8S的API
Kubernetes API 是由 HTTP+JSON 組成的:使用者訪問的方式是HTTP,訪問API 中 content 的內容是JSON格式的。
用Kubectl 命令、Kubernetes UI或者Curl,直接與Kubernetes互動都是使用 HTTP + JSON 的形式。
如下圖,對於這個Pod型別的資源,它的HTTP訪問的路徑就是 API,apiVesion: V1, 之後是相應的Namespaces,以及Pods資源,最終是 Podname,也就是Pod的名字。
當提交一個 Pod,或者 get 一個 Pod 的時候,它的 content 內容都是用JSON 或者是YAML表達的。上圖中YAML的例子,在這個YAML檔案中,對Pod資源的描述分為幾個部分。
第一個部分,一般是 API 的 version。比如在這個例子中是 V1,它也會描述我在操作哪個資源; kind 如果是 pod,在 Metadata 中,就寫上這個 Pod 的名字;比如nginx。也會給pod打一些 label,在 Metadata 中,有時候也會去寫 annotation,也就是對資源的額外的一些使用者層次的描述。
比較重要的一個部分叫 Spec,Spec 也就是希望 Pod 達到的一個預期的狀態。比如pod內部需要有哪些 container 被執行;這裡是一個name為nginx 的 container,它的 image 是什麼?它暴露的 port 是什麼?
當從 Kubernetes API 中去獲取這個資源的時候,一般在 Spec 下面會有一個status欄位 ,它表達了這個資源當前的狀態;比如一個 Pod 的狀態可能是正在被排程、或者是已經 running、或者是已經被 terminates(被執行完畢)。
Label是一個比較有意思的 metadata,可以是一組KeyValue的集合。
如下圖,第一個 pod 中,label 就可能是一個 color 等於 red,即它的顏色是紅顏色。當然也可以加其他 label,比如說 size: big 就是大小,定義為大的,它可以是一組label。
這些 label 是可以被 selector(選擇器)所查詢的。就好比sql 型別的 select 語句。
透過label,kubernetes 的API層就可以對這些資源進行篩選。
例如,Deployment可能代表一組Pod,是一組Pod 的抽象,一組Pod就是透過label selector來表達的。當然Service對應的一組Pod來對它們進行統一的訪問,這個描述也是透過label selector來選取的一組Pod。
四、Depolyment部署pod操作
螢幕。。。