【云原生 | Kubernetes 实战】13、K8s 常见的存储方案及具体应用场景分析(下)

导读:本篇文章讲解 【云原生 | Kubernetes 实战】13、K8s 常见的存储方案及具体应用场景分析(下),希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

目录

k8s 存储类:storageclass

1.1 存储制备器 

1.2 回收策略 

1.3 允许卷扩展 

二、安装 nfs provisioner 用于配合存储类动态生成 pv 

2.1 把 nfs-subdir-external-provisioner.tar.gz 上传到 node2 和 node1 上,手动解压。 

2.2 创建运行 nfs-provisioner 需要的 sa 账号 

2.3 对 sa 授权

2.4 安装 nfs-provisioner 程序 

三、创建 storageclass 动态供给 pv

四、创建 pvc 通过 storageclass 动态生成 pv 

步骤总结:

五、创建 pod 挂载 storageclass 动态生成的 pvc:test-claim1 


k8s 存储类:storageclass

        前面文章介绍的 PV 和 PVC 模式都是需要先创建好 PV,然后定义好 PVC 和 pv 进行一对一的 Bond,但是如果 PVC 请求成千上万,那么就需要创建成千上万的 PV,对于运维人员来说维护成本很高。Kubernetes 提供一种自动创建 PV 的机制,叫 StorageClass,它的作用就是创建 PV的模板。k8s 集群管理员通过创建 storageclass 可以动态生成一个存储卷 pv 供 k8s pvc 使用。

        每个 StorageClass 都包含 provisionerparameters 和 reclaimPolicy 字段, 这些字段会在 StorageClass 需要动态制备 PersistentVolume 时会使用到。 

具体来说,StorageClass 会定义以下两部分:

  1. PV 的属性 ,比如存储的大小、类型等;
  2. 创建这种 PV 需要使用到的存储插件,比如 Ceph、NFS 等。

        有了这两部分信息,Kubernetes 就能够根据用户提交的 PVC,找到对应的 StorageClass,然后 Kubernetes 就会调用 StorageClass 声明的存储插件,创建出需要的 PV。 

1.1 存储制备器 

        每个 StorageClass 都有一个制备器或者也叫供应商(Provisioner),用来决定使用哪个卷插件制备 PV。 该字段必须指定。

        storageclass 需要有一个供应者,用来确定我们使用什么样的存储来创建 pv,常见的provisioner 如下:(“ √ ” 为内部供应商,“ – ” 为外部供应商)

卷插件 内置制备器 配置例子
AWSElasticBlockStore AWS EBS
AzureFile Azure File
AzureDisk Azure Disk
CephFS
Cinder OpenStack Cinder
FC
FlexVolume
GCEPersistentDisk GCE PD
Glusterfs Glusterfs
iSCSI
NFS NFS
RBD Ceph RBD
VsphereVolume vSphere
PortworxVolume Portworx Volume
Local Local

        provisioner 既可以由内部供应商提供,也可以由外部供应商提供,如果是外部供应商可以参考代码仓库 kubernetes-sigs/sig-storage-lib-external-provisioner 包含一个用于为外部制备器编写功能实现的类库。你可以访问代码仓库 kubernetes-sigs/sig-storage-lib-external-provisioner 了解外部驱动列表。

        例如,NFS 没有内部制备器,但可以使用外部制备器。 也有第三方存储供应商提供自己的外部制备器。要想使用 NFS,我们需要一个 nfs-client 的自动装载程序,称之为 provisioner,这个程序会使用我们已经配置好的 NFS 服务器自动创建持久卷,也就是自动帮我们创建 PV。

存储制备器官方参考文档:存储类 | Kubernetes 

1.2 回收策略 

        由 StorageClass 动态创建的 PersistentVolume 会在类的 reclaimPolicy 字段中指定回收策略,可以是 Delete 或者 Retain。如果 StorageClass 对象被创建时没有指定 reclaimPolicy,它将默认为 Delete

通过 StorageClass 手动创建并管理的 PersistentVolume 会使用它们被创建时指定的回收策略。

1.3 允许卷扩展 

PersistentVolume 可以配置为可扩展。将此功能设置为 true 时,允许用户通过编辑相应的 PVC 对象来调整卷大小。

当下层 StorageClass 的 allowVolumeExpansion 字段设置为 true 时,以下类型的卷支持卷扩展:

卷类型 Kubernetes 版本要求
gcePersistentDisk 1.11
awsElasticBlockStore 1.11
Cinder 1.11
glusterfs 1.11
rbd 1.11
Azure File 1.11
Azure Disk 1.11
Portworx 1.11
FlexVolume 1.13
CSI 1.14 (alpha), 1.16 (beta)

说明:此功能仅可用于扩容卷,不能用于缩小卷。

二、安装 nfs provisioner 用于配合存储类动态生成 pv 

Kubernetes 不包含内部 NFS 驱动。你需要使用外部驱动为 NFS 创建 StorageClass。 这里有些例子:

本次使用 NFS subdir 外部驱动为例。

nfs-subdir-external-provisioner.tar.gz 文件下载地址:https://download.csdn.net/download/weixin_46560589/87315292

2.1 把 nfs-subdir-external-provisioner.tar.gz 上传到 node2 和 node1 上,手动解压。 

[root@k8s-node1 ~]# ctr -n=k8s.io images import  nfs-subdir-external-provisioner.tar.gz
[root@k8s-node2 ~]# ctr -n=k8s.io images import  nfs-subdir-external-provisioner.tar.gz

2.2 创建运行 nfs-provisioner 需要的 sa 账号 

[root@k8s-master01 volumes]# vim serviceaccount.yaml 
apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-provisioner

[root@k8s-master01 volumes]# kubectl apply -f serviceaccount.yaml
serviceaccount/nfs-provisioner created

[root@k8s-master01 volumes]# kubectl get sa
NAME              SECRETS   AGE
default           0         56d
nfs-provisioner   0         13s

扩展:什么是 sa?(后面文章会讲到)

        sa 的全称是 serviceaccount。serviceaccount 是为了方便 Pod 里面的进程调用 Kubernetes API 或其他外部服务而设计的。指定了 serviceaccount 之后,我们把 pod 创建出来了,我们在使用这个pod 时,这个 pod 就有了我们指定的账户的权限了。

2.3 对 sa 授权

[root@k8s-master01 volumes]# kubectl create clusterrolebinding nfs-provisioner-clusterrolebinding --clusterrole=cluster-admin --serviceaccount=default:nfs-provisioner

2.4 安装 nfs-provisioner 程序 

# 创建目录
[root@k8s-master01 volumes]# mkdir /data/nfs_pro -pv

# 把 /data/nfs_pro 变成 nfs 共享的目录
[root@k8s-master01 volumes]# vim /etc/exports
/data/nfs_pro *(rw,no_root_squash)

# 使其生效
[root@k8s-master01 volumes]# exportfs -arv
exporting *:/data/nfs_pro

# 创建 deployment 资源文件
[root@k8s-master01 volumes]# vim nfs-deployment.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
  name: nfs-provisioner
spec:
  selector:
    matchLabels:
       app: nfs-provisioner
  replicas: 1
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: nfs-provisioner
    spec:
      serviceAccount: nfs-provisioner
      containers:
        - name: nfs-provisioner
          image: registry.cn-beijing.aliyuncs.com/mydlq/nfs-subdir-external-provisioner:v4.0.0
          imagePullPolicy: IfNotPresent
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: example.com/nfs
            - name: NFS_SERVER
              value: 192.168.78.133
            - name: NFS_PATH
              value: /data/nfs_pro
      volumes:
        - name: nfs-client-root
          nfs:
            server: 192.168.78.133        # NFS 服务器的主机名或 IP 地址。
            path: /data/nfs_pro           # NFS 服务器导出的路径。

# 更新资源清单文件
[root@k8s-master01 volumes]# kubectl apply -f nfs-deployment.yaml 
deployment.apps/nfs-provisioner created

# 查看 nfs-provisioner 是否正常运行
[root@k8s-master01 volumes]# kubectl get pods -o wide 
NAME                               READY   STATUS    RESTARTS   AGE   IP               NODE        NOMINATED NODE   READINESS GATES
nfs-provisioner-6fc44b8b68-k8qpm   1/1     Running   0          7s    10.244.169.173   k8s-node2   <none>           <none>

三、创建 storageclass 动态供给 pv

[root@k8s-master01 volumes]# vim nfs-storageclass.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: nfs
provisioner: example.com/nfs

[root@k8s-master01 volumes]# kubectl apply -f nfs-storageclass.yaml
storageclass.storage.k8s.io/nfs created

[root@k8s-master01 volumes]# kubectl get storageclass
NAME   PROVISIONER       RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
nfs    example.com/nfs   Delete          Immediate           false                  17s

显示内容如上,说明 storageclass 创建成功了。

注意:provisioner 处写的 example.com/nfs 应该跟安装 nfs provisioner 时候的 env下的PROVISIONER_NAME 的 value 值保持一致,如下:

env:

    – name: PROVISIONER_NAME

     value: example.com/nfs

四、创建 pvc 通过 storageclass 动态生成 pv 

[root@k8s-master01 volumes]# vim claim.yaml 
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: test-claim1
spec:
  accessModes:  ["ReadWriteMany"]
  resources:
    requests:
      storage: 1Gi
  storageClassName:  nfs

[root@k8s-master01 volumes]# kubectl apply -f claim.yaml
persistentvolumeclaim/test-claim1 created

# 查看是否动态生成了 pv,pvc 是否创建成功,并和 pv 绑定
[root@k8s-master01 volumes]# kubectl get pvc
NAME          STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
test-claim1   Bound    pvc-a7571e3f-7017-40fa-8e3f-7d96a106450a   1Gi        RWX            nfs            12s

[root@k8s-master01 volumes]# kubectl get pv
NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                 STORAGECLASS   REASON   AGE
pvc-a7571e3f-7017-40fa-8e3f-7d96a106450a   1Gi        RWX            Delete           Bound    default/test-claim1   nfs                     2m28s

# 宿主机挂载的目录下也自动生成了一个新的目录
[root@k8s-master01 volumes]# ls /data/nfs_pro/
default-test-claim1-pvc-a7571e3f-7017-40fa-8e3f-7d96a106450a

        通过上面可以看到 test-claim1 的 pvc 已经成功创建了,绑定的 pv 是 pvc-a7571e3f-7017-40fa-8e3f-7d96a106450a,这个 pv 是由 storageclass 调用 nfs provisioner 自动生成的。

步骤总结:

  1. 创建供应商:创建一个 nfs provisioner
  2. 创建 storageclass,storageclass 指定刚才创建的供应商
  3. 创建 pvc,这个 pvc 指定 storageclass

五、创建 pod 挂载 storageclass 动态生成的 pvc:test-claim1 

[root@k8s-master01 volumes]# vim read-pod.yaml 
kind: Pod
apiVersion: v1
metadata:
  name: read-pod
spec:
  containers:
  - name: read-pod
    image: nginx
    imagePullPolicy: IfNotPresent
    volumeMounts:
      - name: nfs-pvc
        mountPath: /usr/share/nginx/html
  restartPolicy: "Never"
  volumes:
    - name: nfs-pvc
      persistentVolumeClaim:
        claimName: test-claim1

[root@k8s-master01 volumes]# kubectl apply -f read-pod.yaml
pod/read-pod created

[root@k8s-master01 volumes]# kubectl get pods | grep read
read-pod                           1/1     Running   0          9s

# 进入挂载目录下,创建文件
[root@k8s-master01 volumes]# cd /data/nfs_pro/default-test-claim1-pvc-a7571e3f-7017-40fa-8e3f-7d96a106450a/
[root@k8s-master01 default-test-claim1-pvc-a7571e3f-7017-40fa-8e3f-7d96a106450a]# touch 1.txt

# 进入容器内部查看文件是否同步
[root@k8s-master01 default-test-claim1-pvc-a7571e3f-7017-40fa-8e3f-7d96a106450a]# kubectl exec -it read-pod -- bash
root@read-pod:/# ls /usr/share/nginx/html/      
1.txt

 上一篇文章:【云原生 | Kubernetes 实战】13、K8s 常见的存储方案及具体应用场景分析(中)_Stars.Sky的博客-CSDN博客

下一篇文章:【云原生 | Kubernetes 实战】14、K8s 控制器 Statefulset 入门到企业实战应用_Stars.Sky的博客-CSDN博客

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/74543.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!