一、什么是Kubernetes
??Kubernetes,又成為k8s(首字母為k,首字母與尾字母之間有8個字符,尾字母為s,所以簡稱為k8s),或者簡稱為 “kube” ,是一種可自動實施 Linux 容器操作的開源平臺。它可以幫助用戶省去應用容器化過程的許多手動部署和擴展操作。也就是說,你可以將運行 Linux 容器的多組主機聚集在一起,由 Kubernetes 幫助你輕松高效地管理這些集群。而且,這些集群可跨公共云、私有云或混合云部署主機。因此。對于要求快速擴展的云原生而言(例如借助 Apache Kafka 進行的實時數據流處理),Kubernetes 是理想的托管平臺。
??Kubernetes 最初由 Google 的工程師基于 go 語言開發和設計出來并于2014年6月開源。Google 是最早研發 Linux 容器技術的企業之一,曾公開分享介紹 Google 如何將一切都運行與容器之中(這時 Google 云服務背后的技術)。Google 每周會啟用超過20億個容器——全部都由內部平臺 Borg 支撐,Borg 是 Kubernetes 的前身,多年來開發 Borg 的經驗教訓成了影響 Kubernetes 中許多技術的主要因素。
??紅帽是第一批與 Google 合作研發 Kubernetes 的公司之一,作為 Kunernetes 上游項目的第二大貢獻這,甚至在這個項目啟動之前就已參與其中。2015年,Google 將 Kubernetes 項目捐贈給了新成立的云原生計算基金會。
二、為什么需要kubernetes
??在當下風靡的云計算生態中,Docker從發布開始就引領這容器化技術的潮流,Docker非常適合管理單個容器。但是如果我們的分布式應用系統是由多個容器組成的,隨著系統地迭代演化,使用越來越多的容器和容器化應用程序,并處于高并發、高可用等考慮將其劃分為數百個部分,很可能會導致管理和編排變得非常困難。我們迫切需要對容器實施分組,以便跨所有容器提供網絡、存儲、安全、遙測等服務,于是,Kubernetes 應運而生。
??真正的生產型應用會涉及多個容器,這些容器必須跨多個服務器主機進行部署。Kubernetes 可以提供所需的編排和管理功能,以便針對這些工作負載大規模部署容器。借助 Kubernetes 編排功能,我們可以構建跨多個容器的應用服務、跨集群調度、擴展這些容器,并長期持續管理這些容器的健康狀況。
??Kubernetes 還需要與聯網、存儲、安全性、遙測和其他服務集成整合,以提供全面的容器基礎架構。
??當然,這取決你如何在你的環境中使用容器。Linux 容器中的基本應用將它們視作高效、快速的虛擬機。一旦把它部署到生產環境或擴展為多個應用,顯然需要許多托管在相同位置的容器來協同提供各種服務。隨著這些容器的累積,運行環境中容器的數量會急劇增加,復雜度也隨之增長。
??Kubernetes 通過將容器分類組成 “容器集”(pod),解決了容器增殖帶來的許多常見問題。容器集為分組容器增加了一個抽象層,可幫助你調用工作負載,并未這些容器提供所需的聯網和存儲服務。Kubernetes 的其他部分可幫助你在這些容器集之間達成負載平衡,同時確保運行正確數量的容器,充分支持工作負載。
??如果能正確實施 Kubernetes,再輔以其他開源項目(例如 Atomic 注冊表、Open vSwitch、heapster、OAuth 以及 SELinux),你就能夠輕松編排容器基礎架構的各個部分。
三、kubernetes 有哪些用途
??在生產環境中使用 kubernetes 的主要優勢在于,它提供了一個便捷有效的平臺,讓你可以在物理機和虛擬機集群上調度和運行容器。更廣泛一點說,它可以幫助你在生產環境中,完全實施并依托基于容器的基礎架構運行。由于 Kubernetes 的實質在于實現操作任務自動化,所以可以將其他應用平臺或管理系統分配的許多相同任務交給容器來執行。
??利用 Kubernetes ,可以達成以下目標:
- 跨多臺主機進行容器編排。
- 更加充分地利用硬件,最大程度獲取運行企業應用所需的資源。
- 有效地管控應用部署和更新,并實現自動化操作。
- 掛載和增加存儲,用于運行有狀態的應用。
- 快速、按需擴展容器化應用及其資源。
- 對服務進行聲明式管理,保證所部署的應用始終按照部署的方式運行。
- 利用自動布局、自動重啟、自動復制以及自動擴展功能,對應用實施狀況檢查和自我修復。
??但是,Kubernetes 需要依賴其他項目來全面提供這些經過編排的服務。因此,借助其他開源項目可以幫助我們將 kubernetes 的全部公用發揮出來,這些功能包括:
- 注冊表,通過
Atomic
注冊表或Docker
注冊表等項目實現。- 聯網,通過
OpenvSwitch
和智能邊緣路由等項目實現。- 遙測,通過
heapster
、kibana
、hawkular
和elastic
等項目實現。- 安全性,通過
LDAP
、SELinux
、RBAC
和OAUTH
等項目以及多租戶層來實現。- 自動化,參照
Ansible
手冊進行安裝和集群生命周期管理。- 服務,可通過自帶預建版常用應用模式的豐富內容目錄來提供。
四、kubernetes 核心概念
??Kubernetes 有各類資源對象來描述整個集群的運行狀態(Node
、Pod
、Replication Controller
、Service
等都可以看作是一種 “資源對象”)。這些對象都需要通過調用 kubernetes api
來創建、修改、刪除并將其保存在 etcd
中持久化存儲,可以通過 kubectl
命令工具,也可以直接調用 k8s api
,或者使用對象語言的客戶端庫(例如:golang
、python
).
??從這個角度來看,Kubernetes 其實是一個高度自動化的資源控制系統,它通過跟蹤對比 etcd 庫里保存的 “資源期望狀態” 與當前環境中的 “實際資源狀態” 的差異來實現自動控制和自動糾錯的高級功能。
??每個 kunernetes 對象都會包含兩個關鍵字段:Object Spec 和 Object Status。spec 描述了對象所期望達到的狀態,status 描述了該對象的實際狀態。
1、Master
??Kubernetes 里的 Master 指的是集群控制節點,每個 Kubernetes 集群里需要有一個 Master 節點來負責整個集群的管理和控制,基本上 Kubernetes 的所有控制命令都發給它,它來負責具體的執行過程。Master 節點通常會占據一個獨立的服務器(高可用部署建議用3臺服務器),其主要原因是它太重要了,是整個集群的 “首腦”,如果宕機或者不可用,name對集群內容器應用的管理都將失效。
??Master 節點上運行著以下一組關鍵進程:
- Kubernetes API Server(kube-apiserver):提供了 HTTP Reset 接口的關鍵服務進程,是Kubernetes 里所有資源的增、刪、查、改等操作的唯一入口,也是集群控制的入口進程。
- Kubernetes Controller Manager(kube-controller-manager):Kubernetes 里所有資源對象的自動化> 控制中心,由一系列控制器組成:
??Replication Controller
??Node Controller
??CronJob Controller
??Daemon Controller
??Deployment Controller
??Endpoint Controller
??Garbage Collector
??Namespace Controller
??Job Controller
??Pod AutoScaler
??RelicaSet
??Service Controller
??ServiceAccount Controller
??StatefulSet Controller
??Volume Controller
??Resource quota Controller- Kubernetes Scheduler(kube-scheduler):負責資源調度(Pod)調度的進程,相當于公交公司的 “調度室”。
??另外,在Master 節點上還需要啟動一個 etcd 服務,因為 Kubernetes 里的所有資源對象的數據全部是保存在 etcd 中的。
2、Node
??除了 Master,Kubernetes 集群中的其他機器被成為 Node 節點,最開始被稱為minion。與Master 一樣。一個Node可以是VM或物理機。Node 節點是Kubernetes 集群中的工作負載節點,每個Node(節點)具有運行pod
的一些必要服務,由Master組件進行管理分配一些工作負載,Node節點上的服務包括Docker
、kubelet
和kube-proxy
。
??每個Node 節點上都運行這以下一組關鍵進程:
- kubelet:負責 Pod 對象的容器的創建、啟停等任務,同時與 Master 節點密切協作,實現集群管理的基本功能。
- kube-proxy:實現 Kubernetes Service 的通信與負載均衡機制的重要組件。
- Docker Engine(docker):Docker 引擎,負責本機的容器創建和管理工作。
??Node 節點可以在運行期間動態增加到 Kubernetes 集群中,前提是這個節點上已經正確安裝、配置和啟動了上述關鍵進程,在默認情況下 kubelet 會向 Master 注冊自己,這也是 Kubernetes 推薦的 Node管理方式。一旦 Node 被納入集群管理范圍,kubelet 進程就會定時向 Master 節點匯報自身的情報,例如操作系統、Docker 版本、機器的 CPU 和內存情況,以及當前有哪些 Pod 在運行等,這樣 Master 可以獲知每個 Node 的資源使用情況,并實現高效均衡等資源調度策略。而某個 Node 超過指定時間不上報信息時,會被 Master 判斷為“失聯”,Node 的狀態被標記為不可用(Not Ready),隨后 Master 會觸發“工作負
載大轉移”的自動流程。
3、Pod
??Pod 是 Kubernetes 的最重要也是最基本的概念,如下圖所示是Pod的組成示意圖,我們看到每個 Pod 都有一個特殊的被成為“根容器”的 Pause 容器。Pause 容器對應的鏡像屬于 Kubernetes 平臺的一部分,除了 Pause 容器,每個 Pod 還包含一個或多個緊密相關的用戶業務容器。
為什么 Kubernetes 會設計出一個全新的 Pod 概念并且 Pod 有這樣特殊的組成結構?
原因之一:在一組容器作為一個單元的情況下,我們難以對“整體”簡單地進行判斷及有效地進行行動。比如,一個容器死亡了,此時算是整體死亡么?引入業務無關并且不易死亡的 Pause 容器作為 Pod的根容器,以它的狀態代表整體容器組的狀態,就簡單、巧妙地解決了這個難題。
原因之二:Pod 里的多個業務容器共享 Pause 容器的 IP,共享 Pause 容器掛接的 Volume,這樣既簡化了密切關聯的業務容器之間的通信問題,也很好地解決了它們之間的文件共享問題。
??Kubernetes 為每個 Pod 都分配了唯一的 IP 地址,稱之為 Pod IP,一個 Pod 里的多個容器共享 Pod IP 地址。Kubernetes 要求底層網絡支持集群內任意兩個 Pod 之間的 TCP/IP 直接通信,這通常采用虛擬低層網絡技術來實現,例如 Flannel、Open vSwitch 等,因此我們需要牢記一點:在 Kubernetes 里,一個Pod 里的容器與另外主機上的 Pod 容器能夠直接通信。
??Pod 其實有兩種類型:普通的 Pod 及靜態 Pod (Static Pod),后者比較特殊,它并不存放在 Kubernetes的 etcd 存儲里,而是存放在某個具體的 Node 上的一個具體文件中,并且只在此 Node 上啟動運行。而普通的 Pod 一旦被創建,就會被放入到 etcd 中存儲,隨后會被 Kubernetes Master 調度到某個具體的 Node上并進行綁定(Binding),隨后該 Pod 被對應的 Node 上的 kubelet 進程實例化成一組相關的 Docker 容器并且啟動起來。在默認情況下,當 Pod 里的某個容器停止時,Kubernetes 會自動檢測到這個問題并且重新啟動這個 Pod(重啟 Pod 里的所有容器),如果 Pod 所在的 Node 宕機,則會將這個 Node 上的所有 Pod重新調度到其他節點上。Pod、容器與 Node 的關系圖如下圖所示。
4、Label
??Label 是 Kubernetes 系統中另外一個核心概念。一個 Label 是一個 key=value 的鍵值對,其中 key 與 vaue 由用戶自己指定。Label 可以附加到各種資源對象上,例如 Node、Pod、Service、RC 等,一個資源對象可以定義任意數量的 Label,同一個 Label 也可以被添加到任意數量的資源對象上去,Label 通常在資源對象定義時確定,也可以在對象創建后動態添加或者刪除。
??我們可以通過指定的資源對象捆綁一個或多個不同的 Label 來實現多維度的資源分組管理功能,以便于靈活、方便地進行資源分配、調度、配置、部署等管理工作。例如:部署不同版本的應用到不同的環境中;或者監控和分析應用(日志記錄、監控、告警)等。一些常用等 label 示例如下。
??版本標簽:"release" : "stable" , "release" : "canary"...
??環境標簽:"environment" : "dev" , "environment" : "production"
??架構標簽:"tier" : "frontend" , "tier" : "backend" , "tier" : "middleware"
??分區標簽:"partition" : "customerA" , "partition" : "customerB"...
??質量管控標簽:"track" : "daily" , "track" : "weekly"
??Label 相當于我們熟悉的“標簽”,給某個資源對象定義一個 Label,就相當于給它打了一個標簽,隨后可以通過 Label Selector(標簽選擇器)查詢和篩選擁有某些 Label 的資源對象,Kubernetes 通過
這種方式實現了類似 SQL 的簡單又通用的對象查詢機制。
5、Replication Controller
??RC 是 Kubernetes 系統中的核心概念之一,簡單來說,它其實是定義了一個期望的場景,即聲明某種 Pod 的副本數量在任意時刻都符合某個預期值,RC 的定義包括如下幾個部分。
- Pod 期待的副本數(replicas)。
- 用于篩選目標 Pod 的 Label Selector。
- 當 Pod 的副本數量小于預期數量時,用于創建新 Pod 的 Pod 模版(template)。
??在用戶定義范圍內,如果pod增多,則ReplicationController會終止額外的pod,如果減少,RC會創建新的pod,始終保持在定義范圍。例如,RC會在Pod維護(例如內核升級)后在節點上重新創建新Pod。
- ReplicationController會替換由于某些原因而被刪除或終止的pod,例如在節點故障或中斷節點維護(例如內核升級)的情況下。因此,即使應用只需要一個pod,我們也建議使用ReplicationController。
- RC跨多個Node節點監視多個pod。
6、Deployment
??Deployment 是 Kubernetes v1.2 引入的概念,引入的目的是為了更好地解決 Pod 的編排問題。為此,Deployment 在內部使用了 Replica Set 來實現目的,無論從 Deployment 的作用與目的,它的 YAML 定義,還是從它的具體命令行操作來看,我們都可以把它看作 RC 的一次升級,兩者相似度超過 90%。
??Deployment 相對于 RC 的一個最大升級是我們隨時知道當前 Pod“部署”的進度。實際上由于一個 Pod 的創建、調度、綁定節點及在目標 Node 上啟動對應的容器這一完整過程需要一定的時間,所以我們期待系統啟動 N 個 Pod 副本的目標狀態,實際上是一個連續變化的“部署過程”導致的最終狀態。
??Deployment 的典型使用場景有以下幾個。
- 創建一個 Deployment 對象來生成對應的 Replica Set 并完成 Pod 副本的創建過程。
- 檢查 Deployment 的狀態來看部署動作是否完成(Pod 副本的數量是否達到預期的值)。
- 更新 Deployment 以創建新的 Pod(比如鏡像升級)。
- 如果當前 Deployment 不穩定,則回滾到一個早先的 Deployment 版本。
- 暫停 Deployment 以便 于一次性 修改多個 PodTemplateSpec 的配 置項,之 后再恢 復Deployment,進行新的發布。
- 擴展 Deployment 以應對高負載。
- 查看 Deployment 的狀態,以此作為發布是否成功的指標。
- 清理不再需要的舊版本 ReplicaSets。
7、StatefulSet
??在 Kubernetes 系統中,Pod 的管理對象 RC、Deployment、DaemonSet 和 Job 都是面向無狀態的服務。但現實中有很多服務是有狀態的,特別是一些復雜的中間件集群,例如 MySQL 集群、MongoDB 集群、Kafka 集群、Zookeeper 集群等,這些應用集群有以下一些共同點。
- 每個節點都有固定的身份 ID,通過這個 ID,集群中的成員可以相互發現并且通信。
- 集群的規模是比較固定的,集群規模不能隨意變動。
- 集群里的每個節點都是有狀態的,通常會持久化數據到永久存儲中。
- 如果磁盤損壞,則集群里的某個節點無法正常運行,集群功能受損。
??StatefulSet 是為了解決有狀態服務問題(對應 Deployment 和 ReplicaSets 是為無狀態服務而設計),從本質上來說,可以看作 Deployment/RC 的一個特殊變種,它有如下一些特性:
- 穩定性,唯一的網絡標識符。
? 可以用來發現集群內的其他成員。假設StatefulSet 的名字叫 kafka,那么第一個 Pod 叫 kafak-0,
? 第二個 Pod 叫 kafak-1,以此類推。
- 穩定性,持久化存儲。
? 通過 PV/PVC 來實現,刪除 Pod 時默認不會刪除與StatefulSet 相關的存儲卷(為了保證數據的安全)。
- 有序的部署和擴展。
? 操作第 n 個 Pod 時,前 n-1 個 Pod 已經時運行且準備好的狀態。
- 有序的刪除和終止。
- 有序的自動滾動更新。
??Pod調度運行時,如果應用不需要任何穩定的標示、有序的部署、刪除和擴展,則應該使用一組無狀態副本的控制器來部署應用,例如 Deployment 或 ReplicaSet 更適合無狀態服務需求。
??StatefulSet 除了要與 PV 卷捆綁使用以存儲 Pod 的狀態數據,還要與 Headless Service 配合使用,即在每個 StatefulSet 的定義中要聲明它屬于哪個 Headless Service。Headless Service 與普通 Service 的關鍵區別在于,它沒有 Cluster IP,如果解析 Headless Service 的 DNS 域名,則返回的是該 Service對應的全部 Pod 的 Endpoint 列表。StatefulSet 在 Headless Service 的基礎上又為 StatefulSet 控制的每個 Pod 實例創建了一個 DNS 域名,這個域名的格式為:
$(podname).$(headless service name)
??比如一個 3 節點的 Kafka 的 StatefulSet 集群,對應的 Headless Service 的名字為 kafka,StatefulSet 的名字為 kafka,則 StatefulSet 里面的 3 個 Pod 的 DNS 名稱分別為 kafka-0.kafka、kafka-1.kafka、kafka-3.kafka,這些 DNS 名稱可以直接在集群的配置文件中固定下來。
8、Service
??Service 也是 kubernetes 里的最核心的資源對象之一,Kubernetes 里的每個 Service 其實就是我們經常提起的微服務架構中的一個 “微服務”,下圖顯示了 Pod、RC 與 Service 的邏輯關系:
??從圖中可以看到,Kubernetes 的 Service 定義了一個服務的訪問入口地址,前端的應用(Pod)通過這個入口地址訪問其背后的一組由 Pod 副本組成的集群實例,Service 與后端 Pod 副本集群之間則是通過 Label Selector 來實現 “無縫對接” 的。而 RC 的作用實際上是保證 Service 的服務能力和服務質量始終處于預期的標準。
9、Volume
??容器中的磁盤的生命周期是短暫的,這就帶來了一系列的問題,第一,當一個容器損壞之后,kubelet 會重啟這個容器,但是文件會丟失-這個容器會是一個全新的狀態,第二,當很多容器在同一 Pod 中運行的時候,很多時候需要數據文件的共享。Kubernete Volume 解決了這個問題。
??Volume是Pod中能夠被多個容器訪問的共享目錄。Kubernetes 的 Volume 概念、用途和目的與 Docker 的 Volume 比較類似,但兩者不能等價。首先,Kubernetes 中的 Volume 定義在 Pod 上,然后被一個 Pod 里的多個容器掛載到具體的文件目錄下;其次,Kubernetes 中的 Volume 中的數據也不會丟失。最后,Kubernetes 支持多種類型的 Volume,例如 Gluster、Ceph 等先進的分布式文件系統。
10、Annotation
??Annotation 與 Label 類似,也使用 key/value 鍵值對的形式進行定義。不同的是 Label 具有嚴格的命名規則,它定義的是 Kubernetes 對象的元數據(Metadata),并且用于 Label Selector。而 Annotation 則是用戶任意定義的“附加”信息,以便于外部工具進行查找,很多時候,Kubernetes 的模塊自身會通過 Annotation 的方式標記資源對象的特殊信息。
??通常來說,用 Annotation 來記錄的信息如下。
- build 信息、release 信息、Docker 鏡像信息等,例如時間戳、release id 號、PR 號、鏡像hash 值、docker registry 地址等。
- 日志庫、監控庫、分析庫等資源庫的地址信息。
- 程序調試工具信息,例如工具、版本號等。
- 團隊等聯系信息,例如電話號碼、負責人名稱、網址等。
11、kubelet
??kubelet 是主要的節點代理,它會監視已分配給節點的pod,具體功能:
- 安裝Pod所需的volume。
- 下載Pod的Secrets。
- Pod中運行的 docker(或experimentally,rkt)容器。
- 定期執行容器健康檢查。
- Reports the status of the pod back to the rest of the system, by creating a mirror pod if necessary.
- Reports the status of the node back to the rest of the system.
12、kubectl
??kubectl 用于運行 Kubernetes 集群命令的管理工具。