1. 程式人生 > 其它 >kubernetes(k8s)架構和元件,工作流程 ,資源

kubernetes(k8s)架構和元件,工作流程 ,資源

kubernetes 的基礎和架構

目錄

一: kubernetes 概述

1.1 K8S 是什麼

K8S 的全程是kubernetes (k8個字母s)

作用:

用於自動部署,擴充套件和管理 "容器化(containerized) 應用程式" 的開源系統。

可以理解成功k8s 是負責自動化運維管理多個容器化程式(比如Docker)的叢集,是一個生態及其豐富的容器編排框架工具


由來:

k8s 由google 的Borg系統(博格系統,google內部使用的大規模容器編排工具) 作為原型,後經過GO語言沿用Borg 的思路重寫並捐獻給CNCF基金會開源。


含義:

詞根源於希臘與的舵手,飛行員。


官網:

https://kubernetes.io


GitHub

https://github.com/kubernetes/kubernetes


中文社群:

https://www.kubernetes.org.cn/docs



1.2 為什麼使用k8s

1.2.1 傳統後端部署的方法和缺陷

傳統的後端部署方法:

把程式包(包括可執行二進位制檔案,配置檔案等)放到伺服器上,接著執行啟動指令碼把程式跑起來,同時啟動守護指令碼,定期檢查程式執行狀態,必要的話重新拉起程式


缺陷:

當服務的請求量上來,已部署的伺服器可能響應不過來。傳統的做法是當請求量,記憶體,cpu超過閾值做了告警,運維人員立即在部署幾臺伺服器,部署好服務之後,接入負載均衡來分擔已有的服務的壓力

但是,從監控告警到部署服務,中間需要人力介入!我們就可以使用k8s:自動化運維管理容器化程式,來自動完成服務的部署,更新,解除安裝,擴容,縮容


1.2.2 裸跑docker的缺陷

裸跑docker的缺陷:

  • 單機使用,無法有效叢集
  • 隨著容器數量的上升,管理成本攀升
  • 沒有有效的容災,自愈機制
  • 沒有預設編排模板,無法實現快速,大規模容器排程
  • 沒有同一的配置管理中心工具
  • 沒有容器生命週期的管理工具
  • 沒有圖形化運維管理工具

而k8s可以有效的解決這些缺陷



1.3 k8s的特性

k8s提供了容器編排,資源排程,彈性伸縮,部署管理,服務發現等一些列功能

k8s 的特性:

  • 彈性伸縮
    • 使用命令,UI或者基於cpu使用情況自動快速擴容和縮容應用程式例項,保證業務高峰併發時的高可用性
    • 業務低峰時回收資源,以最小成本執行服務
  • 自我修復
    • 在節點故障時重新啟動失敗的容器,替換和重新部署,保證預期的副本數量
    • 殺死健康檢查失敗的容器,並且在未準備好之前不會處理客戶端請求,確保線上服務不中斷
  • 服務發現和負載均衡
    • k8s為多個容器提供一個統一訪問入口(內部IP地址和一個DNS名稱),並且負載均衡關聯的所有容器,使得使用者無需考慮容器IP問題
  • 自動釋出(預設滾動釋出模式)和回滾
    • k8s採用滾動更新策略更新應用,一次更新一個pod,而不是刪除所有pod
    • 如果更新過程中出現問題,將回滾更改,確保升級不影響業務
  • 集中化配置管理和金鑰管理
    • 管理機密資料和應用程式配置,而不需要把敏感資料暴露在映象裡,提高敏感資料安全性
    • 可以將一些常用的配置儲存在k8s中,方便應用程式使用
  • 儲存編排,支援外掛儲存並對外掛儲存資源進行編排
    • 掛載外部存系統,無論是來自本地儲存,公有云(如AWS),還是網路儲存(如NFS,GFS,Ceph)都作為叢集資源的一部分使用,極大提高儲存使用靈活性。
  • 任務批處理執行:
    • 提供一次性任務,定時任務
    • 滿足批量資料吹和分析的場景



二: kubernetes叢集架構和核心元件

2.1 叢集架構

k8s是屬於主從裝置模型(Master-Slave架構),即有Master節點負責叢集的排程,管理和運維,Slave節點時叢集中的運算工作負載節點。

在K8S中,主節點一般稱為Master節點,而從節點則被稱為Worker Node節點,每個Node都會被Master分配一些工作負載。


Master元件可以在叢集中的任何計算機上執行,但建議Master節點佔據一個獨立的伺服器。因為Master是整個叢集的大腦,如果Master所在的節點宕機或不可用,那麼所有的控制命令都將失效。除了Master節點,在k8s叢集中的其他機器都被稱為Worker Node節點,當某個Node宕機時,其上的工作負載會被Master自動轉移到其他節點上。


2.2 Master元件部分

2.2.1 kube-apiserver

  • 用於暴露kubernetes API ,任何資源請求或呼叫操作都是通過 kube-apiserver 提供的介面進行。
  • 以HTTP,Restful API 提供介面服務,所有物件資源的增刪改查和監聽操作都交給API Server 處理後再提交給Etcd儲存
  • 可以理解為API Server 是k8s的請求入口服務。API Server 負責接收 K8S所有請求(來自 UI介面或者 CLI 命令列工具),然後根據使用者的具體請求,去通知其他元件幹活。可以說,API Server 是K8S叢集架構的大腦

2.2.2 kube-controller-manager

  • 執行管理控制器,是k8s叢集中處理常規任務的後臺執行緒,是k8s叢集裡所有資源物件的自動化控制中心
  • 在k8s叢集中,一個資源對應一個控制器,而controller manager 就是負責管理這些控制器的
  • 由一些列控制器組成,通過API Server 監控整個叢集的狀態,並確保叢集處於預期的工作狀態,比如當某個Node意外宕機時,Controller Manager 會及時發現並執行自動化修復流程,確保叢集始終處於預期工作狀態
  • 這些控制器主要包括:
    • Node Controller(節點控制器):負責在節點出現故障時發現和響應
    • Replication Controller(副本控制器):負責保證叢集中一個RC(資源物件Replicaion Contraller)所關聯的Pod副本數始終保持在預設值。可以理解成確保叢集中有且僅有N個Pod例項,N是RC中定義的Pod副本數量
    • Endpoints Controller(端點控制器):填充端點物件(即連線Services和Pods),負責監聽Service和對應Pod副本的變化。可以理解端點是一個服務暴露出來的訪問點,如果需要訪問一個服務,則必須知道它的endpoint
    • Service Accont && Token Controllers(服務賬戶和令牌控制器):為新的名稱空間建立預設賬戶和API訪問令牌。
    • ResourceQuota Controller (資源配置控制器):確保指定的資源物件在任何時候都不會超量佔用系統物理資源
    • Namespace Controller(名稱空間控制器):管理namespace的生命週期
    • Service Controller(服務控制器):屬於K8S叢集與外部的雲平臺之間的一個介面控制器

2.2.3 Kube-scheduler

  • 是負責資源排程的程序,根據排程演算法為新建立的Pod選擇一個合適的Node節點。

  • 可以理解成 K8S 所有 Node 節點的排程器。當用戶要部署服務時,Scheduler 會根據排程演算法選擇最合適的 Node 節點來部署 Pod,先使用預算策略在使用優選策略

    • 預算策略(predicate)
    • 優選策略(priorities)



2.3 etcd儲存中心

  • K8S 的儲存服務
  • etcd是分散式鍵值儲存系統,儲存了K8S的關鍵配置和使用者配置。
  • K8S中僅API Server 才具備讀寫許可權,其他元件必須通過API Server的接口才能讀寫資料



2.4 worker node 元件

2.4.1 Kubelet 元件

監視node 節點上的資源和服務狀態,並彙報給master節點的apiserver;和容器引擎互動,實現容器的生命週期管理

  • Node 節點的監視器,以及與 Master 節點的通訊器

    • Kubelet 是 Master 節點安插在 Node 節點上的 "眼線",它會定時向 API Server 彙報自己Node 節點上執行的服務的狀態,並接受來自 Master 節點的指示採取調整措施。
  • 從 Master 節點獲取自已節點上 Pod 的期望狀態(比如執行什麼容器、執行的副本數量、網路或者儲存如何配置等),直接跟容器引擎互動實現容器的生命週期管理,如果自已節點上Pod 的狀態與期望狀態不一致,則呼叫對應的容器平臺介面 (即 docker 的介面)達到這個狀態。

  • 管理映象和容器的清理工作,保證節點上映象不會佔滿磁碟空間,退出的容器不會佔用太多資源。


2.4.2Kube-Proxy

  • 在每個 Node 節點上實現 Pod 網路代理,是 Kubernetes Service 資源的載體,負責維護網路規則和四層負載均衡工作。負責寫入規則至iptables、ipvs實現服務對映訪問的。
  • Kube-Proxy本身不是直接給 Pod 提供網路,Pod 的網路是由 Kubelet 提供的,Kube-Proxy 實際上維護的是虛擬的 Pod 叢集網路。
  • Kube-apiserver 通過監控 Kube-Proxy 進行對 Kubernetes Service 的更新和端點的維護。
  • 在 K8S 叢集中微服務的負載均衡是由 Kube-proxy 實現的。****Kube-proxy 是 K8S 叢集內部的負載均衡器。它是一個分散式代理伺服器,在 K8S 的每個節點上都會執行一個 Kube-proxy 元件。

2.4.3 docker 或rocket

  • 容器引擎,執行容器,負責本機的容器建立和管理工作。



2.5 kubernetes 的工作過程

  1. 使用者通過客戶端傳送請求給叢集的唯一入口 API Server
  2. API Server 先將使用者的請求資訊寫入到 etcd儲存中。再去找Controller manager 建立對應的pod
  3. Controller Manager通過API Server 去讀取etcd 裡的使用者請求資訊,根據請求去預設的模板(如什麼映象,多少例項,健康檢查等),將模板寫入到etcd中,在根據模板建立pod
  4. Controller Manager 通過 API Server 去找到Scheduler排程pod,為新建立的Pod選擇node節點
  5. Scheduler 通過API Server 再etcd 儲存中讀取node節點的資源資訊,通過預算策略和優選策略,從node節點中挑選最優的,並把pod排程到這個節點執行。
    1. 預算策略:將所有node節點的剩餘資源和pod所需的資源對比,找出符合pod資源需求的node節點
    2. 優選策略:預算策略篩選後的node節點被交給優選策略。通過cpu負載,記憶體剩餘等因素,找出最合適的node節點。把pod排程到這個節點執行
  6. Scheduler 確定了排程的節點後,通過API Server 去找到對應node節點上的kublet,由kublet 建立pod
  7. kublet 不僅和容器引擎互動,實現容器的生命週期管理。還 監控node節點上的資源資訊,pod狀態。將這些通過API Server 儲存到etcd中。
  8. kube-proxy建立網路規則,制定轉發規則。建立service,把使用者的請求負載均衡轉發到關聯的pod上



三:k8s的資源

  • k8s包含多種資源物件:Pod , Label , Service , Replication , Controller 等
  • 所有的資源物件通過k8s提供的kubctl 工具進行增刪改查等操作,並將其儲存在etcd中持久化儲存
  • Kubernets其實是一個高度自動化的資源控制系統,通過跟蹤對比etcd儲存裡儲存的資源期望狀態與當前環境中的實際資源狀態的差異,來實現自動控制和自動糾錯等高階功能



3.1 Pod

  • Pod是 Kubernetes 建立或部署的最小/最簡單的基本單位,一個 Pod 代表叢集上正在執行的一個程序。可以把 Pod 理解成豌豆莢,而同一個Pod內的每個容器是一顆顆豌豆。

  • 一個 Pod 由一個或多個容器組成,Pod中容器共享網路、儲存和計算資源,在同一臺 Docker 主機上執行。一個 Pod 裡可以執行多個容器,又叫邊車模式(SideCara)模式。而在生產環境中一般都是單個容器或者具有強關聯互補的多個容器組成一個Pod。

  • 同一個 Pod 之間的容器可以通過localhost 互相訪問,並且可以掛載Pod內所有的資料卷

不同的 Pod 之間的容器不能用 localhost 訪問,也不能掛載其他 Pod 的資料卷。



3.2 Pod 控制器

  • Pod 控制器是 Pod 啟動的一種模版,用來保證在K8S裡啟動的 Pod 始終按照使用者的預期執行(副本數、生命週期、健康狀態檢查等)

  • K8S內提供了眾多的Pod控制器,常用的有以下幾種:

    1. Deployment:無狀態應用部署。Deployment 的作用是管理和控制Pod和Replicaset, 管控它們執行在使用者期望的狀態中 2
    2. Replicaset: 確保預期的Pod副本數量。Replicaset的作用就是管理和控制Pod,管控他們好好幹活。但是,Replicaset受控於Deployment .
      • 可以理解成Deployment 就是總包工頭,主要負責監督底下的工人Pod幹活,確保每時每刻有使用者要求數量的Pod在工作,如果一旦發現某個工人Pod不行了,就趕緊新拉一個Pod過來替換它。而ReplicaSet就是總包工頭手下的小包工頭。
      • 從K8S使用者角度來看,使用者會直接操作Deployment部署服務,而當Deployment被部署的時候,K8S會自動生成要求的ReplicaSet和Pod。使用者只需要關心Deployment而不操心ReplicaSet 資源物件.
      • Replication Controller是ReplicaSet的前身,官方推薦用Deployment取代Replication Controller來部署服務
    3. Daemonset: 確保所有節點運行同一類Pod,保證每個節點上都有一個此類Pod執行,通常用於實現系統級後臺任務
    4. Statefulset:有狀態應用部署
    5. Job: 一次性任務。根據使用者的設定,Job管理的Pod把任務成功完成就自動退出了
    6. Cronjob: 週期性計劃性任務



3.3 Label 標籤

  • 標籤,是K8S特色的管理方式,便於分類管理資源物件
  • Label可以附加到各種資源物件上,例如Node、Pod、Service、 RC等,用於關聯物件、查詢和篩選
  • 一個Label是一個key-value 的鍵值對,其中key 與value 由使用者自己指定
  • 一個資源物件可以定義任意數量的Label,同一個Label也可以被新增到任意數量的資源物件中,也可以在物件建立後動態新增或者刪除
  • 可以通過給指定的資源物件捆綁一個或多個不同的Label,來實現多維度的資源分組管理功能
  • 與Label類似的,還有Annotation (註釋)。區別在於有效的標籤值必須為63個字元或更少,並且必須為空或以字母數字字元([a-z0-9A-Z]) 開頭和結尾,中間可以包含橫槓(-)、下劃線(_)、點(.)和字母或數字。註釋值則沒有字元長度限制



3.4 Label選擇器(label selector

  • 給某個資源物件定義一個Label, 就相當於給它打了一個標籤;隨後可以通過標籤選擇器(Label selector) 查詢和篩選擁有某些Label的資源物件
  • 標籤選擇器目前有兩種:基於等值關係(等於、不等於)和基於集合關係(屬於、不屬於、存在)



3.5 service

在K8S的叢集裡,雖然每個Pod會被分配一個單獨的IP地址,但由於Pod是有生命週期的(它們可以被建立,而且銷燬之後不會再啟動),隨時可能會因為業務的變更,導致這個IP地址也會隨著Pod的銷燬而消失

Service就是用來解決這個問題的核心概念:

  • K8S中的Service並不是我們常說的“服務”的含義,而更像是閘道器層,可以看作一組提供相同服務的Pod的對外訪問介面、流量均衡器
  • Service作用於哪些Pod是通過標籤選擇器來定義的:
    • 在K8S叢集中,Service可以看作一組提供相同服務的Pod的對外訪問介面。客戶端需要訪問的服務就是Service物件。
    • 每個Service都有一個固定的虛擬ip (這個ip也被稱為Cluster IP) ,自動並且動態地繫結後端的Pod, 所有的網路請求直接訪問Service的虛擬ip,Service會自動向後端做轉發。
    • 通俗來說就是Service通過標籤選擇器選擇那些關聯了對應label的Pod,把Pod的IP加入到自己的endpoints當中,當service收到請求後根據endpoints裡的ip進行轉發
  • Service除了提供穩定的對外訪問方式之外,還能起到負載均衡(Load Balance) 的功能,自動把請求流量分佈到後端所有的服務上,service可以做到對客戶透明地進行水平擴充套件(scale),實現service這一功能的關鍵,就是kube-proxy。
    • kube -proxy執行在每個節點上,監聽API Server中服務物件的變化,
    • 可通過以下三種流量排程模式: userspace (廢棄)、iptables (瀕臨廢棄)、ipvs (推薦,效能最好)來實現網路的轉發
  • Service是K8S服務的核心,遮蔽了服務細節,統一對外暴露服務介面, 真正做到了“微服務”。
    • 比如我們的一個服務A,部署了3個副本,也就是3個Pod;對於使用者來說,只需要關注一個Service 的入口就可以,而不需要操心究競應該請求哪一個Pod。
    • 優勢非常明顯:一方面外部使用者不需要感知因為Pod. 上服務的意外崩潰、 K8S重新拉起Pod而造成的IP變更,外部使用者也不需要感知因升級、變更服務帶來的Pod替換而造成的IP變化

service 不是通過ip地址找到後端pod,而是通過標籤選擇器關聯具有對應label 的pod,然後把相關pod的ip加入到自己的endpoints(端點)中,service再根據endpoints裡的ip進行轉發



3.6 Ingress

  • Service主要負責K8S叢集內部的網路拓撲,那麼叢集外部怎麼訪問叢集內部呢?這個時候就需要Ingress了
  • Ingress是整個K8S叢集的接入層,負責叢集內外通訊
  • Ingress是K8S叢集裡工作在OSI網路參考模型下,第7層的應用,對外暴露的介面,典型的訪問方式是http/https
  • Service只能進行第四層的流量排程,表現形式是ip+port。Ingress則可以排程不同業務域、不同URL訪問路徑的業務流量。
    • 比如:客戶端請求http://www.mynet.com:port ---> Ingress ---> Service ---> Pod
  • 具體訪問流程:客戶端使用http/https通過url路徑訪問K8S叢集裡的Ingress接入層對外暴露的介面,Ingress層收到請求後找到對應是Service,Service根據標籤選擇器篩選查詢label對應的Pod,根據Pod的IP進行轉發獲取相應服務



3.7 Name

  • 由於K8S內部,使用“資源”來定義每一種邏輯概念(功能),所以每種“資源”,都應該有自己的“名稱”
  • “資源”有api版本(apiversion) 、類別(kind)、元資料(metadata) 、定義清單(spec)、狀態(status) 等配置資訊
  • “名稱”通常定義在“資源”的“元資料”資訊裡。在同一個namespace 空間中必須是唯一的



3.8 Namespace

  • 隨著專案增多、人員增加、叢集規模的擴大,需要一種能夠邏輯上隔離K8S 內各種“資源"的方法,這就是Namespace
  • Namespace是為了把一個K8S叢集劃分為若千個資源不可共享的虛擬叢集組而誕生的
  • 不同Namespace 內的“資源”名稱可以相同,相同Namespace 內的同種“資源”, “名稱”不能相同
  • 合理的使用K8S的Namespace,可以使得叢集管理員能夠更好的對交付到K8S裡的服務進行分類管理和瀏覽
  • K8S裡預設存在的Namespace 有: default、 kube-system、 kube-public 等
  • 查詢K8S裡特定“資源”要帶上相應的Namespace