当前位置: 首页 > 工具软件 > argo-events > 使用案例 >

k8s--kubernetes--argo----使用动态存储PVC---基于nfs 的storageclass

龚志
2023-12-01

PVC简介

Docker中有 volumes的概念,在Docker中,volume是 对 物理节点服务器node路径目录的一种映射,也就是 我们可以把服务器的一个目录挂载给镜像使用。

同样的,k8s创建的pod也可以挂载volume,而且不仅仅支持 pod所在的服务器node的目录映射,也可以挂载其他网络存储的作为目录挂载。

k8s支持volumes的类型如下:

1、awsElasticBlockStore
2、azureDisk
3、azureFile
4、cephfs
5、cinder
6、configMap
7、csi
8、downwardAPI
9、emptyDir
10、fc (fibre channel)
11、flexVolume
12、flocker
13、gcePersistentDisk
14、gitRepo (deprecated)
15、glusterfs
16、hostPath
17、iscsi
18、local
19、nfs
20、persistentVolumeClaim
21、projected
22、portworxVolume
23、quobyte
24、rbd
25、scaleIO
26、secret
27、storageos
28、vsphereVolume

相关类型的使用参考 Volumes

PVC是persistentVolumeClaim类型的缩写。

PVC是把云集群的node当成一个资源池,占用相应的物理空间作为 网络的存储空间,提供给k8s的pod来挂载使用。

更多详细参考和pvc的使用方法 Persistent Volumes

Storage Classes

持久型的pvc使用的 预先创建好的nfs或者 node的空间,会一直占用着资源,造成不使用时的浪费。

而且预先创建好的pvc有可能跟pod不是一个 可用区,将造成 跨可用区的流量费用。

k8s针对这种情况 有storageclass的用法,可以让用户动态创建pvc。

详情参考 Storage Classes

使用s3拉取到 动态pvc中,动态创建pvc通过拓扑感知能够让pvc跟 pod在同一个可用区中,通过内网交互,省去流量费用。

因为s3拉取流量是按次数计费,当文件大 次数小时 ,费用可忽略不计。

所以 这种动态pvc方案 可以很好的降低 大参考文件的存储和交互成本。

k8s中使用

声明创建storageClassName,这个地方根据我们使用的底层技术不同会有不同,比如使用rbd,ceph,nfs等等

这里以nfs为例

创建serviceaccount.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-client-provisioner

创建nfs-provisioner.yaml

kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: nfs-provisioner
spec:
  replicas: 1
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: nfs-provisioner
    spec:
      serviceAccount: nfs-client-provisioner  #这个要与刚才创建的serviceaccount 的名字一致
      containers:
        - name: nfs-provisioner
          image: registry.cn-hangzhou.aliyuncs.com/open-ali/nfs-client-provisioner
          volumeMounts:
            - name: nfs-client-root
              mountPath: /persistentvolumes
          env:
            - name: PROVISIONER_NAME
              value: example.com/nfs #这里名字自定义,要记住storageclass 后面要用到
            - name: NFS_SERVER
              value: [已配置的NFS系统的IP地址]
            - name: NFS_PATH
              value: [已配置的NFS系统的挂载路径] 
      volumes:
        - name: nfs-client-root
          nfs:
            server: [已配置的NFS系统的IP地址]
            path: [已配置的NFS系统的挂载路径] #这里需要注意,如果用的公有云服务的nfs 或者nas,必须要提前创建好目录

StorageClass.yaml

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: nfs-name
provisioner: example.com/nfs #这里的名字要跟之前创建nfs-client deployment里写的名字一样

声明创建pvc
spark-pvc.yaml

#声明
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc-name
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 50Gi
  storageClassName: nfs-name

注意这里ReadWriteOnce表示只允许一个pod以读写模式挂载

ReadWriteOnce —— 该volume只能被单个节点以读写的方式映射
ReadOnlyMany —— 该volume可以被多个节点以只读方式映射
ReadWriteMany —— 该volume只能被多个节点以读写的方式映射,这种存储可以以读写的方式被多个Pod共享。不是每一种存储都支持这三种方式,像共享方式,目前支持的还比较少,比较常用的是NFS。在PVC绑定PV时通常根据两个条件来绑定,一个是存储的大小,另一个就是访问模式。

如果设置的属性不对,则会报错

Pod "zzq-1584759188679-exec-1" is invalid: spec.containers[0].volumeMounts[1].mountPath: Invalid value: "/tmp2": must be unique

yaml中使用
spark.yaml

container:
  image: 123.dkr.ecr.cn-northwest-1.amazonaws.com.cn/module
  imagePullPolicy: Always
  volumeMounts:
    - name: volumes-name
      mountPath: /share/tmp/
volumes:
    - name: volumes-name
      persistentVolumeClaim:
        claimName: pvc-name

使用rbac加权限认证的会稍微麻烦些,使用方法参考:

使用rbac的

1,创建serviceaccount.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: nfs-client-provisioner

2,创建nfs客户端deployment.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:
      serviceAccount: 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: example.cn/nfs #这里自定义
            - name: NFS_SERVER
              value: 123.23.xxx.xxx    #写nfs server地址
            - name: NFS_PATH
              value: /localmnt/storage
      volumes:
        - name: nfs-client-root
          nfs:
            server: 123.23.xxx.xxx
            path: /localmnt/storage    #和之前一样,挂在之前,一定要提前创建,不然k8s 不认识,也不能自动创建

3,创建集群绑定规则clusterrolebinding.yaml

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1alpha1
metadata:
  name: run-nfs-client-provisioner
subjects:
  - kind: ServiceAccount
    name: nfs-client-provisioner
roleRef:
  kind: ClusterRole
  name: nfs-client-provisioner-runner
  apiGroup: rbac.authorization.k8s.io

4,创建集群角色clusterrole.yaml

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1alpha1
metadata:
  name: nfs-client-provisioner-runner
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: ["list", "watch", "create", "update", "patch"]

5,创建storageclass.yaml

apiVersion: storage.k8s.io/v1beta1
kind: StorageClass
metadata:
  name: standard
provisioner: example.cn/nfs #这里跟之前创建nfs client端里定义的名字一样

argo中使用

apiVersion: argoproj.io/v1alpha1
kind: Workflow
metadata:
  generateName: volumes-pvc-
spec:
  entrypoint: volumes-pvc-example
  volumeClaimTemplates:                 # define volume, same syntax as k8s Pod spec
  - metadata:
      name: vpcname                     # name of volume claim
    spec:
      accessModes:
        - ReadWriteOnce
      resources:
        requests:
          storage: 50Gi
      storageClassName: gp2-topology

  templates:
  - name: volumes-pvc-example
    steps:
    - - name: generate
        template: whalesay

  - name: whalesay
    container:
      image: docker/whalesay:latest
      command: [sh, -c]
      args: ["echo generating message in volume; cowsay hello world | tee /mnt/vol/hello_world.txt"]
      # Mount workdir volume at /mnt/vol before invoking docker/whalesay
      volumeMounts:                     # same syntax as k8s Pod spec
      - name: vpcname
        mountPath: /iter

argo中的PVC声明参考 argo官方文档的volume章节

 类似资料: