Kubectl scale 命令最佳实践
作者 | 祝祥
来源 | 新钛云服(ID:newtyun)
转载请联系授权(微信ID:zlm935177782)
kubectl scale 是帮助我们管理 Kubernetes 部署的众多工具之一。在本文中我们将了解如何使用此工具以及最佳使用实践。
概述
kubectl scale命令通过调整正在运行的容器的数量来立即缩放应用程序。这是增加部署副本数量的最快、最简单的方法,可用于应对服务高峰以及日常维护变更。
在本文中,我们将了解如何使用kubectl scale来扩展一个简单的Kubernetes Deployment,同时,我们还将更深入的了解该命令相关的各种参数。最终形成kubectl scale的最佳实践,以及一些用于调整 Kubernetes 副`本数的替代方法。
kubectl scale用例
kubectl scale用于更改Kubernetes deployment, replica set, replication controller和 statefulset 等对象的副本数码。当我们增加副本数时,Kubernetes将启动新的Pod来扩我们的服务。降低副本数将导致 Kubernetes 优雅地终止一些 pod,从而释放集群资源。
我们可以运行kubectl scale来手动调整应用程序的副本数,以响应不断变化的服务容量需求。增加的流量负载可以通过增加副本数来处理,提供更多的应用程序实例来服务用户流量。当业务突发降低的时候,可以减少副本的数量。这有助于通过避免使用不需要的资源来降低成本。
使用 kubectl
kubectl scale最基本的用法是这样的:
$ kubectl scale --replicas=3 deployment/demo-deployment
执行此命令将调整名为demo-deployment 的部署,使其拥有三个正在运行的副本。我们可以通过替换其名称而不是部署来定位不同类型的资源:
# ReplicaSet
$ kubectl scale --replicas=3 rs/demo-replicaset
# ReplicationController
$ kubectl scale --replicas=3 rc/demo-replicationcontroller
# StatefulSet
$ kubectl scale --replicas=3 sts/demo-statefulset
基础缩放
现在我们将看一个使用kubectl scale扩展部署的完整示例。这是一个定义简单部署的 YAML 文件:
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-deployment
spec:
replicas: 1
selector:
matchLabels:
app: demo-app
template:
metadata:
labels:
app: demo-app
spec:
containers:
- name: nginx
image: nginx:latest
将此 YAML 保存到工作目录中的demo-deployment.yaml 。接下来,使用kubectl将部署添加到我们的集群:
$ kubectl apply -f demo-deployment.yaml
deployment.apps/demo-deployment created
现在运行kubectl get pods命令来查看已为部署创建的 pod:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
demo-deployment-86897ddbb-jl6r6 1/1 Running 0 33s
只有一个 pod 正在运行。这是意料之中的,因为部署的清单在其spec.replicas字段中声明了一个副本。
单个副本不足以用于生产应用程序。如果托管 pod 的节点出于任何原因离线,我们可能会遇到停机时间。使用kubectl scale增加副本数以提供更多空间:
$ kubectl scale --replicas=5 deployment/demo-deployment
deployment.apps/demo-deployment scaled
重复kubectl get pods命令以确认部署已成功扩容:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
demo-deployment-86897ddbb-66lzc 1/1 Running 0 46s
demo-deployment-86897ddbb-66s9d 1/1 Running 0 46s
demo-deployment-86897ddbb-jl6r6 1/1 Running 0 3m33s
demo-deployment-86897ddbb-sgcjb 1/1 Running 0 46s
demo-deployment-86897ddbb-tgvnw 1/1 Running 0 46s
现在有五个 Pod 正在运行。从AGE列可以看到scale命令保留了原来的 pod 并新增了 4 个。
经过进一步思考,我们可能会决定此应用程序不需要五个副本。它只运行一个静态 NGINX Web 服务器,因此每个用户请求的资源消耗应该很低。再次使用scale命令来降低副本数并避免浪费集群容量:
$ kubectl scale --replicas=3 deployment/demo-deployment
deployment.apps/demo-deployment created
重复kubectl get pods命令:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
demo-deployment-86897ddbb-66lzc 1/1 Terminating 0 3m21s
demo-deployment-86897ddbb-66s9d 1/1 Terminating 0 3m21s
demo-deployment-86897ddbb-jl6r6 1/1 Running 0 6m8s
demo-deployment-86897ddbb-sgcjb 1/1 Running 0 3m21s
demo-deployment-86897ddbb-tgvnw 1/1 Running 0 3m21s
Kubernetes 已将两个正在运行的 pod 标记为终止。这会将正在运行的副本计数减少到请求的三个 pod。选择要驱逐的 pod 会被发送一个SIGTERM(https://www.containiq.com/post/sigterm-signal-15-linux-graceful-termination-exit-code-143) 信号并允许优雅地终止(https://cloud.google.com/blog/products/containers-kubernetes/kubernetes-best-practices-terminating-with-grace)。停止后,它们将从 pod 列表中删除。
条件缩放
有时我们可能想要扩展资源,但前提是已经有特定数量的副本在运行。这可以避免意外覆盖以前的副本,例如集群中其他用户所做的更改。
在命令中包含--current-replicas标志可以达到效果:
$ kubectl scale --current-replicas=3 --replicas=5 deployment/demo-deployment
deployment.apps/demo-deployment scaled
此示例将演示deployment扩展到五个副本,但前提是当前有三个副本正在运行。--current -replicas值始终完全匹配;我们不能将条件表示为“小于”或“大于”特定计数。
扩展多个资源
当我们提供多个名称作为参数时, kubectl scale命令可以一次缩放多个资源。每个资源都将缩放到由--replicas标志设置的相同副本计数。
$ kubectl scale --replicas=5 deployment/app deployment/database
deployment.apps/app scaled
deployment.apps/database scaled
此命令将应用程序和数据库deployment扩展到每个五个副本。
我们可以通过提供--all标志来扩展特定类型的每个资源,例如此示例以扩展默认命名空间中的所有部署:
$ kubectl scale --all --replicas=5 --namespace=default deployment
deployment.apps/app scaled
deployment.apps/database scaled
这会选择当前活动命名空间内的每个匹配资源。缩放的对象显示在命令的输出中。
我们可以对使用--selector标志缩放的对象进行精细控制。这我们可以使用标准选择语法根据对象的标签(https://www.containiq.com/post/using-kubernetes-labels-selectors-annotations) 过滤对象。这是一个使用app-name=demo-app标签扩展所有部署的示例:
$ kubectl scale --replicas=5 --selector=app-name=demo-app deployment
deployment.apps/app scaled
deployment.apps/database scaled
更改超时
--timeout标志设置 Kubectl 在放弃缩放操作之前将等待的时间。默认情况下,没有等待期。该标志接受可读的时间值,例如5m或1h:
$ kubectl scale --replicas=5 --timeout=1m deployment/demo-deployment
如果无法立即完成缩放更改,这可以让我们避免长时间的终端挂起。尽管kubectl scale是一个命令式命令,但在将新 pod 调度到节点时,对缩放的更改有时可能需要几分钟才能完成。
最佳实践
使用kubectl scale通常是扩展工作负载的最快、最可靠的方法。但是,为了安全操作,需要记住一些最佳实践。如下所示:
- 避免过于频繁地缩放:对副本计数的更改应响应特定事件,例如导致请求运行缓慢或丢包的拥塞。最好分析当前的服务性能,估算一下当前需要满足性能的资源需求,同时也预估一下未来的增长容量。避免过于频繁地扩展应用程序,因为在创建和终止POD时,每个操作都可能导致延迟。
副本缩小到零将会导致服务停止。您可以运行kubectl scale--replicas=0,这将删除选定对象中的所有容器。通过使用该命令,调整replicas的参数,从而实现向上的扩容。 - 确保我们选择了正确的对象。没有确认提示,因此请务必注意正在选择的对象。按名称手动选择对象是最安全的方法,可以防止您意外地扩展应用程序的其他部分,从而导致停机或资源浪费。
- 使用 --current-replicas来避免意外。使用--current replications标志可以确保仅当当前计数符合您的期望时,缩放才会更改,从而提高安全性。否则,您可能会无意中覆盖其他用户或Kubernetes autoscaler应用的缩放更改。
kubectl Scale的替代方式
运行kubectl scale是一项必不可少的操作,它对集群有着直接的影响。您正在指示Kubernetes尽快提供特定数量的副本。如果使用命令式的kubectl create命令创建对象,这是合乎逻辑的,但是如果最初使用声明性的YAML文件运行kubectl apply,则这是不合适的,如上所示。运行scale命令后,集群中的副本数量将不同于YAML的spec.replications字段中定义的副本数量。更好的做法是修改YAML文件,然后将其重新应用于集群。
首先将spec.replicas字段更改为我们所需的新副本数:
apiVersion: apps/v1
kind: Deployment
metadata:
name: demo-deployment
spec:
replicas: 5
selector:
matchLabels:
app: demo-app
template:
metadata:
labels:
app: demo-app
spec:
containers:
- name: nginx
image: nginx:latest
现在对修改后的文件重复kubectl apply命令:
$ kubectl apply -f demo-deployment.yaml
kubectl 将自动区分更改并采取措施将集群的状态演变为文件中声明的状态。这将导致 Pod 被自动创建或终止,因此运行实例的数量再次与spec.replicas字段匹配。
kubectl scale的另一个替代方案是 Kubernetes 对自动缩放的支持。配置此机制允许 Kubernetes 根据 CPU 使用率和网络活动等指标在配置的最小值和最大值之间自动调整副本计数。
最后的总结
kubectl scale命令是扩展 Kubernetes deployments, replica sets, replication controllers以及stateful sets的通用方式。它在每次调用时以一个或多个对象为目标,并对其进行缩放,以便运行指定数量的 pod。
我们可以选择设置条件,因此只有在存在特定数量的现有副本时才会更改比例,从而避免在错误方向上意外调整大小。
同时我们也希望能够遵循一些本文所提到的最佳时实践,从而平稳,可靠的实现资源的扩缩容。