文章的翻译是在课程开始前夕准备的
使用 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 上节省云成本的最佳实践是什么? 请让我知道
来源: habr.com