在 Kubernetes 環境中佈署應用程式時,資源管理和多容器 Pod 的管理至關重要。本文將詳細說明如何設定 Pod 的資源請求和限制,確保應用程式在 Kubernetes 叢集中穩定執行。同時,也將介紹如何建立和管理多容器 Pod,以及如何利用分享儲存卷實作容器間通訊。此外,文章還涵蓋了 Kubernetes 中儲存和 CPU 資源單位的定義和使用方法,以及如何使用 JSON Patch 更新資源、建立 Secrets 和選擇合適的企業級容器映像檔。這些技術對於構建高效、穩定和安全的 Kubernetes 應用程式至關重要,能有效提升資源利用率並降低維運成本。
組態無狀態應用程式中的資源管理與多容器管理
在 Kubernetes 中,正確組態無狀態應用程式和管理多容器 Pod 是至關重要的。這不僅能確保資源的高效利用,還能提升系統的穩定性和可用性。本章將重點介紹如何在 Kubernetes 中建立具有資源限制的 Pod,以及如何管理多容器 Pod。
2.5 建立多容器 Pod
在現代微服務架構中,通常需要多個相互依賴的容器在單個 Kubernetes Pod 中執行。這可能是由於分享資源(如儲存卷或網路),或者這些容器代表了更大應用程式的緊密耦合元件(例如主應用程式及其快取服務)。挑戰在於有效地管理這些容器,確保它們能夠通訊、分享資源,並保持高用性和彈性。
問題
管理多容器 Pod 的複雜性包括設定容器間通訊、資源分配、生命週期管理,以及處理依賴關係和排序。此外,還需要實施日誌記錄、監控和更新這些多容器 Pod 的策略,而不會中斷服務。
解決方案
以下是一個 Pod 的 YAML 定義示例:
apiVersion: v1
kind: Pod
metadata:
name: multi-container-pod
labels:
purpose: multi-containers
spec:
containers:
- name: web-app
image: my-web-app:latest
ports:
- containerPort: 80
volumeMounts:
- name: shared-logs
mountPath: /var/log
- name: log-sidecar
image: my-logging-sidecar:latest
volumeMounts:
- name: shared-logs
mountPath: /var/log
volumes:
- name: shared-logs
emptyDir: {}
使用以下命令建立 Pod:
$ kubectl apply -f multicontainer.yaml
pod/multi-container-pod created
驗證 Pod 是否正在執行:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
multi-container-pod 2/2 Running 1 (3s ago) 8s
詳細說明
我們可以看到 multi-container-pod 有兩個容器正在執行。要進入第一個容器,可以使用 -c 引數指定容器名稱:
$ kubectl exec -it multi-container-pod -c web-app -- /bin/bash
root@multi-container-pod:/# ls -la /var/log/shared-logs/
這裡展示瞭如何在容器之間分享資源。建立一個檔案並檢視其內容:
echo "container-web-app-was-here" > /var/log/shared-logs/message1
$ cat /var/log/shared-logs/message1
container-web-app-was-here
若不知道 YAML 檔案位置和容器名稱,可以透過描述 Pod 或使用 kubectl 命令來檢視所有容器:
kubectl get pods POD_NAME_HERE -o jsonpath='{.spec.containers[*].name}'
2.6 建立具有資源限制的 Pod
在 Kubernetes 中,一個常見的挑戰是確保 Pod 高效地使用資源,而不會使叢集不堪重負。如果沒有適當的資源限制,Pod 可能會消耗比預期更多的 CPU 或記憶體,從而影響其他 Pod 並導致資源匱乏。目標是為 Pod 定義資源限制,以最佳化資源使用並保持系統穩定性。
解決方案
以下是一個具有特定 CPU 和記憶體限制的 Pod YAML 定義:
apiVersion: v1
kind: Pod
metadata:
name: example-pod
labels:
purpose: demonstrate-resource-limits
spec:
containers:
- name: example-container
image: nginx
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
- name: log-aggregator
image: log-aggregator:v1
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
詳細說明
Kubernetes 中的資源限制和請求定義了 CPU 和記憶體的限制。記憶體的請求和限制是以位元組為單位的。可以使用以下數量字尾來表示記憶體:E、P、T、G、M、k,或使用根據二進位制的等效單位:Ei、Pi、Ti、Gi、Mi 和 Ki。
| 單位名稱 | 1 個單位 | 二進位制冪 | 位元組等效值 |
|---|---|---|---|
| Ki | Kibibytes | 1 Ki | 2^10 |
| Mi | Mebibytes | 1 Mi | 2^20 |
| Gi | Gibibytes | 1 Gi | 2^30 |
| Ti | Tebibytes | 1 Ti | 2^40 |
| Pi | Pebibytes | 1 Pi | 2^50 |
| Ei | Exbibytes | 1 Ei | 2^60 |
Kubernetes 也支援使用非二進位制冪的單位來指定記憶體限制和請求,如位元組(B)、千位元組(KB)、兆位元組(MB)和吉位元組(GB)。
程式碼詳細解說
在上述 YAML 定義中,我們為兩個容器(example-container 和 log-aggregator)定義了資源請求和限制。請求定義了容器啟動所需的最低資源,而限制則定義了容器可以使用的最大資源。
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
這段程式碼確保了容器在啟動時至少有 64Mi 的記憶體和 250m 的 CPU 資源,並且不會超過 128Mi 的記憶體和 500m 的 CPU 資源。
圖表翻譯
此圖示展示了 Kubernetes 中資源限制和請求的概念。
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
title Kubernetes無狀態應用程式資源組態與多容器Pod管理
package "Kubernetes Cluster" {
package "Control Plane" {
component [API Server] as api
component [Controller Manager] as cm
component [Scheduler] as sched
database [etcd] as etcd
}
package "Worker Nodes" {
component [Kubelet] as kubelet
component [Kube-proxy] as proxy
package "Pods" {
component [Container 1] as c1
component [Container 2] as c2
}
}
}
api --> etcd : 儲存狀態
api --> cm : 控制迴圈
api --> sched : 調度決策
api --> kubelet : 指令下達
kubelet --> c1
kubelet --> c2
proxy --> c1 : 網路代理
proxy --> c2
note right of api
核心 API 入口
所有操作經由此處
end note
@enduml
圖表翻譯: 此圖表示了一個容器向資源管理器提出資源請求和限制的過程。資源管理器根據請求排程容器到合適的節點上,同時確保容器的資源使用不超過設定的限制。
資源單位與 Kubernetes 組態
在 Kubernetes 環境中,正確理解和管理資源單位對於確保應用程式的效能和穩定性至關重要。本章節將探討 Kubernetes 中的資源單位,包括儲存單位和 CPU 資源單位,並提供實際的組態範例。
儲存單位詳解
Kubernetes 使用常見的儲存單位來描述資料大小,包括位元組(Bytes)、千位元組(KB)、兆位元組(MB)、吉位元組(GB)、太位元組(TB)、拍位元組(PB)和艾位元組(EB)。以下是這些單位的定義和範例:
- 位元組(Byte):基本儲存單位
- 千位元組(KB):1 KB = 10^3 = 1,000 位元組
- 兆位元組(MB):1 MB = 10^6 = 1,000,000 位元組
- 吉位元組(GB):1 GB = 10^9 = 1,000,000,000 位元組
- 太位元組(TB):1 TB = 10^12 = 1,000,000,000,000 位元組
- 拍位元組(PB):1 PB = 10^15 = 1,000,000,000,000,000 位元組
- 艾位元組(EB):1 EB = 10^18 = 1,000,000,000,000,000,000 位元組
程式碼範例:計算儲存單位
def calculate_storage_unit(size_in_bytes):
units = ["Byte", "KB", "MB", "GB", "TB", "PB", "EB"]
index = 0
while size_in_bytes >= 1000 and index < len(units) - 1:
size_in_bytes /= 1000
index += 1
return f"{size_in_bytes:.2f} {units[index]}"
# 範例用法
print(calculate_storage_unit(1024)) # 輸出:1.02 KB
內容解密:
此 Python 程式碼定義了一個函式 calculate_storage_unit,用於將以位元組為單位的資料大小轉換為適當的儲存單位(如 KB、MB、GB 等)。函式透過不斷將輸入的大小除以 1000,並遞增單位索引,直到大小小於 1000 或已達到最大單位為止。最後,傳回轉換後的大小和對應的單位。
CPU 資源單位
在 Kubernetes 中,CPU 資源是以 CPU 核心為單位進行測量的。我們可以使用整數或小數來指定 CPU 的限制和請求。
- CPU 核心:1 個 CPU 核心等於 1 個 CPU 資源單位
- Millicores(m):1,000 m 等於 1 個 CPU 核心,用於更精細的分配
| CPU 核心數 | YAML 中的 CPU 單位 | YAML 中的 millicore 單位 |
|---|---|---|
| 2 | cpu: “2” | cpu: “2000m” |
| 1 | cpu: “1” | cpu: “1000m” |
| 0.5 | cpu: “0.5” | cpu: “500m” |
JSON Patch 操作
在 Kubernetes 中,我們可以使用 JSON Patch 操作來更新資源,如 Pod、Deployment 和 Service。以下是一個範例,展示如何使用 JSON Patch 更新 Deployment 的副本數量:
[
{
"op": "replace",
"path": "/spec/replicas",
"value": 5
}
]
使用 kubectl 命令套用此 Patch:
kubectl patch deployment <deployment-name> --type='json' --patch-file=patch.json
圖表翻譯:
此圖示展示了使用 JSON Patch 更新 Kubernetes 資源的流程。首先,建立一個 JSON Patch 檔案,描述要執行的操作(如替換、新增或刪除)。然後,使用 kubectl patch 命令套用此 Patch,從而更新指定的資源。
建立 Secrets
Kubernetes Secrets 用於儲存和管理敏感資訊,如密碼、OAuth token 和 SSH 金鑰。以下是一個建立 Secret 的範例:
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
data:
username: bXl1c2VyCg==
password: bXlwYXNzd29yZAo=
使用 kubectl 命令套用此 Secret:
kubectl apply -f secret.yaml
然後,在 Pod 定義中參考此 Secret:
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
spec:
containers:
- name: myapp-container
image: myapp:1.0
env:
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: db-secret
key: username
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: password
使用企業級和根據 Linux 的映像檔
在 Kubernetes 環境中,使用企業級和根據 Linux 的映像檔對於確保應用程式的安全性和穩定性至關重要。以下是一些常見的企業級映像檔範例:
- Red Hat Universal Base Images (UBI)
- SUSE Linux Enterprise Server (SLES) Containers
- Canonical Ubuntu Pro Images
- Oracle Linux Images
- Amazon Linux
這些映像檔提供了企業級別的安全性、穩定性和支援,是佈署在 Kubernetes 環境中的理想選擇。
精簡且安全的容器映像檔選擇與最佳實踐
在 Kubernetes 環境中佈署應用程式時,選擇適當的容器映像檔(Image)至關重要。企業級環境通常需要穩定、安全且具備官方支援的映像檔。本章節將介紹多種常見的企業級容器映像檔及其使用場景,並探討容器映像檔的最佳實踐。
常見企業級容器映像檔
Amazon Linux
- 映像檔名稱:
amazonlinux:2 - 描述:專為 AWS 環境最佳化的 Linux 映像檔,提供長期支援和安全性更新。
- 用途:適合在 AWS 上執行的應用程式。
- 映像檔名稱:
Alpine Linux with Enterprise Enhancements
- 映像檔名稱:
alpine:enterprise - 描述:根據輕量級的 Alpine Linux,增加企業級的安全特性和支援。
- 用途:適合需要高效能且最小化攻擊面的應用程式。
- 映像檔名稱:
VMware Photon OS
- 映像檔名稱:
vmware/photon - 描述:為 VMware 環境和 Kubernetes 叢集最佳化的輕量級 Linux 映像檔。
- 用途:適合在 VMware Tanzu 或 ESXi 上執行的應用程式。
- 映像檔名稱:
Microsoft CBL-Mariner
- 映像檔名稱:
mcr.microsoft.com/cbl-mariner - 描述:為 Microsoft Azure 和 Kubernetes 工作負載最佳化的容器映像檔,強調安全性和最小化設計。
- 用途:推薦用於 Azure 相關的應用程式。
- 映像檔名稱:
Debian Enterprise Variants
- 映像檔名稱:
debian:enterprise - 描述:企業級的 Debian 版本,提供強固且安全的佈署環境。
- 用途:適合通用工作負載在安全環境中的佈署。
- 映像檔名稱:
IBM Cloud Pak Base Images
- 映像檔名稱:
icr.io/ibm/base - 描述:為 IBM Cloud 環境和企業應用程式最佳化的映像檔,特別適用於 IBM 的 Cloud Pak 解決方案。
- 用途:最適合在 IBM Cloud 或使用 IBM 中介軟體的應用程式。
- 映像檔名稱:
使用容器映像檔的最佳實踐
1. 最小化基礎映像檔
使用如 Alpine Linux 這類別最小化的映像檔,能減少攻擊面。元件越少,潛在漏洞也越少。
2. 官方和已驗證的映像檔
優先使用來自官方倉函式庫或已驗證發行者的映像檔,如 Docker Hub 上的官方映像檔,這些映像檔會定期更新以修補安全漏洞。
3. 定期更新和修補
選擇那些會定期更新和修補的映像檔,不僅是基礎作業系統,還包括所有軟體和依賴項。
4. 針對特定用途的映像檔
針對特定應用程式最佳化的映像檔通常比通用型映像檔更安全,因為它們可以移除不必要的套件和服務。
5. 掃描漏洞
使用 Clair、Trivy 或 Docker 的掃描功能來識別和緩解安全問題。
6. 非 root 使用者組態
組態映像檔以非 root 使用者執行行程,能減少容器突破的潛在損害。
7. 強化安全性的映像檔
使用特定強化安全性的映像檔,如 CIS 提供的基準和強化映像檔。
8. 企業級映像檔
企業級供應商(如 Red Hat Enterprise Linux、SUSE Linux Enterprise 或 Ubuntu Pro)提供的映像檔,通常具備額外的安全特性和支援。
9. 簽署映像檔
使用如 Docker Content Trust 的映像檔簽署機制,確保映像檔未被篡改且來自可信來源。
10. 符合安全標準
選擇符合 NIST 指引、CIS 基準或 ISO 標準等安全標準的映像檔,通常更為安全。
11. Distroless 映像檔
Google 的「distroless」映像檔僅包含執行階段依賴項(無 shell 或套件管理器),最小化安全漏洞的潛力。
12. 不可變的映像檔
設計為不可變的映像檔,其檔案系統為唯讀,能顯著提高安全性,防止執行階段的變更。