k8s之存储卷 

存储卷-----数据卷

容器内的目录和宿主机的目录进行挂载

容器在系统上的生命周期是短暂的,delete,k8s用控制创建的pod,delete相当于重启,容器的状态也会恢复到初始状态

一旦回到初始状态,所有的后天编辑的文件都会消失

容器和节点之间创建一个可以持久保存容器内文件的存储卷,即使容器被销毁,删除,重启,节点上的存储卷的数据依然存在,后续可以继续使用。可以继续将容器内目录和宿主机挂载,保存的数据继续使用

1、emptyDir:

容器内部共享存储卷,k8s系统当中,是一个pod当中的多个容器共享一个存储卷目录

emptyDir卷可以使pod当中容器在这个存储卷上读取和写入

emptyDir是不能挂载到节点的,随着pod的生命周期结束,emptyDir也会结束,数据也不会保留

容器内部共享,lnmp

apiVersion: apps/v1

kind: Deployment

metadata:

  labels:

    app: nginx

  name: nginx

spec:

  replicas: 3

  selector:

    matchLabels:

      app: nginx

  template:

    metadata:

      labels:

        app: nginx

    spec:

      containers:

      - image: nginx:1.22

        name: nginx1

        volumeMounts:

        - name: html

          mountPath: /usr/share/nginx/html

#第一个name,存储卷的名称,可以自定义,mountPath是定义容器内的挂载点,和节点,或者其他容器的共享>目录

      - image: nginx:1.22

        name: nginx2

        volumeMounts:

        - name: html

          mountPath: /data

#引用上一个挂载的名称,表示我将和/usr/share/nginx/html这个目录挂载,由data目录和他挂载

        command: ["/bin/bash", "-c", "while true; do echo $(date) >> /data/index.html; sleep 2; done"]

      volumes:

      - name: html

        emptyDir: {}

kubectl apply -f pod-emptydir.yaml

kubectl exec -it nginx-dir-86ccb4cd78-pttv4 -c nginx1 bash

kubectl exec -it nginx-dir-86ccb4cd78-pttv4 -c nginx2 bash

kubectl get pods -o wide

NAME           READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES

pod-emptydir   2/2     Running   0          36s   10.244.2.19   node02   <none>           <none>

//在上面定义了2个容器,其中一个容器是输入日期到index.html中,

然后验证访问nginx的html是否可以获取日期。以验证两个容器之间挂载的emptyDir实现共享。

curl 10.244.2.19

Thu May 27 18:17:11 UTC 2021

Thu May 27 18:17:13 UTC 2021

Thu May 27 18:17:15 UTC 2021

Thu May 27 18:17:17 UTC 2021

Thu May 27 18:17:19 UTC 2021

Thu May 27 18:17:21 UTC 2021

Thu May 27 18:17:23 UTC 2021

题:

污点设置为NoExecute,节点上的pod会被驱逐,那么文件数据在不在?

答:1、在的,pod被驱逐,并不是node节点被销毁,所有数据还保留在节点上

2、pod被驱逐(基于控制器创建的)会在其他节点重新部署,又会在其他节点生成一个新的存储卷,数据依然可以持久化

emptyDir的共享数据,会丢失

2、hostPath:

将容器内部的挂载点和节点上的目录进行挂载,hostPath可以实现数据的持久化。node节点如果被销毁,那么数据也会丢失

apiVersion: apps/v1

kind: Deployment

metadata:

  labels:

    app: nginx

  name: nginx

spec:

  replicas: 3

  selector:

    matchLabels:

      app: nginx

  template:

    metadata:

      labels:

        app: nginx

    spec:

      containers:

      - image: nginx:1.22

        name: nginx1

        volumeMounts:

        - name: html

          mountPath: /usr/share/nginx/html

#第一个name,存储卷的名称,可以自定义,mountPath是定义容器内的挂载点,和节点,或

者其他容器的共享目录

      - image: nginx:1.22

        name: nginx2

        volumeMounts:

        - name: html

          mountPath: /data

#引用上一个挂载的名称,表示我将和/usr/share/nginx/html这个目录挂载,由data目录>和他挂载

        command: ["/bin/bash", "-c", "while true; do echo $(date) >> /data/index.html; sleep 2; done"]

      volumes:

      - name: html

        hostPath:

          path: /opt/test

          type: DirectoryOrCreate

kubectl apply -f pod-hostpath.yaml

//访问测试

kubectl get pods -o wide

NAME           READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES

pod-hostpath   2/2     Running   0          37s   10.244.2.35   node02   <none>           <none>

curl 10.244.2.35

node02.kgc.com

//删除pod,再重建,验证是否依旧可以访问原来的内容

kubectl delete -f test2.yaml  

kubectl apply -f test2.yaml  

kubectl get pods -o wide

NAME           READY   STATUS    RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES

pod-hostpath   2/2     Running   0          36s   10.244.2.37   node02   <none>           <none>

curl  10.244.2.37

node02.kgc.com

kubectl logs nginx-74769444c-d9g25 -c nginx1:查看不同容器的日志

kubectl exec -it nginx-74769444c-d9g25 -c nginx1 bash:进入指定容器

3NFS共享存储

所有的pod内的目录都和节点上的nfs共享目录形成数据卷,所有的数据文件都保存在共享目录当中。好处就是集中,方便管理

//在94stor01节点上安装nfs,并配置nfs服务

mkdir /data/volumes -p

chmod 777 /data/volumes

vim /etc/exports

/data/volumes 192.168.233.0/24(rw,no_root_squash)

systemctl start rpcbind

systemctl start nfs

showmount -e

Export list for stor01:

/data/volumes 192.168.233.0/24


//master节点操作

apiVersion: apps/v1

kind: Deployment

metadata:

  name: nginx-dir1

  namespace: default

spec:

  replicas: 3

  selector:

    matchLabels:

      app: nginx2

      tier: frontend1

  template:

    metadata:

      labels:

        app: nginx2

        tier: frontend1

    spec:

      containers:

      - name: nginx1

        image: nginx:1.22

        imagePullPolicy: IfNotPresent

        volumeMounts:

        - name: html

          mountPath: /usr/share/nginx/html/

      - name: nginx2

        image: nginx:1.22

        imagePullPolicy: IfNotPresent

        volumeMounts:

        - name: html

          mountPath: /data/

          readOnly: false

        command: ['/bin/sh', '-c', 'while true; do echo $(date) >> /data/index.html; sleep 2; done']

      volumes:

      - name: html

        nfs:

          path: /data/volumes

          server: k8s4

#也可以是用ip地址

注意:最后一行server可以是共享节点的ip地址,也可以是主机名,如果最后一行server用主机名的话,那就要做映射/etc/hosts

pvc和pv

pv:全称Persistent Volume(yaml文件里要写全称)持久化存储卷,描述和定义一个存储卷,pv是由我们运维人员来定的

pvc:全称Persistent Volume Claimyaml(文件里要写全称)持久化存储的请求。pvc实际上是用来描述或者声明我希望使用什么样的pv来进行存储

pvc-pv是一一对应的关系(描述,存储(大小))

pvc-------pv-------NFS

pvc和pv都是虚拟化的概念,是k8s的抽象的虚拟的存储资源

pvc和pv之间静态请求,一旦成百个pvc怎么办,所以还有动态pvc

pv是集群当中的存储资源,pvc请求存储资源,也是对存储资源的一个检索(检查索引),选择一个最合适的pv来存储资源

pv和pvc之间是有生命周期管理:

1、Provisioning(配置)-------pvc请求request-------检索(找一个合适的pv)---------pvc和pv(binding绑定)--------使用-------pod被删除---------pv(releasing释放)--------recycling回收

配置:静态、动态

绑定:就是把pv分配给pvc

使用:就是pod通过pvc使用存储资源

releasing释放:pod解除和volume挂载卷的关系,删除pvc

回收:保留pv,以供下一个pvc使用

pod内的挂载点声明一个请求,就是pvc请求,pvc会找一个最合适的pv来作为pod存储卷,pv和共享目录在一一映射,最终由nfs来提供最终的共享存储空间

pv的状态:

Available:可用,而且没有被任何pvc绑定

Bound:绑定,pv已经绑定到了pvc绑定即使用

released:释放,pvc已经被删除了,但是pv的存储资源还没有被集群回收

Failed:表示pv的资源回收失败,而且pv为不可用状态

ReadWriteOnce简写是RWO,配置文件里是全称,表示存储pv是可读可写,但是只能被单个pod挂载

ReadOnlyMany简写是ROX,存储的pv可以以只读的方式被多个pod挂载

ReadWriteMany简写是RWX,存储可以支持读写的方式被多个pod共享

nfs:可以支持三种读写和挂载方式

hostPath:支持ReadWriteOnce方式

SCSI

ISCSI不支持ReadWriteMany

iscsiadm -m session -P 3

iscsiadm:查看服务器是否有iscsi设备

-m session:指定操作的会话模块,管理iscsi的会话

-P 3:显示详细信息的级别,级别就是3

集群回收pv资源的方式:

1、Retain:保留,pod和挂载点的数据不会被删除

2、Recycle:回收,pv上的数据被删除,挂载点的数据也被删除

3、Delete:淡出,解绑时,自动删除pv上的数据(本地硬盘不能使用,AWS,EBS,GCE)支持动态卷的可以使用,pv也不再可用(云平台自己处理)

补充:当pod运行之后,通过pvc请求到了pv,除非pod被销毁,否则无法删除pvc

#创建共享目录

mkdir -p /data/volumes/v{1..5}

给volumes赋权

#进行exports共项目录的编辑

vim /etc/exports

/data/vulumes/v1 192.168.73.0/24(rw,sync,no_root_squash)

/data/vulumes/v2 192.168.73.0/24(rw,sync,no_root_squash)

/data/vulumes/v3 192.168.73.0/24(rw,sync,no_root_squash)

/data/vulumes/v4 192.168.73.0/24(rw,sync,no_root_squash)

/data/vulumes/v5 192.168.73.0/24(rw,sync,no_root_squash)

systemctl start rpcbind

systemctl start nfs

showmount -e

#发布共享目录

exportfs -avf

然后去主节点showmount -e 192.168.233.34

在主机编写pv资源创建yaml文件

apiVersion: v1

kind: PersistentVolume

metadata:

  name: pv001

  labels:

    name: pv001

spec:

  nfs:

    path: /data/v1

    server: 192.168.233.94

  accessModes: ["ReadWriteMany","ReadWriteOnce"]

  capacity:

    storage: 1Gi

---

apiVersion: v1

kind: PersistentVolume

metadata:

  name: pv00

  labels:

    name: pv002

spec:

  nfs:

    path: /data/v2

    server: 192.168.233.94

  accessModes: ["ReadWriteOnce"]

  capacity:

    storage: 2Gi

---

apiVersion: v1

kind: PersistentVolume

metadata:

  name: pv003

  labels:

    name: pv003

spec:

  nfs:

    path: /data/v3

    server: 192.168.233.94

  accessModes: ["ReadWriteMany","ReadWriteOnce"]

  capacity:

    storage: 2Gi

---

apiVersion: v1

kind: PersistentVolume

metadata:

  name: pv004

  labels:

    name: pv004

spec:

  nfs:

    path: /data/v4

server: 192.168.233.94

accessModes: ["ReadWriteMany","ReadWriteOnce"]

  capacity:

    storage: 4Gi

---

apiVersion: v1

kind: PersistentVolume

metadata:

  name: pv005

  labels:

    name: pv005

spec:

  nfs:

    path: /data/v5

    server: 192.168.233.94

  accessModes: ["ReadWriteMany","ReadWriteOnce","ReadOnlyMany"]

  capacity:

    storage: 5Gi

在主节点上再创建pvc资源,并且设置匹配绑定相应的pv

apiVersion: v1

kind: PersistentVolumeClaim

metadata:

  name: mypvc

spec:

  accessModes: ["ReadWriteMany"]

#pvc期望请求的pv的读写挂载类型是什么

  resources:

    requests:

      storage: 2Gi

#pvc期望请求pv的存储大小是2G,期望的pv类型:readwritemany,大小是2G

---

apiVersion: apps/v1

kind: Deployment

metadata:

  labels:

    app: nginx

  name: nginx

spec:

  replicas: 3

  selector:

    matchLabels:

      app: nginx

  template:

    metadata:

      labels:

        app: nginx

    spec:

      containers:

      - image: nginx:1.22

        name: nginx1

        volumeMounts:

        - name: html

          mountPath: /usr/share/nginx/html

      volumes:

      - name: html

        persistentVolumeClaim:

          claimName: mypvc

进到94节点v3里面echo一个123到index.html

然后在主节点操作:

如果想再次被请求,就进这个命令,然后删除到nfs

总结:

k8s当中存储卷的模式:

emptyDir:容器内存储卷,随着pod被销毁,也会被销毁,数据不保留

hostPath:节点目录的存储卷,可以实现持久化存储。数据在每个节点上都有,不方便集中管理

nfs:共享目录存储卷,可以实现持久化。数据集中在一个目录。方便管理

pv和pvc:

pvc请求--------pv的存储资源---------硬盘空间(NFS)

nfs支持pvc的索引挂载方式和读写模式

hostPath仅支持ReadWriteOnce方式

pvc是以检索的方式找到匹配的pv资源

检索挂载方式和读写模式

检索pv能提供的存储资源的大小

谁合适选谁

保留:默认可以不写

回收:自动回收,节点上的数据会被删除

删除:pv会变成failed模式,不可用,数据也会被删除

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐