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