幾個你或許并不知道 Kubernetes 技巧
使用 PreStop 優(yōu)雅關閉 Pod
apiVersion: v1
kind: Pod
metadata:
name: graceful-shutdown-example
spec:
containers:
- name: sample-container
image: nginx
lifecycle:
preStop:
exec:
command: ["/bin/sh", "-c", "sleep 30 && nginx -s quit"]
PreStop 允許 Pod 在終止前執(zhí)行一個命令或者是腳本,使用它就可以在應用退出前釋放一些資源,確保應用可以優(yōu)雅退出。
比如可以在 Nginx 的 Pod 退出前將當前的請求執(zhí)行完畢。
使用臨時容器調試 Pod
臨時容器可以不修改一個運行的容器的前提下調試容器,可以很方便的調試一些生產環(huán)境的 bug,可以避免重啟應用。
kubectl alpha debug -it podname --image=busybox --target=containername
生產環(huán)境謹慎使用,只有在當前環(huán)境下無法排查問題的時候才使用。
基于自定義的 Metrics 自動擴容Pod
kubernetes 是提供了 HPA 機制可以跟進 CPU 內存等標準數(shù)據(jù)進行自動擴縮容,但有時我們需要根據(jù)自定義的數(shù)據(jù)進行擴縮容。
比如某個接口的延遲、隊列大小等。
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: custom-metric-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: your-application
minReplicas: 1
maxReplicas: 10
metrics:
- type: Pods
pods:
metric:
name: your_custom_metric
target:
type: AverageValue
averageValue: 10
用 Init Containers 配置啟動腳本
初始化容器可以在應用容器啟動前運行,我們可以使用它來初始化應用需要的配置、等待依賴的服務啟動完成等工作:
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
spec:
containers:
- name: myapp-container
image: myapp
initContainers:
- name: init-myservice
image: busybox
command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;']
比如這個初始化容器會等待 myservice 可用后才會啟動應用。
需要注意的是如果初始化容器會阻塞應用啟動,所以要避免在初始化容器里執(zhí)行耗時操作。
Node 親和性調度
當我們需要將某些應用部署到硬件配置較高的節(jié)點時(比如需要 SSD 硬盤),就可以使用節(jié)點親和性來部署應用:
apiVersion: v1
kind: Pod
metadata:
name: with-node-affinity
spec:
containers:
- name: with-node-affinity
image: nginx
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: disktype
operator: In
values:
- ssd
這個 Pod 會被部署到有這個 disktype=ssd 標簽的 節(jié)點上。
動態(tài)配置:ConfigMap 和 Secrets
ConfigMap 和 Secrets可以動態(tài)注入到 Pod 中,避免對這些配置硬編碼。
ConfigMap 適合非敏感的數(shù)據(jù),Secrets 適合敏感的數(shù)據(jù)。
# ConfigMap Example
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
config.json: |
{
"key": "value",
"databaseURL": "http://mydatabase.example.com"
}
# Pod Spec using ConfigMap
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
spec:
containers:
- name: myapp-container
image: myapp
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: app-config
這樣在應用中就可以通過這路徑 /etc/config/config.json 讀取數(shù)據(jù)了。
當然也可以把這些數(shù)據(jù)寫入到環(huán)境變量中。
以上這些個人技巧用的最多的是:
1. 臨時容器調試 Pod,特別是業(yè)務容器缺少一些命令時。
2. Init Container 等待依賴的服務啟動完成。
3. Node 親和性調度。
4. ConfigMap 是基礎操作了。