一、K8S概述
1.1、K8S作用
K8S的全稱為Kubernetes。
用於自動部署、不熟和管理“容器化(containerized)應用程序”的開源系統,可以理解成K8S是負責自動化運維管理多個容器化程序(比如Docker)的集群,是一個生態極其豐富的容器編排框架工具
1.2、由來
K8S由google的Brog系統(博格系統,google內部使用的大規模容器編排工具)作為原型,后經GO語言沿用Brog的思路重寫並捐獻給CNCF基金會開源
1.3、含義
詞根源於希臘語的舵手、飛行員
1.4、官網
https://kubernetes.io/zh/
#GitHub
https://github.com/kubernetes/kubernetes
1.5、為什么要用K8S
試想下傳統的后端部署辦法:把程序包(包括可執行二進制文件、配置文件等)放到服務器上,接着運行啟動腳本把程序跑起來,同時啟動守護腳本定期檢查程序運行狀態,必要的話重新拉起程序。
設想一下,如果服務的請求量上來,已部署的服務響應不過來怎么辦?傳統的做法往往是,如果請求量、內存、CPU超過閾值做了告警,運維人員馬上再加幾台服務器,部署好服務之后,接入負載均衡來分擔已有服務的壓力
這樣問題就出現了:從監控告警到不舒服無,中間需要人力介入。name,有沒有辦法自動完成服務的部署、更新、卸載和擴容和縮容呢
而這就是K8S要做的事情:自動化運維管理容器化(docker)程序
K8S的目標就是讓部署容器化應用簡單高效
1.6、K8S解決了裸跑docker的若干痛點
- 單機使用,無法有效集群
- 隨着容器數量的上升,管理成本攀升
- 沒有有效的容災、自愈機制
- 沒有預設編排模板,無法實現快速、大規模容器調度
- 沒有統一的配置管理中心工具
- 沒有容器生命周期的管理工具
- 沒有圖形化運維管理工具
1.7、K8S的特性
K8S提供了容器編排,資源調度,彈性伸縮,部署管理,服務發現等一系列功能
1.7.1、彈性伸縮
使用命令、UI或者基於CPU使用情況自動快速擴容或縮容應用程序,保證應用業務高峰並發時的高可用性:業務低峰時回收資源,以最小成本運行服務
1.7.2、自我修復
在節點故障時重新啟動失敗的容器,替換和重新部署,保證預期的副本數量,殺死健康檢查失敗的容器,並且在未准備好之前不會處理客戶端請求,確保線上服務不中斷
1.7.3、服務發現和負載均衡
K8S為多個容器提供一個統一訪問入口(內部IP地址和一個DNS名稱),並且負載均衡關聯的所有容器,使得用戶無需考慮容器IP問題
1.7.4、自動發布(默認滾動發布模式)和回滾
K8S采用滾動更新策略更新應用,一次更新一個pod,而不是同時刪除所有pod,如果更新過程中出現問題,將回滾更改,確保升級不影響業務
1.7.5、集中化配置管理和密鑰管理
管理機密數據和應用程序配置,而不需要把敏感數據寶路在鏡像里,提高敏感數據安全性。並可以將一些常用的配置存儲在K8S中,方便應用程序使用
1.7.6、存儲編排,支持外掛存儲並對外掛存儲資源進行編排
掛載外部存儲系統,無論是來自本地存儲,公有雲(如AWS),還是網絡存儲(如NFS、Glusterfs、Ceph)都作為集群資源的一部分使用,極大提高存儲使用靈活性
1.7.7、任務批處理運行
提供一次性任務,定時任務,滿足批量數據處理和分析的場景
二、kubernetes集群架構
K8S是屬於主從設備模型(master-slave架構),即有master節點負責集群的調度、管理和運維,slave節點是集群中的運算工作負載節點
在k8s中,主節點一般稱為master節點,而從節點則被稱為worker node節點,每個node都會被master分配一些工作負載
master組件可以在群集中的任何計算機上運行,但建議master節點占據一個獨立的服務器,因為master是整個集群的大腦,如果master所在節點宕機或不可用,那么所有的控制命令都將失效。除了master,在K8S急群眾的其他機器被稱為worker node節點,當某個node宕機時,其上的工作負載會被master自動轉移到其他節點上去。
2.1、master節點的請求過程
首頁用戶通過證書認證后使用kubctl命令工具向API server發送請求,API Server接收到請求,例如創建一批POD,API Server會讓Controller-manager按照所預設的模板(多少實例、生命周期等)去創建Pod,Controller-manmger會通過Scheduler為新創建的Pod選擇最合適的node節點。比如運行這個Pod需要2C4G的資源,scheduler會通過API Server在Etcd存儲中心找到node節點存儲的元信息、剩余資源等,通過預選策略在所有node節點中挑選最優的,然后將預設的模板通過API Server交個這個node節點上運行。
Node節點中還剩多少資源是通報給API Server存儲在etcd中,API Server會調用一個方法找到etcd里所有node節點的剩余資源,在對比pod所需要的資源,在所有node節點中查找哪些node節點符合要求。如果都符合,預算策略就交個優選策略處理,優選策略在通過CPU的負載、內存的剩余量等因素選擇最合適的node節點,並把pod調度到這個node節點上運行。
2.2、客戶端具體訪問流程
客戶端使用http/https通過url路徑訪問K8S集群里的Ingress接入層對外暴露的接口,Igneress層受到請求后找到對應的Service,Service根據標簽選擇器篩選查詢label對應的POD,根據Pod的IP進行轉發獲取相應服務
2.3、Service作用於哪些集群是通過標簽選擇器來定義的
在K8S集群中,Service可以看做一組提供相同服務的Pod對外訪問接口。客戶端需要訪問的服務就是Service對象。每個Service都有一個固定的虛擬IP(這個IP也被稱為Cluster IP),自動並且動態的綁定后端Pod,所有的網絡請求直接訪問Service的虛擬IP,Service會自動向后端做轉發。通俗來說就是Service通過標簽選擇器選擇哪些關聯了對應label的Pod,把Pod的IP加入到自己的endpoints當中,當service受到請求后根據endpoints里的IP進行轉發
三、kubernetes核心組件
3.1、Master組件
3.1.1、Kube-apiserver
用於暴露Kubernetes API,任何資源請求或調用操作都是通過Kube-apiserver提供的接口進行的。以HTTP Restful API提供接口服務,所有對象資源的增刪改查和監聽操作都交給API Server處理后再提交給Etcd存儲
可以理解成API Server是K8S的請求入口服務。API Server負責接受K8S所有請求(來自UI界面或者CLI命令行工具),然后根據用戶的具體請求,去通知其他組件干活。可以說 API Server是K8S集群架構的大腦。
3.1.2、Kube-controller-manager
運行管理控制器,是K8S集群中處理常規任務的后台線程,是K8S雞群里所有資源對象的自動化控制中心
在K8S集群中,一個資源對應一個控制器,而Controller manager就是負責管理這些控制器的
由一系列控制器組成,通過API Server監控整個集群的狀態,並確保集群處於預期的工作狀態,比如當某個node意外宕機時,crontroller manager會及時發現並執行自動化修復流程,確保集群始終處於預期的工作狀態
這些控制器主要包括:
·Node Controller(節點控制器):負責在節點出現故障時發現和響應
·Replication Controller(副本控制器):負責保證集群中的一個RC(資源對象 Replication Controller)所關聯的Pod副本數始終保持預設值。可以理解成確保集群中有且僅有N個Pod實例,N是RC定義的Pod副本數量
·Endpoints Controller(端口控制器):填充斷點對象(即連接Service和Pods),負責監聽service和對應的pod副本的變化。可以理解斷點是一個服務暴露出來的訪問點,如果需要訪問一個服務,則必須要知道他的endpoint
·Service Account & Token Controllers:(服務專戶和令牌控制器):為新的命名空間創建默認賬戶和API訪問令牌
·ResourceQuota Controller(資源配額控制器):確保指定的資源對象在任何時候都不會超量占用西永物力資源
·Namespace Controller(命名空間控制器):管理namespace的生命周期
·Service Controller(服務控制器):屬於K8S集群與外部的雲平台之間的一個接口控制器
3.1.3、Kube-scheduler
是負責資源調度的進程,根據算法為新創建的Pod選擇一個合適的node節點
可以理解成K8S所有的node節點調度器。當喻戶要部署服務時,Scheduler會根據調度算法選擇最合適的node節點來部署pod
·預算策略(predicate)
·優選策略(priorities)
API Server接收到請求創建一批POD,API Server會讓controller-manager暗戰所預設的模板創建pod,controller-manager會通過API Server去找Schedule為新創建的Pod選擇最適合的NODE節點。比如運行這個Pod需要2C4G資源,schedule會通過預算策略在所有node節點中挑選最優的。node節點中海晟多少資源是通過匯報給API server存儲在etcd里,API server會調用一個方法找到etcd里所有node節點的剩余資源,在對比pod所需要的資源,在所有node節點中查找哪些node節點符合要求
如果都符合,預算策略就會交給優選策略處理,優選策略在通過CPU的負載、內存的剩余量等因素選擇最合適的node節點,並把Pod調度到這個node節點上運行
3.1.4、配置存儲中心etcd
K8S的存儲服務。etcd是分布式鍵值存儲系統,存儲了K8S的關鍵配置和用戶配置,K8S中僅API Server才具備讀寫權限,其他組件必須通過APIserver的接口才能讀寫數據
3.2、Node節點
3.2.1、Kubelet
Node節點的監視器,以及與master節點的通訊器。KUbelet是master節點安插在node節點上的“眼線”,它會定時向API Server匯報自己node節點上運行的服務狀態,並接受來自master節點的指示調整措施
從Master節點獲取自己節點上的Pod的期望狀態(比如運行什么容器、運行的副本數量、網絡或者存儲如何配置等)
直接跟容器引擎交互實現容器的生命周期管理,如果自己節點上Pod的狀態與期望狀態不一樣,則調用對應的容器平台接口(即docker的接口)達到這個狀態
管理鏡像和容器的清理工作,保證節點上鏡像不會占滿磁盤空間,退出的容器不會占用太多資源
3.2.2、Kube-proxy
在每個mnode節點上實現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組件
3.2.3、docker或rocket
容器引擎,運行容器,負責本機的容器創建和管理工作
四、K8S核心概念
K8S包含多種類型的資源對象:Pod、label、service、replication controller 等
所有的資源對象都可以通過K8S提供的kubctl工具進行增刪改查等操作,並將其保存在etcd中持久化存儲
K8S其實是一個高度自動化的資源控制系統,通過跟蹤對比etcd存儲里保存的資源期望狀態與當前環境中的實際資源狀態的差異,來實現自動控制和自動糾錯等高級功能。
4.1、Pod
Pod是kubernetes創建或部署的最小、最簡單的基本單位,一個Pod代表集群上正在運行的一個進程
可以把pod理解成豌豆莢,而同一pod內的每個容器是一顆豌豆
一個pod由一個或多個容器組成,pod中容器共享網絡、存儲和計算資源,在同一台docker主機上運行
一個pod里可以運行多個容器,又叫邊車模式。而在生產環境中一般都是單個容器或者具有強關聯互補的多個容器組成一個pod
同一個pod之間的容器可以通過localhost互相訪問,並且可以掛載pod內所有的數據卷;但是不同的pod之間的容器不能用localhost訪問,也不能掛載其他pod的數據卷
4.2、pod控制器
pod控制器是pod啟動的一種模板,用來保證在K8S里啟動的pod應始終按照用戶的預期運行(副本數、生命周期、健康狀態檢查等)
K8S內提供了眾多的pod控制器,常用的有以下幾種
·Deployment:無狀態應用部署。Deployment的作用是管理和控制pod和replicaSet,管理它們運行在用戶期望的狀態中
·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來部署服務
·Daemonset:確保所有節點運行同一類pod,保證每個節點上都有一個此類pod運行,通常用於實現系統級后台任務
·Statefulset:有狀態應用部署
·Job:一次性任務。根據用戶的設置,Job管理的pod把任務成功完成后就自動退出了
·Cronjob:周期性計划性任務
4.3、Label
標簽,是K8S特色的管理方式,便於分類管理資源對象
Label可以附加到各種資源對向上,例如Node、Pod、Service、RC等,用於管理對象、查詢和篩選
一個Label是一個key-value的鍵值對,其中key與value由用戶自己指定
一個資源對象可以定義任意數量的label,同一個label也可以被添加到任意數量的資源對象中,也可以在對象創建后動態添加或刪除
可以通過給指定的資源對象捆綁一個或多個不同的Label,來實現多維度的資源分組管理功能
與Label類似的,還有Annotation(注釋)
區別在於有效的標簽值必須為63個字符或者更少,並且必須為空或以字母數字字符([a-z0-9A-Z])開頭和結尾,中間可以包含橫杠、下划線、點和字母或數字。注釋值則沒有字符長度限制
4.4、Label選擇器
給某個資源對象定義一個Label,就相當於給它打了一個標簽;隨后可以通過標簽選擇器(Label selector)查詢和篩選擁有某些Label的資源對象
標簽選擇器目前有兩種:基於等值關系(等於、不等於)和基於集合關系(屬於、不屬於、存在)
4.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除了提供穩定的對外訪問方式之外,還能起到負載均衡的功能,自動把請求流量分布到所有的服務商,Service可以辺對客戶透明的進行水平擴展
而實現Service這一功能的關鍵,就是kube-proxy。kube-proxy運行在每個節點上,監聽API Server中服務對象的變化,可通過以下三種流量調度模式:userspace(廢棄)、iptables(瀕臨廢棄)、ipvs(推薦,性能最好)來實現網絡的轉發
Service是K8S服務的和興,屏蔽了服務細節,同一對外暴露服務接口,真正做到了“微服務”。比如我們的一個服務A,部署了3個副本,也就是三個pod;對於用戶來說,只需要關注一個Service的入口就可以,而不需要操心究竟應該請求哪一個Pod,優勢非常冥想;一方面外部用戶不需要感知因為Pod上服務的意外奔潰、K8S重新拉起Pod而造成的IP變更,外部用戶也不需要感知因升級、變更服務帶來的Pod替換而造成的IP變化
4.6、Ingress
Service主要負責K8S集群內部的網絡拓撲,那么集群外部怎么訪問集群內部呢?這個時候就需要Ingress了。Ingress是轉增個K8S集群的接入層,負責集群內外通訊
Ingress是K8S集群里工作在OSI網絡參考模型下,第7層的應用,對外暴露的接口,典型的訪問方式是http/https
Service只能進行第四層的流量調度,表現形式是ip+port。Ingress則可以調度不同業務域、不同URL訪問路徑的業務流量
比如:客戶端請求http://www.123.com:port --->Ingress --->Service --->Pod
4.7、Name
由於K8S內部,使用“資源”來定義每一種邏輯概念(功能),所以每種“資源”,都應該有自己的“名稱”
“資源”有api版本(apiversion)、類別(kind)、元數據(metadata)、定義清單(spec)、狀態(status)等配置信息
“名稱”通常定義在“資源”的“元數據”信息里。在同一個 namespace空間中必須是唯一的
4.8、namespace
隨着項目增多、人員增減、集群規模的擴大,需要一種能夠邏輯上隔離K8S內各種“資源”的方法,這就是namespace
namespace是為了把一個K8S集群划分為若干個資源不可共享的虛擬機群組而誕生的
不同namespace內的“資源”名稱可以相同,相同namespace內的同種“資源”,“名稱”不能相同
合理的使用K8S的namespace,可以使得集群管理員能夠更好的對交付到K8S里的服務進行分類管理和瀏覽
K8S里默認存在的namespace有:default、kube-system、kube-public等
查詢K8S里特定“資源”要帶上響應的Namespace