你可能不知道的13個(gè)Kubernetes技巧
Kubernetes,憑借其完善的生態(tài)系統(tǒng),提供了許多功能,可以顯著增強(qiáng)容器化應(yīng)用程序的管理、可伸縮性和安全性。以下是13個(gè)技巧,每個(gè)技巧都有詳細(xì)的解釋、使用示例、上下文應(yīng)用和需要注意的預(yù)防措施。
1. 使用 PreStop Hooks 優(yōu)雅地關(guān)閉 Pod
PreStop 鉤子允許在 Pod 即將終止之前在其中執(zhí)行特定命令或腳本。這種能力對(duì)于確保應(yīng)用程序優(yōu)雅關(guān)閉、在必要時(shí)保存狀態(tài),或執(zhí)行清理任務(wù)以避免數(shù)據(jù)損壞并確保平穩(wěn)重啟至關(guān)重要。
案例:
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"]
這個(gè)配置確保了 nginx 服務(wù)器在關(guān)閉之前有 30 秒的時(shí)間來(lái)完成正在處理的請(qǐng)求。
什么情況使用呢?
在對(duì)服務(wù)連續(xù)性至關(guān)重要的環(huán)境中實(shí)施PreStop鉤子,以確保在部署、擴(kuò)展或Pod重啟期間零或最小的停機(jī)時(shí)間。
注意:
Kubernetes允許Pod的終止寬限期。如果PreStop鉤子腳本執(zhí)行時(shí)間超過(guò)這個(gè)寬限期,Kubernetes將強(qiáng)制終止Pod。
2. 使用Kubelet進(jìn)行自動(dòng)Secret輪換
Kubernetes支持對(duì)Secret進(jìn)行自動(dòng)輪換,而無(wú)需重新啟動(dòng)使用這些Secret的Pod。這一功能特別有助于保持安全標(biāo)準(zhǔn),定期更改敏感信息,而不影響應(yīng)用程序的可用性。
案例:
假設(shè)您已經(jīng)在 Kubernetes 中更新了一個(gè)Secret。Kubernetes 將自動(dòng)更新掛載在 Pod 中的Secret,無(wú)需任何干預(yù),確保應(yīng)用程序始終具有最新的憑據(jù),無(wú)需手動(dòng)更新或重新啟動(dòng)。
什么情況使用呢?
這一功能對(duì)于需要高水平安全合規(guī)性的應(yīng)用程序至關(guān)重要,需要頻繁進(jìn)行Secret輪換,比如數(shù)據(jù)庫(kù)、API密鑰或TLS證書(shū)。
注意:
應(yīng)用程序必須設(shè)計(jì)成能夠動(dòng)態(tài)讀取更新的Secret。一些應(yīng)用程序在啟動(dòng)時(shí)會(huì)緩存Secret,這意味著它們?cè)跊](méi)有重新啟動(dòng)的情況下無(wú)法識(shí)別更新的Secret。確保您的應(yīng)用程序定期檢查Secret的更新,或者對(duì)變化做出適當(dāng)?shù)姆磻?yīng)。
3. 使用臨時(shí)容器調(diào)試 Pod
Ephemeral containers 提供了一種臨時(shí)將調(diào)試容器附加到運(yùn)行中的 Pod 上的方式,而不會(huì)改變其原始規(guī)范。這對(duì)于在生產(chǎn)環(huán)境中調(diào)試實(shí)時(shí)問(wèn)題非常有幫助,因?yàn)槟荒軘_亂服務(wù)。
案例:
kubectl alpha debug -it podname --image=busybox --target=containername
這個(gè)命令會(huì)向您現(xiàn)有的 Pod 中添加一個(gè) busybox 容器,使您能夠執(zhí)行命令并檢查 Pod 的環(huán)境,而不會(huì)改變其運(yùn)行狀態(tài)。
什么情況使用呢?
在實(shí)時(shí)環(huán)境中診斷問(wèn)題時(shí),特別是當(dāng)標(biāo)準(zhǔn)日志和指標(biāo)無(wú)法提供足夠信息時(shí),可以利用短暫容器。這是一個(gè)強(qiáng)大的工具,用于實(shí)時(shí)深入分析生產(chǎn)問(wèn)題。
注意:
由于臨時(shí)容器可以訪問(wèn)Pod的資源和敏感數(shù)據(jù),因此在生產(chǎn)環(huán)境中要謹(jǐn)慎使用它們。確保只有授權(quán)人員可以部署臨時(shí)容器,以避免潛在的安全風(fēng)險(xiǎn)。
4. Horizontal Pod Autoscaling 基于自定義指標(biāo)
HPA可以根據(jù)自定義指標(biāo)而非僅僅是標(biāo)準(zhǔn)的 CPU 和內(nèi)存使用情況來(lái)調(diào)整Pod副本。這對(duì)于需要根據(jù)特定業(yè)務(wù)指標(biāo)或性能指標(biāo)進(jìn)行調(diào)整的應(yīng)用程序特別有用,比如隊(duì)列長(zhǎng)度、請(qǐng)求延遲或自定義應(yīng)用程序指標(biāo)。
案例:
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
這個(gè) HPA 配置根據(jù)自定義指標(biāo) your_custom_metric 的平均值來(lái)調(diào)整您的應(yīng)用程序的規(guī)模。
什么情況使用呢?
為那些傳統(tǒng)基于資源的度量無(wú)法準(zhǔn)確反映負(fù)載情況或基于業(yè)務(wù)需求進(jìn)行精細(xì)調(diào)整的應(yīng)用程序,采用自定義度量標(biāo)度。
注意:
建立自定義指標(biāo)涉及與支持自定義指標(biāo)的指標(biāo)服務(wù)器集成,例如Prometheus。確保您的指標(biāo)是可靠的負(fù)載指標(biāo),以防止過(guò)度或不足擴(kuò)展。
使用初始化容器來(lái)運(yùn)行腳本
初始化容器在 Pod 中的應(yīng)用容器之前運(yùn)行,非常適合需要在應(yīng)用啟動(dòng)之前完成的初始化配置腳本。這可能包括數(shù)據(jù)庫(kù)遷移、配置文件創(chuàng)建或等待外部服務(wù)可用等任務(wù)。初始化容器可以運(yùn)行一系列初始化任務(wù),確保在主應(yīng)用容器啟動(dòng)之前每個(gè)步驟都成功完成。
案例:
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;']
這個(gè)示例使用一個(gè)初始化容器來(lái)等待一個(gè)名為"myservice"的服務(wù)在啟動(dòng)主應(yīng)用容器之前變得可用。
什么情況使用呢?
初始化容器在您的應(yīng)用容器在啟動(dòng)之前依賴于外部服務(wù)或配置可用時(shí)非常重要。它們確保您的應(yīng)用在環(huán)境準(zhǔn)備就緒的情況下啟動(dòng)。
注意:
整個(gè) Pod 的啟動(dòng)將被阻塞,直到所有 init 容器成功完成。確保 init 容器高效且能夠優(yōu)雅地處理失敗,以防止它們成為瓶頸或?qū)е?Pod 啟動(dòng)失敗。
6. 適用于特定工作負(fù)載調(diào)度的節(jié)點(diǎn)親和性
節(jié)點(diǎn)親和性允許您指定規(guī)則,根據(jù)節(jié)點(diǎn)上的標(biāo)簽限制您的 Pod 可以調(diào)度到哪些節(jié)點(diǎn)上。這對(duì)于將工作負(fù)載定向到具有特定硬件(如 GPU)的節(jié)點(diǎn),確保數(shù)據(jù)局部性,或遵守合規(guī)性和數(shù)據(jù)主權(quán)要求非常有用。
案例:
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
這個(gè) Pod 只會(huì)被調(diào)度到具有標(biāo)簽 disktype=ssd
的節(jié)點(diǎn)上。
什么情況使用呢?
當(dāng)您的應(yīng)用程序需要特定節(jié)點(diǎn)功能時(shí),請(qǐng)使用節(jié)點(diǎn)親和性。
注意:
過(guò)度使用節(jié)點(diǎn)親和性可能導(dǎo)致集群利用率低和調(diào)度復(fù)雜性增加。確保您的集群具有標(biāo)簽和親和性的平衡分布,以保持資源利用的高效性。
7. Pod的污點(diǎn)和容忍配置
Taints和tolerations共同作用,確保Pods不會(huì)被調(diào)度到不適當(dāng)?shù)墓?jié)點(diǎn)上。節(jié)點(diǎn)上的Taint會(huì)排斥不容忍該Taint的Pods。Tolerations應(yīng)用于Pods,使它們能夠在帶有Taint的節(jié)點(diǎn)上調(diào)度。這種機(jī)制對(duì)于將節(jié)點(diǎn)專門用于特定工作負(fù)載(例如GPU密集型應(yīng)用程序)或確保只有特定的Pods在帶有敏感數(shù)據(jù)的節(jié)點(diǎn)上運(yùn)行至關(guān)重要。
案例:
# Applying a taint to a node
kubectl taint nodes node1 key=value:NoSchedule
# Pod specification with toleration
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: nginx
tolerations:
- key: "key"
operator: "Equal"
value: "value"
effect: "NoSchedule"
這個(gè)配置確保了 mypod 可以被調(diào)度到具有特定污點(diǎn)的 node1 上,其他 pod 無(wú)法容忍這個(gè)污點(diǎn)。
什么情況使用呢?
Taints和tolerations在多租戶集群中特別有用,對(duì)于安全性或性能原因而隔離工作負(fù)載至關(guān)重要。它們還有助于運(yùn)行需要專用資源的專業(yè)工作負(fù)載。
注意:
配置污點(diǎn)和容忍度不當(dāng)可能導(dǎo)致調(diào)度問(wèn)題,導(dǎo)致Pod未按預(yù)期調(diào)度或某些節(jié)點(diǎn)被低效利用。定期審查您的污點(diǎn)和容忍度設(shè)置,確保其符合您的調(diào)度要求。
8. 工作負(fù)載的 Pod 優(yōu)先級(jí)和搶占
Kubernetes允許您為Pod分配優(yōu)先級(jí),如果必要,較高優(yōu)先級(jí)的Pod可以搶占(驅(qū)逐)較低優(yōu)先級(jí)的Pod。這確保了關(guān)鍵工作負(fù)載在高度擁擠的集群中也能獲得所需的資源。
案例:
# PriorityClass definition
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: high-priority
value: 1000000
globalDefault: false
description: "This priority class should be used for XYZ service pods only."
# Pod specification with priorityClassName
apiVersion: v1
kind: Pod
metadata:
name: high-priority-pod
spec:
containers:
- name: high-priority
image: nginx
priorityClassName: high-priority
這個(gè)配置定義了一個(gè)高優(yōu)先級(jí)類,并將其分配給一個(gè) pod,確保它可以搶占其他低優(yōu)先級(jí)的 pods。
什么情況使用呢?
使用Pod優(yōu)先級(jí)和搶占功能來(lái)管理那些對(duì)您的業(yè)務(wù)運(yùn)營(yíng)至關(guān)重要的應(yīng)用程序,特別是在資源爭(zhēng)用頻繁的集群環(huán)境中運(yùn)行時(shí)。
注意:
不當(dāng)使用可能導(dǎo)致次要應(yīng)用程序資源匱乏。平衡不同工作負(fù)載的需求,并考慮對(duì)集群健康和應(yīng)用程序性能的整體影響是至關(guān)重要的。
9. 動(dòng)態(tài)配置的ConfigMaps和Secrets
ConfigMaps和Secrets提供了將配置數(shù)據(jù)注入到Pod中的機(jī)制。這使得配置外部化,使得應(yīng)用程序更容易配置,而無(wú)需硬編碼配置數(shù)據(jù)。ConfigMaps適用于非敏感數(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
這個(gè)配置將 app-config 的內(nèi)容注入到 pod 中,使應(yīng)用程序能夠從 /etc/config/config.json 中讀取其配置。
什么情況使用呢?每當(dāng)您需要將應(yīng)用程序的配置或機(jī)密數(shù)據(jù)外部化,使其更易于管理、更新和維護(hù),而無(wú)需重新構(gòu)建容器映像時(shí)。
注意:雖然 ConfigMaps 非常適合存儲(chǔ)非敏感數(shù)據(jù),但應(yīng)避免將需要保密的任何數(shù)據(jù)存儲(chǔ)在其中。始終使用 Secrets 來(lái)存儲(chǔ)、令牌、密鑰和其他敏感數(shù)據(jù),并且要了解保護(hù) Secrets 的最佳實(shí)踐,例如在靜態(tài)狀態(tài)下對(duì)其進(jìn)行加密。
10. Kubectl Debug 用于直接容器調(diào)試
kubectl debug 提供了一種方法,可以創(chuàng)建一個(gè)臨時(shí)的 pod 副本,并用調(diào)試版本的容器替換其原有的容器,或者在不影響原始 pod 的情況下添加新的故障排查工具。這對(duì)于在不影響應(yīng)用程序運(yùn)行狀態(tài)的情況下調(diào)試實(shí)時(shí)環(huán)境中的問(wèn)題非常有用。
案例:
kubectl debug pod/myapp-pod -it --copy-to=myapp-debug --container=myapp-container --image=busybox
這個(gè)命令創(chuàng)建了一個(gè)myapp-pod的副本,為了調(diào)試目的,用busybox鏡像替換了myapp-container。
什么情況使用呢?
當(dāng)你需要對(duì)崩潰的或在生產(chǎn)中表現(xiàn)不如預(yù)期的pod進(jìn)行故障排查時(shí)進(jìn)行實(shí)時(shí)調(diào)試,對(duì)服務(wù)的影響最小。
注意:
調(diào)試Pod仍然可能影響整個(gè)集群的資源分配,并可能訪問(wèn)敏感數(shù)據(jù)。請(qǐng)確保嚴(yán)格控制對(duì)調(diào)試命令的訪問(wèn),并在使用后清理調(diào)試Pod。
11. 通過(guò)請(qǐng)求和限制進(jìn)行高效的資源管理
Kubernetes允許您為pod中的每個(gè)容器指定CPU和內(nèi)存(RAM)的請(qǐng)求和限制。請(qǐng)求保證容器獲得指定數(shù)量的資源,而限制確保容器永遠(yuǎn)不會(huì)使用超過(guò)分配的數(shù)量。這有助于有效管理資源分配,并防止任何單一應(yīng)用程序壟斷集群資源。
案例:
apiVersion: v1
kind: Pod
metadata:
name: resource-demo
spec:
containers:
- name: demo-container
image: nginx
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
這個(gè)pod規(guī)格要求為demo-container分配特定數(shù)量的CPU和內(nèi)存,以確保它具有實(shí)現(xiàn)最佳性能所需的資源,同時(shí)防止其超過(guò)指定的限制。
什么情況使用呢?
請(qǐng)對(duì)所有容器應(yīng)用請(qǐng)求和限制,以確保應(yīng)用程序的性能可預(yù)測(cè),并避免在集群中運(yùn)行的應(yīng)用程序之間的資源爭(zhēng)搶。
注意:將限制設(shè)置得過(guò)低可能會(huì)導(dǎo)致如果集群無(wú)法提供請(qǐng)求的資源,Pods可能會(huì)被終止或無(wú)法調(diào)度。相反,將它們?cè)O(shè)置得過(guò)高可能會(huì)導(dǎo)致集群資源的利用效率低下。請(qǐng)監(jiān)控應(yīng)用程序的性能,并根據(jù)需要調(diào)整請(qǐng)求和限制
12. 用于擴(kuò)展Kubernetes的自定義資源定義(CRD)
CRD 允許你通過(guò)自己的 API 對(duì)象擴(kuò)展 Kubernetes,從而實(shí)現(xiàn)創(chuàng)建像原生 Kubernetes 對(duì)象一樣運(yùn)作的自定義資源。這對(duì)于向你的集群添加特定領(lǐng)域的功能、促進(jìn)自定義操作以及與外部系統(tǒng)集成具有強(qiáng)大的作用。
案例:
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: crontabs.stable.example.com
spec:
group: stable.example.com
versions:
- name: v1
served: true
storage: true
scope: Namespaced
names:
plural: crontabs
singular: crontab
kind: CronTab
shortNames:
- ct
這個(gè)CRD在集群中定義了一種新的資源類型CronTab,它可以像傳統(tǒng)的cron作業(yè)一樣用于調(diào)度任務(wù),但是采用了Kubernetes原生的管理方式。
什么情況使用呢?CRD 是擴(kuò)展 Kubernetes 功能以滿足您的應(yīng)用程序或服務(wù)特定需求的理想選擇,例如引入特定領(lǐng)域的資源類型或與外部服務(wù)和 API 進(jìn)行集成。
注意:
設(shè)計(jì)和管理CRD需要對(duì)Kubernetes內(nèi)部結(jié)構(gòu)和API機(jī)制有深入的理解。設(shè)計(jì)不良的CRDs可能會(huì)導(dǎo)致性能問(wèn)題,并使集群管理變得復(fù)雜。始終確保對(duì)CRDs進(jìn)行徹底的測(cè)試,并考慮其對(duì)集群穩(wěn)定性和性能的影響。
13. 用于動(dòng)態(tài)交互和自動(dòng)化的Kubernetes API
Kubernetes API使您能夠動(dòng)態(tài)地與您的集群進(jìn)行交互,從而可以以編程方式自動(dòng)化擴(kuò)展、部署和管理任務(wù)。通過(guò)利用API,您可以創(chuàng)建與您的集群實(shí)時(shí)交互的腳本或應(yīng)用程序,實(shí)現(xiàn)復(fù)雜的自動(dòng)化和集成場(chǎng)景,這超出了靜態(tài)配置文件和手動(dòng)命令所能實(shí)現(xiàn)的范圍。
案例:
以下是一個(gè)基本示例,使用curl與Kubernetes API交互,以獲取默認(rèn)命名空間中的pod列表。這假設(shè)您有一個(gè)訪問(wèn)令牌,并且可以在https://處訪問(wèn)Kubernetes API。
curl -X GET https://<kubernetes-api-server>/api/v1/namespaces/default/pods \
-H "Authorization: Bearer <your-access-token>" \
-H 'Accept: application/json'
對(duì)于更復(fù)雜的交互,可以考慮使用各種編程語(yǔ)言(如Go、Python、Java)中可用的客戶端庫(kù),這些庫(kù)抽象化了HTTP請(qǐng)求,并提供了更便捷的接口來(lái)操作Kubernetes API。
什么情況使用呢?
Kubernetes API對(duì)于開(kāi)發(fā)自定義自動(dòng)化、動(dòng)態(tài)擴(kuò)展策略、CI/CD集成,甚至擴(kuò)展Kubernetes功能的自定義控制器具有難以置信的強(qiáng)大功能。當(dāng)你需要將Kubernetes操作與外部系統(tǒng)集成或創(chuàng)建自定義部署工作流時(shí),它尤其有用。
注意:
與Kubernetes API進(jìn)行交互時(shí),需要謹(jǐn)慎處理身份驗(yàn)證和授權(quán)。確保你的腳本和應(yīng)用程序堅(jiān)持最小權(quán)限原則,只請(qǐng)求它們運(yùn)行所需的權(quán)限。此外,當(dāng)進(jìn)行頻繁或復(fù)雜的查詢時(shí),要注意可能對(duì)API服務(wù)器的負(fù)載產(chǎn)生的影響,因?yàn)檫@可能會(huì)影響集群性能。始終驗(yàn)證并清理你的API客戶端的輸入,以避免安全漏洞,特別是如果它們與外部系統(tǒng)或用戶生成的內(nèi)容進(jìn)行交互。