在 Kubernetes 叢集中佈署應用程式,主要有兩種方式:使用 kubectl run
命令直接佈署 Pod 或使用 Deployment 進行佈署。kubectl run
適合快速佈署單個 Pod,而 Deployment 則更適合管理多個 Pod 副本,並提供滾動更新等功能。佈署 Pod 後,需要將其服務暴露出來才能被外部存取,這可以透過建立 Service 資源來實作。本文將詳細介紹這兩種佈署方式,並說明如何使用 kubectl describe
命令檢視 Deployment、Pod 和 Service 的詳細組態。
透過 kubectl run
命令,可以快速地將本地映像 local/mynginx:01
佈署到 Kubernetes 叢集,並透過埠轉發進行測試。然而,生產環境中更推薦使用 Deployment 進行佈署,因為 Deployment 可以確保 Pod 的高用性和自動還原。Deployment 還支援滾動更新,可以降低服務中斷的風險。此外,使用 YAML 格式的佈署檔案可以更方便地管理和版本控制佈署組態,並實作自動化佈署和擴充套件。透過 kubectl describe
命令,可以深入瞭解 Deployment、Pod 和 Service 的詳細組態和狀態,方便排查問題和最佳化佈署。
在Kubernetes中佈署第一個應用程式:詳細
在前面的章節中,我們已經建立了一個名為local/mynginx:01
的容器映像。現在,我們將探討如何在Kubernetes叢集中佈署這個映像。
使用kubectl run命令佈署Pod
首先,我們使用kubectl run
命令來佈署一個Pod。這個命令允許我們直接啟動一個Pod,而不需要建立一個Deployment或其他資源。
步驟1:啟動Pod
我們使用以下命令來啟動一個名為myrun01
的Pod,並將容器的80埠暴露給Kubernetes叢集:
kubectl delete pod myrun01
kubectl run myrun01 --port 80 --image local/mynginx:01
shiva@wks01:~$ kubectl delete pod myrun01
pod "myrun01" deleted
shiva@wks01:~$ kubectl run myrun01 --port 80 --image local/mynginx:01
pod/myrun01 created
shiva@wks01:~$
步驟2:驗證Pod狀態
使用kubectl get pods
命令來驗證Pod是否正在執行:
kubectl get pods
shiva@wks01:~$ kubectl get pods
NAME READY STATUS RESTARTS AGE
myrun01 1/1 Running 0 4m58s
shiva@wks01:~$
步驟3:暴露服務並測試
雖然我們已經將Pod的80埠暴露給Kubernetes叢集,但由於Pod執行在自己的內部網路中,我們需要進行埠轉發,以便從本地工作站存取Pod的服務。
kubectl port-forward pods/myrun01 4567:80
shiva@wks01:~$ kubectl port-forward pods/myrun01 4567:80
Forwarding from 127.0.0.1:4567 -> 80
Forwarding from [::1]:4567 -> 80
Handling connection for 4567
這個命令將本地工作站的4567埠轉發到Pod的80埠。然後,我們可以使用curl
命令來測試服務:
curl localhost:4567
shiva@wks01:~$ curl localhost:4567
<html>
<title>My own container image </title>
<body>
Hello world!<br>
This is my index file embedded in my first container image!!<br>
</body>
</html>
shiva@wks01:~$
步驟4:刪除Pod
完成測試後,我們可以刪除Pod:
kubectl delete pod myrun01
shiva@wks01:~$ kubectl delete pod myrun01
pod "myrun01" deleted
shiva@wks01:~$ kubectl get pods
No resources found in default namespace.
shiva@wks01:~$
使用Deployment佈署Pod
除了直接使用kubectl run
命令外,我們還可以使用create deployment
命令來佈署Pod。
步驟1:建立Deployment
kubectl create deployment dep-webserver --image local/mynginx:01
shiva@wks01:~$ kubectl create deployment dep-webserver --image local/mynginx:01
deployment.apps/dep-webserver created
shiva@wks01:~$ kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
dep-webserver 1/1 1 1 10s
shiva@wks01:~$
#### 內容解密:
kubectl create deployment
命令用於建立一個新的Deployment。dep-webserver
是Deployment的名稱,可以根據需要自定義。--image local/mynginx:01
指定了要使用的容器映像。
步驟2:暴露服務
為了存取佈署的服務,我們需要定義一個Service,將外部流量對映到容器埠。
kubectl expose deployment dep-webserver --type=LoadBalancer --port=80
shiva@wks01:~$ kubectl expose deployment dep-webserver --type=LoadBalancer --port=80
service/dep-webserver exposed
shiva@wks01:~$
#### 內容解密:
kubectl expose deployment
命令用於暴露一個Deployment。--type=LoadBalancer
指定了Service的型別,這裡使用的是LoadBalancer型別。--port=80
指定了要暴露的埠。
未來方向
在接下來的章節中,我們將探討Kubernetes中的各種資源,如Deployment、Service和Pod,以及如何管理和擴充套件它們。這將幫助我們更好地理解Kubernetes的工作原理,並能夠更有效地佈署和管理複雜的應用程式。
Kubernetes佈署流程
graph LR; A[建立容器映像] --> B[使用kubectl run佈署Pod]; A --> C[使用create deployment建立Deployment]; B --> D[暴露服務並測試]; C --> E[暴露服務]; D --> F[刪除Pod]; E --> G[管理和擴充套件Deployment];
圖表翻譯:
此圖表展示了在Kubernetes中佈署應用程式的不同方法。我們可以透過kubectl run
直接佈署Pod,或使用create deployment
建立Deployment。無論哪種方法,都需要暴露服務以便存取。之後,可以根據需要管理和擴充套件Deployment。
程式碼範例與解析
以下是一個簡單的Nginx組態檔案示例,用於演示如何在容器中執行Nginx服務:
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
#### 內容解密:
listen 80;
指定Nginx監聽80埠。server_name localhost;
定義了伺服器的名稱。location / { ... }
組態了根路徑的處理邏輯,包括根目錄和索引檔案。
這個組態示例展示瞭如何設定Nginx以提供靜態內容服務。透過調整組態檔案,可以實作不同的功能和行為。
Kubernetes 佈署檔案與自動化管理
在前一章中,我們探討瞭如何使用命令列佈署網站容器。在本章中,我們將深入瞭解如何編寫佈署檔案以實作組態選項的外部化,並探討如何利用這些檔案進行自動化管理。使用佈署和服務檔案是組態 Kubernetes(K8S)服務、佈署及其他元件的首選方法,因為這種方法允許自動擴充套件,使團隊能夠更快地根據應用程式的交易需求進行擴充或縮減。
佈署檔案 - kind: Deployment
佈署檔案負責維護一組正在執行的 Pod。使用您慣用的編輯器,將清單 7-1 中的內容輸入到名為 mydep01.yaml
的檔案中,然後儲存。
清單 7-1. Kubernetes 佈署檔案
apiVersion: apps/v1
kind: Deployment
metadata:
name: mydeployment
spec:
selector:
matchLabels:
app: label-nginx
template:
metadata:
labels:
app: label-nginx
spec:
containers:
- name: name-nginx
image: local/mynginx:01
ports:
- containerPort: 80
內容解密:
apiVersion: apps/v1
:表示該規範檔案的版本,這個值是由 K8S 規範定義的。目前,我們使用apps/v1
版本。kind: Deployment
:表示該資源型別為 Deployment。metadata
:包含有關該佈署的中繼資料。name
:佈署的名稱,可以是任意的,用於識別該佈署。
spec
:描述了該佈署所需的最終狀態。selector
:指定哪些服務可以與該佈署匹配。matchLabels
:定義了匹配的標籤。
template
:定義了 Pod 的範本。metadata
:範本的中繼資料。labels
:實際標記佈署的標籤,這裡的app: label-nginx
應與matchLabels
相匹配。
spec
:範本的規格。containers
:描述了要執行的容器。name
:容器的名稱。image
:容器的映像位置。ports
:容器提供的服務埠。
佈署檔案的注意事項
- YAML 格式
- 大小寫敏感
- 空格/製表符敏感
建議使用 YAML 語法檢查工具或 Monokle 管理 K8S 叢集的佈署檔案。
應用佈署檔案
假設檔名稱為 deployment.yaml
,現在我們準備應用這個佈署。首先,使用 get deployments
命令列出目前的佈署,如清單 7-2 所示。
清單 7-2. 取得佈署列表
microk8s kubectl get deployments
輸出結果顯示目前只有之前建立的佈署 dep-webserver
。現在,我們將使用剛建立的佈署檔案新增另一個相同性質的佈署,並使用 kubectl apply
和 get deployments
命令驗證佈署,如清單 7-3 所示。
清單 7-3. 使用佈署定義檔案建立 Kubernetes 佈署
kubectl apply -f mydep01.yaml
kubectl get deployments
輸出結果顯示新的佈署 mydeployment
已建立並處於 READY
、UP-TO-DATE
和 AVAILABLE
狀態。
您的任務
- 使用您自己的容器映像建立一個佈署檔案。
- 應用佈署檔案並驗證佈署狀態。
Kubernetes 佈署自動化優勢
使用佈署檔案進行自動化管理具有多項優勢,包括:
- 自動擴充套件:根據應用程式的需求自動增加或減少 Pod 的數量。
- 版本控制:佈署檔案可以納入版本控制系統,方便追蹤變更。
- 重複使用:佈署檔案可以在不同的環境中重複使用。
使用 Mermaid 圖表呈現佈署流程
graph LR A[開始] --> B[建立佈署檔案] B --> C[應用佈署檔案] C --> D[驗證佈署狀態] D --> E[自動擴充套件] E --> F[版本控制] F --> G[重複使用]
**圖表翻譯:**此圖表呈現了使用 Kubernetes 佈署檔案的流程,從建立佈署檔案到應用佈署檔案、驗證佈署狀態、自動擴充套件、版本控制,最後到重複使用佈署檔案的過程。
Kubernetes 佈署檔案最佳實踐
- 使用有意義的名稱:為佈署和容器使用描述性的名稱。
- 版本控制:將佈署檔案納入版本控制系統。
- 自動化測試:使用自動化測試驗證佈署檔案的正確性。
- 檔案化:為佈署檔案新增註解和檔案。
詳細檢視 Kubernetes Deployment 組態
在 Kubernetes 中,Deployment 是管理應用程式佈署的核心資源。透過 kubectl describe
指令,我們可以深入瞭解 Deployment 的詳細組態和狀態。
使用 kubectl describe
檢視 Deployment 詳情
執行以下指令來檢視名為 mydeployment
的 Deployment 詳情:
kubectl describe deployment mydeployment
輸出結果分析
執行結果如下所示:
Name: mydeployment
Namespace: default
CreationTimestamp: Sat, 08 Apr 2023 00:00:13 +0000
Labels: <none>
Annotations: deployment.kubernetes.io/revision: 1
Selector: app=label-nginx
Replicas: 1 desired | 1 updated | 1 total | 1 available | 0 unavailable
StrategyType: RollingUpdate
MinReadySeconds: 0
RollingUpdateStrategy: 25% max unavailable, 25% max surge
Pod Template:
Labels: app=label-nginx
Containers:
name-nginx:
Image: local/mynginx:01
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>
Conditions:
Type Status Reason
---- ------ ------
Available True MinimumReplicasAvailable
Progressing True NewReplicaSetAvailable
OldReplicaSets: <none>
NewReplicaSet: mydeployment-756d77bc56 (1/1 replicas created)
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ScalingReplicaSet 59s deployment-controller Scaled up replica set mydeployment-756d77bc56 to 1
#### 內容解密:
- 基本資訊:Deployment 名稱為
mydeployment
,位於default
名稱空間,建立時間為2023-04-08 00:00:13
。 - 選擇器與標籤:Deployment 使用
app=label-nginx
作為選擇器,匹配具有相同標籤的 Pod。 - 副本數量:當前期望、更新、總計和可用的副本數均為 1,表示應用正常執行。
- 更新策略:採用滾動更新(
RollingUpdate
),最大不可用和最大激增比例均為 25%,確保平滑升級。 - 容器範本:定義了名為
name-nginx
的容器,使用local/mynginx:01
映象,並暴露 80 埠。 - 狀態與事件:顯示 Deployment 的當前狀態和事件記錄,例如 ReplicaSet 的擴充操作。
檢視 Pod 詳情
Deployment 背後由 Pod 執行具體的應用程式。我們可以使用 kubectl get pods
指令列出相關的 Pod。
執行指令
kubectl get pods
輸出結果如下:
NAME READY STATUS RESTARTS AGE
dep-webserver-7b5cb75775-xqfs7 1/1 Running 0 19m
mydeployment-756d77bc56-trgjx 1/1 Running 0 98s
#### 內容解密:
- Pod 名稱:
mydeployment-756d77bc56-trgjx
是由 Deploymentmydeployment
管理的 Pod 例項。 - 狀態資訊:Pod 處於
Running
狀態,表示應用程式正在執行中。 - 關聯性:Pod 名稱中的
756d77bc56
與 ReplicaSet 名稱一致,表明其隸屬關係。
進一步使用 kubectl describe pod
檢視 Pod 的詳細資訊:
kubectl describe pod mydeployment-756d77bc56-trgjx
輸出結果如下:
Name: mydeployment-756d77bc56-trgjx
Namespace: default
Priority: 0
Service Account: default
Node: wks01/192.168.235.137
Start Time: Sat, 08 Apr 2023 00:00:13 +0000
Labels: app=label-nginx
pod-template-hash=756d77bc56
Annotations: cni.projectcalico.org/podIP: 10.1.166.11/32
cni.projectcalico.org/podIPs: 10.1.166.11/32
Status: Running
IP: 10.1.166.11
IPs:
IP: 10.1.166.11
Controlled By: ReplicaSet/mydeployment-756d77bc56
Containers:
name-nginx:
Container ID: containerd://3c3c546ba795eb50e50862ffe3e86a8d22b20024
Image: local/mynginx:01
Image ID: sha256:390c89ba092dafeb232dca8ebc96a0d90ad0ff008661e17f8a51d2baaff73e00
Port: 80/TCP
Host Port: 0/TCP
State: Running
Started: Sat, 08 Apr 2023 00:00:14 +0000
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-5dx7z (ro)
#### 內容解密:
- 容器資訊:Pod 中執行的容器
name-nginx
使用local/mynginx:01
映象,埠 80 已暴露。 - 網路組態:Pod 的 IP 地址為
10.1.166.11
,由 CNI 網路外掛分配。 - 掛載與環境變數:目前未組態任何環境變數或額外掛載卷。
- 事件記錄:顯示了 Pod 的排程、建立和啟動過程中的事件,例如映象提取和容器啟動。
檢視服務組態
目前,Pod 和 Deployment 已成功佈署,但尚未對外暴露服務。我們需要建立一個 Service 資源來存取應用。
檢視現有服務
kubectl get service
輸出結果如下:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.152.183.1 <none> 443/TCP 149m
dep-webserver LoadBalancer 10.152.183.170 <pending> 80:32491/TCP 19m
#### 內容解密:
- 現有服務:目前有兩個服務,分別是預設的
kubernetes
服務和之前透過命令列建立的dep-webserver
。 - 服務型別:
dep-webserver
為 LoadBalancer 型別,但尚未分配外部 IP。
接下來,我們將建立一個新的 Service 資源,以暴露 mydeployment
Deployment。
#### Kubernetes Deployment 與 Pod 關係圖示
graph LR A[Deployment:mydeployment] -->|管理|> B[ReplicaSet:mydeployment-756d77bc56] B -->|控制|> C[Pod:mydeployment-756d77bc56-trgjx] C -->|執行|> D[容器:name-nginx] D -->|使用|> E[映象:local/mynginx:01]
圖表翻譯: 此圖表展示了 Kubernetes 中 Deployment 與 Pod 的層級關係。Deployment 管理 ReplicaSet,而 ReplicaSet 控制 Pod 的建立與維護。Pod 內部執行具體的容器,並使用指定的 Docker 顡像。