Kubernetes新手完全指南
運行應用程序通常需要使用服務器。然而,傳統的服務器模式存在一些限制,無法有效定義和強制執行應用程序的邊界,也無法確保資源利用的公平性,導致資源利用率低下。
為了克服這些問題,虛擬化技術應運而生。虛擬化技術允許在一臺物理服務器上創建多個虛擬機(VM)。
虛擬機(VM)是由軟件管理的虛擬化計算機系統的實例,也被稱為hypervisor。每個虛擬機都是獨立且隔離的實體,擁有自己的虛擬資源。多個虛擬機可以共存于同一臺物理服務器上,這樣就提高了資源利用率。每個虛擬機都是完全隔離的,并且有自己的操作系統。虛擬化技術有一些限制,其中之一是每臺物理系統可以承載的虛擬機數量的限制。
虛擬機和容器
與虛擬機相比,容器提供了一種輕量級的虛擬化解決方案,因為在托管物理系統上運行的多個容器共享操作系統。與虛擬機類似,每個容器都有自己的資源集,包括CPU共享,但它與其他容器共享操作系統。Docker是廣泛用于管理容器的容器運行時。
與虛擬機相比,容器具有多個優點,并且被廣泛用于打包應用程序。然而,在生產環境中管理容器并提供容錯和負載均衡等服務是一項具有挑戰性的任務。
這就是Kubernetes發揮作用的地方。它是一個開源且可擴展的容器編排平臺。該項目由Google于2014年開源。它自動化容器化應用程序的部署、擴展和管理。Kubernetes允許管理和協調跨多個主機的容器集群,提供容錯性和可伸縮性等服務。
注意:Kubernetes通常被稱為K8s,因為在“K”和“s”之間有八個字母。
1 架構和組件
一個Kubernetes部署被稱為一個Kubernetes集群,具有兩種類型的資源:控制平面和節點。每個集群都有一個工作節點池,在Pod上運行容器化應用程序,Pod代表一個或多個共存的容器。這些節點由控制平面管理,如下圖所示。在生產環境中,集群將包含多個工作節點,控制平面將在多臺機器上運行,確保高可用性和容錯性。
1.1 控制平面組件
控制平面的主要組件如下所述:
- etcd:這是用于存儲Kubernetes集群數據、服務發現詳細信息和API對象的鍵值存儲。
- kube-scheduler:它在工作節點上調度新創建的Pod。
- kube-controller-manager:它運行控制器進程,如處理節點故障的節點控制器和作業控制器。云集成有一個單獨的控制器組件。
- kube-apiserver:Kubernetes API服務器是集群的主要管理實體,接收所有REST請求。
Kubernetes架構
1.2 節點組件
Kubernetes集群中的每個工作節點都會運行一些組件。這里選擇了Docker作為容器運行時,但Kubernetes還支持其他多種運行時。以下是這些運行時的高級概述:
- Kubelet:它管理Pod中的容器,并確保它們運行并保持健康狀態。
- Kube-proxy:它允許來自互聯網或集群內部的Pod之間進行網絡通信。
2 關鍵概念
熟悉一些與Kubernetes相關的關鍵概念:
- Pods:Kubernetes的基本構建塊。Pod是Kubernetes中最小的可部署單位,代表一個或多個共存的容器。
- ReplicaSets:確保始終運行指定數量的Pod副本。通常,我們不直接管理ReplicaSets,而是使用高級概念Deployments。
- Deployments:一個更高級的抽象,用于管理ReplicaSets。Deployments允許我們以聲明方式定義和更新應用程序的期望狀態。
- Services:同一主機上的Pod可以與其他Pod進行通信。但是,如果我們希望將運行在Pod上的應用程序暴露給外部世界(或集群內部),我們可以使用Service API。Service允許我們抽象出底層的Pod IP,并提供諸如負載均衡之類的服務。
- 命名空間:提供一種邏輯上劃分集群資源的方式,因此,命名空間內的資源名稱需要是唯一的。
3 部署示例應用程序
本節將在minikube上部署一個示例應用程序,minikube是一個本地的Kubernetes集群。開發人員需要遵循minikube網站上提到的步驟,在本地系統上安裝minikube。然后,使用以下命令啟動集群:
minikube start
要與Kubernetes集群交互,可以使用kubectl命令行工具使用Kubernetes API對集群進行各種操作。請按照Kubernetes網站上提供的說明安裝kubectl CLI。或者,minikube也附帶了kubectl,可以使用minikube kubectl -- [commands]來訪問。本文假設已經安裝了kubectl。
kubectl命令的一般結構是提供要在<resource>上執行的<action>。要獲取節點列表,可以使用以下命令。這里還提供了一些其他常見示例,以幫助開發人員入門。請注意,通過在命令的末尾添加--help,可以獲取有關其用法的更多信息。
kubectl get nodes
kubectl get nodes --help
kubectl get pods
kubectl describe pods nginx-pod
3.1 創建一個Pod
實際上,這里不會直接創建Pods,而是使用工作負載資源(例如Deployments)來創建它們。不過,為了幫助入門,以下是創建Pod的YAML模板:
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.25.1
ports:
- containerPort: 80
上面顯示的YAML文件更容易理解。將Pod命名為nginx-pod,并指定它包含一個運行nginx的單個容器。重申一下,Pods是Kubernetes的基本構建塊。Pod是Kubernetes中最小的可部署單元,最常見的用例是每個Pod運行一個單獨的容器的模型。
kubectl可以以兩種不同的方式使用:命令式或聲明式。在聲明式使用時,提供一個描述所需狀態的清單,例如上面顯示的YAML文件,并且kubectl將其提交給集群,確定如何實現它。另一方面,在命令式使用時,提供特定于集群的命令來指示kubectl要執行的操作。
要創建上述文件中顯示的Pod,請將內容保存到名為nginx-pod的文件中,然后使用以下命令運行kubectl apply:
kubectl apply -f nginx-pod.yaml
kubectl get pods
Pod的狀態從ContainerCreating更改為Running可能需要幾秒鐘的時間。在READY列中應該能夠看到1/1。
第二個命令獲取Pod列表,如果一切順利,會在列表中找到Pod。
圖片
至此已經在Kubernetes上創建了第一個Pod!
可以看到Pod正在運行一個監聽端口80的nginx容器。然而,無法通過http://127.0.0.1:80訪問它。這是可以理解的,Pod在集群內部運行,默認情況下無法直接訪問。
通常,不會直接訪問Pods,但是為了幫助入門,可以使用kubectl的port-forward功能,它可以在主機和Pod上指定端口之間建立隧道。
kubectl port-forward nginx-pod 8080:80
運行以上命令后,在瀏覽器中瀏覽到http://127.0.0.1:8080,應該能夠看到nginx服務器的歡迎頁面。按下“Ctrl + C”結束端口轉發會話?,F在可以刪除這個Pod,因為將通過創建Deployments來管理它們。
kubectl delete pod nginx-pod
kubectl get pods
3.2 創建一個部署
在前面的部分中,創建了第一個Pod,但在實踐中,通常不直接創建Pod,而是使用工作負載資源,如Deployments。在本部分中,將使用下面的清單創建第一個Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx-pod
template:
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.25.1
ports:
- containerPort: 80
該清單有三個重要部分。將部署命名為nginx-deployment,然后通過指定副本數為2創建一個ReplicaSet。之前學到過,ReplicaSets確保指定數量的Pod副本始終運行。部署名稱將指導副本的命名,稍后會看到。最后,在第12-21行中指定Pods模板。這是一個示例,重申下通常不直接創建Pods,而是使用更高級的概念(如Deployments)管理它們。
將清單保存到名為nginx-deployment.yaml的文件中,然后使用以下命令創建一個部署:
kubectl apply -f nginx-deployment.yaml
kubectl get deployments
如果一切順利,應該能夠在列表中看到部署??梢宰⒁獾絉EADY列中的2/2與ReplicaSet規范相匹配。還可以獲取Pod列表來確認這一點。
現在,可以通過刪除Pods來測試部署的可用性,并觀察它如何通過啟動新的Pods自動實現期望的狀態。需要使用以下命令:
kubectl get pods
kubectl delete pod nginx-deployment-7d6955794c-s8c2h
kubectl get pods
被刪除的Pod的名稱對您來說可能會有所不同,但是您會注意到一旦刪除一個Pod,就會實例化另一個具有不同名稱的Pod??梢杂^察AGE列來確認這種行為。
現在已經成功創建了第一個部署!
3.3 創建一個服務
開發人員可以使用服務API將運行在Pods上的應用程序暴露給外部世界。服務允許我們抽象底層的Pod IP,并提供負載均衡等服務。通常,可以創建多種類型的服務,并存在許多相關的用例。可以使用以下命令為部署創建一個服務:
kubectl expose deployment nginx-deployment --type=LoadBalancer --name=nginx-service --port=80
kubectl expose允許將Kubernetes對象(在我們的情況下是部署)作為新的Kubernetes服務暴露出來??梢栽诜樟斜碇锌吹叫聞摻ǖ姆眨⑹褂胐escribe命令獲取有關服務的更多詳細信息,如下所示:
kubectl get services
kubectl describe service nginx-service
NodePort字段的值指定了一個隨機端口,可以用于訪問服務。由于在本文中使用minikube,可以使用以下命令訪問服務:
minikube service nginx-service
這將打開nginx的歡迎頁面。但是,我們不直接訪問Pods,可以通過刪除現有的Pods并重新訪問服務來確認這一行為。
4 總結
Kubernetes是一個開源的、可擴展的容器編排平臺。Kubernetes允許管理和協調跨多個主機的容器集群,提供容錯和可擴展性等服務。
本文詳細介紹了Kubernetes的架構和組件,結合了各種關鍵概念的簡介。本文提供了一個實踐指南,介紹了如何在本地的Kubernetes集群minikube上部署樣例應用程序。