服務的分類
有狀態服務:會對本地環境產生依賴,例如需要把數據存儲到本地磁盤,如mysql、redis;
無狀態服務:不會對本地環境產生任何依賴,例如不會存儲數據到本地磁盤,如nginx、apache;
資源和對象
kubernetes中的所有內容都被抽象為“資源”,如Pod、Service、Node等都是資源。“對象”就是“資源”的實例,是持久化的實體。如某個具體的Pod、某個具體的Node。Kubernetes使用這些實體去表示整個集群的狀態。
對象的創建、刪除、修改都是通過“kubernetes api”,也就是“api server”組件提供的api接口,這些是restful風格的api,與k8s“萬物皆對象”的理念相符。命令行工具“kubectl”,實際上也是調用kubernetes api。
k8s中的資源類別有很多種,kubectl可以通過配置文件來創建這些“對象”,配置文件更像是描述對象“屬性”的文件,配置文件格式可以是“json”或“yaml”,常用“yaml”。
對象的規約和狀態
規約(spec)是必需的,它描述了對象的期望狀態(desired state),即希望對象所具有的特征。當創建kubernetes對象時,必需提供對象的規約,用來描述該對象的期望狀態,以及關于對象的一些基本信息(例如名稱)。
狀態表示了對象的實際狀態,該屬性由k8s自己維護,k8s會通過一系列的控制器對對應對象進行管理,讓對象盡可能的讓實際狀態與期望狀態重合。
資源的分類
資源一共分為命名空間級資源、集群級資源、元數據型資源。
-
命名空間級別的資源,如果不同的資源放在不同的命名空間下,他們就相互隔離。比如,有一個包租婆,他有一棟樓,張三和李四各租了其中的一間房子,那么資源是由包租婆統一分配的,但是張三和李四相互之間是隔離的。那么在張三房間中創建的pod,李四是不能訪問的。命名空間下的資源類型有:工作負載型資源workload(Pod、ReplicaSet、Deployment、StatefulSet、DaemonSet、Job、CronJob)、服務發現及負載均衡性資源ServiceDiscovery LoadBalance(Service、Ingress)、配置與存儲型資源(Volume、CSI)、特殊類型的存儲卷(ConfigMap、Secret、DownwardAPI)。
-
工作負載型資源(workLoad)
-
Pod(容器組):是kubernetes中最小的可部署單元。一個pod(容器組)包含了一個應用程序容器(某些情況下是多個容器)、存儲資源、一個唯一的網絡IP地址、以及一些確定容器該如何運行的選項。pod容器組代表了kubernetes中一個獨立的應用程序運行實例,該實例可能由單個容器或者幾個緊耦合在一起的容器組成。docker是kubernetes pod中使用最廣泛的容器引擎;kubernetes pod同時也支持其他類型的容器引擎。kubernetes集群中的pod存在兩種使用途徑:
-
一個pod中只運行一個容器。“one-container-per-pod”是kubernetes中最常見的使用方式。此時,可以認為pod容器組是該容器的wrapper,kubernetes通過pod管理容器,而不是直接管理容器。
-
一個pod中運行多個需要相互協作的容器,可以將多個緊密耦合、共享資源且始終在一起運行的容器編排在同一個pod。
-
-
replicas(副本):一個pod可以被復制成多份,每一份可以被稱之為一個“副本”,這些“副本”除了一些描述性的信息(pod的名字、uid等)不一樣之外,其他信息都是一樣的,譬如pod內部的容器、容器數量、容器里面運行的應用等這些信息都是一樣的,這些副本提供同樣的功能。pod的“控制器”通常包含一個名為“replicas”的屬性。“replicas”屬性則指定了特定的pod的副本的數量,當當前集群中該pod的數量與該屬性指定的值不一致時,k8s會采取一些策略去使得當前狀態滿足配置的要求。
-
ReplicationController(適用于無狀態服務):RC
-
ReplicaSet(適用于無狀態服務):RS,調度器、控制器,通過標簽去控制pod的創建、副本數量
-
Deployment(適用于無狀態服務):控制器,通過控制RS的創建去創建pod
-
StatefulSet(適用于有狀態服務):為有狀態服務所建立的管理器
-
DaemonSet(守護進程):可以在每一個節點都運行一個pod的組件
-
Job(任務/定時任務):工作、任務
-
CronJob(任務/定時任務):輪詢工作、輪詢任務,為批處理而生的
-
-
服務發現及負載均衡型資源(ServiceDiscory LoadBalance)
-
Service:簡稱svc,服務,將服務暴露出去
-
Ingress:將服務暴露出去
-
-
配置與存儲型資源
-
Volume(存儲卷):給pod提供持久化的能力
-
CSI:容器存儲接口,可以擴展各種各樣的第三方存儲卷
-
-
特殊類型的存儲卷
-
ConfigMap:當配置中心來使用的資源類型,一般用來存儲配置文件達到熱更新的狀態
-
Secret:保存敏感數據,加密方案存儲數據,一般用來保存密碼文件、密鑰等等
-
DownwardAPI:把外部環境中的信息輸出給容器,類似于CSI
-
-
-
集群級別的資源,范圍比命名空間要大,一個集群下可能會有多個命名空間。集群管理著命名空間資源。同一個集群下的各個命名空間均可見,在定義的時候不需要指定命名空間。集群下的資源類型有:名稱空間Namespace、節點Node、角色Role、ClusterRole、RoleBinding、ClusterRoleBinding。
-
Namespace:名稱空間就是集群級別資源的一種。
-
node:不像其他的資源(如pod和namespace),Node本質上不是kubernetes來創建的,kubernetes只是管理node上的資源。雖然可以通過manifest創建一個node對象,單kubernetes也只是去檢查是否真的是有這么一個node,如果檢查失敗,也不會往上調度pod。
-
ClusterRole:集群角色,作用在集群下的,類似于學校的校長。如果給集群賦予了某一個集群角色,那么所有的名字空間都具有這個角色的權限。
-
Role:角色,他是作用在名字空間下的。類似于一個班的班長。
-
ClusterRoleBinding:集群角色綁定。比如學校和教室之間的關系可以理解為集群和名字空間的關系,校長就是集群角色。那么一個人要升職為校長,那么需要有委任書,這個委任書就是集群角色綁定,只要有這個委任書,這個人就是校長,將集群和角色綁定在一起了。
-
相對應的還有RoleBinding:角色綁定,作用在名字空間下。
-
-
元數據可以理解為一個模板,不是直接作用在資源或者對象上的,而是管控中間的變量,可以通過指標進行操作。元數據資源類型有:HPA、PodTemplate、LimitRange。
-
HPA(Horizontal Pod Autoscaler):pod自動擴容,可以根據CPU使用率或自定義指標(metrics)自動對pod進行擴/縮容。
-
控制管理器每隔30s(可以通過horizontal-pod-autoscaler-sync-period修改)查詢metrics的資源使用情況;
-
支持三種metrics類型
-
預定義metrics(比如Pod的CPU)以利用率的方式計算
-
自定義的pod metrics,以原始值(raw value)的方式計算
-
自定義的object metrics
-
-
支持兩種metrics查詢方式:heapster和自定義的rest api
-
支持多metrics
-
-
PodTemplate:pod模板,是關于pod的定義,但是被包含在其他的kubernetes對象中(例如deployment、statefulSet、Daemonset等控制器中),控制器通過pod template信息來創建pod;
-
LimitRange:對集群內request和limits的配置做一個全局的統一的限制,相當于批量設置了某一個范圍內(某個命名空間)的pod的資源使用限制;
-
Pause容器
pause容器是一個很特殊的容器,又叫做infra容器,是每個pod都會自動創建的容器,不屬于用戶自定義的容器。
一個pod中的容器共享存儲、網絡資源就是通過pause容器來實現的。實際上K8S是通過讓pod中的用戶容器加入(join)另一個第三方容器的network namespace實現的共享,而這個第三方容器就是pause容器。
這么做的目的其實也比較簡單,沒有 pause 容器,那么 A 和 B 要共享網絡,要不就是 A 加入 B 的 network namespace,要嘛就是 B 加入 A 的 network namespace, 而無論是誰加入誰,只要 network 的 owner 退出了,該 Pod 里的所有其他容器網絡都會立馬異常。
反過來,由于 pause 里只有是掛起一個容器,里面沒有任何復雜的邏輯,只要不主動殺掉 Pod,pause 都會一直存活,這樣一來就能保證在 Pod 運行期間同一 Pod 里的容器網絡的穩定。
我們在同一 Pod 里所有容器里看到的網絡視圖,都是完全一樣的,包括網絡設備、IP 地址、Mac 地址等等,因為他們其實全是同一份,而這一份都來自于 Pod 第一次創建的這個 Infra container。
由于所有的業務容器都要依賴于 pause 容器,因此在 Pod 啟動時,它總是創建的第一個容器,可以說 Pod 的生命周期就是 pause 容器的生命周期。
控制器
kubernetes中內建了很多controller(控制器),這些相當于一個狀態機,用來控制pod的具體狀態和行為,控制器包含:ReplicationController、ReplicaSet、Deployment、DaemonSet、StatefulSet、Job/CronJob、HorizontalPodAutoscaler
ReplicationController(RC)和ReplicaSet(RS)
ReplicationController (RC)用來確保容器應用的副本數始終保持在用戶定義的副本數,即如果有容器異常退出,會自動創建新的pod來替代;而異常多出來的容器也會自動回收。
在新版的Kubernetes中建議使用ReplicaSet (RS)來取代ReplicationController。ReplicaSet跟ReplicationController沒有本質的不同,只是名字不一樣,但ReplicaSet支持集合式selector。
雖然 ReplicaSets 可以獨立使用,但如今它主要被Deployments 用作協調 Pod 的創建、刪除和更新的機制。當使用 Deployment 時,你不必擔心還要管理它們創建的 ReplicaSet,Deployment 會擁有并管理它們的 ReplicaSet。
ReplicaSet 是下一代的 Replication Controller。 ReplicaSet 和 Replication Controller 的唯一區別是選擇器的支持。ReplicaSet 支持新的基于集合的選擇器需求,這在標簽用戶指南中有描述。而 Replication Controller 僅支持基于相等選擇器的需求。
Deployment
Deployment是Kubernetes中一種聲明式控制器,用于管理和維護一組Pod副本。它主要用于管理無狀態應用的生命周期,通過聲明Deployment,可以自動化地控制應用的副本數量、進行無停機更新、擴展、縮容等。
Deployment 控制器為 Pods和 ReplicaSets提供描述性的更新方式,用來替代以前的ReplicationController以方便管理應用。
Deployment的主要功能:
-
定義期望狀態:指定希望部署的應用配置和數量。
-
管理副本:確保應用副本數量與配置的期望值一致。
-
無停機更新:支持滾動更新,逐步更新Pod,更新過程中不會中斷服務。
-
版本回滾:可以回滾到之前的某個版本,以應對更新失敗的情況。
-
擴展性:支持自動擴容和縮容,通過HPA(Horizontal Pod Autoscaler)等資源進行彈性管理。
Deployment與其他Kubernetes組件的關系:
-
Pod:Kubernetes中最基本的部署單元,表示一個或多個容器的集合。Pod共享存儲、網絡和上下文。
-
ReplicaSet:確保指定數量的Pod實例在任何時候都在運行。它通過監控Pod的狀態來管理Pod的創建和刪除。如果某個Pod異常終止,ReplicaSet會創建一個新的Pod來替代它。
-
Deployment:更高級別的抽象,管理ReplicaSet的創建和更新。Deployment允許用戶聲明希望運行的應用狀態,包括Pod的模板、副本數量和更新策略。
-
Service: Deployment創建的Pod可以通過標簽與Service進行關聯。當創建一個Service時,可以指定一個或多個標簽選擇器來匹配Pod。這些匹配的Pod就會被Service所管理,并通過Service提供的虛擬IP地址和端口號進行訪問。Service為Deployment創建的Pod提供了一個穩定的網絡訪問入口。這樣,外部客戶端或集群內的其他Pod就可以通過訪問Service來間接訪問到Pod提供的服務。Service還提供了負載均衡功能,可以將請求分發到多個Pod上,以實現高可用性和可擴展性。這對于提高應用的性能和可靠性具有重要意義。
StatefulSet
StatefulSet是用來管理有狀態應用的服務。和無狀態的Deployment不同,StatefulSet需要保持每個Pod的唯一性和持久性。比如數據庫、消息隊列這樣的應用,每個實例的數據都是獨立的,不能隨意替換或刪除,這時候就需要StatefulSet來管理。
StatefulSet的核心特性
-
唯一標識與穩定性
-
每個Pod分配唯一索引標識(如pod-0, pod-1),即使重啟或遷移,標識不變。
-
依賴Headless Service提供穩定DNS記錄(如pod-0.example.com),確保客戶端始終連接到同一實例。
-
-
持久化存儲
- 通過volumeClaimTemplates自動生成獨立的PersistentVolumeClaim(PVC),每個Pod擁有專屬存儲卷,數據持久化。
-
有序擴縮容
- 擴容時按索引順序創建新Pod(如從pod-2到pod-N),縮容時逆序刪除舊Pod(如先刪pod-0),保障服務連續性。
-
滾動更新策略
- 支持配置maxSurge(最大并發更新數)和maxUnavailable(最大不可用數),默認策略為逐個更新,減少對集群的影響。
StatefulSet VS Deployment
生命周期管理
-
StatefulSet
- 當增加或減少副本時,它會按順序創建或刪除Pod,確保舊的Pod先下線,新的Pod再上線,這樣可以避免服務中斷。
-
Deployment
- 并行更新,可能導致短暫的服務不可用。
應用場景
-
StatefulSet
-
主要用于管理有狀態應用。
-
有狀態應用需要持久化數據或具有唯一網絡標識符。
-
StatefulSet提供了持久化存儲和穩定的網絡標識符,適用于需要保持數據完整性和服務身份的應用。
-
-
Deployment
-
主要用于管理無狀態應用。
-
無狀態應用通常不需要持久化數據或唯一網絡標識符。
-
Deployment提供了一種簡單的方式來部署和更新應用,支持滾動更新和回滾。
-
Pod管理
-
StatefulSet
-
Pod名稱是基于索引的,具有固定的順序和標識。每個Pod都有一個唯一的、持久的身份標識。
-
每個Pod可以有獨自的存儲卷,通常與PersistentVolumeClaim(PVC)結合使用,以確保數據的持久化和隔離。
-
Pod具有穩定的網絡標識,如DNS名稱,可以通過Headless Service精確訪問到每一個Pod。
-
-
Deployment
-
Pod名稱是隨機生成的,沒有固定的順序或標識。每個Pod都是可替換的,具有相同的配置和環境。
-
Pod通常共享存儲卷,但這不適用于有狀態應用,因為數據可能會相互干擾。
-
Pod沒有穩定的網絡標識,通常通過Service進行通信。
-
部署與更新策略
-
StatefulSet
-
支持有序的創建和刪除Pod,這在需要特定順序執行初始化腳本或清理操作的情況下非常有用。StatefulSet不直接支持滾動更新,因為需要考慮數據的一致性和服務的連續性,更新過程通常需要更謹慎的操作,可能需要手動干預。
-
支持自動回滾和暫停/恢復更新。
-
-
Deployment
-
通過ReplicaSet管理Pod的副本數,支持滾動更新策略,允許逐個替換Pod以保持服務的可用性。
-
支持自動回滾和暫停/恢復更新。
-
其它特性
-
StatefulSet
- 適用于數據庫集群(如MySQL、Cassandra)、分布式緩存系統(如Redis集群)以及任何需要持久化數據或特定網絡標識的應用。
-
Deployment
- 適用于Web應用服務器、微服務以及任何不需要持久化數據或特定網絡標識的應用。
Service&Ingress
概念以及作用
Ingress主要負責七層負載,將外部 HTTP/HTTPS 請求路由到集群內部的服務。它可以基于域名和路徑定義規則,從而將外部請求分配到不同的服務。
Ingress的作用:
-
提供 基于 HTTP/HTTPS 的路由。
-
支持 TLS 終止(HTTPS)。
-
為集群內部多個服務提供一個 統一的訪問入口。
-
提供高級功能,如 路徑重寫、反向代理、負載均衡。
Service主要是面向四層負載,基于TCP傳輸,用于將流量分發到一組 Pod。Service 抽象出 Pod 的網絡訪問,提供穩定的網絡接口,即使 Pod 動態變化,其訪問方式仍保持不變。
Service的作用:
-
提供 Pod 的 服務發現 和 負載均衡。
-
允許集群內外部流量訪問特- 定的 Pod。
-
支持多種訪問類型,包括 ClusterIP、NodePort、LoadBalancer 和 ExternalName。
使用場景對比
使用場景 | Ingress | Service |
---|---|---|
服務訪問入口 | Ingress 可配置域名和路徑規則,為多個服務提供統一入口。 | Service 無法管理多個服務,只能處理一個服務的流量。 |
內部服務通信 | 不適合用于集群內部通信。 | 使用 ClusterIP 類型的 Service 實現 Pod 之間通信。 |
外部流量接入 | 通過 Ingress 控制器暴露服務,適用于 HTTP/HTTPS 流量。 | 通過 NodePort 或 LoadBalancer 類型暴露服務。 |
TCP/UDP 流量 | 不支持,僅處理 HTTP/HTTPS。 | 支持 TCP、UDP 流量,通過 Service 直接轉發。 |
域名路由 | 支持基于域名的路由規則。 | 不支持域名路由。 |
復雜流量管理(SSL、重定向等) | 支持多種高級功能,如 TLS、路徑重寫等。 | 只提供基礎的流量轉發功能。 |
關鍵特性對比
Ingress特性:
-
協議支持:僅支持HTTP和HTTPS;
-
路由規則:基于域名和路徑進行路由,例如,根據路徑/app1路由到Service A,路徑/app2路由到service B;
-
TLS支持:直接HTTPS,TLS終止直接在Ingress層進行,配置TLS后,用戶訪問時自動升級為HTTPS;
-
負載均衡:在Ingress層負載均衡到不同的Service,每個Service內部pod之間的負載均衡由Service實現;
Service特性:
-
協議支持:支持HTTP、HTTPS、TCP、UDP等多種協議;
-
Service類型:
-
ClusterIP(默認):僅在集群內部可訪問;
-
NodePort:通過每個節點上的特定端口暴露服務;
-
LoadBalancer:通過云提供商的負載均衡器暴露服務;
-
ExternalName:將請求重定向到外部DNS名稱;
-
-
負載均衡:Service 將流量分發到其關聯的多個 Pod,實現 Pod 級別的負載均衡;
-
服務發現:Kubernetes 自動為每個 Service 創建一個 DNS 入口,集群內其他服務可以通過服務名訪問;
Ingress和Service之間的關系
Ingress依賴于Service,Ingress 本身并不直接與 Pod 通信,它將請求轉發到 Service,而 Service 再將流量分發到具體的 Pod。
Ingress的典型流量場景:
-
用戶請求 通過域名或 IP 訪問 Ingress。
-
Ingress 根據配置規則,將流量轉發到對應的 Service。
-
Service 負責將流量分配到 Pod。
Service 可以單獨使用,而不需要依賴 Ingress。例如,NodePort 和 LoadBalancer 類型的 Service 可以直接暴露服務給外部。