k8s教程(基础篇)-基本概念和术语
文章目錄
- 01 資源對象概述
- 02 集群類
- 2.1 Master
- 2.2 Node
- 2.3 命名空間
- 03 應用類
- 3.1 service和pod
- 3.2 label與標簽選擇器
- 3.3 Pod和Deployment
- 3.4 Service和ClusterIp
- 3.5 Service外網訪問
- 3.6 有狀態的應用集群
- 3.7 批處理應用
- 3.8 應用的配置
- 3.8.1 ConfigMap
- 3.8.2 Secret
- 3.9 應用的運維
- 3.9.1 HPA橫向擴容
- 3.9.2 VPA垂直擴容
- 04 存儲類
- 4.1 Volume(存儲卷)
- 4.1.1 emptyDir(臨時目錄)
- 4.1.2 hostPath(宿主機目錄)
- 4.1.3 公有云Volume
- 4.1.4 其它類型的Volume
- 4.1.5 動態存儲
- 05 安全類
- 5.1 Service Account
- 5.2 Role
- 5.2 Role Binding
- 5.3 NetworkPolicy(網絡策略)
01 資源對象概述
Kubernetes 中的基本概念和術語大多是圍繞 資源對象(Resource Object)來說 的,而資源對象在總體上可分為以下兩類:
資源對象一般包括幾個通用屬性:版本、類別(Kind)、名稱、標簽、注解,如下所述。
- 版本信息:包括了此對象所屬的資源組,一些資源對象的屬性會隨著版本的升級而變化,在定義資源對象時要特別注意這一點。
- 類別屬性:用于定義資源對象的類型。
- 資源對象的名稱(Name)、標簽、注解這三個屬性屬于資源對象的元數據(metadata),資源對象的名稱要唯一。資源對象的標簽是很重要的數據,也是 Kubernetes 的一大設計特性,比如通過標簽來表明資源對象的特征、類別,以及通過標簽篩選不同的資源對象并實現對象之間的關聯、控制或協作功能。
- 注解:可被理解為一種特殊的標簽,不過更多地是與程序掛鉤,通常用于實現資源對象屬性的自定義擴展。
我們可以采用 YAML 或 JSON 格式聲明(定義或創建)一個 Kubernetes 資源對象,每個資源對象都有自己的特定結構定義(可以理解為數據庫中一個特定的表),并且統一保存在 etcd 這種非關系型數據庫中,以實現最快的讀寫速度。此外,所有資源對象都可以通過 Kubernetes 提供的kubectl工具(或者 API 編程調用)執行增、刪、改、查等操作。
這里按照功能或用途對眾多資源對象其進行分類,將其分為集群類、應用類、存儲類及安全類這四大類,下面來講解。
02 集群類
集群(Cluster)表示一個由 Master 和 Node 組成的 Kubernetes 集群。
2.1 Master
Master指的是集群的控制節點。在每個 Kubernetes 集群中都需要有一個或一組被稱為 Master 的節點,來負責整個集群的管理和控制。Master 通常占據一個獨立的服務器(在高可用部署中建議至少使用 3 臺服務器),是整個集群的“大腦”,如果它發生宕機或者不可用,那么對集群內容器應用的管理都將無法實施。
在 Master上運行著以下關鍵進程:
- Kubernetes API Server (kube-apiserver):提供 HTTP RESTful API 接口的主要服務,是 Kubernetes 里對所有資源進行增、刪、改、查等操作的唯一入口,也是集群控制的入口進程。
- Kubernetes Controller Manager:Kubernetes 里所有資源對象的自動化控制中心,可以將其理解為資源對象的“大總管”。
- Kubernetes Scheduler:負責資源調度(Pod 調度)的進程,相當于公交公司的調度室。
- 在 Master上通常還需要部署etcd服務。
2.2 Node
Kubernetes集群中除 Master 外的其他服務器被稱為 Node。Node 可以是一臺物理主機,也可以是一臺虛擬機。Node 是Kubernetes集群中的工作負載節點,每個 Node 都會被 Master 分配一些工作負載(Docker 容器),當某個Node宕機時,其上的工作負載會被 Master 自動轉移到其他 Node 上。
在每個 Node 上都運行著以下關鍵進程:
- kubelet:負責 Pod 對應容器的創建、啟停等任務,同時與 Master 密切協作,實現集群管理的基本功能。
- kube-proxy:實現 Kubernetes Service 的通信與負載均衡機制的服務。
- 容器運行時(如 Docker) : 負責本機的容器創建和管理。
我們可以運行以下命令查看在集群中有多少個 Node:
查詢node詳情:
2.3 命名空間
在集群類里還有一個重要的基礎概念一一命名空間,它在很多情況下用于實現多租戶的資源隔離,典型的一種思路就是給每個租戶都分配一個命名空間。每個命名空間都是相互獨立的存在,屬于不同命名空間的資源對象從邏輯上相互隔離。
在每個 Kubernetes 集群安裝完成且正常運行之后,Master 會自動創建兩個命名空間。
- 默認級(default):用戶創建的資源對象如果沒有指定命名空間,則被默認存放在default命名空間中;
- 系統級(kube-system):系統相關的資源對象如網絡組件、DNS 組件、監控類組件等,都被安裝在 kube-system 命名空間中。
我們可以通過命名空間將集群內部的資源對象“分配”到不同的命名空間中,形成邏輯上分組的不同項目、小組或用戶組,便于不同的分組在共享使用整個集群的資源的同時能被分別管理。當給每個租戶都創建一個命名空間來實現多租戶的資源隔離時,還能結合 Kubernetes 的資源配額管理,限定不同租戶能占用的資源,例如 CPU 使用量、內存使用量等。
命名空間的定義很簡單,如下所示的 YAML 文件定義了名為development的命名空間:
查看(注意加上-namespace或-n):
03 應用類
3.1 service和pod
Node、Pod與容器間的關系圖如下:
Pod及周邊對象:
應用類相關的資源對象主要是圍繞 Service(服務)和 Pod 這兩個核心對象展開的。
- Service :一般指的是無狀態服務,通常由多個程序副本提供服務,在特殊情況下也可以是有狀態的單實例服務,比如 MySQL 這種數據存儲類的服務。
- Pod:有一個特殊的被稱為“根容器”的 Pause 容器,Pause 容器對應的鏡像屬于 Kubernetes 平臺的一部分,還包含一個或多個緊密相關的用戶業務容器。
3.2 label與標簽選擇器
給某個資源對象定義一個 label,就相當于給它打了一個標簽,隨后可以通過 Label Selector(標簽選擇器)查詢和篩選擁有某些 Label 的資源對象,Kubernetes 通過這種方式實現了類似 SQL 的簡單又通用的對象查詢機制。
寫法舉例:
舉例圖:
3.3 Pod和Deployment
Pod、Deployment和Service的關系:
前面提到,大部分 Service 都是無狀態的服務,可以由多個Pod副本實例提供服務。通常情況下,每個 Service 對應的Pod服務實例數量都是固定的,如果一個一個地手工創建 Pod 實例,就太麻煩了,最好是用模板的思路,即提供一個 Pod 模板(Template),然后由程序根據我們指定的模板自動創建指定數量的 Pod 實例。這就是Deployment這個資源對象所要完成的事情了,舉例:
3.4 Service和ClusterIp
Kubernetes 內部在每個 Node 上都運行了一套全局的虛擬負載均衡器,自動注入并自動實時更新集群中所有 Service 的路由表,通過 iptables或者 IPVS 機制,把對 Service 的請求轉發到其后端對應的某個 Pod 實例上,并在內部實現服務的負載均衡與會話保持機制。
不僅如此,Kubernetes 還采用了一種很巧妙又影響深遠的設計一 ClusterIP 地址。
Service 一旦被創建,Kubernetes 就會自動為它分配一個全局唯一的虛擬 IP 地址,即ClusterIP 地址,而且在Service的整個生命周期內,其 ClusterIP 地址不會發生改變,這樣一來,每個服務就變成了具備唯一 IP 地址的通信節點,遠程服務之間的通信問題就變成了基礎的 TCP 網絡通信問題。
3.5 Service外網訪問
我們需要先弄明白 Kubernetes 的三種 IP,分別如下:
- Node IP: 是 Kubernetes集群中每個節點的物理網卡的 IP 地址,是一個真實存在的物理網絡,所有屬于這個網絡的服務器都能通過這個網絡直接通信。
- Pod IP: 每個 Pod 的 IP 地址,在使用 Docker 作為容器支持引擎的情況下,它是 Docker Engine 根據 dockero 網橋的 IP 地址段進行分配的,通常是一個虛擬二層網絡,通過Pod IP所在的虛擬二層網絡進行通信的,真實的TCP/IP 流量是通過Node IP 所在的物理網卡流出。
- Service IP: Service 的 ClusterIP 地址屬于集群內的地址,無法在集群外直接使用這個地址。為了解決這個問題,Kubernetes 首先引入了 NodePort。
對于每個 Service,我們通常需要配置一個對應的負載均衡器實例來轉發流量到后端的 Node 上,這的確增加了工作量及出錯的概率,如下圖:
NodePort 的確功能強大且通用性強,但也存在一個問題,即每個 Service 都需要在 Node 上獨占一個端口,而端口又是有限的物理資源,那能不能讓多個 Service 共用一個對外端口呢,這就是后來增加的 Ingress資源對象所要解決的問題。
Ingress其實只能將多個 HTTP (HTTPS)的 Service“聚合”,通過虛擬域名或者 URL Path 的特征進行路由轉發功能,考慮到常見的微服務都采用了 HTTP REST 協議,所以 Ingress 這種聚合多個 Service 并將其暴露到外網的做法還是很有效的。
在一定程度上,我們可以把 Ingress 的實現機制理解為基于 Nginx 的支持虛擬主機的 HTTP 代理。下面是一個 Ingress 的實例:
3.6 有狀態的應用集群
我們知道,Deployment 對象是用來實現無狀態服務的多副本自動控制功能的,那么有狀態的服務,比如: ZooKeeper:集群、MySQL 高可用集群(3 節點集群)、Kafka 集群等是怎么實現自動部署和管理的呢?
這個問題就復雜多了,這些一開始是依賴 StatefulSet 解決的,但后來發現對于一些復雜的有狀態的集群應用來說,StatefulSet 還是不夠通用和強大,所以后面又出現了 Kubernetes Operator。
平臺開發者借助 Operator 框架提供的 API,可以更方便地開發一個類似 StatefulSet 的控制器。在這個控制器里,開發者通過編碼方式實現對目標集群的自定義操控,包括集群部署、故障發現及集群調整等方面都可以實現有針對性的操控,從而實現更好的自動部署和智能運維功能。
從發展趨勢來看,未來主流的有狀態集群基本都會以 Operator 方式部署到 Kubernetes集群中。
3.7 批處理應用
除了無狀態服務、有狀態集群、常見的第三種應用,還有批處理應用。批處理應用的特點是一個或多個進程處理一組數據(圖像、文件、視頻等),在這組數據都處理完成后,批處理任務自動結束。為了支持這類應用,Kubernetes 引入了新的資源對象一一 Job,下面是一個計算圓周率的經典例子:
Jobs 控制器提供了兩個控制并發數的參數:completions 和 parallelism, completions 表示需要運行任務數的總數,parallelism 表示并發運行的個數。后來kubernetes增加了cronjob可以周期性的執行某個任務。
3.8 應用的配置
通過前面的學習,我們初步理解了三種應用建模的資源對象,總結如下。
- 無狀態服務的建模:Deployment
- 有狀態集群的建模:StatefulSet
- 批處理應用的建模:Job
在進行應用建模時,應該如何解決應用需要在不同的環境中修改配置的問題呢?這就涉及 ConfigMap 和 Secret 兩個對象。
3.8.1 ConfigMap
用戶將配置文件的內容保存到 ConfigMap 中,文件名可作為 key, value 就是整個文件的內容,多個配置文件都可被放入同一個 ConfigMap。
在建模用戶應用時,在 Pod 里將 ConfigMap。定義為特殊的 Volume 進行掛載。在 Pod 被調度到某個具體 Node 上時,ConfigMap 里的配置文件會被自動還原到本地目錄下,然后映射到 Pod 里指定的配置目錄下,這樣用戶的程序就可以無感知地讀取配置了。
在 ConfigMap 的內容發生修改后,Kubernetes 會自動重新獲取 ConfigMap 的內容,并在目標節點上更新對應的文件。
3.8.2 Secret
Secrett也用于解決應用配置的問題,不過它解決的是對敏感信息的配置問題,比如數據庫的用戶名和密碼、應用的數字證書、Tokn、SSH 密鑰及其他需要保密的敏感配置。對于這類敏感信息,我們可以創建一個 Secret 對象,然后被 Pod 引用。Secret 中的數據要求以 BASE64 編碼格式存放。注意,BASE64 編碼并不是加密的,在 Kubernetes1.7 版本以后,Secret 中的數據才可以以加密的形式進行保存,更加安全。
3.9 應用的運維
3.9.1 HPA橫向擴容
首先就是 HPA (Horizontal Pod Autoscaler),我們可以將 HPA 理解為 Pod 橫向自動擴容,即自動控制 Pod 數量的增加或減少。通過追蹤分析指定 Deployment 控制的所有目標Pod的負載變化情況,來確定是否需要有針對性地調整目標 Pod 的副本數量,這是 HPA 的實現原理。
例如:Kubernetes 內置了基于Pod的 CPU利用率進行自動擴縮容的機制,應用開發者也可以自定義度量指標如每秒請求數,來實現自定義的 HPA 功能。下面是一個 HPA 定義的例子:
根據上面的定義,我們可以知道這個 HPA 控制的目標對象是一個名為 php-apache 的 Deployment里的 Pod 副本,當這些 Pod 副本的 CPU 利用率的值超過 90% 時,會觸發自動動態擴容。
3.9.2 VPA垂直擴容
VPA (Vertical Pod Autoscaler) 即垂直 Pod 自動擴縮容,它根據容器資源使用率自動推測并設置 Pod 合理的CPU和內存的需求指標,從而更加精確地調度 Pod,實現整體上節省集群資源的目標,因為無須人為操作,因此也進一步提升了運維自動化的水平。
04 存儲類
存儲類的資源對象主要包括: Volume、Persistent Volume、PVC 和 StorageClass。
4.1 Volume(存儲卷)
Volume 是 Pod 中能夠被多個容器訪問的共享目錄。
首先Kubernetes 中的 Volume 被定義在 Pod上,被一個 Pod 里的多個容器掛載到具體的文件目錄下;其次,Kubernetes 中的 Volume 與 Pod 的生命周期相同,但與容器的生命周期不相關,當容器終止或者重啟時,Volume 中的數據也不會丟失;最后,Kubernetes支持多種類型的 Volume,例如 GlusterFS、Ceph 等分布式文件系統。
Volume 的使用:在大多數情況下,我們先在 Pod 上聲明一個 Volume,然后在容器里引用該 Volume并將其掛載(Mount)到容器里的某個目錄下。
舉例來說,若我們要給之前的 Tomcat Pod增加一個名為 datavol的Volume,并將其掛載到容器的/mydata-data 目錄下,則只對Pod 的定義文件做如下修正即可(代碼中的粗體部分):
Kubernetes提供了非常豐富的Volume類型供容器使用,例如:臨時目錄、宿主機目錄、共享存儲等,下面對其中一些常見的類型進行說明。
4.1.1 emptyDir(臨時目錄)
一個 emptyDir 是在 Pod 分配到 Node 時創建的。從它的名稱就可以看出,它的初始內容為空,并且無須指定宿主機上對應的目錄文件,因為這是 Kubernetes 自動分配的一個目錄,當 Pod 從 Node 上移除時,emptyDir 中的數據也被永久移除。
emptyDir 的一些用途如下。
- 臨時空間,例如用于某些應用程序運行時所需的臨時目錄,且無須永久保留。
- 長時間任務執行過程中使用的臨時目錄。
- 一個容器需要從另一個容器中獲取數據的目錄(多容器共享目錄)。在默認情況下,emptyDir 使用的是節點的存儲介質,例如磁盤或者網絡存儲。
還可以使用 emptyDir. Nedium 屬性,把這個屬性設置為“Memory”,就可以使用更快的基于內存的后端存儲了。需要注意的是,這種情況下的 emptyDir 使用的內存會被計入容器的內存消耗,將受到資源限制和配額機制的管理。
4.1.2 hostPath(宿主機目錄)
HostPath 為在 Pod 上掛載宿主機上的文件或目錄,通??梢杂糜谝韵聨追矫?#xff1a;
- 在容器應用程序生成的日志文件需要永久保存時,可以使用宿主機的高速文件系統對其進行存儲。
- 需要訪問宿主機上 Docker 引擎內部數據結構的容器應用時,可以通過定hostPath為宿主機/var/Iib/docker目錄,使容器內部的應用可以直接訪問 Docker 的文件系統。
在使用這種類型的 Volume時,需要注意以下幾點。
- 在不同的 Node 上具有相同配置的 Pod,可能會因為宿主機上的目錄和文件不同,而導致對 Volume上目錄和文件的訪問結果不一致。
- 如果使用了資源配額管理,則 Kubernetes 無法將 hostPath 在宿主機上使用的資源納入管理。
在下面的例子中使用了宿主機的/data目錄定義了一個hostPath 類型的 Volume:
4.1.3 公有云Volume
公有云提供的 Volume 類型包括谷歌公有云提供的 GCEPersistentDisk、亞馬遜公有云提供的 AWS Elastic Block Store (EBS Volume)等。當我們的Kubernetes集群運行在公有云上或者使用公有云廠家提供的 Kubernetes 集群時,就可以使用這類 Volume。
4.1.4 其它類型的Volume
- Iscsi:將 SCSI 存儲設備上的目錄掛載到 Pod 中。
- nfs:將 NFS Server上的目錄掛載到 Pod 中。
- glusterfs:將開源 GlusterFS 網絡文件系統的目錄掛載到 Pod 中。
- rbd:將 Ceph 塊設備共享存儲(Rados Block Device)掛載到Pod中。
- gitRepo:通過掛載一個空目錄,并從 Git 庫克隆(clone)一個 git repository 以供 Pod 使用。
- configmap:將配置數據掛載為容器內的文件。
- secret:將 Secret數據掛載為容器內的文件。
4.1.5 動態存儲
Volume屬于靜態管理的存儲,即我們需要事先定義每個 Volume,然后將其掛載到 Pod 中去用,這種方式存在很多弊端,典型的弊端如下。
- 配置參數煩瑣,存在大量手工操作,違背了 Kubernetes 自動化的追求目標。
- 預定義的靜態 Volume 可能不符合目標應用的需求,比如容量問題、性能問題。
所以 Kubernetes 后面就發展了存儲動態化的新機制,來實現存儲的自動化管理。相關的核心對象(概念)有三個:Persistent Volume(簡稱 PV)、StorageClass、PVC。
- PV: 表示由系統動態創建(dynamically provisioned)的一個存儲卷,可以被理解成 Kubernetes集群中某個網絡存儲對應的一塊存儲,它與 Volume 類似,但 PV 并不是被定義在 Pod 上的,而是獨立于 Pod 之外定義的。PV 目前支持的類型主要有 gcePersistentDisk、AWSElasticBlockStore、AzureFile、AzureDisk、FC (Fibre Channel)、NFS、iSCSI、RBD (Rados Block Device)、CephFS、Cinder、GlusterFS、VsphereVolume、Quobyte Volumes、Mware Photon、Portworx Volumes、ScaleIO Volumes、ostPath、Local 等。
- StorageClass 用來描述和定義某種存儲系統的特征,例如:StorageClass 有幾個關鍵屬性:provisioner、parameters 和 reclaimPolicy,系統在動態創建 PV 時會用到這幾個參數。簡單地說,provisioner 代表了創建 PV 的第三方存儲插件,parameters 是創建 PV 時的必要參數,reclaimPolicy則表明了 PV 回收策略,回收策略包括刪除或則保留。
- PVC :StorageClass名稱會在 PVC (PV Claim)中出現,下面就是一個典型的 PVC 定義:PVC 正如其名,表示應用希望申請的 PV 規格,其中重要的屬性包括 accessModes(存儲訪問模式)、storageClassName(用哪種 StorageClass 來實現動態創建)及 resources(存儲的具體規格)
有了以 StorageClass 與 PVC 為基礎的動態 PV 管理機制,我們就很容易管理和使用 Volume 了,只要在 Pod 里引用 PVC 即可達到目的,如下面的例子所示:
05 安全類
安全始終是 Kubernetes 發展過程中的一個關鍵領域。
從本質上來說 ,Kubernetes 可被看作一個多用戶共享資源的資源管理系統,這里的資源主要是各種Kubernetes里的各類資源對象,比如 Pod、Service、Deployment 等。只有通過認證的用戶才能通過 Kubernetes 的 API Server 查詢、創建及維護相應的資源對象,理解這一點很關鍵。
5.1 Service Account
在默認情況下,Kubernetes在每個命名空間中都會創建一個默認的名稱為 default 的 Service Account,因此 Service Account 是不能全局使用的,只能被它所在命名空間中的 Pod 使用。通過以下命令可以查看集群中的所有 Service Account:
Service Account 是通過 Secret 來保存對應的用戶(應用)身份憑證的,這些憑證信息有 CA 根證書數據(ca.crt)和簽名后的Token信息(Token)。
在 Token 信息中就包括了對應的Service Account的名稱,因此 API Server 通過接收到的Token信息就能確定 Service Account 的身份。在默認情況下,用戶創建一個 Pod 時,Pod 會綁定對應命名空間中的 default 這個 Service Account 作為其“公民身份證”。
當 Pod 里的容器被創建時,Kubernetes 會把對應的Secret對象中的身份信息(ca.crt、Token 等)持久化保存到容器里固定位置的本地文件中,因此當容器里的用戶進程通過 Kubernetes 提供的客戶端 API 去訪問 API Server 時,這些API會自動讀取這些身份信息文件,并將其附加到 HTTPS 請求中傳遞給API Server以完成身份認證邏輯。在身份認證通過以后,就涉及“訪問授權”的問題,這就是 RBAC 要解決的問題了。
5.2 Role
首先我們要學習的是 Role 這個資源對象,包括 Role 與 ClusterRole兩種類型的角色。角色定義了一組特定權限的規則,比如可以操作某類資源對象。局限于某個命名空間的角色由Role對象定義,作用于整個 Kubernetes 集群范圍內的角色則通過 Cluster Role 對象定義。
下面是 Role 的一個例子,表示在命名空間 default 中定義一個Role對象,用于授予對 Pod 資源的讀訪問權限,綁定到該 Role 的用戶則具有對 Pod 資源的 get、watch 和list權限:
5.2 Role Binding
接下來就是如何將 Role 與具體用戶綁定(用戶授權)的問題了。我們可以通過 RoleBinding 與 ClusterRoleBinding 來解決這個問題。下面是一個具體的例子,在命名空間 default 中將“pod-reader”角色授予用戶“Caden”,結合對應的 Role 的定義,表明這一授權將允許用戶“Caden”從命名空間 default 中讀取 pod:
在 RoleBinding 中使用 subjects(目標主體)來表示要授權的對象,這是因為我們可以授權三類目標賬號:Group(用戶組)、User(某個具體用戶)和 Service Account (Pod 應用所使用的賬號)。
5.3 NetworkPolicy(網絡策略)
在安全領域,除了以上針對 API Server 訪問安全相關的資源對象,還有一種特殊的資源對象一一 NetworkPolicy(網絡策略),它是網絡安全相關的資源對象,用于解決用戶應用之間的網絡隔離和授權問題。
NetworkPolicy 是一種關于 Pod 間相互通信,以及 Pod 與其他網絡端點間相互通信的安全規則設定。
NetworkPolicy資源使用標簽選擇 Pod,并定義選定 Pod 所允許的通信規則。在默認情況下,Pod 間及Pod與其他網絡端點間的訪問是沒有限制的,這假設了 Kubernetes集群被一個廠商(公司/租戶)獨占,其中部署的應用都是相互可信的,無須相互防范。但是,如果存在多個廠商共同使用一個Kubernetes集群的情況,則特別是在公有云環境中,不同廠商的應用要相互隔離以增加安全性,這就可以通過 NetworkPolicy 來實現了。
總結
以上是生活随笔為你收集整理的k8s教程(基础篇)-基本概念和术语的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: php离线bt下载,transmissi
- 下一篇: 比较经典的一些话