1、先從K8s不是什麼講起
首先,K8s並不是一個傳統意義上的 PaaS平臺即服務的工具,它充分給使用者提供了很多很多選擇的空間。
不限制支援的應用程式型別,K8s並不插手應用程式框架, 也不限制支援的語言 (如 Java, Python, Ruby 等),只要應用符合 12 因素即可。也就是說,只需要應用可以在容器中執行,那麼它就可以很好的在 Kubernetes 上執行。
不提供內建的中介軟體 (如訊息中介軟體)、資料處理框架 (如 Spark)、資料庫 (如 Mysql) 或叢集儲存系統 (如 Ceph) 等。這些應用直接執行在 Kubernetes 之上。
不直接部署程式碼,也不會構建您的應用程式,但是可以在 Kubernetes 之上構建需 要的持續整合 (CI) 工作流。
不提供機器配置、維護、管理或自愈系統。
不提供應用程式配置語言或系統。
不提供點選即部署的服務市場。
K8s 不僅僅是一個 “編排系統”,它消除了編排的需要。K8s透過宣告式的 API 和一系列獨立、可組合的控制器保證了應用總是在期望的狀態,使用者並不需要關心中間狀態是如何轉換的。
2、K8s是什麼及核心基礎概念
K8s 是谷歌開源的容器叢集管理系統,即一個大規模容器編排系統,是 Google 多年大規模容器管理技術 Borg 的開源版本。
可以用來完成以下一些主要功能:
基於容器的應用部署、維護和滾動升級。
負載均衡和服務發現:
跨機器和跨地區的叢集排程。
自動伸縮。
廣泛的 Volume 支援。
外掛機制保證擴充套件性。
使用者可以使用 Label 以自己的方式組織管理資源,還可以使用 Annotation 來自定義資源的描述資訊,比如為管理工具提供狀態檢查等。控制器也是構建在跟開發人員和使用者使用的相同的 API 之上。使用者 還可以編寫自己的控制器和排程器,也可以透過各種外掛機制擴充套件系統的功能。這使得可以方便地在 K8s 之上構建各種應用系統。
2.1 Container容器
Container(容器)是一種行動式、輕量級的作業系統級虛擬化技術。
它使用 namespace 隔離不同的軟體執行環境,並透過映象自包含軟體的執行環境,從而使得容器可以很方便的在任何地方執行。
容器體積小且啟動快,可以在每個容器映象中打包一個應用程式。這種一對一 的應用映象關係擁有很多好處。使用容器,不需要與外部的基礎架構環境繫結, 因為每一個應用程式都不需要外部依賴,不需要與外部的基礎架構環境依賴,從而完美解決了開發到生產環境的一致性問題。
容器同樣比虛擬機器更加透明,這有助於監測和管理。容器程序的生命週期由基礎設施管理,而不是被程序管理器隱藏在容器內部。每個應用程式用容器封裝,管理容器部署就等同於管理應用程式部署。
2.2 Pod
Kubernetes 使用 Pod 來管理容器,每個 Pod 可以包含一個或多個緊密關聯的容器。
Pod 是一組緊密關聯的容器集合,它們共享 PID、IPC、Network 和 UTS namespace, 是 K8s排程的基本單位。Pod 內的多個容器共享網路和檔案系統,可以透過程序間通訊和檔案共享這種簡單高效的方式組合完成服務。
在 Kubernetes 中,所有物件都使用 manifest(yaml 或 json)來定義,比如一個簡單的 nginx 服務可以定義為 nginx.yaml,它包含一個映象為 nginx 的容器:
apiVersion: v1
kind: Pod
metadata:
name: nginx
labels: app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
1
2
3
4
5
6
7
8
9
10
11
2.3 Node
Node 是 Pod 真正執行的主機,可以是物理機,也可以是虛擬機器。每個 Node 節點上至少要執行 container
runtime(比如 docker 或者 rkt)、 kubelet 和 kube-proxy 服務。
2.4 Label
Label 是識別 Kubernetes 物件的標籤,以 key/value 的方式附加到物件上(key 最長不能超過 63 位元組,value 可以為空,也可以是不超過 253 位元組的字串)。
Label 不提供唯一性,實際上經常是很多物件(如 Pods)都使用相同的 label 來標 志具體的應用。
Label 定義好後其他物件可以使用 Label Selector 來選擇一組相同 label 的物件(比如 ReplicaSet 和 Service 用 label 來選擇一組 Pod)
2.5 Annotations
Annotations 是 key/value 形式附加於物件的註解。不同於 Labels 用於標誌和選擇物件,Annotations 用來記錄一些附加資訊,用來輔助應用部署、安全策略以及排程策略等。
2.6 Service
Service 是應用服務的抽象,透過 labels 為應用提供負載均衡和服務發現。匹配 labels 的 Pod IP 和埠列表組成 endpoints,由 kube-proxy 負責將服務 IP 負載均衡到這些 endpoints 上。
每個 Service 都會自動分配一個 cluster IP(僅在叢集內部可訪問的虛擬地址)和 DNS 名,其他容器可以透過該地址或 DNS 來訪問服務,不需要了解後端容器的執行。
3、K8s架構
3.1 K8s的工作方式
Kubernetes Cluster = N Master Node + N Worker Node:N主節點+N工作節點; N>=1
3.2 K8s的元件架構
3.2.1 控制平面元件
控制平面元件-Control Plane Components:
控制平面的元件對叢集做出全域性決策(如排程等),以及檢測和響應叢集事件(例如,當不滿足部署的 replicas 欄位時,啟動新的 pod)。控制平面元件可以在叢集中的任何節點上執行。但為了簡單起見,設定指令碼通常會在同一個計算機上啟動所有控制平面元件,並且不會在此計算機上執行使用者容器。
kube-apiserver
API 伺服器是 K8s 控制面的元件, 該元件公開了 Kubernetes API。 API 伺服器是 Kubernetes 控制面的前端。Kubernetes API 伺服器的主要實現是 kube-apiserver。 kube-apiserver 設計上考慮了水平伸縮,即它可透過部署多個例項進行伸縮。 可以執行 kube-apiserver 的多個例項,並且在這些例項之間平衡流量。
etcd
etcd 是兼具一致性和高可用性的鍵值資料庫,可以作為儲存 K8s 所有叢集資料的後臺資料庫。通常etcd需要有備份計劃。
kube-scheduler
kube-scheduler是控制平面元件,負責監視新建立的、未指定執行節點(node)的 Pods,選擇節點讓 Pod 在上面執行。
kube-controller-manager
kube-controller-manager是在主節點上執行 控制器 的元件。
從邏輯上講,每個控制器都是一個單獨的程序, 為了降低複雜性,它們都被編譯到同一個可執行檔案,並在一個程序中執行。這些控制器有:
節點控制器(Node Controller): 負責在節點出現故障時進行通知和響應。
任務控制器(Job controller): 監測代表一次性任務的 Job 物件,然後建立 Pods 來執行這些任務直至完成
端點控制器(Endpoints Controller): 填充端點(Endpoints)物件(即加入 Service 與 Pod)
服務帳戶和令牌控制器(Service Account & Token Controllers): 為新的名稱空間建立預設帳戶和 API 訪問令牌
cloud-controller-manager
雲控制器管理器是指嵌入特定雲的控制邏輯的控制平面元件。 雲控制器管理器允許連結叢集到雲提供商的應用程式設計介面中,並把和該雲平臺互動的元件與只和使用者叢集互動的元件分離開。
3.2.2 Node元件
節點元件在每個節點上執行,維護執行的 Pod 並提供 Kubernetes 執行環境
kubelet
一個在叢集中每個節點(node)上執行的代理。 它保證容器(containers)都 執行在 Pod 中。kubelet 接收一組透過各類機制提供給它的 PodSpecs,確保這些 PodSpecs 中描述的容器處於執行狀態且健康。 kubelet 不會管理不是由 Kubernetes 建立的容器。
kube-proxy
kube-proxy 是叢集中每個節點上執行的網路代理, 實現 Kubernetes 服務(Service) 概念的一部分。kube-proxy 維護節點上的網路規則。這些網路規則允許從叢集內部或外部的網路會話與 Pod 進行網路通訊。如果作業系統提供了資料包過濾層並可用的話,kube-proxy 會透過它來實現網路規則。否則, kube-proxy 僅轉發流量本身。