k8s-存储(pv/pvc)

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
简介: pv 介绍pvc 介绍存储基本组件PV 类型PV 卷阶段状态插件实现方法NFS 实现存储NFS 静态存储NFS-CSI 动态存储

Volumn和PV的关系



image.png


Volumn卷


属于 Pod 内部共享资源存储,生命周期和 Pod 相同,与 Container 无关,即使 Pod 上的容 器停止或者重启,Volume 不会受到影响,但是如果 Pod 终止,那么这个 Volume 的生命周 期也将结束。



存储的基本组件



在 k8s 中 对 于 存 储 的 资 源 抽 象 了 两 个 概 念 , 分 别 是 PersistentVolume(PV)和PersistentVolumeClaim(PVC)。


PV 是集群中的资源


PVC 是对这些资源的请求



PV 和 PVC 都只是抽象的概念,在 k8s 中是通过插件的方式提供具体的存储实现。

目前包含 有 NFS、ceph、iSCSI 和云提供商指定的存储系统



image.png


管理存储是管理计算的一个明显问题。


该 PersistentVolume 子系统为用户和管理员提供 了一个 API,用于抽象如何根据消费方式提供存储的详细信息。


为此,我们引入了两个新的 API 资源:PersistentVolume 和 PersistentVolumeClaim



PV/PVC/StorageClass


PersistentVolume(持久化卷):


是对底层的共享存储的一种抽象,PV 由管理员 进行创建和配置,它和具体的底层的共享存储技术的实现方式有关,比如 Ceph、GlusterFS、 NFS 等,都是通过插件机制完成与共享存储的对接



PersistentVolumeClaim(PVC):


是由用户进行存储的请求。 它类似于 pod。 Pod 消耗 节点资源,PVC 消耗 PV 资源。Pod 可以请求特定级别的资源(CPU 和内存)。声明可以请 求特定的大小和访问模式(例如,可以一次读/写或多次只读)。





StorageClass :


为管理员提供了一种描述他们提供的存储的“类”的方法。

不同的类可能映 射到服务质量级别,或备份策略,或者由群集管理员确定的任意策略。

Kubernetes 本身对于什么类别代表是不言而喻的。 这个概念有时在其他存储系统中称为“配置文件”。



PV 是运维人员来创建的,开发操作 PVC,可是大规模集群中可能会有很多 PV,如果这 些 PV 都需要运维手动来处理这也是一件很繁琐的事情,所以就有了动态供给概念.


也就是 Dynamic Provisioning,动态供给的关键就是 StorageClass,它的作用就是创建 PV 模板。


创 建 StorageClass 里面需要定义 PV 属性比如存储类型、大小等;另外创建这种 PV 需要用到 存储插件。最终效果是,用户提交PVC,里面指定存储类型,如果符合我们定义的StorageClass, 则会为其自动创建 PV 并进行绑定


PVC 和 PV 是一一对应



PV 和 PVC 中的 spec 关键字段要匹配,比如存储(storage)大小。


PV 和 PVC 中的 storageClassName 字段必须一致。




四个概念的关系


image.png




Kubernetes 中 存 储 中 有 四 个 重 要 的 概 念 : Volume 、 PersistentVolume ( PV )、 PersistentVolumeClaim(PVC)、StorageClass。




声明周期


PV 是群集中的资源。PVC 是对这些资源的请求,并且还充当对资源的检查。

PV 和 PVC 之间的相互作用遵循以下生命周期:


Provisioning ——-> Binding ——–>Using——>Releasing——>Recycling



供应准备 Provisioning


通过集群外的存储系统或者云平台来提供存储持久化支持



- 静态提供 Static:集群管理员创建多个 PV。 它们携带可供集群用户使用的真实存储的详 细信息。 它们存在于 Kubernetes API 中,可用于消费


- 动态提供 Dynamic:当管理员创建的静态 PV 都不匹配用户的 PersistentVolumeClaim 时, 集群可能会尝试为 PVC 动态配置卷。 此配置基于 StorageClasses:PVC 必须请求一个类, 并且管理员必须已创建并配置该类才能进行动态配置。 要求该类的声明有效地为自己禁用 动态配置。



绑定 Binding


用户创建 pvc 并指定需要的资源和访问模式。在找到可用 pv 之前,pvc 会 保持未绑定状态。



使用 Using


用户可在 pod 中像 volume 一样使用 pvc。




释放 Releasing


用户删除 pvc 来回收存储资源,pv 将变成“released”状态。由于还保留着 之前的数据,这些数据需要根据不同的策略来处理,否则这些存储资源无法被其他 pvc 使 用。



回收Recycling



pv可以设置三种回收策略:保留(Retain),回收(Recycle)和删除(Delete)。


  • 保留策略:允许人工处理保留的数据。
  • 删除策略:将删除 pv 和外部关联的存储资源,需要插件支持。
  • 回收策略:将执行清除操作,之后可以被新的 pvc 使用,需要插件支持。 注:目前只有 NFS 和 HostPath 类型卷支持回收策略,AWS EBS,GCE PD,Azure Disk 和 Cinder 支持删除(Delete)策略



PV 类型


  • GCEPersistentDisk
  • AWSElasticBlockStore
  • AzureFile AzureDisk
  • FC (Fibre Channel)
  • Flexvolume
  • NFS
  • iSCSI
  • RBD (Ceph Block Device)
  • CephFS
  • Cinder (OpenStack block storage)
  • Glusterfs
  • VsphereVolume
  • Quobyte Volumes
  • StorageOS


PV 卷阶段状态


  • Available – 资源尚未被 claim 使用
  • Bound – 卷已经被绑定到 claim 了
  • Released – claim 被删除,卷处于释放状态,但未被集群回收。
  • Failed – 卷自动回收失败




k8s存储架构图



image.png


Kubernetes 卷插件实现方法



In Tree


Kubernetes 卷插件目前是“in-tree”,意味着它们与核心 kubernetes 二进制文件链接,编译, 构建和一起发布。


有不利于核心代码的发布,增加了工作量,并且卷插件的权限太高等缺点 需要将后端存储的代码逻辑放到 K8S 的代码中运行。逻辑代码可能会引起与 K8S 其他部件 之间的相互影响




image.png




Out-of-tree Provisioner-FlexVolume


现有的 Flex Volume 插件需要访问节点和主机的根文件系统才能部署第三方驱动程序文件, 并且对主机的依赖性强.


调用一个主机的可执行程序包的方式执行存储卷的挂载使用。


解决了 In-Tree 方式的强耦合, 不过命令行调用的方式,在主机安全性、部署依赖的容器化、与 K8S 服务之间的相互扩展性 等方面存在不足Flexvolume 运行在 host 空间,不能使用 rbac授权机制访问Kubernetes API, 导致其功能极大的受限 Storage providers support this type and develop Driver




image.png







Out-of-tree Provisioner -CSI


容器存储接口(CSI)是由来自各个 CO 的社区成员(包括 Kubernetes,Mesos,Cloud Foundry 和 Docker)之间的合作产生的规范。


此接口的目标是为 CO 建立标准化机制,以将任意存 储系统暴露给其容器化工作负载。


CSI 标准使 K8S 和存储提供者之间将彻底解耦,将存储的所有的部件作为容器形式运行在 K8S 上。 CO Container Orchestrer Storage providers support this type and develop Driver





image.png


NFS实现存储


创建一个 NFS 服务器作为 K8s 的存储系统, nfs 默认不支持动态存储。


使用了第三方的 NFS 插件 实现 flexvolume and CSI 方式使用存 储。



image.png




NFS服务建立



  1. 安装nfs-server
yum install nfs-utils rpcbind -y
systemctl enable rpcbind nfs-server
systemctl start rpcbind nfs-server
systemctl status rpcbind nfs-server



  1. 创建共享目录
mkdir /nfs-server


  1. 配置共享目录
vi /etc/exports  # 编辑或创建/etc/exports文件
/nfs-server *(rw,sync,no_root_squash   # 配置nfs-server

image.png


  1. 对/etc/exports 增加或修改的部分进行挂载和卸载
exportfs -a

注意: exportfs 命令,参考 https://wker.com/linux-command/exportfs.html



Client 安装NFS服务


Note: 在每一个节点都需要安装NFS服务



yum install nfs-utils rpcbind -y
systemctl enable rpcbind nfs-server
systemctl start rpcbind nfs-server
systemctl status rpcbind nfs-server



测试共享卷是否可用


showmount -e 192.168.56.5   # nfs server 的ip
mount -t nfs 192.168.56.5:/nfs-server /home   # bind 共享卷
umount /home   # unbind 共享卷



NFS共享存储实践



静态供应



  1. 创建PV


pv1.yaml


apiVersion: v1
kind: PersistentVolume
metadata:
 name: pv0001
spec:
 capacity:
  storage: 5Gi
 accessModes:
  - ReadWriteMany
 persistentVolumeReclaimPolicy: Recycle
 nfs:
   path: "/nfs-server"
   server: 192.168.10.201


  1. 创建PVC


pvc1.yaml


apiVersion: v1
kind: PersistentVolumeClaim
metadata:
 name: nfs-pvc
spec:
 accessModes:
 - ReadWriteMany
 resources:
  requests:
   storage: 1Gi


  1. 创建Pod


pod1.yaml


kind: Pod
apiVersion: v1
metadata:
 name: nfs-test
spec:
 containers:
  - name: my-busybox
    image: busybox
    volumeMounts:
    - mountPath: "/data"
      name: sample-volume
    command: ["sleep", "1000000"]
    imagePullPolicy: IfNotPresent
 volumes:
  - name: sample-volume
    persistentVolumeClaim:
      claimName: nfs-pvc


  1. 测试


进入 pod容器中,在/data目录创建一个test.txt文件


image.png


查看nfs-server 是否包含共享了test.txt文件


image.png




NFS CSI类型动态供应




NFS CSI Driver 是 K8s 官方提供的 CSI 示例程序,只实现了 CSI 的最简功能 Controller 由 CSI Plugin+csi-provisioner+livenessprobe 组成 node-server 由 CSI Plugin+liveness-probe+node-driver-registrar 组成



安装CSI组件


rbac-csi.yaml 文件配置

---apiVersion: v1
kind: ServiceAccount
metadata:  name: csi-nfs-controller-sa
  namespace: kube-system
---kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:  name: nfs-external-provisioner-role
rules:  - apiGroups: [""]    resources: ["persistentvolumes"]    verbs: ["get","list","watch","create","delete"]  - apiGroups: [""]    resources: ["persistentvolumeclaims"]    verbs: ["get","list","watch","update"]  - apiGroups: ["storage.k8s.io"]    resources: ["storageclasses"]    verbs: ["get","list","watch"]  - apiGroups: [""]    resources: ["events"]    verbs: ["get","list","watch","create","update","patch"]  - apiGroups: ["storage.k8s.io"]    resources: ["csinodes"]    verbs: ["get","list","watch"]  - apiGroups: [""]    resources: ["nodes"]    verbs: ["get","list","watch"]  - apiGroups: ["coordination.k8s.io"]    resources: ["leases"]    verbs: ["get","list","watch","create","update","patch"]  - apiGroups: [""]    resources: ["secrets"]    verbs: ["get"]---kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:  name: nfs-csi-provisioner-binding
subjects:  - kind: ServiceAccount
    name: csi-nfs-controller-sa
    namespace: kube-system
roleRef:  kind: ClusterRole
  name: nfs-external-provisioner-role
  apiGroup: rbac.authorization.k8s.io


csi-nfs-driverinfo.yaml 文件配置

---apiVersion: storage.k8s.io/v1
kind: CSIDriver
metadata:  name: nfs.csi.k8s.io
spec:  attachRequired: false  volumeLifecycleModes:    - Persistent
    - Ephemeral




csi-nfs-node.yaml 文件配置



---# This YAML file contains driver-registrar & csi driver nodeplugin API objects# that are necessary to run CSI nodeplugin for nfskind: DaemonSet
apiVersion: apps/v1
metadata:  name: csi-nfs-node
  namespace: kube-system
spec:  updateStrategy:    rollingUpdate:      maxUnavailable: 1    type: RollingUpdate
  selector:    matchLabels:      app: csi-nfs-node
  template:    metadata:      labels:        app: csi-nfs-node
    spec:      hostNetwork: true  # original nfs connection would be broken without hostNetwork setting      dnsPolicy: ClusterFirstWithHostNet
      nodeSelector:        kubernetes.io/os: linux
      tolerations:        - operator: "Exists"      containers:        - name: liveness-probe
          image: registry.cn-hangzhou.aliyuncs.com/liuyik8s/livenessprobe:v2.5.0
          args:            - --csi-address=/csi/csi.sock
            - --probe-timeout=3s
            - --health-port=29653
            - --v=2
          volumeMounts:            - name: socket-dir
              mountPath: /csi
          resources:            limits:              memory: 100Mi
            requests:              cpu: 10m
              memory: 20Mi
        - name: node-driver-registrar
          image: registry.cn-hangzhou.aliyuncs.com/liuyik8s/csi-node-driver-registrar:v2.4.0
          args:            - --v=2
            - --csi-address=/csi/csi.sock
            - --kubelet-registration-path=$(DRIVER_REG_SOCK_PATH)
          livenessProbe:            exec:              command:                - /csi-node-driver-registrar
                - --kubelet-registration-path=$(DRIVER_REG_SOCK_PATH)
                - --mode=kubelet-registration-probe
            initialDelaySeconds: 30            timeoutSeconds: 15          env:            - name: DRIVER_REG_SOCK_PATH
              value: /var/lib/kubelet/plugins/csi-nfsplugin/csi.sock
            - name: KUBE_NODE_NAME
              valueFrom:                fieldRef:                  fieldPath: spec.nodeName
          volumeMounts:            - name: socket-dir
              mountPath: /csi
            - name: registration-dir
              mountPath: /registration
          resources:            limits:              memory: 100Mi
            requests:              cpu: 10m
              memory: 20Mi
        - name: nfs
          securityContext:            privileged: true            capabilities:              add: ["SYS_ADMIN"]            allowPrivilegeEscalation: true          image: mcr.microsoft.com/k8s/csi/nfs-csi:v3.1.0
          args:            - "-v=5"            - "--nodeid=$(NODE_ID)"            - "--endpoint=$(CSI_ENDPOINT)"          env:            - name: NODE_ID
              valueFrom:                fieldRef:                  fieldPath: spec.nodeName
            - name: CSI_ENDPOINT
              value: unix:///csi/csi.sock
          ports:            - containerPort: 29653              name: healthz
              protocol: TCP
          livenessProbe:            failureThreshold: 5            httpGet:              path: /healthz
              port: healthz
            initialDelaySeconds: 30            timeoutSeconds: 10            periodSeconds: 30          imagePullPolicy: "IfNotPresent"          volumeMounts:            - name: socket-dir
              mountPath: /csi
            - name: pods-mount-dir
              mountPath: /var/lib/kubelet/pods
              mountPropagation: "Bidirectional"          resources:            limits:              memory: 300Mi
            requests:              cpu: 10m
              memory: 20Mi
      volumes:        - name: socket-dir
          hostPath:            path: /var/lib/kubelet/plugins/csi-nfsplugin
            type: DirectoryOrCreate
        - name: pods-mount-dir
          hostPath:            path: /var/lib/kubelet/pods
            type: Directory
        - hostPath:            path: /var/lib/kubelet/plugins_registry
            type: Directory
          name: registration-dir


csi-nfs-controller.yaml 文件配置


---kind: Deployment
apiVersion: apps/v1
metadata:  name: csi-nfs-controller
  namespace: kube-system
spec:  replicas: 2  selector:    matchLabels:      app: csi-nfs-controller
  template:    metadata:      labels:        app: csi-nfs-controller
    spec:      hostNetwork: true  # controller also needs to mount nfs to create dir      dnsPolicy: ClusterFirstWithHostNet
      serviceAccountName: csi-nfs-controller-sa
      nodeSelector:        kubernetes.io/os: linux  # add "kubernetes.io/role: master" to run controller on master node      priorityClassName: system-cluster-critical
      tolerations:        - key: "node-role.kubernetes.io/master"          operator: "Exists"          effect: "NoSchedule"        - key: "node-role.kubernetes.io/controlplane"          operator: "Exists"          effect: "NoSchedule"      containers:        - name: csi-provisioner
          image: registry.cn-hangzhou.aliyuncs.com/liuyik8s/csi-provisioner:v2.2.2
          args:            - "-v=2"            - "--csi-address=$(ADDRESS)"            - "--leader-election"          env:            - name: ADDRESS
              value: /csi/csi.sock
          volumeMounts:            - mountPath: /csi
              name: socket-dir
          resources:            limits:              memory: 400Mi
            requests:              cpu: 10m
              memory: 20Mi
        - name: liveness-probe
          image: registry.cn-hangzhou.aliyuncs.com/liuyik8s/livenessprobe:v2.5.0
          args:            - --csi-address=/csi/csi.sock
            - --probe-timeout=3s
            - --health-port=29652
            - --v=2
          volumeMounts:            - name: socket-dir
              mountPath: /csi
          resources:            limits:              memory: 100Mi
            requests:              cpu: 10m
              memory: 20Mi
        - name: nfs
          image: mcr.microsoft.com/k8s/csi/nfs-csi:v3.1.0
          securityContext:            privileged: true            capabilities:              add: ["SYS_ADMIN"]            allowPrivilegeEscalation: true          imagePullPolicy: IfNotPresent
          args:            - "-v=5"            - "--nodeid=$(NODE_ID)"            - "--endpoint=$(CSI_ENDPOINT)"          env:            - name: NODE_ID
              valueFrom:                fieldRef:                  fieldPath: spec.nodeName
            - name: CSI_ENDPOINT
              value: unix:///csi/csi.sock
          ports:            - containerPort: 29652              name: healthz
              protocol: TCP
          livenessProbe:            failureThreshold: 5            httpGet:              path: /healthz
              port: healthz
            initialDelaySeconds: 30            timeoutSeconds: 10            periodSeconds: 30          volumeMounts:            - name: pods-mount-dir
              mountPath: /var/lib/kubelet/pods
              mountPropagation: "Bidirectional"            - mountPath: /csi
              name: socket-dir
          resources:            limits:              memory: 200Mi
            requests:              cpu: 10m
              memory: 20Mi
      volumes:        - name: pods-mount-dir
          hostPath:            path: /var/lib/kubelet/pods
            type: Directory
        - name: socket-dir
          emptyDir: {}


storageclass-nfs.yaml 文件配置


---apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:  name: nfs-csi
provisioner: nfs.csi.k8s.io
parameters:  server: 192.168.56.5  #修改为自己的nfs的服务器地址  share: /nfs-server  #修改为nfs的目录reclaimPolicy: Retain  # only retain is supported,目前这个回收策略只支持RetainvolumeBindingMode: Immediate
mountOptions:  - hard
  - nfsvers=4.1



安装CSI


kubectl apply -f rbac-csi.yaml
kubectl apply -f csi-nfs-driverinfo.yaml
kubectl apply -f csi-nfs-node.yaml
kubectl apply -f csi-nfs-controller.yaml
kubectl apply -f storageclass-nfs.yaml



官网连接更新参考:

https://artifacthub.io/packages/helm/keyporttech/csi-driver-nfs/0.1.4https://github.com/kubernetes-csi/csi-driver-nfs/blob/master/deploy/example/README.md



CSI动态供应存储创建 PVC/POD


Deployment 无状态使用



pod-pvc-csi.yaml 文件配置

apiVersion: v1
kind: PersistentVolumeClaim
metadata:   name: nfs2
#   annotations:#    hitachi.io/note: "pvc-sample"spec:   accessModes:   - ReadWriteOnce
   resources:      requests:         storage: 5Gi
   storageClassName: nfs-csi      # 指定className,动态创建pv---kind: Pod
apiVersion: v1
metadata:  name: nfs-test-csi
spec:  containers:    - name: my-busybox
      image: busybox
      volumeMounts:      - mountPath: "/data"        name: sample-volume
      command: ["sleep","1000000"]      imagePullPolicy: IfNotPresent
  volumes:    - name: sample-volume
      persistentVolumeClaim:        claimName: nfs2


安装 pod-pvc-csi.yaml


kubectl apply -f pod-pvc-csi.yaml



image.png



查看pvc


image.png



查看storageClassName



image.png




测试


进入 nfs-test-csi 容器中,创建 test-csi.txt

image.png


查看nfs-server的共享卷


image.png



Statefulset 有状态使用


apiVersion: v1
kind: Service
metadata:  name: nginx
  labels:    app: nginx
spec:  ports:  - port: 80    name: web
  clusterIP: None
  selector:    app: nginx
---apiVersion: apps/v1
kind: StatefulSet
metadata:  name: web
spec:  serviceName: "nginx"  replicas: 3  selector:    matchLabels:      app: nginx
  volumeClaimTemplates:  - metadata:      name: test
      annotations:        volume.beta.kubernetes.io/storage-class: "nfs-csi"    spec:      accessModes: ["ReadWriteOnce"]      resources:        requests:          storage: 2Gi
#----  template:    metadata:      labels:        app: nginx
    spec:      containers:      - name: nginx
        image: nginx:1.9        ports:        - containerPort: 80          name: web
        volumeMounts:        - name: test
          readOnly: false          mountPath: "/usr/share/nginx/html"






相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
3月前
|
JSON Kubernetes Shell
【Azure K8S | AKS】在不丢失文件/不影响POD运行的情况下增加PVC的大小
【Azure K8S | AKS】在不丢失文件/不影响POD运行的情况下增加PVC的大小
|
3月前
|
Kubernetes Shell Perl
【Azure K8S|AKS】进入AKS的POD中查看文件,例如PVC Volume Mounts使用情况
【Azure K8S|AKS】进入AKS的POD中查看文件,例如PVC Volume Mounts使用情况
|
3月前
|
存储 Kubernetes 容器
Kubernetes 存储选项:持久化卷与存储类
【8月更文第29天】随着容器化的普及,越来越多的应用程序需要持久化数据以保持状态信息。Kubernetes 提供了一套完整的解决方案来管理和配置持久化存储,包括持久卷 (Persistent Volume, PV)、持久卷声明 (Persistent Volume Claim, PVC) 和存储类 (StorageClass)。本文将详细介绍这些概念,并通过实际示例来演示如何在 Kubernetes 中配置存储。
299 1
|
3月前
|
存储 Kubernetes Go
【Azure K8S | AKS】在AKS集群中创建 PVC(PersistentVolumeClaim)和 PV(PersistentVolume) 示例
【Azure K8S | AKS】在AKS集群中创建 PVC(PersistentVolumeClaim)和 PV(PersistentVolume) 示例
|
2月前
|
存储 Kubernetes 测试技术
k8s使用pvc,pv,sc关联ceph集群
文章介绍了如何在Kubernetes中使用PersistentVolumeClaim (PVC)、PersistentVolume (PV) 和StorageClass (SC) 来关联Ceph集群,包括创建Ceph镜像、配置访问密钥、删除默认存储类、编写和应用资源清单、创建资源以及进行访问测试的步骤。同时,还提供了如何使用RBD动态存储类来关联Ceph集群的指南。
151 7
|
3月前
|
存储 Kubernetes 容器
k8s创建NFS动态存储
k8s创建NFS动态存储
|
3月前
|
存储 Kubernetes 容器
在K8S中,PV的生命周期状态有哪些?
在K8S中,PV的生命周期状态有哪些?
|
3月前
|
存储 Kubernetes 调度
在K8S中,什么是PV和PVC?
在K8S中,什么是PV和PVC?
|
6天前
|
Kubernetes 监控 Cloud Native
Kubernetes集群的高可用性与伸缩性实践
Kubernetes集群的高可用性与伸缩性实践
27 1
|
27天前
|
JSON Kubernetes 容灾
ACK One应用分发上线:高效管理多集群应用
ACK One应用分发上线,主要介绍了新能力的使用场景