Kubernetes 系列:持久化存储StorageClass

Posted weiblog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kubernetes 系列:持久化存储StorageClass相关的知识,希望对你有一定的参考价值。

前面的课程中我们学习了 PV 和 PVC 的使用方法,但是前面的 PV 都是静态的,什么意思?就是我要使用的一个 PVC 的话就必须手动去创建一个 PV,我们也说过这种方式在很大程度上并不能满足我们的需求,比如我们有一个应用需要对存储的并发度要求比较高,而另外一个应用对读写速度又要求比较高,特别是对于 StatefulSet 类型的应用简单的来使用静态的 PV 就很不合适了,这种情况下我们就需要用到动态 PV,也就是我们今天要讲解的 StorageClass

创建 Provisioner

要使用 StorageClass,我们就得安装对应的自动配置程序,比如我们这里存储后端使用的是 nfs,那么我们就需要使用到一个 nfs-client 的自动配置程序,我们也叫它 Provisioner,这个程序使用我们已经配置好的 nfs 服务器,来自动创建持久卷,也就是自动帮我们创建 PV。

  • 自动创建的 PV 以$namespace-$pvcName-$pvName这样的命名格式创建在 NFS 服务器上的共享数据目录中
  • 而当这个 PV 被回收后会以archieved-$namespace-$pvcName-$pvName这样的命名格式存在 NFS 服务器上。

当然在部署nfs-client之前,我们需要先成功安装上 nfs 服务器,前面的课程中我们已经过了,服务地址是1192.168.3.131,共享数据目录是/data/k8s/,然后接下来我们部署 nfs-client 即可,我们也可以直接参考nfs-client 的文档,进行安装即可。

 

第一步:配置 Deployment,将里面的对应的参数替换成我们自己的 nfs 配置(nfs-client.yaml)

kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: nfs-client-provisioner
spec:
  replicas: 1
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      serviceAccountName: nfs-client-provisioner
      containers:
        - name: nfs-client-provisioner
          image: quay.io/external_storage/nfs-client-provisioner:latest
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: fuseim.pri/ifs
            - name: NFS_SERVER
              value: 192.168.3.131
            - name: NFS_PATH
              value: /data/k8s
      volumes:
        - name: nfs-client-root
          nfs:
            server: 192.168.3.131
            path: /data/k8s

第二步:将环境变量 NFS_SERVER 和 NFS_PATH 替换,当然也包括下面的 nfs 配置,我们可以看到我们这里使用了一个名为 nfs-client-provisioner 的serviceAccount,所以我们也需要创建一个 sa,然后绑定上对应的权限:(nfs-client-sa.yaml)

我们这里新建的一个名为 nfs-client-provisioner 的ServiceAccount,然后绑定了一个名为 nfs-client-provisioner-runner 的ClusterRole,而该ClusterRole声明了一些权限,其中就包括对persistentvolumes的增、删、改、查等权限,所以我们可以利用该ServiceAccount来自动创建 PV。

第三步:nfs-client 的 Deployment 声明完成后,我们就可以来创建一个StorageClass对象了:(nfs-client-class.yaml)

我们声明了一个名为 course-nfs-storage 的StorageClass对象,注意下面的provisioner对应的值一定要和上面的Deployment下面的 PROVISIONER_NAME 这个环境变量的值一样。

现在我们来创建这些资源对象吧:

kubectl create -f nfs-client.yaml
kubectl create -f nfs-client-sa.yaml
kubectl create -f nfs-client-class.yaml

创建完成后查看下资源状态:

[root@localhost nfs]# kubectl get pods
NAME                                      READY   STATUS              RESTARTS   AGE
nfs-client-provisioner-5db79cb75f-nk952   0/1     ContainerCreating   0          12s
[root@localhost nfs]# kubectl
get storageclass NAME PROVISIONER AGE course-nfs-storage fuseim.pri/ifs 31s harbor-data fuseim.pri/ifs 90d

新建 StorageClass

上面把StorageClass资源对象创建成功了,接下来我们来通过一个示例测试下动态 PV,首先创建一个 PVC 对象:(test-pvc.yaml)

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

我们这里声明了一个PVC对象,采用 ReadWriteMany 的访问模式,请求 1Mi 的空间,但是我们可以看到上面的 PVC 文件我们没有标识出任何和 StorageClass 相关联的信息,那么如果我们现在直接创建这个 PVC 对象能够自动绑定上合适的 PV 对象吗?显然是不能的(前提是没有合适的 PV),我们这里有两种方法可以来利用上面我们创建的 StorageClass 对象来自动帮我们创建一个合适的 PV:

  • 第一种方法:在这个PVC对象中添加一个声明StorageClass对象的标识,这里我们可以利用一个annotations属性来标识,如下
  • kind: PersistentVolumeClaim
    apiVersion: v1
    metadata:
      name: test-pvc
      annotations:
        volume.beta.kubernetes.io/storage-class: "course-nfs-storage"
    spec:
      accessModes:
      - ReadWriteMany
      resources:
        requests:
          storage: 1Mi
  • 第二种方法:我们可以设置这个 course-nfs-storage 的 StorageClass 为 Kubernetes 的默认存储后端,我们可以用kubectl patch命令来更新: yaml $ kubectl patch storageclass course-nfs-storage -p ‘"metadata": "annotations":"storageclass.kubernetes.io/is-default-class":"true"‘
  • 上面这两种方法都是可以的,当然为了不影响系统的默认行为,我们这里还是采用第一种方法,直接创建即可:

上面这两种方法都是可以的,当然为了不影响系统的默认行为,我们这里还是采用第一种方法,直接创建即可:

(注意网络问题 这里需要拉取外网镜像)

kubectl create -f test-pvc.yaml
persistentvolumeclaim "test-pvc" created
[root@localhost nfs]# kubectl get pvc
NAME       STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS         AGE
pvc-nfs    Bound    pv1                                        1Gi        RWO                                 12h
test-pvc   Bound    pvc-a7293619-bb8c-11e9-93e7-000c29ecf8a8   1Mi        RWX            course-nfs-storage   11h

我们可以看到一个名为 test-pvc 的 PVC 对象创建成功了,状态已经是Bound了,是不是也产生了一个对应的VOLUME 对象,最重要的一栏是STORAGECLASS,现在是不是也有值了,就是我们刚刚创建的StorageClass对象 course-nfs-storage。

然后查看下 PV 对象呢:

[root@localhost nfs]# kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM              STORAGECLASS         REASON   AGE
pvc-a7293619-bb8c-11e9-93e7-000c29ecf8a8   1Mi        RWX            Delete           Bound    default/test-pvc   course-nfs-storage            3m48s

可以看到是不是自动生成了一个关联的 PV 对象,访问模式是RWX,回收策略是 Delete,这个 PV 对象并不是我们手动创建的吧,这是通过我们上面的 StorageClass 对象自动创建的。这就是 StorageClass 的创建方法。

 

OK,到这里我们大体明白了StorageClass的作用,下一篇我们会实际把它利用起来。

以上是关于Kubernetes 系列:持久化存储StorageClass的主要内容,如果未能解决你的问题,请参考以下文章

容器化 RDS:借助 CSI 扩展 Kubernetes 存储能力

k8s实战系列:3-存储的花样玩法(下)

k8s实战系列:3-存储的花样玩法(下)

k8s实战系列:3-存储的花样玩法(下)

2个Kubernetes使用同一个Ceph存储达到Kubernetes间持久化数据迁移

Kubernetes存储