AKS Pod自动弹性伸缩(HPA) 至ACI 实现
弹性伸缩是基于云部署Kubernetes(比如 AKS) 的最大优势之一,可以让我们的成本最大化的匹配我们的真实负载需要。AKS支持二级伸缩,节点的(Nodepool)和Pod的:
节点的自动化伸缩,是基于VMSS实现的,只需要在节点池里打开即可。
而Pod的伸缩是基于HPA(Horizontal Pod AutoScaler), 具体AKS的弹性伸缩文档有详细描述,这里就不多赘述,参考 : 概念 - 在 Azure Kubernetes 服务 (AKS) 中缩放应用程序 - Azure Kubernetes Service | Microsoft Docs
下面主要探讨如何实现利用Azure 容器实例(ACI)来加速伸缩的响应过程,ACI是直接部署容器实例的PaaS服务,从而跳过节点资源的创建,加速了扩容的过程,而收缩的时候可以优先把ACI实例回收掉,理论上只需要配置固定的最少节点数就可以。
主要关注:
-
- 需要启用ContainerInstance服务提供。
az provider list --query "[?contains(namespace,'Microsoft.ContainerInstance')]" -o table
-
- 给AKS集群启用虚拟节点(Virtual Node), AKS集群需要用CNI的网络,同时需先创建好一个单独的subnet。
az aks enable-addons \ --resource-group myResourceGroup \ --name myAKSCluster \ --addons virtual-node \ --subnet-name myVirtualNodeSubnet
完成后节点会多出一个virtual_node:
- 需要伸缩的Pod的配置修改
- 需要显式加上资源申请,request和limit一致(2021-1-20)。
Pod定义加上资源需求:
resources:
requests:
cpu: 500m
limits:
cpu: 500m
-
- 节点选择的偏向性上,优先不选择ACI, 权重1-100, 设为1.
affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - preference: matchExpressions: - key: type operator: NotIn values: - virtual-kubelet weight: 1 tolerations: - key: virtual-kubelet.io/provider operator: Exists - key: azure.com/aci effect: NoSchedule
完整的服务示例:
apiVersion: apps/v1 kind: Deployment metadata: name: aci-helloworld spec: replicas: 1 selector: matchLabels: app: aci-helloworld template: metadata: labels: app: aci-helloworld spec: containers: - name: aci-helloworld image: mcr.microsoft.com/azuredocs/aci-helloworld ports: - containerPort: 80 resources: requests: cpu: 500m limits: cpu: 500m affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - preference: matchExpressions: - key: type operator: NotIn values: - virtual-kubelet weight: 100 tolerations: - key: virtual-kubelet.io/provider operator: Exists - key: azure.com/aci effect: NoSchedule --- apiVersion: v1 kind: Service metadata: name: helloaci labels: app: aci-helloworld spec: ports: - port: 80 selector: app: aci-helloworld
- 定义HPA规则,为了测试,cpu设置到5%就加实例。最少实例数为2,最多10
apiVersion: autoscaling/v1 kind: HorizontalPodAutoscaler metadata: name: aci-helloworld-hpa spec: maxReplicas: 10 # define max replica count minReplicas: 2 # define min replica count scaleTargetRef: apiVersion: apps/v1 kind: Deployment name: aci-helloworld targetCPUUtilizationPercentage: 5 # target CPU utilization
kubectl apply -f hpa.yaml
可以观察hpa的情况:
kubectl get hpa
指标收集的间隔默认为10s, 在扩容后收缩的时间为10分钟,有需要可以调整: 使用 Azure Kubernetes 服务 (AKS) 中的群集自动缩放程序 - Azure Kubernetes Service | Microsoft Docs
- 测试
测试前pod情况, 都在正常节点池上:
运行一个生成负载的pod:
kubectl run -i --tty load-generator --rm --image=busybox --restart=Never -- /bin/sh
在其shell下生成访问负载:
while true; do wget -q -O- http://helloaci; done >&1 >1.out
确认负载已产生:
由于节点都满了,新的pod都在ACI上
都起来后,REPLICAS数为最大,10, 整体负载有所下降
停掉测试负载,大概10分钟后,REPLICAS数会烣复到最少2, 所有ACI实例被停止。
kubectl describe hpa aci-helloworld-hpa
至此,Pod的自动伸缩至ACI完成。