阿里云K8S服务支持CSI存储卷

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 目前阿里云CSI存储插件支持云盘、OSS、NAS等存储类型,并支持通过StorageClass创建动态存储卷; 开源地址:https://github.com/AliyunContainerService/csi-plugin

CSI插件简介

CSI是Container Storage Interface的简称,为容器编排系统和存储系统之间建立一套标准的存储调用接口。

Kubernetes支持CSI接口标准,并在1.10版本进入beta阶段。K8S除了支持CSI方式提供存储接口外,还有In-Tree方式、Flexvolume方式提供的各种存储接口。

In-Tree方式是嵌入在K8S源码内部的存储挂载实现,存在以下问题:

存储插件需要一同随K8S发布。
存储插件的问题有可能会影响K8S部件正常运行。
存储插件享有K8S部件同等的特权存在安全隐患。
存储插件开发者必须遵循K8S社区的规则开发代码。

FlexVolume机制通过调用一个可执行文件方式去实现挂载,它能够做到让存储提供方进行独立开发维护。

部署可执行文件时,需要host的root权限,依然存在安全隐患。
存储插件在执行mount、attach操作时,往往需要到host去安装第三方工具或加载依赖库,这样会使部署变得复杂。

CSI标准的出现解决了上述问题,后续K8S与存储系统的集成标准将全面支持CSI。

阿里云存储支持CSI Plugin

目前阿里云CSI存储插件支持云盘、OSS、NAS等存储类型,并支持通过StorageClass创建动态存储卷;

开源地址:https://github.com/AliyunContainerService/csi-plugin

插件的部署拓扑如下:
csi-disk.png

使用演示

云盘CSI Plugin部署

环境准备

  1. 通过阿里云容器服务[创建K8S集群](1.10版本及以上),或者自己通过阿里云ECS服务器搭建K8S集群。
  2. 配置Kubelet启动参数:--enable-controller-attach-detach=true;

部署 CSI Attacher

# kubectl create -f attacher.yaml

CSI attacher使用0.2.0版本,attacher.yaml内容如下:

# This YAML file contains RBAC API objects,
# which are necessary to run external csi attacher for cinder.

apiVersion: v1
kind: ServiceAccount
metadata:
  name: csi-attacher

---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: external-attacher-runner
rules:
  - apiGroups: [""]
    resources: ["events"]
    verbs: ["get", "list", "watch", "update"]
  - apiGroups: [""]
    resources: ["persistentvolumes"]
    verbs: ["get", "list", "watch", "update"]
  - apiGroups: [""]
    resources: ["nodes"]
    verbs: ["get", "list", "watch"]
  - apiGroups: ["storage.k8s.io"]
    resources: ["volumeattachments"]
    verbs: ["get", "list", "watch", "update"]

---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: csi-attacher-role
subjects:
  - kind: ServiceAccount
    name: csi-attacher
    namespace: default
roleRef:
  kind: ClusterRole
  name: external-attacher-runner
  apiGroup: rbac.authorization.k8s.io
---

kind: Service
apiVersion: v1
metadata:
  name: csi-attacher
  labels:
    app: csi-attacher
spec:
  selector:
    app: csi-attacher
  ports:
    - name: dummy
      port: 12345

---
kind: StatefulSet
apiVersion: apps/v1beta1
metadata:
  name: csi-attacher
spec:
  serviceName: "csi-attacher"
  replicas: 1
  template:
    metadata:
      labels:
        app: csi-attacher
    spec:
      tolerations:
      - effect: NoSchedule
        operator: Exists
        key: node-role.kubernetes.io/master
      - effect: NoSchedule
        operator: Exists
        key: node.cloudprovider.kubernetes.io/uninitialized
      nodeSelector:
         node-role.kubernetes.io/master: ""
      serviceAccount: csi-attacher
      containers:
        - name: csi-attacher
          image: registry.cn-hangzhou.aliyuncs.com/plugins/csi-attacher:v0.2.0
          args:
            - "--v=5"
            - "--csi-address=$(ADDRESS)"
          env:
            - name: ADDRESS
              value: /var/lib/kubelet/plugins/csi-diskplugin/csi.sock
          imagePullPolicy: "IfNotPresent"
          volumeMounts:
            - name: socket-dir
              mountPath: /var/lib/kubelet/plugins/csi-diskplugin
      volumes:
        - name: socket-dir
          hostPath:
            path: /var/lib/kubelet/plugins/csi-diskplugin
            type: DirectoryOrCreate

部署CSI Provsioner

# kubectl create -f provisioner.yaml

CSI provisioner使用0.2.0版本,内容如下:

apiVersion: v1
kind: ServiceAccount
metadata:
  name: csi-provisioner

---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: external-provisioner-runner
rules:
  - apiGroups: [""]
    resources: ["secrets"]
    verbs: ["get", "list"]
  - 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: ["list", "watch", "create", "update", "patch"]

---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: csi-provisioner-role
subjects:
  - kind: ServiceAccount
    name: csi-provisioner
    namespace: default
roleRef:
  kind: ClusterRole
  name: external-provisioner-runner
  apiGroup: rbac.authorization.k8s.io

---
kind: Service
apiVersion: v1
metadata:
  name: csi-provisioner
  labels:
    app: csi-provisioner
spec:
  selector:
    app: csi-provisioner
  ports:
    - name: dummy
      port: 12345

---
kind: StatefulSet
apiVersion: apps/v1beta1
metadata:
  name: csi-provisioner
spec:
  serviceName: "csi-provisioner"
  replicas: 1
  template:
    metadata:
      labels:
        app: csi-provisioner
    spec:
      tolerations:
      - effect: NoSchedule
        operator: Exists
        key: node-role.kubernetes.io/master
      - effect: NoSchedule
        operator: Exists
        key: node.cloudprovider.kubernetes.io/uninitialized
      nodeSelector:
         node-role.kubernetes.io/master: ""
      serviceAccount: csi-provisioner
      containers:
        - name: csi-provisioner
          image: registry.cn-hangzhou.aliyuncs.com/plugins/csi-provisioner:v0.2.0
          args:
            - "--provisioner=csi-diskplugin"
            - "--csi-address=$(ADDRESS)"
            - "--v=5"
          env:
            - name: ADDRESS
              value: /var/lib/kubelet/plugins/csi-diskplugin/csi.sock
          imagePullPolicy: "IfNotPresent"
          volumeMounts:
            - name: socket-dir
              mountPath: /var/lib/kubelet/plugins/csi-diskplugin
      volumes:
        - name: socket-dir
          hostPath:
            path: /var/lib/kubelet/plugins/csi-diskplugin
            type: DirectoryOrCreate

部署Disk Plugin

Disk Plugin部署为DaemonSet应用,命令:

# kubectl create -f plugin.yaml

CSI driver-registrar使用0.2.0版本;

Socket地址设置为:/var/lib/kubelet/plugins/csi-diskplugin/csi.sock;

apiVersion: v1
kind: ServiceAccount
metadata:
  name: csi-diskplugin

---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: csi-diskplugin
rules:
  - apiGroups: [""]
    resources: ["nodes"]
    verbs: ["get", "list", "update"]
  - apiGroups: [""]
    resources: ["namespaces"]
    verbs: ["get", "list"]
  - apiGroups: [""]
    resources: ["persistentvolumes"]
    verbs: ["get", "list", "watch", "update"]
  - apiGroups: ["storage.k8s.io"]
    resources: ["volumeattachments"]
    verbs: ["get", "list", "watch", "update"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: csi-diskplugin
subjects:
  - kind: ServiceAccount
    name: csi-diskplugin
    namespace: default
roleRef:
  kind: ClusterRole
  name: csi-diskplugin
  apiGroup: rbac.authorization.k8s.io

---
# This YAML file contains driver-registrar & csi driver nodeplugin API objects,
# which are necessary to run csi nodeplugin for disk.

kind: DaemonSet
apiVersion: apps/v1beta2
metadata:
  name: csi-diskplugin
spec:
  selector:
    matchLabels:
      app: csi-diskplugin
  template:
    metadata:
      labels:
        app: csi-diskplugin
    spec:
      tolerations:
        - key: node-role.kubernetes.io/master
          operator: Exists
          effect: NoSchedule
      serviceAccount: csi-diskplugin
      hostNetwork: true
      hostPID: true
      containers:
        - name: driver-registrar
          image: registry.cn-hangzhou.aliyuncs.com/plugins/driver-registrar:v0.2.0
          args:
            - "--v=5"
            - "--csi-address=$(ADDRESS)"
          env:
            - name: ADDRESS
              value: /var/lib/kubelet/plugins/csi-diskplugin/csi.sock
            - name: KUBE_NODE_NAME
              valueFrom:
                fieldRef:
                  fieldPath: spec.nodeName
          volumeMounts:
            - name: socket-dir
              mountPath: /var/lib/kubelet/plugins/csi-diskplugin
        - name: csi-diskplugin
          securityContext:
            privileged: true
            capabilities:
              add: ["SYS_ADMIN"]
            allowPrivilegeEscalation: true
          image: registry.cn-hangzhou.aliyuncs.com/plugins/csi-diskplugin:v1.10-7424d08
          args :
            - "--nodeid=$(NODE_ID)"
            - "--endpoint=$(CSI_ENDPOINT)"
            - "--v=5"
          env:
            - name: NODE_ID
              valueFrom:
                fieldRef:
                  fieldPath: spec.nodeName
            - name: CSI_ENDPOINT
              value: unix://var/lib/kubelet/plugins/csi-diskplugin/csi.sock
          imagePullPolicy: "IfNotPresent"
          volumeMounts:
            - name: plugin-dir
              mountPath: /var/lib/kubelet/plugins/csi-diskplugin
            - name: pods-mount-dir
              mountPath: /var/lib/kubelet/pods
              mountPropagation: "Bidirectional"
            - mountPath: /dev
              name: host-dev
            - mountPath: /sys
              name: host-sys
            - mountPath: /lib/modules
              name: lib-modules
              readOnly: true
            - mountPath: /run/dbus
              name: host-run
              readOnly: true
            - mountPath: /var/log/alicloud
              name: host-log
      volumes:
        - name: plugin-dir
          hostPath:
            path: /var/lib/kubelet/plugins/csi-diskplugin
            type: DirectoryOrCreate
        - name: pods-mount-dir
          hostPath:
            path: /var/lib/kubelet/pods
            type: Directory
        - name: socket-dir
          hostPath:
            path: /var/lib/kubelet/plugins/csi-diskplugin
            type: DirectoryOrCreate
        - name: host-dev
          hostPath:
            path: /dev
        - name: host-run
          hostPath:
            path: /run/dbus
        - name: host-sys
          hostPath:
            path: /sys
        - name: lib-modules
          hostPath:
            path: /lib/modules
        - name: host-log
          hostPath:
            path: /var/log/alicloud/

部署检查

# kubectl get pod
NAME                                 READY     STATUS    RESTARTS   AGE
csi-attacher-0                       1/1       Running   0          1d
csi-diskplugin-5w7wz                 2/2       Running   0          1d
csi-diskplugin-j99h9                 2/2       Running   0          1d
csi-diskplugin-ljg9s                 2/2       Running   0          1d
csi-diskplugin-nhbfp                 2/2       Running   0          1d
csi-provisioner-0                    1/1       Running   0          1d

使用CSI插件挂载云盘

下面以创建动态云盘数据卷为例,介绍如何使用CSI插件挂载;

创建云盘StorageClass

定义一个SSD、ReadWrite、北京B区的StorageClass;

# kubectl create -f storageclass.yaml

storageclass.yaml内容如下:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
   name: csi-disk
provisioner: csi-diskplugin
parameters:
    zoneId: cn-beijing-b
    regionId: cn-beijing
    fsType: ext4
    type: cloud_ssd
    readOnly: "false"
reclaimPolicy: Delete

创建应用

创建Nginx服务并通过PVC挂载云盘,在PVC配置csi-disk storageClassName;

# kubectl create -f nginx.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: disk-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 25Gi
  storageClassName: csi-disk
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment1
  labels:
    app: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80
        volumeMounts:
          - name: disk-pvc
            mountPath: "/data"
      volumes:
        - name: disk-pvc
          persistentVolumeClaim:
            claimName: disk-pvc

云盘挂载验证

查看nginx容器:

# kubectl get pod | grep nginx
# nginx-deployment1-5879d9db88-wr9j9   1/1       Running   0          1d

查看容器内挂载信息:

# kubectl exec -ti nginx-deployment1-5879d9db88-wr9j9 df | grep data
/dev/vdd        25671908   45084  24299720   1% /data
# kubectl exec -ti nginx-deployment1-5879d9db88-wr9j9 touch /data/aliyun
# kubectl exec -ti nginx-deployment1-5879d9db88-wr9j9 ls /data
aliyun    lost+found

删除容器,验证云盘高可用:

# kubectl delete pod nginx-deployment1-5879d9db88-wr9j9
# kubectl get pod
NAME                                 READY     STATUS    RESTARTS   AGE
nginx-deployment1-5879d9db88-mjb5p   1/1       Running   0          14s
# kubectl exec -ti nginx-deployment1-5879d9db88-mjb5p ls /data
aliyun    lost+found

上述操作通过CSI插件成功挂载阿里云云盘,并验证了应用数据的高可用性;

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
目录
相关文章
|
11天前
|
人工智能 运维 监控
阿里云ACK容器服务生产级可观测体系建设实践
本文整理自2024云栖大会冯诗淳(花名:行疾)的演讲,介绍了阿里云容器服务团队在生产级可观测体系建设方面的实践。冯诗淳详细阐述了容器化架构带来的挑战及解决方案,强调了可观测性对于构建稳健运维体系的重要性。文中提到,阿里云作为亚洲唯一蝉联全球领导者的容器管理平台,其可观测能力在多项关键评测中表现优异,支持AI、容器网络、存储等多个场景的高级容器可观测能力。此外,还介绍了阿里云容器服务在多云管理、成本优化等方面的最新进展,以及即将推出的ACK AI助手2.0,旨在通过智能引擎和专家诊断经验,简化异常数据查找,缩短故障响应时间。
阿里云ACK容器服务生产级可观测体系建设实践
|
11天前
|
运维 Kubernetes 调度
阿里云容器服务 ACK One 分布式云容器企业落地实践
阿里云容器服务ACK提供强大的产品能力,支持弹性、调度、可观测、成本治理和安全合规。针对拥有IDC或三方资源的企业,ACK One分布式云容器平台能够有效解决资源管理、多云多集群管理及边缘计算等挑战,实现云上云下统一管理,提升业务效率与稳定性。
|
11天前
|
Kubernetes 算法 调度
阿里云 ACK FinOps成本优化最佳实践
本文源自2024云栖大会梁成昊演讲,讨论了成本优化策略的选择与实施。文章首先介绍了成本优化的基本思路,包括优化购买方式、调整资源配置等基础策略,以及使用弹性、资源混部等高级策略。接着,文章详细探讨了集群优化和应用优化的具体方法,如使用抢占式实例降低成本、通过资源画像识别并优化资源配置,以及利用智能应用弹性策略提高资源利用效率。
|
11天前
|
弹性计算 调度 数据中心
阿里云 ACK One 注册集群云上弹性:扩展业务新利器
随着企业数字化转型深入,传统IDC数据中心因物理容量限制,难以实现动态扩容,缺乏弹性能力。阿里云ACK One注册集群凭借其高度灵活性和丰富资源选择,成为解决此问题的最佳方案。通过与阿里云资源的整合,ACK One不仅实现了计算资源的按需扩展,提高了资源利用率,还通过按需付费模式降低了成本,使企业能够更高效地应对业务增长和高峰需求。
|
11天前
|
运维 Kubernetes Serverless
阿里云Argo X K8s玩转工作流引擎,实现大规模并行计算
本文基于2024云栖大会田双坤的演讲,介绍了Kubernetes作为云原生操作系统的角色及其在各类任务中的应用,重点探讨了Argo Workflows在Kubernetes上编排并行任务的能力。面对自建Argo Workflows的挑战,如稳定性、成本和安全性等问题,阿里巴巴云推出了全托管的Serverless Argo工作流,提供全托管、免运维、可观测和易集成的特点,显著提升了任务编排的效率和稳定性。适用于数据处理、科学计算、自动驾驶仿真等多个领域。
|
11天前
|
Kubernetes 容灾 调度
阿里云 ACK 高可用稳定性最佳实践
本文整理自2024云栖大会刘佳旭的演讲,主题为《ACK高可用稳定性最佳实践》。文章探讨了云原生高可用架构的重要性,通过Kubernetes的高可用案例分析,介绍了ACK在单集群高可用架构设计、产品能力和最佳实践方面的方法,包括控制面和数据面的高可用策略、工作负载高可用配置、企业版容器镜像服务高可用配置等内容,旨在帮助企业构建更加可靠和高效的应用运行环境。
|
11天前
|
存储 Kubernetes 关系型数据库
阿里云ACK备份中心,K8s集群业务应用数据的一站式灾备方案
本文源自2024云栖大会苏雅诗的演讲,探讨了K8s集群业务为何需要灾备及其重要性。文中强调了集群与业务高可用配置对稳定性的重要性,并指出人为误操作等风险,建议实施周期性和特定情况下的灾备措施。针对容器化业务,提出了灾备的新特性与需求,包括工作负载为核心、云资源信息的备份,以及有状态应用的数据保护。介绍了ACK推出的备份中心解决方案,支持命名空间、标签、资源类型等维度的备份,并具备存储卷数据保护功能,能够满足GitOps流程企业的特定需求。此外,还详细描述了备份中心的使用流程、控制台展示、灾备难点及解决方案等内容,展示了备份中心如何有效应对K8s集群资源和存储卷数据的灾备挑战。
|
容器 Kubernetes Perl
阿里云Kubernetes平台构建和管理实践(上)
阿里云智能容器平台解决方案架构师徐征讲解阿里云Kubernetes平台构建和管理实践,徐征主要从事帮助企业在面向云原生的应用转型的过程中提供解决方案和相应的工作。
10908 0
|
容器 Perl 监控
阿里云Kubernetes平台构建和管理实践(下)
阿里云智能容器平台解决方案架构师徐征讲解阿里云Kubernetes平台构建和管理实践,徐征主要从事帮助企业在面向云原生的应用转型的过程中提供解决方案和相应的工作。
3291 0
|
1月前
|
Kubernetes 监控 Cloud Native
Kubernetes集群的高可用性与伸缩性实践
Kubernetes集群的高可用性与伸缩性实践
71 1

相关产品

  • 容器服务Kubernetes版
  • 下一篇
    DataWorks