刘伟业 阿里云智能混合云PDSA团队 高级解决方案工程师

曾就职于新华三云做软件定义数据中心解决方案,负责多个省级云平台的架构设计和落地。现就职于阿里云智能混合云PDSA团队负责容器和云原生产品的方案设计、POC和最佳实践工作。

1.容器服务弹性伸缩简介

本小节将基于使用原理对容器服务弹性伸缩进行简要的描述。

本实践基于K8s的业务集群运行在专有云上,对测试业务进行压力测试,主要基于以下三种产品和能力:
  • 利用阿里云的云企业网专线打通专有云和公共云,实现两朵云上VPC网络互通。
  • 利用K8s(Kubernetes)的HPA能力,实现容器的水平伸缩。
  • 利用K8s的Cluster Autoscaler和阿里云弹性伸缩组ESS能力实现节点的自动伸缩。

当被测试业务指标达到上限时,触发HPA自动扩容业务pod;当业务集群无法承载更多pod时,触发公共云的ESS服务,在公共云内扩容出ECS并自动添加到专有云的K8s集群。

图1:容器服务弹性伸缩原理图

2.软件环境

本次最佳实践的软件环境要求如下:

应用环境:
  • 容器服务ACK基于专有云V3.10.0版本。
  • 公共云云企业网服务CEN。
  • 公共云弹性伸缩组服务ESS。
配置条件:
  • 使用专有云的容器服务或者在ECS上手动部署敏捷PaaS。
  • 开通云专线,打通容器服务所在VPC与公共云上的VPC。
  • 开通公共云弹性伸缩组服务(ESS)。

3.配置指导

  • 3.1配置HPA

    本小节将介绍配置HPA的详细步骤。

    HPA(Horizontal Pod Autoscaler)是K8s的一种资源对象,能够根据CPU、内存等指标对statefulset、deployment等对象中的pod数量进行动态伸缩,使运行在上面的服务对指标的变化有一定的自适应能力。

    本示例创建了一个支持HPA的nginx应用,创建成功后,当pod的利用率超过本例中设置的20%利用率时,则会进行水平扩容,低于20%的时候会进行缩容。具体操作步骤如下。

    • 3.1.1若使用自建K8s集群,则通过yaml文件配置HPA

      ①创建一个nginx应用,必须为应用设置request值,否则HPA不会生效。

      apiVersion: app/v1beta2
      kind: Deployment
      spec:
        template:
          metadata:
            creationTimestamp: null
            labels:
              app: hpa-test
          spec:
            dnsPolicy: ClusterFirst
            terminationGracePeriodSeconds:30
            containers:
              image: '192.168.**.***:5000/admin/hpa-example:v1'
              imagePullPolicy: IfNotPresent
              terminationMessagePolicy:File
              terminationMessagePath:/dev/termination-log
              name: hpa-test
              resources:
                requests:
                  cpu: //必须设置request值
              securityContext: {}
              restartPolicy:Always
              schedulerName:default-scheduler
        replicas: 1
        selector: 
          matchLabels:
              app: hpa-test
        revisionHistoryLimit: 10
        strategy: 
          type: RollingUpdate
          rollingUpdate:
              maxSurge: 25%
              maxUnavailable: 25%
        progressDeadlineSeconds: 600

      ②创建HPA。

      apiVersion: autoscaling/v1
      kind: HorizontalPodAutoscaler
      metadata:
        annotations:
      autoscaling.alpha.kubernetes.io/conditions:'[{"type":"AbleToScale","status":"True","lastTransitionTime":"2020-04-29T06:57:28Z","reason":"ScaleDownStabilized","message":"recent recommendations were higher than current one, applying the highest recent recommendation"},{"type":"ScalingActive","status":"True","lastTransitionTime":"2020-04-29T06:57:28Z","reason":"ValidMetricFound","message":"theHPA was able to successfully calculate a replica count from cpu resource utilization(percentage of request)"},{"type":"ScalingLimited","status":"False","lastTransitionTime":"2020-04-29T06:57:28Z","reason":"DesiredWithinRange","message":"thedesired count is within the acceptable range"}]' autoscaling.alpha.kubernetes.io/currentmetrics:'[{"type":"Resource","resource":{"name":"cpu","currentAverageUtilization":0,"currentAverageValue":"0"}}]'
        creationTimestamp: 2020-04-29T06:57:13Z
        name: hpa-test
        namespace: default
        resourceVersion: "3092268"
        selfLink: /apis/autoscaling/v1/namespaces/default/horizontalpodautoscalers/hpa01
        uid: a770ca26-89e6-11ea-a7d7-00163e0106e9
      spec:
        maxReplicas: //设置pod数量
        minReplicas: 1
        scaleTargetRef:
          apiVersion: apps/v1beta2
          kind: Deployment
          name: centos
        targetCPUUtilizationPercentage://设置CPU阈值
    • 3.1.2若使用阿里云容器服务,需要在部署应用时选择配置HPA图2:阿里云容器服务配置HPA
  • 3.2配置Cluster Autoscaler

    本小节将介绍配置Cluster Autoscaler的详细步骤。

    节点自动伸缩组件基于K8s资源调度的分配情况进行伸缩判断,节点中资源的分配通过资源请求(Request)进行计算。

    当pod由于资源请求(Request)无法满足并进入等待(Pending)状态时,节点自动伸缩组件会根据弹性伸缩组配置信息中的资源规格以及约束配置,计算所需的节点数目。

    如果可以满足伸缩条件,则会触发伸缩组的节点加入。而当一个节点在弹性伸缩组中且节点上pod的资源请求低于阈值时,节点自动伸缩组件会将节点进行缩容。

    因此资源请求(Request)的正确、合理设置,是弹性伸缩的前提条件。

    • 3.2.1配置弹性伸缩组ESS

      ①创建ESS弹性伸缩组,记录最小实例数和最大实例数。

      图3:创建弹性伸缩组并配置-1图4:创建弹性伸缩组并配置-2

      ②创建伸缩配置,记录伸缩配置的id。

      图5:创建伸缩配置
      #!/bin/sh
      yum install -y ntpdate && ntpdate -u ntp1.aliyun.com && curl http:// example.com/public/hybrid/attach_local_node_aliyun.sh | bash -s -- --docker-version 17.06.2-ce-3 --token 9s92co.y2gkocbumal4fz1z --endpoint 192.168.**.***:6443 --cluster-dns 10.254.**.** --region cn-huhehaote
      echo "{" > /etc/docker/daemon.json
      echo "\"registry-mirrors\": [" >> /etc/docker/daemon.json
      echo "\"https://registry-vpc.cn-huhehaote.aliyuncs.com\"" >> /etc/docker/daemon.json
      echo "]," >> /etc/docker/daemon.json
      echo "\"insecure-registries\": [\"https://192.168.**.***:5000\"]" >> /etc/docker/daemon.json
      echo "}" >> /etc/docker/daemon.json
      systemctl restart docker
    • 3.2.2 K8s集群部署autoscaler
      kubectl apply -f ca.yml

      参考ca.yml创建autoscaler,注意修改如下配置与实际环境相对应。

      access-key-id: "TFRB********************"
      access-key-secret: "bGIy********************W***************"
      region-id: "Y24t************"

4.压力测试

本小节将对最佳实践的运用场景进行说明。

  • 4.1模拟业务访问

    启动busybox镜像,在pod内执行如下命令访问以上应用的service,可以同时启动多个pod增加业务负载。

    while true;do wget  -q -O-  http://hpa-test/index.html;done
  • 4.2观察HPA

    加压前:

    图6:加压前指标值

    加压后,当CPU值达到阈值后,会触发pod的水平扩容:

    图7:加压后指标值图8:触发pod水平扩容
  • 4.3观察pod

    当集群资源不足时,新扩容出的pod处于pending状态,此时将触发cluster autoscaler,自动扩容节点。

    图9:触发cluster autoscaler自动扩容节点