Kubernetes 中的拓扑感知卷配置

作者 :Michelle Au(Google)

Kubernetes 1.12中具有拓扑感知的动态预配置beta功能,可提高持久性卷的多区域群集体验。该功能允许Kubernetes在动态调配卷时通过在最佳位置获取调度程序输入以调配Pod的容量来做出明智的决策。在多区域群集中,这意味着将在可运行您的Pod的适当区域中配置卷,从而使您能够轻松跨故障域部署和扩展有状态工作负载,以提供高可用性和容错能力。

先前的挑战

在使用此功能之前,在多区域群集中使用区域持久性磁盘(例如AWS ElasticBlockStore,Azure磁盘,GCE PersistentDisk)运行有状态工作负载面临许多挑战。动态配置是独立于Pod调度处理的,这意味着一旦创建了PersistentVolumeClaim(PVC),就将自动配置卷。这意味着预配者不知道正在使用哪个容器的卷,以及它可能影响调度的任何容器约束。

这导致计划外的豆荚,因为在以下区域中配置了卷:

  • 没有足够的CPU或内存资源来运行Pod
  • 与节点选择器,pod相似性或反相似性策略冲突
  • 由于污点而无法运行吊舱

另一个常见的问题是,使用多个持久卷的非StatefulSet吊舱可能会将每个卷置备在不同的区域中,这又导致了不可调度的吊舱。

次优的解决方法包括节点的过度配置,或在正确区域中手动创建卷,这使得动态部署和扩展有状态工作负载变得困难。

拓扑感知的动态预配置功能解决了上述所有问题。

支持的卷类型

在1.12中,以下驱动程序支持可感知拓扑的动态预配置:

  • AWS EBS
  • Azure磁盘
  • GCE PD(包括区域PD)
  • CSI(alpha)-当前,只有GCE PD CSI驱动程序已实现拓扑支持

设计原则

虽然最初支持的插件都是基于区域的,但我们设计此功能时必须遵循Kubernetes跨环境可移植性原则。拓扑规范是通用的,并且使用类似的基于标签的规范,例如Pod nodeSelectors和nodeAffinity中的规范。该机制允许您定义自己的拓扑边界,例如本地群集中的机架,而无需修改调度程序以了解这些自定义拓扑。

此外,拓扑信息是从Pod规范中抽象出来的,因此Pod不需要了解底层存储系统的拓扑特征。这意味着您可以在多个集群,环境和存储系统上使用相同的Pod规范。

入门

To enable this feature, all you need to do is to create a StorageClass with volumeBindingMode set to WaitForFirstConsumer:

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: topology-aware-standard
provisioner: kubernetes.io/gce-pd
volumeBindingMode: WaitForFirstConsumer
parameters:
  type: pd-standard

This new setting instructs the volume provisioner to not create a volume immediately, and instead, wait for a pod using an associated PVC to run through scheduling. Note that previous StorageClass zone and zones parameters do not need to be specified anymore, as pod policies now drive the decision of which zone to provision a volume in.

接下来,使用此StorageClass创建一个容器和PVC。此顺序与之前相同,但在PVC中指定了不同的StorageClass。以下是一个假设示例,通过指定许多吊舱约束和调度策略来演示新功能的功能:

  • 吊舱中有多个PVC
  • 跨区域子集的nodeAffinity
  • 区域上的pod反亲和力
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:   
  serviceName: "nginx"
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: failure-domain.beta.kubernetes.io/zone
                operator: In
                values:
                - us-central1-a
                - us-central1-f
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - nginx
            topologyKey: failure-domain.beta.kubernetes.io/zone
      containers:
      - name: nginx
        image: gcr.io/google_containers/nginx-slim:0.8
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
        - name: logs
          mountPath: /logs
 volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: topology-aware-standard
      resources:
        requests:
          storage: 10Gi
  - metadata:
      name: logs
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: topology-aware-standard
      resources:
        requests:
          storage: 1Gi

之后,您可以看到根据窗格设置的策略在区域中配置了卷:

$ kubectl get pv -o=jsonpath='{range .items[*]}{.spec.claimRef.name}{"\t"}{.metadata.labels.failure\-domain\.beta\.kubernetes\.io/zone}{"\n"}{end}'
www-web-0       us-central1-f
logs-web-0      us-central1-f
www-web-1       us-central1-a
logs-web-1      us-central1-a

我该如何学习?

提供了有关拓扑感知的动态预配置功能的官方文档 这里

CSI驱动程序的文档可从以下网站获得: //kubernetes-csi.github.io/docs/

下一步是什么?

我们正在积极致力于改进此功能,以支持:

  • 更多卷类型,包括本地卷的动态配置
  • 每个节点的动态卷可连接数量和容量限制

我该如何参与?

如果您对此功能有反馈,或者有兴趣参与设计和开发,请加入 Kubernetes 存储特殊兴趣组 (SIG)。我们正在迅速发展,并随时欢迎新的贡献者。

特别感谢所有将此功能带入Beta版的贡献者,包括Cheng Xing( 真实的 ),李楚强( 李楚强 ),朱大卫( davidz627 ),深德布罗(( 德布罗伊 ),JanŠafránek( 沙弗拉恩 ),乔丹·利吉特( liggitt ),欧锦绣( msau42 ),倪鹏飞( 费斯基 ),萨阿德(( 萨阿里 ),蒂姆·霍金( ock )和叶成富( 科菲 )。