前置条件

创建 Horizontal Pod Autoscaler
  • 需要注意的是,targetCPUUtilizationPercentage 字段已经被名为 metrics 的数组所取代。 CPU 利用率这个度量指标是一个 resource metric(资源度量指标),因为它表示容器上指定资源的百分比。 除 CPU 外,你还可以指定其他资源度量指标。默认情况下,目前唯一支持的其他资源度量指标为内存。 只要 metrics.k8s.io API 存在,这些资源度量指标就是可用的,并且他们不会在不同的 Kubernetes 集群中改变名称。
Pod水平自动伸缩
  • 水平扩缩意味着对增加的负载的响应是部署更多的 Pods。 这与 垂直(Vertical) 扩缩不同,对于 Kubernetes, 垂直扩缩意味着将更多资源(例如:内存或 CPU)分配给已经为工作负载运行的 Pod。
  • Kubernetes 将水平 Pod 自动扩缩实现为一个间歇运行的控制回路(它不是一个连续的过程)。
    间隔由 kube-controller-manager--horizontal-pod-autoscaler-sync-period 参数设置(默认间隔为 15 秒)。
必须依赖: K8S 容器性能指标 metrics-server
Kubernetes v1.23: 可配置的扩缩行为



通过压测CPU来验证HPA

1. 创建部署压测程序的yaml文件
cat > php-apache.yaml << ERIC
apiVersion: apps/v1
kind: Deployment
metadata:
  name: php-apache
spec:
  selector:
    matchLabels:
      run: php-apache
  replicas: 1
  template:
    metadata:
      labels:
        run: php-apache
    spec:
      containers:
      - name: php-apache
        # CPU 密集型计算,应用程序
        image: registry.cn-qingdao.aliyuncs.com/cn-aliyun/hpa-example:v0.1.0
        ports:
        - containerPort: 80
        resources:
          limits:
            cpu: 500m
          requests:
            cpu: 200m

---

apiVersion: v1
kind: Service
metadata:
  name: php-apache
  labels:
    run: php-apache
spec:
  type: NodePort
  ports:
  - port: 80
    # targetPort 是pod的端口
    targetPort: 80
    # 可以被外网访问的端口
    nodePort: 30808
  selector:
    run: php-apache

ERIC


2. 创建部署HPA的yaml文件
cat > php-apache-autoscale.yaml << ERIC
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: php-apache
spec:
  # 告诉k8s你要指定的缩放目标是谁
  scaleTargetRef:
    apiVersion: apps/v1
    # 缩放目标是名为php-apache的Deployment
    kind: Deployment
    name: php-apache

  # 至少1个pod
  minReplicas: 1
  # 最多不超过3个pod
  maxReplicas: 3
  # 根据监控指标执行动态扩缩容
  metrics:
  - type: Resource
    resource:
      name: cpu
      # 按数值
      target:
        type: AverageValue
        # 当CPU的使用率超过200m时,进行扩容
        averageValue: 200m

ERIC


3. 开始测试,执行测试命令
kubectl run -i --tty load-generator --rm --image=busybox:1.28 --restart=Never -- /bin/sh -c "while sleep 0.01; do wget -q -O- http://php-apache; done"



通过压测内存来验证HPA

1. 创建部署压测程序的yaml文件
cat > iris-server-stress.yaml << ERIC
apiVersion: apps/v1
kind: Deployment
metadata:
  name: iris-server-stress
spec:
  selector:
    matchLabels:
      run: iris-server-stress
  replicas: 1
  template:
    metadata:
      labels:
        run: iris-server-stress
    spec:
      containers:
      - name: iris-server-stress
        # 消耗指定内存大小的应用程序
        image: registry.cn-qingdao.aliyuncs.com/cn-aliyun/iris-server-stress:v0.1.0
        ports:
        - containerPort: 8080
        resources:
          limits:
            memory: "2Gi"
          requests:
            memory: "1Gi"

---

apiVersion: v1
kind: Service
metadata:
  name: iris-server-stress
  labels:
    run: iris-server-stress
spec:
  type: NodePort
  ports:
  - port: 80
    # targetPort 是pod的端口
    targetPort: 8080
    # 可以被外网访问的端口
    nodePort: 30808
  selector:
    run: iris-server-stress

ERIC


2. 创建部署HPA的yaml文件
cat > iris-server-stress-autoscale.yaml << ERIC
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: iris-server-stress
spec:
  # 告诉k8s你要指定的缩放目标是谁
  scaleTargetRef:
    apiVersion: apps/v1
    # 缩放目标是名为iris-server-stress的Deployment
    kind: Deployment
    name: iris-server-stress

  # 至少1个pod
  minReplicas: 1
  # 最多不超过3个pod
  maxReplicas: 3
  # 根据监控指标执行动态扩缩容
  metrics:
  - type: Resource
    resource:
      name: memory
      # 按资源使用率(百分比)
      target:
        type: Utilization
        averageUtilization: 70


ERIC


3. 开始测试,执行测试命令
## 不会触发扩容
curl http://localhost:30808/v1/stressMEM?mem=512

## 会触发扩容
curl http://localhost:30808/v1/stressMEM?mem=1433

结论
  • 从测试结果可以确定,HPA的扩容指标是参照容器资源.资源请求限制的数值,做为百分比的参考;
  • 因此我们运行应用程序的虚拟机的资源限制,不要小于 containers.resources.requests.memory 这个数值,更不能超出 containers.resources.limits.memory 这个数值,否则会 内存溢出






教学 自定义,创建测试程序

可以使用kubectl命令生成Deployment模板(新手学习)
kubectl create deploy container-pressure-test --image=polinux/stress:1.0.4 --dry-run=client -o yaml > container-pressure-test.yaml

还可以直接创建Deployment模板(推荐使用)
cat > container-pressure-test.yaml << ERIC
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: container-pressure-test
  name: container-pressure-test
spec:
  replicas: 1
  selector:
    matchLabels:
      app: container-pressure-test
  template:
    metadata:
      labels:
        app: container-pressure-test
    spec:
      containers:
      - image: polinux/stress:1.0.4
        name: stress
        command: [ "/bin/sh" ]
        # 压测目标:保持3个CPU满负载工作,并且每次只测试16秒
        # 每隔400s进行一次压测
        #args: [ "-c", "while true; do stress -c 3 -t 16s; sleep 400; done" ]

        # 压测目标:模拟产生6个进程,每个进程分配2G内存,持续消耗内存60秒后在释放,测试300S
        # 每隔5s进行一次压测
        args: [ "-c", "while true; do stress --vm 6 --vm-bytes 2G --vm-hang 60 -t 300s; sleep 5; done" ]

ERIC


## 运行
kubectl apply -f container-pressure-test.yaml




创建HPA
可以使用kubectl命令生成HPA模板(新手学习)
kubectl autoscale deployment container-pressure-test --cpu-percent=5 --min=1 --max=10 --dry-run -o yaml > pressure-test-hpa.yaml

## 生成的文件内容如下
apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  creationTimestamp: null
  name: container-pressure-test
spec:
  maxReplicas: 10
  minReplicas: 1
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: container-pressure-test
  targetCPUUtilizationPercentage: 5
status:
  currentReplicas: 0
  desiredReplicas: 0


还可以直接创建HPA模板(推荐使用)

提示HPA是要与你的工作负载进行绑定使用的

cat > pressure-test-hpa.yaml << ERIC
apiVersion: autoscaling/v2beta2
kind: HorizontalPodAutoscaler
metadata:
  name: pressure-test
spec:
  # 告诉k8s你要指定的缩放目标是谁
  scaleTargetRef:
    apiVersion: apps/v1
    # 缩放目标是名为container-pressure-test的Deployment
    kind: Deployment
    name: container-pressure-test

  # 至少1个pod
  minReplicas: 1
  # 最多不超过3个pod
  maxReplicas: 3
  # 根据监控指标执行动态扩缩容
  metrics:
  - type: Resource
    resource:
      name: cpu
#      # 按利用率(百分比)
#      target:
#        type: Utilization
#        averageUtilization: 50
      # 按数值
      target:
        type: AverageValue
        averageValue: 3m

ERIC


## 运行
kubectl apply -f pressure-test-hpa.yaml




说明
  • 测试程序启动以后,它会执行一条CPU的压测命令,会给工作节点的CPU增加压力
  • 之后启动HPA去监控这个工作负载,它会根据 metrics-server 返回的监控数据,自动调整测试程序的副本数



分类: Kubernetes

毛巳煜

高级软件开发全栈架构师