k8s 中的 PV 的动态供给

目录

[1 存储类 Storageclass 介绍](#1 存储类 Storageclass 介绍)

[1.1 StorageClass 说明](#1.1 StorageClass 说明)

[1.2 StorageClass 的属性](#1.2 StorageClass 的属性)

[2 存储分配器 NFS Client Provisioner](#2 存储分配器 NFS Client Provisioner)

[2.1 官网存储分配器的部署介绍](#2.1 官网存储分配器的部署介绍)

[2.2 实现动态创建 PV 模版清单文件的介绍](#2.2 实现动态创建 PV 模版清单文件的介绍)

[2.2.1 Storageclass 存储类的模版](#2.2.1 Storageclass 存储类的模版)

[2.2.2 创建 Provisioner 制备器的模版](#2.2.2 创建 Provisioner 制备器的模版)

[2.2.3 rbac 的模版](#2.2.3 rbac 的模版)

[2.2.4 PVC 的模版](#2.2.4 PVC 的模版)

[2.2.5 使用 pod 测试使用的模版](#2.2.5 使用 pod 测试使用的模版)

[3 PV 动态供给的实践操作](#3 PV 动态供给的实践操作)

[3.1 修改完的声明步骤顺序:](#3.1 修改完的声明步骤顺序:)

[3.2 rbac 创建sa权限](#3.2 rbac 创建sa权限)

[3.3 class 创建存储类](#3.3 class 创建存储类)

[3.4 deployment(控制制备器)](#3.4 deployment(控制制备器))

[3.5 PVC 创建卷申领](#3.5 PVC 创建卷申领)

[3.6 test-nginx (测试)](#3.6 test-nginx (测试))


1 存储类 Storageclass 介绍

官网: https://github.com/kubernetes-sigs/nfs-subdir-external-provisionerhttps://github.com/kubernetes-sigs/nfs-subdir-external-provisioner

1.1 StorageClass 说明

  • StorageClass提供了一种描述存储类(class)的方法,不同的class可能会映射到不同的服务质量等级和备份策略或其他策略等。

  • 每个 StorageClass 都包含 provisioner、parameters 和 reclaimPolicy 字段, 这些字段会在StorageClass需要动态分配 PersistentVolume 时会使用到

StorageClass存储类 和 Provisioner制备器 的关联以及NFS服务器与StorageClass存储类的关联

整个步骤如下图也说得很明白,无非就是StorageClass需要使用到provisioner制备器去选择到底使用的是那一块存储,而 provisioner 有一个镜像nfs-subdir-external-provisioner此镜像就是专门来进行选择存储的类型,在使用这个镜像可以使用多种资源类型来创建,如deployment,pod 等等,这次使用的为deployment控制器 在创建完资源类型之后需要手动去指定存储服务器的地址,如这次使用的就为NFS服务器,得在deployment清单文件的volumes.nfs.server 指定NFS的服务器地址与在containers.env 中以键值对的方式去指定NFS的地址为变量。

StorageClass 存储类 和 PVC 的关联

StorageClass 存储类 定义了自己的名字,在PVC中为了使用存储类,得指定存储类的名称spec.storageClassName

1.2 StorageClass 的属性

属性说明:存储类 | Kubernetes本文描述了 Kubernetes 中 StorageClass 的概念。 建议先熟悉卷和持久卷的概念。StorageClass 为管理员提供了描述存储类的方法。 不同的类型可能会映射到不同的服务质量等级或备份策略,或是由集群管理员制定的任意策略。 Kubernetes 本身并不清楚各种类代表的什么。Kubernetes 存储类的概念类似于一些其他存储系统设计中的"配置文件"。StorageClass 对象 每个 StorageClass 都包含 provisioner、parameters 和 reclaimPolicy 字段, 这些字段会在 StorageClass 需要动态制备 PersistentVolume 以满足 PersistentVolumeClaim (PVC) 时使用到。StorageClass 对象的命名很重要,用户使用这个命名来请求生成一个特定的类。 当创建 StorageClass 对象时,管理员设置 StorageClass 对象的命名和其他参数。作为管理员,你可以为没有申请绑定到特定 StorageClass 的 PVC 指定一个默认的存储类: 更多详情请参阅 PersistentVolumeClaim 概念。storage/storageclass-low-latency.yaml apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: low-latency annotations: storageclass.kubernetes.io/is-default-class: "false" provisioner: csi-driver.example-vendor.example reclaimPolicy: Retain # 默认值是 Delete allowVolumeExpansion: true mountOptions: - discard # 这可能会在块存储层启用 UNMAP/TRIM volumeBindingMode: WaitForFirstConsumer parameters: guaranteedReadWriteLatency: "true" # 这是服务提供商特定的 默认 StorageClass 你可以将某个 StorageClass 标记为集群的默认存储类。 关于如何设置默认的 StorageClass, 请参见更改默认 StorageClass。https://kubernetes.io/zh/docs/concepts/storage/storage-classes/

Provisioner(存储分配器):用来决定使用哪个卷插件分配 PV,该字段必须指定。可以指定内部分配器,也可以指定外部分配器。外部分配器的代码地址为: kubernetes-incubator/external-storage,其中包括NFS和Ceph等。

Reclaim Policy(回收策略):通过reclaimPolicy字段指定创建的Persistent Volume的回收策略,回收策略包括:Delete 或者 Retain,没有指定默认为Delete。

2 存储分配器 NFS Client Provisioner

2.1 官网存储分配器的部署介绍

访问 kubernetes 官网

源码地址: https://github.com/kubernetes-sigs/nfs-subdir-external-provisionerhttps://github.com/kubernetes-sigs/nfs-subdir-external-provisioner

  • NFS Client Provisioner是一个automatic provisioner,使用NFS作为存储,自动创建PV和对应的PVC,本身不提供NFS存储,需要外部先有一套NFS存储服务。

  • PV以 {namespace}-{pvcName}-${pvName}的命名格式提供(在NFS服务器上)

  • PV回收的时候以 archieved-{namespace}-{pvcName}-${pvName} 的命名格式(在NFS服务器上)

点击项目中的 deploy(部署)

2.2 实现动态创建 PV 模版清单文件的介绍

模版文件内容如下

这些只是模版,之后还需修改

2.2.1 Storageclass 存储类的模版

2.2.2 创建 Provisioner 制备器的模版

2.2.3 rbac 的模版

此次只需要在里面修改命名空间就可以了

2.2.4 PVC 的模版

2.2.5 使用 pod 测试使用的模版

3 PV 动态供给的实践操作

3.1 修改完的声明步骤顺序:

rbac(创建权限) --> class(创建存储类) --> deployment(使用制备器) --> pvc(pvc 关联存储类调用制备器) --> test-nginx(测试)

bash 复制代码
# 将 github 上的项目烤下来
[root@k8s-master storageClass-dynamic]# ls 
class.yaml  deployment.yaml  pvc.yaml  rbac.yaml  test-nginx.yml

3.2 rbac 创建sa权限

bash 复制代码
# 创建命名空间
[root@k8s-master storageClass-dynamic]# kubectl create namespace  nfs-pvc-dynamic

# 修改模版参数
[root@k8s-master storageClass-dynamic]# vim rbac.yaml 
apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: nfs-pvc-dynamic    # 指定命名空间 
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: nfs-client-provisioner-runner
rules:
  - apiGroups: [""]
    resources: ["nodes"]
    verbs: ["get", "list", "watch"]
  - 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: ["create", "update", "patch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: run-nfs-client-provisioner
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    # replace with namespace where provisioner is deployed
    namespace: nfs-pvc-dynamic     # 指定命名空间
roleRef:
  kind: ClusterRole
  name: nfs-client-provisioner-runner
  apiGroup: rbac.authorization.k8s.io
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: nfs-pvc-dynamic
rules:
  - apiGroups: [""]
    resources: ["endpoints"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: leader-locking-nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace: nfs-pvc-dynamic     # 指定命名空间
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
    # replace with namespace where provisioner is deployed
    namespace: nfs-pvc-dynamic     # 指定命名空间
roleRef:
  kind: Role
  name: leader-locking-nfs-client-provisioner
  apiGroup: rbac.authorization.k8s.io


# 声明 rbac 清单文件
[root@k8s-master storageClass-dynamic]# kubectl apply -f rbac.yaml 
serviceaccount/nfs-client-provisioner created
clusterrole.rbac.authorization.k8s.io/nfs-client-provisioner-runner created
clusterrolebinding.rbac.authorization.k8s.io/run-nfs-client-provisioner created
role.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created
rolebinding.rbac.authorization.k8s.io/leader-locking-nfs-client-provisioner created

# 查看是否成功创建
[root@k8s-master storageClass-dynamic]# kubectl get namespaces nfs-pvc-dynamic 
NAME              STATUS   AGE
nfs-pvc-dynamic   Active   118m


[root@k8s-master storageClass-dynamic]# kubectl -n nfs-pvc-dynamic get sa
NAME                     SECRETS   AGE
default                  0         123m
nfs-client-provisioner   0         90m

3.3 class 创建存储类

bash 复制代码
[root@k8s-master storageClass-dynamic]# vim class.yaml 

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: nfs-client     # 指定存储类名
provisioner: k8s-sigs.io/nfs-subdir-external-provisioner # 制备器的名称
parameters:
  archiveOnDelete: "false"

# 声明存储类
[root@k8s-master storageClass-dynamic]# kubectl apply -f class.yaml 

# 查看存储类
[root@k8s-master storageClass-dynamic]# kubectl get sc
NAME         PROVISIONER                                   RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
nfs-client   k8s-sigs.io/nfs-subdir-external-provisioner   Delete          Immediate           false                  88m

3.4 deployment(控制制备器)

bash 复制代码
[root@k8s-master storageClass-dynamic]# vim deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nfs-client-provisioner
  labels:
    app: nfs-client-provisioner
  # replace with namespace where provisioner is deployed
  namespace:  nfs-pvc-dynamic
spec:
  replicas: 1
   # 更新策略,此处设置为Recreate,表示更新时会先停止旧的Pod,然后再启动新的Pod
  strategy:
    type: Recreate
  selector:
    matchLabels:
      app: nfs-client-provisioner
  template:
    metadata:
      labels:
        app: nfs-client-provisioner
    spec:
      # 指定Pod使用的Service Account名称。Service Account用于Pod与API Server之间的认证,
      # 以便Pod能够调用API Server进行存储类型的选取等操作。
      # 注意:ServiceAccountName 需要与RBAC中定义的服务账户名称一致,
      # 以确保有足够的权限来执行存储相关的操作
      serviceAccountName: nfs-client-provisioner # 要与rbac中的sa名称相同,因为需要调用apiserver去选择使用哪一类型的存储,所以在这上面需要使用到创建的rbac的权限
      # 定义了一个存储卷
      volumes:
        - name: nfs-client-root
          nfs:
            server: 192.168.239.50
            path: /nfsdata

      containers:
        - name: nfs-client-provisioner # 使用的是制备器的镜像,并且此名称需要与storaClass中的存储类名一致
          image: sig-storage/nfs-subdir-external-provisioner:v4.0.2 # 需要用到的镜像,使用docker拉取
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes  # 将卷挂载到在容器内的这一个目录
          env:
            - name: PROVISIONER_NAME
              value: k8s-sigs.io/nfs-subdir-external-provisioner
            - name: NFS_SERVER
              value: 192.168.239.50
            - name: NFS_PATH
              value: /nfsdata

# 声明制备器
[root@k8s-master storageClass-dynamic]# kubectl apply -f deployment.yaml

# 查看制备器是否正常运行
[root@k8s-master storageClass-dynamic]# kubectl -n nfs-pvc-dynamic get deployments.apps 
NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
nfs-client-provisioner   1/1     1            1           121m

3.5 PVC 创建卷申领

bash 复制代码
[root@k8s-master storageClass-dynamic]# vim pvc.yaml 
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: test-claim
  namespace: nfs-pvc-dynamic
spec:
  storageClassName: nfs-client # 与类名需要一致
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 1Gi

# 声明 PVC
[root@k8s-master storageClass-dynamic]# kubectl apply -f pvc.yaml 

# NFS 服务端查看是否正常创建 PV 存储卷
# 可以发现在NFS服务器上是以 ${namespace}-${pvcName}-${pvName} 的命名格式提供
[root@harbor nfsdata]# ls /nfsdata/
nfs-pvc-dynamic-test-claim-pvc-29a134a4-a4dc-40f6-a378-820de948d34a 

3.6 test-nginx (测试)

bash 复制代码
[root@k8s-master storageClass-dynamic]# vim test-nginx.yml 
apiVersion: v1
kind: Pod
metadata:
  name: nginx-test
  namespace: nfs-pvc-dynamic    # 指定命名空间
spec:
  volumes:
  - name: nfs-pvc
    persistentVolumeClaim:    # 指定 PVC 的名称
      claimName: test-claim

  containers:
  - image: nginx
    name: nginx-test-01
    volumeMounts:
    - mountPath: /usr/share/nginx/html    # 容器挂载点
      name: nfs-pvc

[root@k8s-master storageClass-dynamic]# kubectl apply -f test-nginx.yml 

# 这个时候由于是新的卷,不能直接去访问因为直接访问是没有默认发布文件,需要手动创建测试
[root@k8s-master storageClass-dynamic]# kubectl -n nfs-pvc-dynamic get pods -o wide 
NAME                                     READY   STATUS    RESTARTS   AGE     IP            NODE        NOMINATED NODE   READINESS GATES
nfs-client-provisioner-8c78dc5f9-5hrpb   1/1     Running   0          5m57s   10.244.1.40   k8s-node1   <none>           <none>
nginx-test                               1/1     Running   0          76s     10.244.2.67   k8s-node2   <none>           <none>

# 在 NFS 服务器中创建index.html默认发布文件,这个卷会挂载到容器中的
# /usr/share/nginx/html/ 的目录中
[root@harbor nfsdata]# echo this is nfs-dynamic nginx > /nfsdata/nfs-pvc-dynamic-test-claim-pvc-29a134a4-a4dc-40f6-a378-820de948d34a/index.html


[root@k8s-master storageClass-dynamic]# kubectl -n nfs-pvc-dynamic get pods -o wide 
NAME                                     READY   STATUS    RESTARTS   AGE     IP            NODE        NOMINATED NODE   READINESS GATES
nfs-client-provisioner-8c78dc5f9-5hrpb   1/1     Running   0          5m57s   10.244.1.40   k8s-node1   <none>           <none>
nginx-test                               1/1     Running   0          76s     10.244.2.67   k8s-node2   <none>           <none>
[root@k8s-master storageClass-dynamic]# curl 10.244.2.67
this is nfs-dynamic nginx
相关推荐
chuanauc5 小时前
Kubernets K8s 学习
java·学习·kubernetes
小张是铁粉5 小时前
docker学习二天之镜像操作与容器操作
学习·docker·容器
烟雨书信5 小时前
Docker文件操作、数据卷、挂载
运维·docker·容器
IT成长日记5 小时前
【Docker基础】Docker数据卷管理:docker volume prune及其参数详解
运维·docker·容器·volume·prune
这儿有一堆花5 小时前
Docker编译环境搭建与开发实战指南
运维·docker·容器
LuckyLay5 小时前
Compose 高级用法详解——AI教你学Docker
运维·docker·容器
Uluoyu5 小时前
redisSearch docker安装
运维·redis·docker·容器
IT成长日记9 小时前
【Docker基础】Docker数据持久化与卷(Volume)介绍
运维·docker·容器·数据持久化·volume·
疯子的模样14 小时前
Docker 安装 Neo4j 保姆级教程
docker·容器·neo4j
虚伪的空想家14 小时前
rook-ceph配置dashboard代理无法访问
ceph·云原生·k8s·存储·rook