【Kubernetes】Pod 之 扩容和缩容

1,272 阅读4分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第13天,点击查看活动详情

一、前言

在实际的生产环境中,当服务的请求数量急剧增加的时候,我们需要对某个服务进行扩容,当资源紧张或服务的工作负载降低时,我们可以对某个服务进行缩容。

通过 Deployment/ReplicationController/ReplicaSetScale 机制可以完成 Pod 扩缩容。

Pod 扩缩容分为两种模式,手动扩缩容和自动扩缩容:

  • 手动扩缩容:通过执行命令 kubectl scale 或通过 RESTful APIDeployment/rc/rs 进行 Pod 副本数量设置来一键完成扩缩容。
  • 自动扩缩容:指定某个性能指标或自定义业务指标的范围,以及指定 Pod 副本数量的范围,kubernetes 系统会自动在副本数量的范围内根据性能指标的变化进行调整。



二、手动扩缩容

通过命令 kubectl scale 可以进行手动扩缩容,使用参数 --replicas 指定需要增加或是减少 Pod 的数量到某个指定的数字。

  1. 创建nginx-deployment.yaml文件
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80
  1. 执行创建
$ kubectl create -f nginx-deployment.yaml
deployment.apps/nginx-deployment created
  1. 查看
$ kubectl get pods
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-5754944d6c-hkz57   1/1     Running   0          55s
nginx-deployment-5754944d6c-jvhwq   1/1     Running   0          55s
nginx-deployment-5754944d6c-z7ccp   1/1     Running   0          55s
  1. 扩容(将 nginx-deployment Pod 副本数量从 3 个扩容到 5 个)
# 执行扩容
$ kubectl scale deployment nginx-deployment --replicas 5
deployment.extensions/nginx-deployment scaled
  1. 查看
# 可以看到有两个新创建的 Pod
$ kubectl get pods
  1. 缩容(将 nginx-deployment Pod 副本数量从 5 个缩容到 1 个)
# 执行缩容
$ kubectl scale deployment nginx-deployment --replicas 1
deployment.extensions/nginx-deployment scaled
  1. 查看
# 从结果中可以看出,系统 kill 掉了一些运行中的 Pod,只保留了一个 Pod 来实现缩容
$ kubectl get pods



三、 自动扩缩容

Kubernetes v1.1 版本开始,添加了名为 Horizontal Pod Autoscaler(HPA) 的控制器,用于实现 Pod 自动扩缩容的功能。HPA 控制器基于 Masterkube-controller-manager 服务启动参数 --horizontal-pod-autoscaler-sync-period 定义的检测周期(默认值为 15s),周期性检测目标 Pod 的资源性能指标,并与 HPA 资源对象中的扩缩容条件进行对比,当满足条件时对 Pod 副本数量进行调整。

扩缩容会根据内存、CPU 资源使用率、或是自定义的业务监控指标作为资源性能指标。

kubernetes系统的资源采集,由这两种 API实现:

  • Resource Metrics API(通过 metrics-server 实现):负责采集 NodePod 的核心资源数据
  • Custom Metrics API(通常使用 Prometheus 实现):负责自定义的指标数据采集,比如:网卡流量、磁盘 IOPSHTTP 请求数、数据库连接数等



四、 扩缩容算法

Autoscaler 控制器从聚合 API 获取到 Pod 性能指标数据之后,通过下面的算法计算目标 Pod 副本数量:

desiredReplicas = ceil[currentReplicas * ( currentMetricValue / desiredMetricValue )]
目标副本数量 = 当前副本数 * (当前指标值/期望指标值)

举个栗子

CPU 请求数量为例,假设当前系统运行了一个 Pod 副本,用户设置的期望值为 100m:

  • 如果当前实际使用的指标值为 200m,则:目标副本数量 = 1 * (200/100) = 2,也就是期望 Pod 副本数量为 2,这个时候就会进行 Pod 扩容
  • 如果当前实际使用的指标值为 50m,则:目标副本数量 = 1 * (50/100) = 0.5,将计算结果向上取整为 1,也就是期望 Pod 副本数量为 1,这个时候就不会改变 Pod 的数量

当计算结果与 1 非常接近时,可以设置一个容忍度使系统不做扩缩容处理,通过 kube-controller-manager 服务的启动参数 --horizontal-pod-autoscaler-tolerance 进行设置,该参数的默认值为 0.1(10%),所以上述算法计算结果在正负 10% 的区间中都不会执行扩缩容操作。

期望指标值(desiredMetricValue)也可以是指标的平均值,比如:targetAverageValue,这时当前指标值(currentMetricValue)的算法为:

当前指标值 = 所有 Pod 副本当前指标值总和 / Pod 副本数量