AKS PersistentVolume 亲和力?

AKS PersistentVolume Affinity?

免责声明:这个问题是关于所用平台和我们试图用它解决的用例的。它还比较了我们目前至少在开发阶段使用的两种方法,并且正在尝试比较,但可能还没有完全理解。我正在寻求关于这个非常具体的主题的指导...

A) 我们正在 运行将 Kafka 集群作为 DC/OS 上的 Kafka 任务,其中数据的持久性是通过本地磁盘存储维护的在与相应的 kafka 代理实例相同的主机上配置。

B) 我们正在尝试 运行 Kafka on Kubernetes(通过 Strimzi Operator),特别是 Azure Kubernetes 服务 (AKS),并且正在努力获得可靠的数据持久性使用您在 AKS 中获得的 StorageClasses。我们尝试了三种可能性:

  1. (默认)Azure 磁盘
  2. Azure 文件
  3. 空目录

我发现 Azure 磁盘有两个主要问题,因为我们能够以一种方式设置 Kafka Pod 亲和性,使它们不会最终出现在同一维护区域/主机上,我们没有工具来绑定相应的 PersistentVolume Pod 附近的任何地方。没有什么比 AzureDisks 的 NodeAffinity 更好的了。此外,Azure 磁盘最终位于与其对应的 pod 不同的另一台主机上也很常见,这可能会受到网络带宽的限制?

对于 Azure 文件,我们不会因为维护区域暂时关闭而遇到问题,但作为高延迟存储选项,它似乎不太适合,而且 Kafka 也难以删除/更新保留文件。

所以我最终使用了一个通常不推荐但没有出现上述问题的临时存储集群。 Volume“存在于”pod 附近,并且只要 pod 本身 运行 在任何节点上就可以使用。在维护案例中,pod 和 volume 一起死了。只要我能够维持法定人数,我就看不出这可能会导致问题。

Is there anything like podAffinity for PersistentVolumes as Azure-Disk is per definition Node bound?

据我所知,没有什么比 PersistentVolumes 的 podaffinity 更像 Azure-Disk 了。 Azure 磁盘应附加到节点,因此如果 pod 更改主机节点,则 pod 无法使用该磁盘上的卷。只有 Azure 文件共享是 podAffinity。

What are the major downsides in using emptyDir for persistence in a Kafka Cluster on Kubernetes?

你可以看看emptyDir:

scratch space, such as for a disk-based merge sort

这是你使用AKS最需要注意的地方。您需要计算磁盘 space,也许您需要将多个 Azure 磁盘附加到节点。

开始 - 我不确定你所说的 Azure 磁盘结束在一个节点而不是分配 pod 的节点上是什么意思 - 根据我的理解,这是不可能的(为了完整起见,你可以做这在 AKS 之外具有 shared disks 功能的 VM 上,但据我所知,在撰写本文时,AKS 不支持动态磁盘)。如果您正在查看 PVC 上的 volume.kubernetes.io/selected-node 注释,我认为它在初始创建后不会更新。

您可以通过使用具有反关联性的有状态集来获得您正在寻找的配置。考虑 this statefulset。它创建了三个 pods,它们必须位于不同的可用性区域中。我正在将其部署到带有节点池 (nodepool2) 的 AKS 集群,每个 AZ 有两个节点:

❯ kubectl get nodes -o jsonpath='{range .items[*]}{.metadata.name}{","}{.metadata.labels.topology\.kubernetes\.io\/zone}{"\n"}{end}'
aks-nodepool1-25997496-vmss000000,0
aks-nodepool2-25997496-vmss000000,westus2-1
aks-nodepool2-25997496-vmss000001,westus2-2
aks-nodepool2-25997496-vmss000002,westus2-3
aks-nodepool2-25997496-vmss000003,westus2-1
aks-nodepool2-25997496-vmss000004,westus2-2
aks-nodepool2-25997496-vmss000005,westus2-3

部署并启动 statefulset 后,您可以看到每个 pod 都分配给了 nodepool2 节点之一:

❯ kubectl get pods -o wide
NAME     READY   STATUS    RESTARTS   AGE     IP             NODE                                NOMINATED NODE   READINESS GATES
echo-0   1/1     Running   0          3m42s   10.48.36.102   aks-nodepool2-25997496-vmss000001   <none>           <none>
echo-1   1/1     Running   0          3m19s   10.48.36.135   aks-nodepool2-25997496-vmss000002   <none>           <none>
echo-2   1/1     Running   0          2m55s   10.48.36.72    aks-nodepool2-25997496-vmss000000   <none>           <none>

每个 pod 根据模板创建了一个 PVC:

❯ kubectl get pvc
NAME          STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS      AGE
demo-echo-0   Bound    pvc-bf6104e0-c05e-43d4-9ec5-fae425998f9d   1Gi        RWO            managed-premium   25m
demo-echo-1   Bound    pvc-9d9fbd5f-617a-4582-abc3-ca34b1b178e4   1Gi        RWO            managed-premium   25m
demo-echo-2   Bound    pvc-d914a745-688f-493b-9b82-21598d4335ca   1Gi        RWO            managed-premium   24m

让我们看一下创建的其中一个PV:

apiVersion: v1
kind: PersistentVolume
metadata:
  annotations:
    pv.kubernetes.io/bound-by-controller: "yes"
    pv.kubernetes.io/provisioned-by: kubernetes.io/azure-disk
    volumehelper.VolumeDynamicallyCreatedByKey: azure-disk-dynamic-provisioner
  creationTimestamp: "2021-04-05T14:08:12Z"
  finalizers:
  - kubernetes.io/pv-protection
  labels:
    failure-domain.beta.kubernetes.io/region: westus2
    failure-domain.beta.kubernetes.io/zone: westus2-3
  name: pvc-9d9fbd5f-617a-4582-abc3-ca34b1b178e4
  resourceVersion: "19275047"
  uid: 945ad69a-92cc-4d8d-96f4-bdf0b80f9965
spec:
  accessModes:
  - ReadWriteOnce
  azureDisk:
    cachingMode: ReadOnly
    diskName: kubernetes-dynamic-pvc-9d9fbd5f-617a-4582-abc3-ca34b1b178e4
    diskURI: /subscriptions/02a062c5-366a-4984-9788-d9241055dda2/resourceGroups/rg-sandbox-aks-mc-sandbox0-westus2/providers/Microsoft.Compute/disks/kubernetes-dynamic-pvc-9d9fbd5f-617a-4582-abc3-ca34b1b178e4
    fsType: ""
    kind: Managed
    readOnly: false
  capacity:
    storage: 1Gi
  claimRef:
    apiVersion: v1
    kind: PersistentVolumeClaim
    name: demo-echo-1
    namespace: zonetest
    resourceVersion: "19275017"
    uid: 9d9fbd5f-617a-4582-abc3-ca34b1b178e4
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: failure-domain.beta.kubernetes.io/region
          operator: In
          values:
          - westus2
        - key: failure-domain.beta.kubernetes.io/zone
          operator: In
          values:
          - westus2-3
  persistentVolumeReclaimPolicy: Delete
  storageClassName: managed-premium
  volumeMode: Filesystem
status:
  phase: Bound

如您所见,failure-domain.beta.kubernetes.io/zone 中节点的 PV 具有值 westus2-3 所需的 nodeAffinity。这确保拥有该 PV 的 pod 只会被放置在 westus2-3 中的节点上,并且当 pod 启动时,该 PV 将绑定到磁盘所在的节点 运行。

此时,我删除了所有 pods 以将它们放在其他节点上:

❯ kubectl get pods -o wide
NAME     READY   STATUS    RESTARTS   AGE     IP             NODE                                NOMINATED NODE   READINESS GATES
echo-0   1/1     Running   0          4m4s    10.48.36.168   aks-nodepool2-25997496-vmss000004   <none>           <none>
echo-1   1/1     Running   0          3m30s   10.48.36.202   aks-nodepool2-25997496-vmss000005   <none>           <none>
echo-2   1/1     Running   0          2m56s   10.48.36.42    aks-nodepool2-25997496-vmss000003   <none>           <none>

无法通过 Kubernetes 查看它,但您可以通过 Azure 门户查看管理磁盘 kubernetes-dynamic-pvc-bf6104e0-c05e-43d4-9ec5-fae425998f9d,它支持 pv pvc-bf6104e0-c05e-43d4-9ec5-fae425998f9d,它支持 PVC zonetest/demo-echo-0,是列为 Managed by: aks-nodepool2-25997496-vmss_4,因此它已被删除并分配给 pod 所在的节点 运行。

Portal screenshot showing disk attached to node 4

如果我要删除节点以致我在 AZ 3 中没有节点,我将无法启动 pod echo-1,因为它绑定到 AZ 3 中的磁盘,这可以' 附加到不在 AZ 3 中的节点。