kubernetes 当达到节点卷限制时,如何触发AKS群集自动扩展

dddzy1tm  于 2023-10-17  发布在  Kubernetes
关注(0)|答案(3)|浏览(101)

在Azure Kubernetes Service中,可以附加到节点的Azure服务器数量取决于VM大小。例如https://learn.microsoft.com/en-us/azure/virtual-machines/dv4-dsv4-series。请参见数据磁盘列。
我有使用disk.csi.azure.com提供程序连接磁盘的Pod。只要有少于4个这样的并发pod,这就可以工作。第五个进程停止并出错,因为我们使用的VM大小仅支持4个磁盘。
如何在考虑磁盘限制的情况下调度Pod,以便在所有节点上达到磁盘限制时自动伸缩器扩展集群?
基于此,我希望AKS将此限制作为扩展资源公开,但在节点的capacity状态中没有任何提示。亲和力似乎是把pod放在节点上的二元规则;我看不出有什么办法可以对“最多x个pod可以去一个节点”进行建模。
编辑上下文:pod是由gitlab-runner生成的CI作业。我想使用持久卷作为构建区域,以避免在每个作业中从头开始克隆整个项目。从Kubenernetes的Angular 来看,这看起来像是动态生成的Pod,每个Pod都请求挂载之前定义的一组持久卷声明中的一个。PVC:s是可替换的(它们缓存相同的克隆),但是配置强制我们为每个pod请求一个特定的名称。
更新:我正在探索一个基于Extended Resources的解决方案。我尝试通过Kyverno根据VM大小标签设置它们,但是Kyverno对改变现有资源的支持似乎不适用于状态子资源。或者至少我的配置成功地更新了现有节点上的标签,以及新节点上的扩展资源,但没有在现有节点上设置扩展资源。以下是我的尝试:

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
  name: azure-disk-resource-limit
spec:
  mutateExistingOnPolicyUpdate: true
  background: true
  rules:
  - name: add-disk-limit
    match:
      any:
      - resources:
          kinds:
          - Node
          - Node/status
    mutate:
      targets:
        - apiVersion: v1
          kind: Node
        - apiVersion: v1
          kind: Node/status
      patchStrategicMerge:
        metadata:
          labels:
            kyverno-dummy: "babar1"
        status:
          capacity:
            kyverno-dummy: 9
#      patchesJson6902: |-
#          - path: "/status/capacity/kyverno-dummy"
#            op: add
#            value: 8

注意:我必须编辑Kyverno设置以启用对节点的更改:1)我更改了resourceFilter并删除了隐藏Node的过滤器。2)我给了后台和准入控制器编辑节点的权利:

# In values.yml for the kyverno chart:
admissionController:
  rbac:
    clusterRole:
      extraResources:
        - apiGroups:
            - ''
          resources:
            - nodes
            - nodes/status
            - namespaces
          verbs:
            - update
            - patch
backgroundController:
  nodeSelector:
    kubernetes.io/os: linux
  rbac:
    clusterRole:
      extraResources:
        - apiGroups:
            - ''
          resources:
            - nodes
            - nodes/status
            - namespaces
          verbs:
            - update
            - patch

我正在考虑创建一个自定义控制器来设置扩展资源,但这感觉不太明智。
PS.我发现一个UserVoice请求AKS会自动添加限制:https://feedback.azure.com/d365community/idea/02e94731-f824-ec11-b6e6-000d3a4f0da0

yb3bgrhw

yb3bgrhw1#

您可以考虑使用S3 bucket而不是附加的磁盘,它们可能更适合于需要特定于Pod命名约定的存储的大量(未知)Pod。
另一种可能性是尝试topologyKey“节点”的拓扑扩展约束,例如

kind: Pod
apiVersion: v1
metadata:
  name: mypod
  labels:
    foo: bar
spec:
  topologySpreadConstraints:
  - maxSkew: 4
    topologyKey: node
    whenUnsatisfiable: DoNotSchedule
    labelSelector:
      matchLabels:
        foo: bar
  containers:
  - name: pause
    image: registry.k8s.io/pause:3.1

https://kubernetes.io/docs/concepts/scheduling-eviction/topology-spread-constraints/#example-one-topologyspreadconstraint

kgsdhlau

kgsdhlau2#

您可能需要创建一个自定义解决方案,因为默认情况下,AKS不具有此功能。
为了管理Azure Kubernetes Service中的存储和磁盘附件限制,您可以使用KubernetesPersistent Volume ClaimsPersistent Volume Claims。这些工具将帮助您以更加动态和抽象的方式管理存储。
1.了解持久卷和基于持久卷的声明。

永久卷:PV是群集中的存储单元,它使用存储类静态提供或由管理员提供。与节点和Pod相同,PV是集群中的资源。
**连续卷声明:**PVC是用户对存储的请求。它相当于一个pod要求CPU和内存。pod使用PVC并利用PV资源。

1.建立存储类
如果您使用动态存储资源调配,请创建存储类,概述您要提供的不同存储“类”。底层存储特性的类型可以由存储类指定。

AKS存储类示例:

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: standard
provisioner: kubernetes.io/azure-disk
parameters:
  storageaccounttype: Standard_LRS

将存储类应用于群集:

kubectl apply -f azure-standard-storage-class.yaml

1.确定持久卷声明:
要请求所需的存储,请在Kubernetes pod设置中包含PVC。您的pod通过PVC连接到底层PV。

示例PVC:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: standard
  resources:
    requests:
      storage: 10Gi

1.将PVC应用于群集:

kubectl apply -f my-pvc.yaml

4.将PVC连接到Pod:

参考您在pod设置中定义的PVC。它连接了pod和PVC中提到的存储器。

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
    - name: my-container
      image: nginx
      volumeMounts:
        - name: my-volume
          mountPath: /data
  volumes:
    - name: my-volume
      persistentVolumeClaim:
        claimName: my-pvc

将pod应用到您的集群:

kubectl apply -f my-pod.yaml

在这里,pod“my-pod”使用名为“my-pvc”的PVC来请求和访问存储。存储器安装在pod中的路径“/data”处。

5.扩展Pod:

现在,如果您选择动态配置,当您需要通过添加更多pod来扩展应用程序时,Kubernetes将自动配置额外的PV,并通过PVC将它们连接到新的pod。因此,您可以动态地管理存储,而不必担心特定于节点的磁盘连接限制。

POD负载增加自动伸缩。

负载增加:

6kkfgxo0

6kkfgxo03#

现在看起来AKS支持开箱即用。
我认为它没有的原因是这样的错误:

Warning  FailedAttachVolume  2m57s (x9 over 5m9s)  attachdetach-controller  AttachVolume.Attach failed for volume "pvc-5c518d52-7f4d-4a02-a17f-7030bbbfd84c" : rpc error: code = Internal desc = Attach volume /subscriptions/[redacted]/resourceGroups/[redacted]/providers/Microsoft.Compute/disks/[redacted] to instance akswin000001 failed with Retriable: false, RetryAfter: 0s, HTTPStatusCode: 409, RawError: {\r
  "error": {\r
    "code": "OperationNotAllowed",\r
    "message": "The maximum number of data disks allowed to be attached to a VM of this size is 4.",\r
    "target": "dataDisks"\r
  }\r
}

但是当我进行实验时,我突然在事件中遇到了这样一个信息:

Warning  FailedScheduling  52s   default-scheduler   0/4 nodes are available: 1 node(s) didn't match Pod's node affinity/selector, 1 node(s) exceed max volume count, 2 node(s) had untolerated taint {node.kubernetes.io/unreachable: }. preemption: 0/4 nodes are available: 1 No preemption victims found for incoming pod, 3 Preemption is not helpful for scheduling..
  Normal   TriggeredScaleUp  45s   cluster-autoscaler  pod triggered scale-up: [{akswin 1->2 (max: 2)}]

请注意,1个节点超过了最大卷计数。所以现在看起来AKS实际上是足够聪明的开箱即用,以解决磁盘限制。要么这个机制是在我调查这个问题的那一周添加的,要么它上周失败的事实只是一个随机的打嗝。我倾向于后一种解释,因为我仍然能够观察到至少一次错误,这次系统只是从它恢复过来(当新的自动缩放节点与磁盘插槽可用时)。上周,它在循环中永远失败了。
所以,谢谢大家的回答。如果你有一个相同的形状的问题,@Vitaly的trick可能是要走的路,但它似乎是不必要的AKS毕竟。

相关问题