一、 Kubernetes 概述
1、K8S 是什么?
K8S 的全稱為 Kubernetes ( K12345678S ) ,縮寫為 K8S。
作用:
用於自動部署、擴展和管理“容器化(containerized)應用程序”的開源系統。
可以理解成 K8S 是負責自動化運維管理多個容器化程序(比如 Docker)的群集,是一個生態極其豐富的容器編排框架工具。
由來:
K8S 由 google 的 Borg 系統(博格系統,google 內部使用的大規模容器編排工具)作為原型,后經GO語言延用Borg的思路重寫並捐獻給CNCF基金會開源。
含義:
詞根源於希臘語的 舵手、飛行員
官網:https://kubernetes.io
GitHub∶https://qithub.com/kubernetes/kubernetes
2、為什么要用 K8S ?
試想下傳統的后端部署辦法:把程序包(包括可執行二進制文件、配置文件等)放到服務器上,接着運行啟動腳本把程序跑起來,同時啟動守護腳本定期檢查程序運行狀態、必要的話重新拉起程序。
設想一下,如果服務的請求量上來,已部署的服務響應不過來怎么辦?傳統的做法往往是,如果請求量、內存、CPU 超過閾值做了告警,運維人員馬上再加幾台服務器,部署好服務之后,接入負載均衡來分擔已有服務的壓力。
這樣問題就出現了:從監控告警到部署服務,中間需要人力介入!那么,有沒有辦法自動完成服務器的部署、更新、卸載和擴容、縮容呢?
K8S 的目標是讓部署容器化應用簡單高效。
(1)K8S 解決了裸跑 Docker 的若干痛點:
- 單機使用,無法有效集群,
- 隨着容器數量的上升,管理成本攀升
- 沒有有效的容災、自愈機制
- 沒有榆社編排模板,無法實現快速、大規模容器調度
- 沒有統一的配置管理中心工具
- 沒有容器生命周期的管理工具
- 沒有圖形化運維管理工具
K8S 提供了容器編排,資源調度,彈性伸縮,部署管理,服務發現等一系列功能。
(2)K8S 的特性:
●彈性伸縮
使用命令、UI或者基於CPU使用情況自動快速擴容和縮容應用程序實例,保證應用業務高峰並發時的高可用性,業務低峰時回收資源,以最小成本運行服務。
●自我修復
在節點故障時重新啟動失敗的容器,替換和重新部署,保證預期的副本數量,殺死健康檢查失敗的容器,並且在未准備好之前不會處理客戶端請求,確保線上服務不中斷。
●服務發現和負載均衡
K8S為多個容器提供一個統一訪問入口(內部IP地址和一個DNS名稱),並且負載均衡關聯的所有容器,使得用戶無需考慮容器IP問題。
●自動發布(默認滾動發布模式)和回滾
K8S采用滾動更新策略更新應用,一次更新一個Pod,而不是同時刪除所有Pod,如果更新過程中出現問題,將回滾更改,確保升級不影響業務。
三種發布模式:
藍綠發布:兩套環境交替升級,舊版本保留一定時間便於回滾。
灰度發布:根據比例將老版本升級,例如80%用戶訪問是老版本,20%用戶訪問是新版本。
滾動發布(金絲雀發布):按批次停止老版本實例,啟動新版本實例
●集中化配置管理和密鑰管理
管理機密數據和應用程序配置,而不需要把敏感數據暴露在鏡像里,提高敏感數據安全性。並可以將一些常用的配置存儲在K8S中,方便應用程序使用。
●存儲編排,支持外掛存儲並對外掛存儲資源進行編排
掛載外部存儲系統,無論是來自本地存儲,公有雲(如AWS),還是網絡存儲(如NFS、Glusterfs、Ceph)都作為集群資源的一部分使用,極大提高存儲使用靈活性。
●任務批處理運行
提供一次性任務,定時任務,滿足批量數據處理和分析的場景。
3、Kubernetes 集群架構與組件
K8S是屬於主從設備模型(Master-Slave 架構),即有Master節點負責集群的調度、管理和運維,slave節點是集群中的運算工作負載節點。在 K8S 中,主節點一般被稱為 Master 節點,而從節點則被稱為 Worker Node 節點,每個 Node 都會被 Master 分配一些工作負載。
Master 組件可以在群集中的任何計算機上運行,但建議 Master 節點占據一個獨立的服務器。因為 Master 是整個集群的大腦,如果 Master 所在節點宕機或不可用,那么所有的控制命令都將失效。除了 Master,在 K8S 集群中的其他機器被稱為 Worker Node 節點,當某個 Node 宕機時,其上的工作負載會被 Master 自動轉移到其他節點上去。

二、核心組件
1、Master 組件
(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)Kube-controller-manager <管理資源控制器的控制器>
運行管理控制器,是 K8S 集群中處理常規任務的后台線程,是 K8S 集群里所有資源對象的自動化控制中心。在 K8S 集群中,一個資源對應一個控制器,而 Controller manager 就是負責管理這些控制器的。
由一系列控制器組成,通過 API server 監控整個集群的狀態,並確保集群處於預期的工作狀態,比如當某個 Node 意外宕機時,Controller Manager 會及時發現並執行自動化修復流程,確保集群始終處於預期的工作狀態。
主要控制器包括:
| Controller Name | 中文名稱 | 作用 |
| Node Controller | 節點控制器 | 負責在節點出現故障時發現和響應 |
| Replication Controller | 副本控制器 | 負責保證集群中一個 RC(資源對象 Replication Controller)所關聯的 Pod 副本數始終保持預設值。一直確保集群中有且僅有 N 個 Pod 實例,N是RC中定義的Pod副本數量 |
| Endpoints Controller | 端點控制器 | 填充端點對象(即連接 Services 和 Pods),負責監聽 Service 和對應的 Pod 副本的變化可以理解端點是個服務暴露出來的訪問點,如果需要訪問一個服務,則必須知道它的 endpoint |
| Service Account & Token Controllers | 服務帳戶和令牌控制器 | 為新的命名空間創建默認帳戶和 API 訪問令牌 |
| ResourceQuota Controller | 資源配額控制器 | 確保指定的資源對象在任何時候都不會超量占用系統物理資源 |
| Namespace Controller | 命名空間控制器 | 管理 namespace 的生命周期 |
| Service Controller | 服務控制器 | 屬於 K8S 集群與外部的雲平台之間的一個接口控制器 |
(3)Kube-scheduler <選擇最適合的 node 節點調度 pod>
是負責資源調度的進程,根據調度算法為新創建的 Pod 選擇一個合適的 Node節點。
可以理解成 K8S 所有 Node 節點的調度器。當用戶要部署服務時,Scheduler 會根據調度算法選擇最合適的 Node 節點來部署 Pod,先使用預算策略在使用優選策略
- 預算策略(predicate)
- 優選策略(priorities)
API Server 接收到請求創建一批 Pod ,API Server 會讓Controller-manager 按照所預設的模板去創建 Pod,Controller-manager 會通過 PI Server 去找 Scheduler 為新創建的 Pod 選擇最合適的 Node 節點。比如運行這個 Pod 需要 2C4G 的資源,Scheduler 會通過預算策略在所有 Node 節點中挑選最優的。Node 節點中還剩多少資源是通過匯報給 API Server 存儲在 etcd 里,API Server 會調用一個方法找到 etcd 里所有Node 節點的剩余資源,在對比 Pod 所需要的資源,在所有 Node 節點中查找哪些 Node 節點符合要求。
如果都符合,預算策略就交給優選策略處理,優選策略再通過 CPU 負載、內存的剩余量等因素選擇最合適的 Node 節點,並把 Pod 調度到這個 Node 節點上運行。
三、配置存儲中心
1、etcd
<鍵值對數據庫。存儲k8s集群所有的重要信息,並持久化保持,只有 apiserver 才對 etcd 有讀寫權限>
K8S的存儲服務。etcd 是分布式鍵.值存儲系統(鍵值對數據庫),存儲了K8S的關鍵配置和用戶配置,K8S中僅API Server才具有讀寫權限,其他組件必須通過API Server的接口才能讀寫數據。
2、Worker Node 組件
(1)Kubelet
<監視node節點上的資源和服務狀態並匯報給apiserver跟容器引擎交互實現容器的生命周期管理>
Node 節點的監視器,以及與 Master 節點的通訊器。Kubelet 是 Master 節點安插在 Node 節點上的 "眼線",它會定時向 API Server 匯報自己Node 節點上運行的服務的狀態,並接受來自 Master 節點的指示采取調整措施。
從 Master 節點獲取自已節點上 Pod 的期望狀態(比如運行什么容器、運行的副本數量、網絡或者存儲如何配置等),直接跟容器引擎交互實現容器的生命周期管理,如果自已節點上Pod 的狀態與期望狀態不一致,則調用對應的容器平台接口 (即 docker 的接口)達到這個狀態。
管理鏡像和容器的清理工作,保證節點上鏡像不會占滿磁盤空間,退出的容器不會占用太多資源。
(2)Kube-Proxy
<實現負載均衡,是 service 資源的載體,負載寫入規則至 iptables、ipvs實現服務映射訪問的>
在每個 Node 節點上實現 Pod 網絡代理,是 Kubernetes Service 資源的載體,負責維護網絡規則和四層負載均衡工作。負責寫入規則至iptables、ipvs實現服務映射訪問的。(K8S 默認只支持四層,七層需要安裝工具,默認使用的是 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)docker 或 rocket
容器引擎,運行容器,負責本機的容器創建和管理工作。
四、Kubernetes 核心概念
Kubernetes 包含多種類型的資源對象:Pod、Label、Server、Replication Controller 等。
所有的資源對象都可以通過 Kubernetes 提供的 kubectl 工具進行增、刪、改、查等操作,並將其保存在 etcd 中持久化存儲。
Kubernets其實是一個高度自動化的資源控制系統,通過跟蹤對比etcd存儲里保存的資源期望狀態與當前環境中的實際資源狀態的差異,來實現自動控制和自動糾錯等高級功能。
1、Pod
Pod是 Kubernetes 創建或部署的最小/最簡單的基本單位,一個 Pod 代表集群上正在運行的一個進程。
可以把 Pod 理解成豌豆莢,而同一個Pod內的每個容器是一顆顆豌豆。
一個 Pod 由一個或多個容器組成,Pod中容器共享網絡、存儲和計算資源,在同一台 Docker 主機上運行。
一個 Pod 里可以運行多個容器,又叫邊車模式(SideCara)模式。而在生產環境中一般都是單個容器或者具有強關聯互補的多個容器組成一個Pod。
同一個 Pod 之間的容器可以通過localhost 互相訪問,並且可以掛載Pod內所有的數據卷
不同的 Pod 之間的容器不能用 localhost 訪問,也不能掛載其他 Pod 的數據卷。
(1)Pod 控制器
Pod 控制器是 Pod 啟動的一種模版,用來保證在K8S里啟動的 Pod 始終按照用戶的預期運行(副本數、生命周期、健康狀態檢查等)
K8S 內提供了眾多的 Pod 控制器,常用的有以下幾種:
| Deployment | 無狀態應用部署。Deployment 的作用是管理和控制 Pod 和 ReplicaSet,管控它們運行在用戶期望的狀態中。 |
| 無狀態:不論是第幾次訪問都是同樣的響應狀態,例如:nginx、apache 有狀態:有狀態服務在服務端保留之前請求的信息,用以處理當前請求,訪問上下之間都是有關系的比如session等 |
|
| 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 | 周期性計划性任務 |
2、Lable
標簽,是 K8S 特色的管理方式,便於分類管理資源對象。
Label 可以附加到各種資源對象上,例如 Node、Pod、Service、RC 等,用於關聯對象、查詢和篩選。
一個 Label 是一個 key-value 的鍵值對,其中 key 與 value 由用戶自己指定。
一個資源對象可以定義任意數量的Label,同一個Label 也可以被添加到任意數量的資源對象中,也可以在對象創建后動態添加或者刪除。
可以通過給指定的資源對象捆綁一個或多個不同的 Label,來實現多維度,細粒度(更加細分)的資源分組管理功能。
與 Label 類似的,還有 Annotation(注釋)。
區別在於有效的標簽值必須為63個字符或更少,並且必須為空或以字母數字字符([a-z0-9A-Z])開頭和結尾,中間可以包含橫杠(-)、下划線(_)、點(.)和字母或數字。注釋值則沒有字符長度限制。
(2)Lable 選擇器(Lable selector)
給某個資源對象定義一個 Label,就相當於給它打了一個標簽,隨后可以通過標簽選擇器(Label selector)查詢和篩選擁有某些 Label 的資源對象。
標簽選擇器目前有兩種∶基於等值關系(等於、不等於)和基於集合關系(屬於、不屬於、存在)。
3、Service
<是通過標簽選擇器 關聯具有對應 lable 的 pod , 再把相關的 pod 的 IP 加入到自己的 endpoints 當中,service 再根據 endpoints 里的 IP 進行轉發>
在K8S的集群里,雖然每個Pod會被分配一個單獨的IP地址,但由於Pod是有生命周期的(它們可以被創建,而且銷毀之后不會再啟動),隨時可能會因為業務的變更,導致這個 IP 地址也會隨着 Pod 的銷毀而消失。
Service 就是用來解決這個問題的核心概念,防止pod因為生命周期或其他原因發生業務變更IP地址失效導致用戶無法正常訪問服務
K8S 中的 Service 並不是我們常說的"服務"的含義,而更像是網關層,可以看作一組提供相同服務的Pod的對外訪問接口、流量均衡器。
Service 通過標簽選擇器選擇那些關聯了對應label的Pod,把Pod的IP加入到自己的endpoints當中,當service收到請求后根據endpoints里的ip進行轉發
在 K8S 集群中,Service 可以看作一組提供相同服務的 Pod 的對外訪問接口。客戶端需要訪問的服務就是 Service 對象。每個 Service 都有一個固定的虛擬 ip(這個 ip 也被稱為 Cluster IP),自動並且動態地綁定后端的 Pod,所有的網絡請求直接訪問 Service 的虛擬ip,Service 會自動向后端做轉發。
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 變化。
4、Ingress
Service 主要負責 K8S 集群內部的網絡拓撲,集群外部訪問集群內部就需要 Ingress 了。Ingress 是整個 K8S 集群的接入層,負責集群內外通訊。
Ingress 是 K8S 集群里工作在 OSI 網絡參考模型下,第7層的應用,對外暴露的接口,典型的訪問方式是 http/https。Service 只能進行第四層的流量調度,表現形式是 IP+PORT。Ingress 則可以調度不同業務域、不同URL訪問路徑的業務流量。
比如∶客戶端請求 http://www.accp.com:port ---> Ingress ---> Service --->Pod
5、Name
由於 K8S 內部,使用 "資源" 來定義每一種邏輯概念(功能),所以每種"資源",都應該有自己的 "名稱"。
"資源" 有 api 版本(apiversion)、類別(kind)、元數據(metadata)、定義清單(spec)、狀態(status)等配置信息。"名稱" 通常定義在 "資源" 的"元數據" 信息里。在同一個 namespace 空間中必須是唯一的。
6、Namespace
隨着項目增多、人員增加、集群規模的擴大,需要一種能夠邏輯上隔離 K8S 內各種"資源"的方法,這就是 Namespace。
Namespace 是為了把一個 K8S 集群划分為若干個資源不可共享的虛擬集群組而誕生的。
不同 Namespace 內的 "資源" 名稱可以相同,同一 Namespace 內的同種"資源","名稱" 不能相同。
合理的使用 K8S 的 Namespace, 可以使得集群管理員能夠更好的對交付到 K8S 里的服務進行分類管理和瀏覽。
K8S 里默認存在的 Namespace 有∶default、kube-system、kube-public 等。
查詢 K8S 里特定 "資源" 要帶上相應的 Namespace。

k8s有兩種節點:
Master節點、worknode節點
Master節點
中有3個組件:Kube-API Server(集群統一入口)、Kube-controller manger(負責維護集群狀態)、Kube-scheduler(負責資源調度)。
與API Server對接的還有一個 etcd(分布式存儲) 作為整個k8s集群的存儲
worknode節點:
有 kubelet(處理pod清單)、kube-proxy(創建網絡規則)、Docker 容器引擎(可以是docker,也可以是其他的能夠滿足k8s的容器引擎)
工作流程:
用戶通過客戶端發送請求給API server ,API server 會把請求信息保存在etcd中,然后controller-manager會通過API server 來讀取etcd中的用戶請求信息,根據預設的模板創建pod,后通過API server ,找到scheduler去調度pod,scheduler會根據預算和優選策略去篩選node節點,來確定將pod調度到哪個節點,之后再通過API server ,去找相關節點的kubelet,來創建pod資源。kubelet不僅和容器引擎交互,實現容器的生命周期管理;還監控node節點上的資源信息、pod狀態,反饋給 API server 並存儲在etcd中。kube-proxy用於創建網絡規則來承載service,service可以對它所承載的pod進行負載均衡,和作為訪問入口,把用戶的請求通過負載均衡轉發到關聯的pod上,從而發布pod里的業務。
flannel 工作流程:
數據從源node節點的pod出發,經由所有主機docker0 網卡轉發到flannel0 網卡,在flannel0 網卡有個flanneld 服務會把這個podIP頭數據包封裝到 udp 報文中,然后根據自己在etcd中維護路由表通過物理網卡轉發到目標node節點,數據包到達目標node節點后會被flanneld 服務解封裝,暴露出udp里面的目的地址,在經由flannel0 網卡和docker0 網卡轉發到目標node容器中。
