freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

点我创作

试试在FreeBuf发布您的第一篇文章 让安全圈留下您的足迹
我知道了

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

Kubernetes HPA 实战:Pod水平自动伸缩—实现全纪录
Prog77X 2025-03-26 14:11:34 44205
所属地 上海

1. 基本概念

Horizontal Pod Autoscaler(HPA,Pod水平自动伸缩),根据平均 CPU 利用率、平均内存利用率或你指定的任何其他自定义指标自动调整 Deployment 、ReplicaSet 或 StatefulSet 或其他类似资源,实现部署的自动扩展和缩减,让部署的规模接近于实际服务的负载。HPA不适用于无法缩放的对象,例如DaemonSet。
实际生产中,一般使用这四类指标:

  1. Resource metrics——CPU核 和 内存利用率指标。
  2. Pod metrics——例如网络利用率和流量。
  3. Object metrics——特定对象的指标,比如Ingress, 可以按每秒使用请求数来扩展容器。
  4. Custom metrics——自定义监控,比如通过定义服务响应时间,当响应时间达到一定指标时自动扩容。

2. 安装 metrics-server

2.1 HAP 前提条件

默认情况下,Horizontal Pod Autoscaler 控制器会从一系列的 API 中检索度量值。 集群管理员需要确保下述条件,以保证 HPA 控制器能够访问这些 API:

  1. 对于资源指标,将使用 metrics.k8s.ioAPI,一般由 metrics-server 提供。 它可以作为集群插件启动。
  2. 对于自定义指标,将使用 custom.metrics.k8s.ioAPI。 它由其他度量指标方案厂商的“适配器(Adapter)” API 服务器提供。 检查你的指标管道以查看是否有可用的 Kubernetes 指标适配器。
  3. 对于外部指标,将使用 external.metrics.k8s.ioAPI。可能由上面的自定义指标适配器提供。
  4. 自动检测周期由 kube-controller-manager 的 --horizontal-pod-autoscaler-sync-period 参数设置(默认间隔为 15 秒)。
  5. metrics-server 提供 metrics.k8s.ioAPI 为pod资源的使用提供支持。
  6. 15s/周期 -> 查询metrics.k8s.ioAPI -> 算法计算 -> 调用scale 调度 -> 特定的扩缩容策略执行。

Kubernetes Metrics Server:

  • Kubernetes Metrics Server 是 Cluster 的核心监控数据的聚合器,kubeadm 默认是不部署的。
  • Metrics Server 供 Dashboard 等其他组件使用,是一个扩展的 APIServer,依赖于 API Aggregator。所以,在安装 Metrics Server 之前需要先在 kube-apiserver 中开启 API Aggregator。
  • Metrics API 只可以查询当前的度量数据,并不保存历史数据。
  • Metrics API URI 为 /apis/metrics.k8s.io/,在k8s.io/metrics下维护。
  • 必须部署 metrics-server 才能使用该 API,metrics-server 通过调用 kubelet Summary API 获取数据。

2.2 开启 API Aggregator

修改每个 API Server 的 kube-apiserver.yaml 配置开启 Aggregator Routing
vim /etc/kubernetes/manifests/kube-apiserver.yaml
# 添加这行
# --enable-aggregator-routing=true

1735633844_6773abb49c833a5c993fa.png!small?1735633845657

修改 manifests 配置后 API Server 会自动重启生效。
使用 kubectl describe 命令来查看 kube-apiserver 的 Pod 描述,确认是否包含了相应的配置。

kubectl describe pod kube-apiserver-k8s-master -n kube-system

1735633828_6773aba45385bd95b42f8.png!small?1735633838154

2.3 下载 components.yaml

GitHub地址:https://github.com/kubernetes-sigs/metrics-server/releases

wget https://github.com/kubernetes-sigs/metrics-server/releases/download/metrics-server-helm-chart-3.8.2/components.yaml

下载后修改如下部分

...
  template:
    metadata:
      labels:
        k8s-app: metrics-server
    spec:
      containers:
      - args:
        - --cert-dir=/tmp
        - --secure-port=4443
        - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
        - --kubelet-use-node-status-port
        - --kubelet-insecure-tls                    #   加上该启动参数,不加可能会报错
        image: registry.aliyuncs.com/google_containers/metrics-server:v0.6.1   # 镜像地址根据情况修改
        imagePullPolicy: IfNotPresent
...

metrics-server pod 若无法启动,出现日志 unable to fully collect metrics
解决方法:在metrics-server中添加--kubelet-insecure-tls参数跳过证书校验

2.4 开始安装

kubectl apply -f components.yaml

# 查看
kubectl get pod -n kube-system | grep metrics-server

1735633844_6773abb49acbcd29309cf.png!small?1735633845658

2.5 查看node和pod资源使用情况

# 查看node和pod资源使用情况
kubectl top nodes
kubectl top pods -n kube-system

1735633859_6773abc36e99474211d65.png!small?1735633859887

3. Horizontal Pod Autoscaler 工作原理

3.1 原理架构图

1735633874_6773abd243bdfbbe4db64.png!small?1735633874449

  1. 自动检测周期由 kube-controller-manager 的 --horizontal-pod-autoscaler-sync-period 参数设置(默认间隔为 15 秒)。
  2. metrics-server 提供 metrics.k8s.ioAPI 为pod资源的使用提供支持。
  3. 15s/周期 -> 查询metrics.k8s.ioAPI -> 算法计算 -> 调用scale 调度 -> 特定的扩缩容策略执行。

3.2 HPA扩缩容算法

从最基本的角度来看,Pod 水平自动扩缩控制器根据当前指标和期望指标来计算扩缩比例。
期望副本数 = ceil[当前副本数 * (当前指标 / 期望指标)]

1、扩容

如果计算出的扩缩比例接近 1.0, 将会放弃本次扩缩, 度量指标 / 期望指标接近1.0。

2、缩容

冷却/延迟: 如果延迟(冷却)时间设置的太短,那么副本数量有可能跟以前一样出现抖动。

默认值是 5 分钟:–horizontal-pod-autoscaler-downscale-stabilization

3、特殊处理

  1. 丢失度量值:缩小时假设这些 Pod 消耗了目标值的 100%, 在需要放大时假设这些 Pod 消耗了 0% 目标值。 这可以在一定程度上抑制扩缩的幅度。
  2. 存在未就绪的pod的时候:我们保守地假设尚未就绪的 Pod 消耗了期望指标的 0%,从而进一步降低了扩缩的幅度。
  3. 未就绪的 Pod 和缺少指标的 Pod 考虑进来再次计算使用率。 如果新的比率与扩缩方向相反,或者在容忍范围内,则跳过扩缩。 否则,我们使用新的扩缩比例。
  4. 指定了多个指标, 那么会按照每个指标分别计算扩缩副本数,取最大值进行扩缩。

3.3 HPA 对象定义

apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: nginx
spec:
  behavior:
    scaleDown:
      policies:
      - type: Pods
        value: 4
        periodSeconds: 60
      - type: Percent
        value: 10
        periodSeconds: 60
      stabilizationWindowSeconds: 300
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: nginx
  minReplicas: 1
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 50

主要部分解释:

  1. apiVersion:autoscaling/v2beta2

    • 表示 HPA 使用的 API 版本。
  2. kind:HorizontalPodAutoscaler

    • 资源类型是 HPA。
  3. metadata:

    • name:nginx- HPA 对象的名称。
  4. spec:

    • behavior: 定义 HPA 的缩放行为。

      • scaleDown: 定义缩减副本时的行为策略。
        • policies:
          • type: Pods- 每次缩减固定数量的 Pod。
            • value: 4- 每次缩减 4 个 Pod。
            • periodSeconds: 60- 每 60 秒执行一次该策略。
          • type: Percent- 每次缩减副本的百分比。
            • value: 10- 每次缩减 10% 的 Pod。
            • periodSeconds: 60- 每 60 秒执行一次该策略。
        • stabilizationWindowSeconds:300- 缩减副本时的稳定窗口期,为 300 秒。
    • scaleTargetRef: 指定 HPA 关联的目标对象。

      • apiVersion: apps/v1
      • kind: Deployment
      • name: nginx- 目标 Deployment 的名称。
    • minReplicas:1- 最小副本数量。

    • maxReplicas:10- 最大副本数量。

    • metrics: 定义缩放的指标。

      • type: Resource
        • resource:
          • name: cpu- 基于 CPU 资源的利用率。
          • target:
            • type: Utilization
            • averageUtilization: 50- 目标 CPU 利用率为 50%。

HPA对象默认行为:

behavior:
  scaleDown:
    stabilizationWindowSeconds: 300
    policies:
    - type: Percent
      value: 100
      periodSeconds: 15
  scaleUp:
    stabilizationWindowSeconds: 0
    policies:
    - type: Percent
      value: 100
      periodSeconds: 15
    - type: Pods
      value: 4
      periodSeconds: 15
    selectPolicy: Max

默认行为解释:

  1. behavior:
    • scaleDown: 默认缩减副本的行为。

      • stabilizationWindowSeconds:300- 缩减副本时的稳定窗口期,为 300 秒。
      • policies:
        • type: Percent- 每次缩减副本的百分比。
          • value: 100- 每次可以缩减 100% 的 Pod,即全部缩减。
          • periodSeconds: 15- 每 15 秒执行一次该策略。
    • scaleUp: 默认增加副本的行为。

      • stabilizationWindowSeconds:0- 增加副本时没有稳定窗口期。
      • policies:
        • type: Percent- 每次增加副本的百分比。
          • value: 100- 每次可以增加 100% 的 Pod。
          • periodSeconds: 15- 每 15 秒执行一次该策略。
        • type: Pods- 每次增加固定数量的 Pod。
          • value: 4- 每次增加 4 个 Pod。
          • periodSeconds: 15- 每 15 秒执行一次该策略。
      • selectPolicy:Max- 当多个策略同时生效时,选择能产生最大效果的策略。

4. 安装镜像

实验以通过 Docker 命令手动拉取nginx:latest镜像为例

docker pull nginx:latest
# 输出类似如下(表示拉取成功):
Using default tag: latest
latest: Pulling from library/nginx
aed007321795: Pull complete
3ab6bcb2dcd4: Pull complete
81d0c4dffcf1: Pull complete
Digest: sha256:cd842bc5ad3b26cc950a139bd8e55f28e06edda963d0a162f9a96e41f110d920
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest

确认镜像已下载,可以通过以下命令查看本地镜像:

docker images

输出类似如下(表示 nginx 镜像已存在):

执行

1735633926_6773ac0642f8989a4a428.png!small?1735633926991

5. 编排yaml

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler 
metadata:
  name: hap-nginx
spec:
  maxReplicas: 10 
  minReplicas: 1
  metrics:
  - resource:
      name: cpu
      target:
        averageUtilization: 40 
        type: Utilization
    type: Resource
  scaleTargetRef: 
    apiVersion: apps/v1
    kind: Deployment
    name: hap-nginx
---
apiVersion: v1
kind: Service
metadata:
  name: hap-nginx
spec:
  type: NodePort
  ports:
    - name: "http"
      port: 80
      targetPort: 80
      nodePort: 30080
  selector:
    service: hap-nginx 
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hap-nginx 
spec:
  replicas: 1 
  selector:
    matchLabels:
      service: hap-nginx
  template:
    metadata:
      labels:
        service: hap-nginx
    spec:
      containers:
        - name: hap-nginx
          image: nginx:latest
          resources:
            requests:
              cpu: 100m 
              memory: 100Mi
            limits:
              cpu: 200m
              memory: 200Mi

对于 yaml 详细说明一下:

Horizontal Pod Autoscaler(HPA),我们命名成 hap-nginx,具体来说:

  • maxReplicas 和 minReplicas 分别指定了允许的最大和最小 Pod 副本数。
  • metrics 定义了用于调整副本数的指标。在这里,使用 CPU 使用率作为指标,并设置目标 CPU 平均利用率为 40%。
  • scaleTargetRef 指定了需要自动缩放的目标对象,这里是一个 Deployment,名称为 hap-nginx。

Service,用于将流量路由到后端的 Pod,具体来说:

  • type 指定了服务类型为 NodePort,允许外部流量通过节点端口访问服务。
  • ports 定义了服务暴露的端口和目标端口。在这里,服务将监听端口 80,并将流量转发到后端 Pod 的端口 80。
  • selector 指定了要将流量路由到哪些 Pod。这里选择了标签为 service: hap-nginx 的 Pod。

Deployment,用于管理运行在 Pod 中的应用程序,具体来说:

  • replicas 指定了期望的 Pod 副本数,这里设置为 1。
  • selector 定义了标签选择器,用于选择由该 Deployment 管理的 Pod。在这里,选择器匹配标签为 service: hap-nginx 的 Pod。
  • template 定义了 Pod 的模板,包括标签和容器规格。在这里,定义了一个名为 hap-nginx 的容器,使用最新版本的 nginx 镜像,并设置了容器的 CPU 和内存资源请求与限制。

执行:

kubectl apply -f 1.yaml

1735633947_6773ac1bc4b15bdb5fc43.png!small?1735633948021

表示已成功将 YAML 文件 /home/as/桌面/1.yaml 中定义的 Horizontal Pod Autoscaler、Service 和 Deployment 应用到集群中。

6. 查看状态信息

查看服务运行在哪个节点上:

kubectl get pods -o wide

1735633967_6773ac2f0c0913502dec7.png!small?1735633967307

访问:

1735633977_6773ac39bca761c0812ee.png!small?1735633978051

虽然显示运行在 worker1 上,但使用 worker1 的 ip 和 worker2 的 ip 都可以访问。

7. 安装 ab 压测工具

ab(Apache Benchmark)是 apache 自带的一款功能强大的测试工具,常用的参数为-n 和-c。

ab -n 1000 -c 100 url
# 将会发送 1000 个请求(-n 1000)给指定的服务,同时并发地发送 100 个请求(-c 100)

直接通过yum安装apache:

yum install httpd -y
ab -V

1735633992_6773ac48b7fff1dd7e3ca.png!small?1735633993092

8. 开始压测

ab -n 100000 -c 800 http://192.168.136.130:30080/
#-c:并发数
#-n:总请求数

1735634019_6773ac635635d6736102c.png!small?1735634020292

可以看到已经实现了根据CPU 动态扩容了。

1735634030_6773ac6e101d354ceec36.png!small?1735634030698

如果想在扩容后重新设置只起固定数量的pod,不可以删除,删除后会重启相同数量的pod

kubectl scale deployment hap-nginx --replicas=1

hap-nginx Deployment 的副本数量设置为 1,停止其他相关的 Pod 的运行

1735634041_6773ac79a4b5289ceed4d.png!small?1735634042009


# 搭建 # 环境搭建 # k8s # 场景搭建 # Kubernetes集群
本文为 Prog77X 独立观点,未经授权禁止转载。
如需授权、对文章有疑问或需删除稿件,请联系 FreeBuf 客服小蜜蜂(微信:freebee1024)
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
Prog77X LV.2
这是一个全栈偏前端的开发人员,期待多多交流。
  • 5 文章数
  • 10 关注者
Kubernetes :k8s一主两从集群搭建—实现全纪录
2025-03-26
Ant Design 的 CSS-in-JS 实现与最佳实践
2025-03-26
viper:一款中国人写的红队服务器——记一次内网穿透练习
2024-12-31
文章目录