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完成。
浙公网安备 33010602011771号