YAML 與 Kubernetes:必備清單模式
Kubernetes 完全透過 YAML 清單來進行設定。每個 Pod、Deployment、Service 和 Ingress 都是以 YAML 定義。掌握這些模式對於任何從事容器編排工作的人來說都是不可或缺的。本指南涵蓋最重要的資源類型,附帶可用於正式環境的範例。
四個必要欄位
每個 Kubernetes 清單都需要:
apiVersion: apps/v1 # 此資源類型的 API 版本
kind: Deployment # 資源類型
metadata: # 資源識別資訊
name: my-app
namespace: production
labels:
app: my-app
spec: # 期望狀態規格
# ... 資源專屬設定
Deployment
最常見的資源——管理一組相同的 Pod:
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-server
labels:
app: api-server
environment: production
spec:
replicas: 3
selector:
matchLabels:
app: api-server
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
template:
metadata:
labels:
app: api-server
spec:
containers:
- name: api
image: myapp/api:v1.2.3
ports:
- containerPort: 8080
env:
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: db-credentials
key: url
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 15
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
關鍵模式
務必設定資源請求和限制:若缺少這些設定,單一 Pod 可能會消耗所有節點資源。
務必設定健康探測:
livenessProbe:當 Pod 無回應時重新啟動readinessProbe:在 Pod 就緒前停止轉發流量
使用具體的映像檔標籤:在正式環境中絕不使用 latest——這會讓回滾變得不可能。
Service
將 Pod 暴露於網路流量:
apiVersion: v1
kind: Service
metadata:
name: api-server
spec:
type: ClusterIP
selector:
app: api-server
ports:
- port: 80
targetPort: 8080
protocol: TCP
Service 類型:
- ClusterIP(預設):僅限叢集內部存取
- NodePort:在每個節點 IP 的靜態連接埠上暴露
- LoadBalancer:配置雲端負載平衡器
- ExternalName:對映到 DNS 名稱
ConfigMap 與 Secret
ConfigMap(非敏感資料)
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
LOG_LEVEL: "info"
MAX_CONNECTIONS: "100"
config.yaml: |
server:
port: 8080
timeout: 30s
Secret(敏感資料)
apiVersion: v1
kind: Secret
metadata:
name: db-credentials
type: Opaque
stringData:
url: "postgres://user:password@db:5432/myapp"
api-key: "sk-1234567890"
在 Pod 中使用
# 作為環境變數
env:
- name: LOG_LEVEL
valueFrom:
configMapKeyRef:
name: app-config
key: LOG_LEVEL
# 作為掛載檔案
volumes:
- name: config
configMap:
name: app-config
Ingress
將外部 HTTP 流量路由到 Service:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: api-ingress
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
ingressClassName: nginx
tls:
- hosts:
- api.example.com
secretName: tls-secret
rules:
- host: api.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: api-server
port:
number: 80
Horizontal Pod Autoscaler
根據 CPU 或自訂指標自動擴縮 Pod:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-server-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api-server
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
常見錯誤
1. 縮排錯誤
YAML 的縮排在 Kubernetes 中至關重要。一個放錯的空格就會完全改變結構。使用我們的 YAML 驗證器來驗證你的清單。
2. 標籤不匹配
Service 的 selector 必須與 Pod 的 labels 完全匹配。不匹配代表 Service 找不到任何可以路由流量的 Pod。
3. 缺少資源限制
沒有設定資源限制的 Pod 可能會搶佔其他工作負載的資源。務必同時設定 requests(保證最小值)和 limits(允許最大值)。
4. 可變的映像檔標籤
使用 latest 或其他可變標籤會讓回滾變得不可能,部署也變得不可預測。請固定使用特定版本或不可變的摘要值。
多文件清單
使用 --- 作為文件分隔符,將相關資源合併到一個檔案中:
apiVersion: apps/v1
kind: Deployment
metadata:
name: api-server
spec:
# ... deployment 規格
---
apiVersion: v1
kind: Service
metadata:
name: api-server
spec:
# ... service 規格
更多 YAML 語法模式,請參閱我們的 YAML 語法教學。
常見問題
應該手寫 Kubernetes YAML 還是使用產生器?
先從手寫 YAML 開始以了解其結構。在正式環境中,使用 Helm(模板化清單)、Kustomize(基於覆層的自訂)或 CDK8s(基於程式碼的產生)等工具。這些工具可以減少重複,並在不複製清單的情況下實現環境特定的設定。
如何除錯 Kubernetes YAML 錯誤?
使用 kubectl apply --dry-run=client -f manifest.yaml 來驗證而不實際套用。對於語法錯誤,kubectl explain deployment.spec.template.spec.containers 會顯示預期的結構。kubeval 和 kubeconform 工具可在部署前根據 Kubernetes API 結構描述進行驗證。
相關資源
- YAML 驗證器 — 驗證 Kubernetes 清單
- YAML 與 Docker Compose — Docker YAML 模式
- YAML 程式碼檢查最佳實踐 — 部署前捕捉錯誤