入門Kubernetes的優秀途徑:從基本操作到實際示例
運行應用程序通常需要服務器。在早期,無法為服務器上運行的應用程序定義和強制執行邊界,并確保資源使用的公平性。因此,一個服務器一般限制只運行單個應用程序,顯然這導致了資源利用率低下。
后面引入了虛擬化技術,允許我們在一臺物理計算機上創建多個虛擬實例。
虛擬機(VM)是由軟件(稱為Hypervisor)管理的虛擬化計算機系統的實例。每個虛擬機都作為一個自包含和隔離的實體運行,具有自己的虛擬資源。多個虛擬機可以共存于同一臺物理服務器上。虛擬化提高了資源利用率。重要的是每個虛擬機都完全隔離,并擁有自己的操作系統。這種方法有一些限制,包括限制可以共享物理系統的虛擬機數量。
虛擬機和容器
與虛擬機相比,容器提供了輕量級虛擬化解決方案,因為在主機物理系統上運行的多個容器共享操作系統。與虛擬機一樣,每個容器都有自己的一組資源,包括 CPU 共享,但它與其他容器共享操作系統。Docker 是一種廣泛使用的容器運行時,用于管理容器。
與虛擬機相比,容器具有許多優勢,并且被廣泛用于打包應用程序。然而,在生產環境中管理容器并提供諸如容錯性和負載均衡等服務是一項具有挑戰性的任務。
Kubernetes提供了解決方案,它是一個開源且可擴展的容器編排平臺,該項目由Google于2014年開源。它對容器化應用程序的部署、擴展和管理實現了自動化。Kubernetes允許在多個主機上管理和協調容器集群,提供容錯性和可擴展性等服務。
注意:Kubernetes通常被稱為K8s,因為在“K”和“s”之間有八個字母。
架構和組件
Kubernetes部署被稱為Kubernetes集群,包含兩種類型的資源:控制面板(control plane)和節點(nodes)。每個集群都有一組工作節點,它們在Pod中運行容器化應用程序,Pod中存在一個或多個容器。這些節點由控制面板進行管理,如下圖所示。在生產環境中,集群將包含多個工作節點,并且控制面板將跨多臺機器運行,確保高可用性和容錯性。
控制面板組件
控制面板的主要組件如下:
- etcd:用于存儲Kubernetes集群數據、服務發現詳細信息和API對象的鍵值存儲。
- kube-scheduler:用于在工作節點上調度新創建的Pod。
- kube-controller-manager:它運行控制器進程,例如用于處理節點故障的節點控制器和作業控制器。還有一個獨立的控制器組件用于云集成。
- kube-apiserver:Kubernetes API服務器是集群的主要管理實體,接收所有REST請求。
節點組件
Kubernetes集群中的每個工作節點也運行一些組件,如上圖所示。我們已經指定Docker作為容器運行時;不過,Kubernetes也支持許多其他運行時。總體如下:
- Kubelet:管理Pod中的容器,并確保它們正常運行和保持健康。
- Kube-proxy:允許從互聯網或集群內部對Pod進行網絡通信。
核心概念
首先讓我們熟悉一些與Kubernetes相關的核心概念:
- Pods:Kubernetes的基本構建塊。Pod是Kubernetes中最小的可部署單元,包含一個或多個容器。
- ReplicaSets:確保運行指定數量的Pod副本。通常,我們不直接管理ReplicaSets,而是使用更高級別的概念——Deployments。
- Deployments:一個更高級別的抽象,用于管理ReplicaSets。Deployments允許我們以聲明性的方式定義和更新應用程序的期望狀態。
- Services:在主機上的Pod可以相互通信。然而,如果我們希望將運行在Pod上的應用程序暴露給外界(或集群內部),可以使用Service API。Services允許我們抽象底層的Pod IP,并提供諸如負載均衡等服務。
- Namespaces:提供了一種邏輯上劃分集群資源的方式,因此資源名稱在命名空間內必須唯一。
部署示例應用程序
在本節中,我們將在minikube上部署一個示例應用程序,這是一個本地的Kubernetes集群。需要按照minikube網站上提到的步驟來安裝minikube到本地系統。然后,使用下面的命令啟動集群:
minikube start
要與 Kubernetes 集群交互,可以使用kubectl命令行,通過 Kubernetes API 在集群上執行各種操作。按照 Kubernetes 網站上提供的說明安裝kubectlCLI。或者,minikube也附帶了kubectl,可以使用minikube kubectl -- [commands]來訪問。
kubectl命令的一般結構是在<resource>上提供一個<action>來執行操作。要獲取節點列表,可以使用以下命令,以下是一些示例。請注意,在命令的末尾添加--help,可以獲取有關其用法的更多信息。
kubectl get nodes
kubectl get nodes --help
kubectl get pods
kubectl describe pods nginx-pod
創建Pod
首先創建第一個Pod。實際上,我們不會直接創建Pod;它們是使用工作負載資源(如Deployments)創建的。以下是通過YAML模板創建Pod示例:
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.25.1
ports:
- containerPort: 80
Pod 命名為nginx-pod并包含一個容器nginx。需要重申的是,Pod 是 Kubernetes 的基本構建塊。Pod 是 Kubernetes 中最小的可部署單元,最常見的用例是每個 Pod 一個容器模型,其中每個 Pod 運行一個容器。
kubectl可以以兩種不同的方式使用:命令式或聲明式。當以聲明方式使用時,需要提供一個清單,例如上面所示的 YAML 文件,它描述了所需的狀態,并將kubectl其提交到集群,確定如何實現它。另一方面,當強制使用時,需要提供特定于集群的命令來指示kubectl要采取的操作。
要創建上面文件中顯示的 Pod,首先將內容保存在nginx-pod的文件中,然后運行以下命令:
kubectl apply -f nginx-pod.yaml
kubectl get pods
Pod 的狀態可能需要幾秒鐘的時間才能從 更改ContainerCreating為Running。
第二個命令獲取 Pod 列表,如果一切順利,我們將能夠找到其中列出的 Pod。
那么第一個Pod就已經創建完成。
但是,我們將無法訪問http://127.0.0.1:80,因為 Pod 在集群內運行,默認情況下無法直接訪問。
通常,我們不會直接訪問 Pod,但為了演示,可以使用kubectl的端口轉發(port-forward)功能,它會在主機和Pod之間建立一個隧道,將流量從主機傳遞到Pod上指定的端口。
kubectl port-forward nginx-pod 8080:80
在運行上述命令后,在瀏覽器中訪問http://127.0.0.1:8080,應該能夠看到nginx服務器的歡迎頁面。按下“Ctrl + C”來結束端口轉發會話。現在我們可以刪除這個Pod,接下來我們將通過創建Deployments來管理它們。
kubectl delete pod nginx-pod
kubectl get pods
創建 Deployment
使用下面的清單來創建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
這個清單有三個重要的部分。
- Deployment名稱為nginx-deployment。
- 通過指定副本數量為2來創建一個ReplicaSet。我們之前學到過,ReplicaSets確保始終運行指定數量的Pod副本。Deployment的名稱會在后面影響副本的名稱。
- 最后,在第12至21行中,指定了Pods的模板。
保存清單到nginx-deployment.yaml文件中,然后使用以下命令創建一個Deployment:
kubectl apply -f nginx-deployment.yaml
kubectl get deployments
如果順利的話,我們應該能夠在列表中看到Deployment。其中READY列中的2/2與ReplicaSet指定的數量相匹配。
現在,我們可以通過刪除Pods并觀察它如何自動啟動新的Pods來測試Deployment的可用性。命令如下:
kubectl get pods
kubectl delete pod nginx-deployment-7d6955794c-s8c2h
kubectl get pods
可以看到一旦刪除一個Pod,就會立即創建另一個具有不同名稱的Pod。
創建Service
使用Service API可以將運行在Pod上的應用程序暴露給外部。Service允許我們抽象出底層Pod的IP,并提供負載均衡等服務。通常情況下,可以創建多種類型的Service。使用以下命令來創建一個Service:
kubectl expose deployment nginx-deployment --type=LoadBalancer --name=nginx-service --port=80
kubectl expose命令允許我們將Kubernetes對象(這里是一個Deployment)公開為一個新的Kubernetes Service。命令執行后,可以在服務列表中看到新創建的Service,并可以使用描述命令獲取有關該Service的更多詳細信息,如下所示:
kubectl get services
kubectl describe service nginx-service
我們需要關注NodePort字段的值,它指定了一個隨機端口,可以用來訪問Service。由于我們使用的是minikube,可以使用以下命令訪問Service:
minikube service nginx-service
如果順利的話,將打開nginx的歡迎頁面。
總結
Kubernetes是一個開源且可擴展的容器編排平臺。Kubernetes允許管理和協調跨多個主機的容器集群,提供故障容忍和可伸縮性等服務。