文章的翻譯是在課程開始前夕準備的
使用 Kubernetes 時如何節省雲端成本? 沒有單一正確的解決方案,但本文介紹了幾種可以幫助您更有效地管理資源並降低雲端運算成本的工具。
我寫這篇文章時考慮的是適用於 AWS 的 Kubernetes,但它將以(幾乎)完全相同的方式應用於其他雲端供應商。 我假設您的叢集已經配置了自動縮放(
本文將涵蓋:
清理未使用的資源
在快節奏的環境中工作非常棒。 我們需要科技組織
(亨寧雅各布斯:
智雜:
(引述)科里·奎因:
迷思:您的 AWS 帳戶取決於您擁有的使用者數量。
事實:您的 AWS 分數取決於您擁有的工程師數量。
伊凡·庫爾諾索夫(回應):
事實:您的 AWS 分數是您忘記禁用/刪除的事物數量的函數。)
- 群集範圍的規則可以定義 PR/測試部署的最大生存時間 (TTL)。
- 單一資源可以使用 janitor/ttl 進行註釋,例如在 7 天後自動刪除尖峰/原型。
一般規則在 YAML 檔案中定義。 它的路徑是透過參數傳遞的 --rules-file
在 kube-janitor 中。 以下是刪除所有命名空間的範例規則 -pr-
兩天後的名字:
- id: cleanup-resources-from-pull-requests
resources:
- namespaces
jmespath: "contains(metadata.name, '-pr-')"
ttl: 2d
以下範例規範了 2020 年所有新 Deployments/StatefulSet 的 Deployment 和 StatefulSet Pod 上應用程式標籤的使用,但同時允許在一周內執行沒有此標籤的測試:
- id: require-application-label
# удалить deployments и statefulsets без метки "application"
resources:
- deployments
- statefulsets
# см. http://jmespath.org/specification.html
jmespath: "!(spec.template.metadata.labels.application) && metadata.creationTimestamp > '2020-01-01'"
ttl: 7d
在執行 kube-janitor 的叢集上執行 30 分鐘的限時示範:
kubectl run nginx-demo --image=nginx
kubectl annotate deploy nginx-demo janitor/ttl=30m
成本增加的另一個來源是持久卷 (AWS EBS)。 刪除 Kubernetes StatefulSet 不會刪除其持久性磁碟區 (PVC - PersistentVolumeClaim)。 未使用的 EBS 磁碟區很容易導致每月數百美元的成本。 Kubernetes Janitor 有一個功能可以清理未使用的 PVC。 例如,此規則將刪除所有未由模組安裝且未由 StatefulSet 或 CronJob 引用的 PVC:
# удалить все PVC, которые не смонтированы и на которые не ссылаются StatefulSets
- id: remove-unused-pvcs
resources:
- persistentvolumeclaims
jmespath: "_context.pvc_is_not_mounted && _context.pvc_is_not_referenced"
ttl: 24h
Kubernetes Janitor 可以幫助您保持叢集清潔並防止雲端運算成本慢慢堆積。 有關部署和配置說明,請遵循
減少非工作時間結垢
測試和登台系統通常只需要在工作時間內運作。 某些生產應用程式(例如後台/管理工具)也只需要有限的可用性,並且可能會在一夜之間被停用。
image: hjacobs/kube-downscaler:20.4.3
args:
- --interval=30
# не отключать компоненты инфраструктуры
- --exclude-namespaces=kube-system,infra
# не отключать kube-downscaler, а также оставить Postgres Operator, чтобы исключенными БД можно было управлять
- --exclude-deployments=kube-downscaler,postgres-operator
- --default-uptime=Mon-Fri 08:00-20:00 Europe/Berlin
- --include-resources=deployments,statefulsets,stacks,cronjobs
- --deployment-time-annotation=deployment-time
下面是週末擴展叢集工作節點的圖表:
從大約 13 個工作節點縮減到 4 個工作節點肯定會對您的 AWS 帳單產生顯著影響。
但是如果我需要在叢集「停機」期間工作怎麼辦? 透過新增 downscaler/exclude: true 註釋,可以永久排除某些部署的擴充。 可以使用 downscaler/exclude-until 註解和格式為 YYYY-MM-DD HH:MM (UTC) 的絕對時間戳暫時排除部署。 如果有必要,可以透過部署帶有註解的 pod 來縮減整個集群 downscaler/force-uptime
,例如,透過啟動 nginx 空白:
kubectl run scale-up --image=nginx
kubectl annotate deploy scale-up janitor/ttl=1h # удалить развертывание через час
kubectl annotate pod $(kubectl get pod -l run=scale-up -o jsonpath="{.items[0].metadata.name}") downscaler/force-uptime=true
見
使用水平自動縮放
許多應用程式/服務處理動態載入模式:有時它們的模組空閒,有時它們會滿載工作。 營運永久的 Pod 隊列來應對最大尖峰負載並不經濟。 Kubernetes 支援跨資源的水平自動縮放
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: my-app
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
averageUtilization: 100
type: Utilization
Zalando 創建了一個元件來輕鬆連接自訂指標以進行擴展:
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
name: myapp-hpa
annotations:
# metric-config.<metricType>.<metricName>.<collectorName>/<configKey>
metric-config.pods.requests-per-second.json-path/json-key: "$.http_server.rps"
metric-config.pods.requests-per-second.json-path/path: /metrics
metric-config.pods.requests-per-second.json-path/port: "9090"
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: myapp
minReplicas: 1
maxReplicas: 10
metrics:
- type: Pods
pods:
metric:
name: requests-per-second
target:
averageValue: 1k
type: AverageValue
使用 HPA 配置水平自動縮放應該是提高無狀態服務效率的預設操作之一。 Spotify 有一個演示,介紹了他們對 HPA 的經驗和建議:
減少資源超額預訂
Kubernetes 工作負載透過「資源請求」確定其 CPU/記憶體需求。 CPU 資源以虛擬核心或更常見的「毫核心」來衡量,例如 500m 意味著 50% vCPU。 記憶體資源以位元組為單位,可以使用常見的後綴,如500Mi,表示500兆位元組。 資源請求「鎖定」工作節點上的容量,這表示在具有 1000 個 vCPU 的節點上具有 4m CPU 請求的 pod 將僅留下 3 個 vCPU 可供其他 pod 使用。
鬆弛(超額儲備) 是請求的資源和實際使用之間的差異。 例如,請求 2 GiB 記憶體但僅使用 200 MiB 的 Pod 具有約 1,8 GiB 的「過剩」記憶體。 過量需要花錢。 人們可以粗略估計 1 GiB 冗餘記憶體的成本約為每月 10 美元。
將 CPU 請求從 3000m 減少到約 400m 可以為其他工作負載釋放資源,並允許叢集更小。
“EC2 執行個體的平均 CPU 使用率通常徘徊在個位數百分比範圍內,”
但我們真的希望人們更改 YAML 檔案中的值嗎? 不,機器可以做得更好! 庫伯內斯
我寫了一個小
使用 EC2 Spot 實例
最後但並非最不重要的一點是,透過使用 Spot 執行個體作為 Kubernetes 工作節點可以降低 AWS EC2 成本
如何在 EC2 Spot 上運行 Kubernetes? 有幾種選擇:使用 SpotInst 等第三方服務(現在稱為“Spot”,不要問我為什麼),或者只是將 Spot AutoScalingGroup (ASG) 添加到您的叢集。 例如,以下是具有多種實例類型的「容量最佳化」Spot ASG 的 CloudFormation 程式碼片段:
MySpotAutoScalingGroup:
Properties:
HealthCheckGracePeriod: 300
HealthCheckType: EC2
MixedInstancesPolicy:
InstancesDistribution:
OnDemandPercentageAboveBaseCapacity: 0
SpotAllocationStrategy: capacity-optimized
LaunchTemplate:
LaunchTemplateSpecification:
LaunchTemplateId: !Ref LaunchTemplate
Version: !GetAtt LaunchTemplate.LatestVersionNumber
Overrides:
- InstanceType: "m4.2xlarge"
- InstanceType: "m4.4xlarge"
- InstanceType: "m5.2xlarge"
- InstanceType: "m5.4xlarge"
- InstanceType: "r4.2xlarge"
- InstanceType: "r4.4xlarge"
LaunchTemplate:
LaunchTemplateId: !Ref LaunchTemplate
Version: !GetAtt LaunchTemplate.LatestVersionNumber
MinSize: 0
MaxSize: 100
Tags:
- Key: k8s.io/cluster-autoscaler/node-template/label/aws.amazon.com/spot
PropagateAtLaunch: true
Value: "true"
有關將 Spot 與 Kubernetes 結合使用的一些注意事項:
總結
我希望您發現所提供的一些工具對於減少雲端費用很有用。 您也可以在以下位置找到本文的大部分內容
在 Kubernetes 上節省雲端成本的最佳實踐是什麼? 請讓我知道
來源: www.habr.com