存储卷:

如果想要使用存储卷需要定义:
第一、在Pod上要定义volume,而这个volume要指明关联到什么设备上的
第二、在容器中要使用存储卷挂载然后才能使用存储卷
emptyDir:临时目录

特性为相关Pod被删除,该存储卷也一并被删除,就算被控制器重新创建后,数据也无法恢复

示例:

以下为一个Pod中存在两个容器,第一个容器为nginx容器,第二个为nginx的index.html主页文件生成数据,一主一辅,其中第一个容器的主页文件路径是/usr/share/nginx/html 而第二个辅助容器生成的数据存放在/data/index.html中,但是访问的时候是显示容器二提供的数据,因此可以得出结论,

apiVersion: v1
kind: Pod
metadata:
  name: pod-demo
  namespace: default
  labels:
    app: myapp
    tier: frontend
  annotations:
      tomcat.com/created-by: "cluster admin"
spec:
  containers: 
  - name: myapp
    image: ikubernetes/myapp:v1
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
      containerPort: 80
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html/
    - name: busybox
      image: busybox:latest
      imagePullPolicy: IfNotPresent
      volumeMounts:
      - name: html
        mountPath: /data/
      command:
      - "/bin/sh"
      - "-c"
      - "while true; do echo $(date) >> /data/index.html; sleep 2; done"
  volumes:
  - name: html
    emptyDir: {}

gitRepo:

类似于emptyDir,于其不同的地方是,他会去git仓库之上把指定的内容克隆到Pod之中,此操作依赖于宿主机拥有git命令才能完成相关操作,且克隆之后在Pod之中修改源文件不会同步到git仓库中,在git仓库中修改数据也不会同步到Pod中

hostPath:

hostPath:分为三类
SAN:iSCSI
NAS:nfs cifs
分布式存储:
  glusterfs,rbd,cephfs
云端存储:
  EBS,Azure Disk...在云端存储的都算是云端存储。

具体kubernetes支持多少存储通过以下命令获得:

kubectl explain pods.spec.volumes

在Pod中挂载宿主机的文件系统,其中挂载类型为:

DirectoryOrCreate:如果给定路径中不存在任何内容,则会根据需要在那里创建一个空目录,其权限设置为 0755,与 Kubelet 具有相同的组和所有权。
Directory:给定路径中必须存在的目录
FileOrCreate:如果给定路径中不存在任何内容,则会根据需要在那里创建一个空文件,其权限设置为 0644,与 Kubelet 具有相同的组和所有权。
File:文件必须存在于给定的路径之中
Socket:给定路径中必须存在 UNIX 套接字
CharDevice:字符设备必须存在于给定的路径中
BlockDevice:块设备必须存在于给定的路径

举例:

apiVersion: v1
kind: Pod
metadata:
  name: pod-vol-hostpath
  namespace: default
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    imagePullPolicy: IfNotPresent
    volumeMounts: 
    - name: html                            #名称
      mountPath: /usr/share/nginx/html      #这个是容器中要挂载路径的路径信息
    volumes:
    - name: html
      hostPath:
        path: /data/pod/volume1    #这个位置要写NFS中共享出来的存储路径
        type: DirectoryOrCreate    #这个是类型,详细信息上方有

NFS:

在K8S中需要K8S管理员创建PV和PVS,多个pvc可以和PV建立关系。一个PV只能绑定一个存储系统之上的路径

注意:

一个卷一次只能使用一种访问模式挂载,即使它支持多种访问模式。例如:
GCEPersistentDisk 可以由单个节点挂载为 ReadWriteOnce 或由多个节点挂载为 ReadOnlyMany,但不能同时挂载。

PV访问模型:

https://kubernetes.io/zh/docs/concepts/storage/persistent-volumes/    官网提供信息
ReadWriteOnce:该卷可以由单个节点以读写方式挂载。ReadWriteOnce 访问模式仍然可以允许多个 Pod 在同一节点上运行时访问该卷。
ReadOnlyMany:  该卷可以被许多节点以只读方式挂载。
ReadWriteMany:该卷可以被许多节点以读写方式挂载。
ReadWriteOncePod:该卷可以由单个 Pod 以读写方式挂载。如果您想确保整个集群中只有一个 Pod 可以读取该 PVC 或写入该 PVC,请使用 ReadWriteOncePod 访问模式。这仅支持 CSI 卷和 Kubernetes 1.22+ 版。

在CLI中,访问模式缩写为:

RWO - ReadWriteOnce
ROX - ReadOnlyMany
RWX - ReadWriteMany
RWOP - ReadWriteOncePod

PV在k8S中属于集群类资源,和命名空间一样,所以不可以在部署PV中设置namespace
举例:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv001
  labels:
    name: pv001
spec:
  nfs:                              #文件系统类型
    path: /data/volumes/v1          #nfs的共享路径
    server: data_har                #NFS的地址,此名为解析地址,可写为IP地址
  accessModes: ["ReadWriteMany","ReadWriteOnce"]        #访问模型 支持多节点读写,支持单节点读写 
  capacity:                                             #指定空间大小
    storage: 2Gi                                        #大小为2G
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv002
    labels:
      name: pv002
spec:
  nfs:
    path: /data/volumes/v2
    server: data_har
  accessModes: ["ReadWriteOnce"]
  capacity:
    storage: 5Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv003
  labels:
    name: pv003
spec:
  nfs:
    path: /data/volumes/v3
    0server: data_har
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 20Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv004
  labels:
    name: pv004
spec:
  nfs:
    path: /data/volumes/v4
    server: data_har
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 10Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv005
  labels:
    name: pv005
spec:
  nfs:
    path: /data/volumes/v5
    server: data_har
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    torage: 10Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv006
  labels:
    name: pv006
spec:
  nfs:
    path: /data/volumes/v6
    server: data_har
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 1Gi

以上PV有6个,每个路径都不一样,每个路径都和nfs路径相对应

showmount -e
Export list for data_har:
/data/volumes/v6 10.5.0.0/8
/data/volumes/v5 10.5.0.0/8
/data/volumes/v4 10.5.0.0/8
/data/volumes/v3 10.5.0.0/8
/data/volumes/v2 10.5.0.0/8
/data/volumes/v1 10.5.0.0/8

创建完成后可以kubectl get pv查看具体创建信息
举例:以上创建的结果是:

NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
pv001   2Gi        RWO,RWX        Retain           Available                                   3h12m
pv002   5Gi        RWO            Retain           Available                                   3h12m
pv003   20Gi       RWO,RWX        Retain           Available                                   3h12m
pv004   10Gi       RWO,RWX        Retain           Available                                   3h12m
pv005   10Gi       RWO,RWX        Retain           Available                                   3h12m
pv006   1Gi        RWO,RWX        Retain           Available                                   3h12m

其中RECLAIM POLICY这一项是回收策略,本文没有制定回收策略所以默认显示Retain意为保留策略。建议使用保留策略,而STATUS一栏显示Available,意为可用状态,可以被PVC所绑定
PVC:在k8s中PVC是保存在ETCD中的,一般情况下只删除POD,不会去动PVC,PV在绑定PVC的情况下是无法删除,需解绑后才能删除,在1.9版本以下是可以直接删除PV的

示例:

apiVersion: v1
kind: PersistentVolumeClaim         #创建PVC类型
metadata:
  name: mypvc                       #PVC名字
  namespace: default                #PVC隶属于那个名称空间,要和绑定的Pod在同一种名称空间中,因为下方Pod属于default所以这里也要写default
spec:
  accessModes: ["ReadWriteMany"]    #PVC支持的格式,此处支持多节点读写,注意此处要和绑定的PV属于同一种类型,或者多类型中的其中一种
  resources:          
    requests:
      storage: 5Gi                  #指定需要的大小空间
---
apiVersion: v1
kind: Pod
metadata:
  name: pod-vol-pvc
  namespace: default
spec:
  containers:
    - name: myapp
      image: ikubernetes/myapp:v1
      imagePullPolicy: IfNotPresent
      volumeMounts: 
      - name: html
        mountPath: /usr/share/nginx/html
    volumes:
    - name: html
      persistentVolumeClaim:
        claimName: mypvc                #此处要和上方的name相对应,以name的方式来绑定PVC

举例挂载nginx的html目录和日志目录到nfs:

apiVersion: v1
kind: Service
metadata:
  labels:
    app: nginx-deploy-svc
  name: nginx-deploy-svc
spec:
  type: NodePort
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30008
      protocol: TCP
  selector:
    app: nginx-deploy-pvc
---
apiVersion: v1
kind: PersistentVolumeClaim         #创建PVC类型
metadata:
  name: nginx-pvc                   #PVC名字
spec:
  accessModes: ["ReadWriteMany"]    #PVC支持的格式,此处支持多节点读写,注意此处要和绑定的PV属于同一种类型,或者多类型中的其中一种
  resources:          
    requests:
      storage: 5Gi                  #指定需要的大小空间
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nginx-log
spec:
  accessModes: ["ReadWriteMany"]
  resources:          
    requests:
      storage: 5Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx-deploy-pvc
  name: nginx-deploy-pvc
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx-deploy-pvc
  template:
    metadata:
      labels:
        app: nginx-deploy-pvc
    spec:
      containers:
      - image: ikubernetes/myapp:v1
        name: myapp
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 80
          protocol: TCP
        volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html
        - name: log
          mountPath: /var/log/nginx/
      volumes:
        - name: html
          persistentVolumeClaim:
            claimName: nginx-pvc
        - name: log
          persistentVolumeClaim:
            claimName: nginx-log
最后修改:2023 年 06 月 09 日
如果觉得我的文章对你有用,请随意赞赏