k8s的存储卷---数据卷

前言

容器磁盘上的文件的生命周期是短暂的,这就使得在容器中运行重要应用时会出现一些问题。首先,当容器崩溃时,kubelet 会重启它,但是容器中的文件将丢失——容器以干净的状态(镜像最初的状态)重新启动。其次,在Pod中同时运行多个容器时,这些容器之间通常需要共享文件。Kubernetes 中的Volume抽象就很好的解决了这些问题。Pod中的容器通过Pause容器共享Volume。
 

1.emptyDir(主要用于容器内部共享数据)

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

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

emptyDir是不能挂载到节点的,随着pod的生命周期结束

kubectl create deployment nginx --image=nginx:1.22 --replicas=3 --dry-run=client -o yaml > /opt/test1.yaml

vim test1.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx1
  name: nginx1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx1
  template:
    metadata:
      labels:
        app: nginx1
    spec:
      containers:
      - image: nginx:1.22
        name: nginx1
        volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html
      - image: nginx:1.22
        name: nginx2
        volumeMounts:
        - name: html
          mountPath: /data
        command: ["/bin/bash","-c","while true; do echo $(date) >> /data/index.html; sleep 2; done"]
      volumes:
      - name: html
        emptyDir: {}


 kubectl exec -it nginx1-6b677dd6bc-4rnkc -c nginx2 bash

k8s的存储卷---数据卷_第1张图片

k8s的存储卷---数据卷_第2张图片

k8s的存储卷---数据卷_第3张图片

k8s的存储卷---数据卷_第4张图片

2.hostPath

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

污点设置为:

NoExecute:节点上的pod会被驱逐,文件数据不在?

pod被驱逐,并不是node节点被销毁,所有数据还保留在节点上。

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

hostPath模拟展示

apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx1
  name: nginx1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx1
  template:
    metadata:
      labels:
        app: nginx1
    spec:
      containers:
      - image: nginx:1.22
        name: nginx1
        volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html
      - image: nginx:1.22
        name: nginx2
        volumeMounts:
        - name: html
          mountPath: /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

k8s的存储卷---数据卷_第5张图片

k8s的存储卷---数据卷_第6张图片

-c 进入不同容器内的信息

logs -c 查看不同容器输出的日志

3.NFS共享存储

所有的pod内的目录都和节点上的nfs共享目录形成数据卷,所有的数据文件都保存在共享目录当中。

使用nfs服务将共享存储设备空间挂载到容器中,可实现持久化数据存储,且Pod能实现跨节点共享数据 

k8s的存储卷---数据卷_第7张图片

node02
先把共享目录创建出来
mkdir /data/volumes
chmod 777 volumes/
vim /etc/exports

/data/volumes 20.0.0.0/24(rw,no_root_squash)
wq

systemctl restart rpcbind
systemctl restart nfs
showmount -e

master01
showmount -e 20.0.0.64

vim test1.yaml
    spec:
      containers:
      - image: nginx:1.22
        name: nginx1
        volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html
      - image: nginx:1.22   
        name: nginx2
        volumeMounts: 
        - name: html
          mountPath: /data 
        command: ["/bin/bash","-c","while true; do echo $(date) >> /data/index.html; sleep 2; done"]
      volumes:
      - name: html
        nfs:
          path: /data/volumes
          server: 20.0.0.64

wq

kubectl apply -f test1.yaml

node02
touch 123 456 789

去master01
kubectl exec -it nginx1-
cd /usr/share/html
exit

      volumes:
      - name: html
        nfs:
          path: /data/volumes
          server: node02   / 20.0.0.63
server可以是共享目录的ip地址,也可以是主机名。主机名要做映射   

k8s的存储卷---数据卷_第8张图片

k8s的存储卷---数据卷_第9张图片

k8s的存储卷---数据卷_第10张图片

k8s的存储卷---数据卷_第11张图片

PVC和PV的静态存储卷

pv:全称Persistent Volume 持久化存储卷,描述和定义一个存储卷,pv是由我们运维人员来定义。

pvc:persistent Volume Claim是持久化存储的请求。

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

pvc实际上是用来描述或者声明我希望使用什么样的pv来进行存储。

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

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

pvc和pv之间静态请求,一旦成百个pvc怎么办?-----使用动态pvc

PV是集群中的资源。 PVC是对这些资源的请求,也是对资源的索引检查。

k8s的存储卷---数据卷_第12张图片

PVC和PV的创建和销毁过程

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

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

●Provisioning,即 PV 的创建,可以直接创建 PV(静态方式),也可以使用 StorageClass 动态创建
●Binding,将 PV 分配给 PVC
●Using,Pod 通过 PVC 使用该 Volume,并可以通过准入控制StorageProtection(1.9及以前版本为PVCProtection) 阻止删除正在使用的 PVC
●Releasing,Pod 释放 Volume 并删除 PVC
●Reclaiming,回收 PV,可以保留 PV 以便下次使用,也可以直接从云存储中删除

根据这 5 个阶段,PV 的状态有以下 4 种:
●Available(可用):表示可用状态,还未被任何 PVC 绑定
●Bound(已绑定):表示 PV 已经绑定到 PVC
●Released(已释放):表示 PVC 被删掉,但是资源尚未被集群回收
●Failed(失败):表示该 PV 的自动回收失败

读写方式:

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

ReadOnlyMany:ROX,存储的pv可以以只读的方式被多个pod挂载。

ReadWriteMany:RWX存储可以支持读写的方式被多个pod共享。

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

SCSI

ISCSI:不支持 RWX

hostPath:只支持RWO,其他都不支持。

lsscsi可以查看当前设备的所有设备

iscsiadm -m session -P 3

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

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

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

k8s的存储卷---数据卷_第13张图片

回收策略

集群回收pv资源的方式:

Retain(默认策略):保留,pod和挂载点的数据不会被删除

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

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

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

vim /etc/exports
/data/v1 20.0.0.0/24(rw,no_root_squash)
/data/v2 20.0.0.0/24(rw,no_root_squash)
/data/v3 20.0.0.0/24(rw,no_root_squash)
/data/v4 20.0.0.0/24(rw,no_root_squash)
/data/v5 20.0.0.0/24(rw,no_root_squash)
wq

exportfs -arv
showmount -e
各个节点都查看一下

vim pv.yaml 
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv001
  labels:
    name: pv001
spec:
  nfs:
    path: /data/v1
    server: 20.0.0.64
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 1Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv002
  labels:
    name: pv002
spec:
  nfs:
    path: /data/v2
    server: 20.0.0.64
  accessModes: ["ReadWriteOnce"]
  capacity:
    storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv003
  labels:
    name: pv003
spec:
  nfs:
    path: /data/v3
    server: 20.0.0.64
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv004
  labels:
    name: pv004
spec:
  nfs:
    path: /data/v4
    server: 20.0.0.64
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 4Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv005
  labels:
    name: pv005
spec:
  nfs:
    path: /data/v5
    server: 20.0.0.64
  accessModes: ["ReadWriteMany","ReadWriteOnce","ReadOnlyMany"]
  capacity:
    storage: 5Gi

wq

kubectl apply -f pv.yaml
kubectl get pv


vim pvc.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mypvc
spec:
  accessModes: ["ReadWrtieMany"]
#pvc期望请求的pv的读写挂载类型是什么。
  resources:
    requests:
      storage: 2Gi
#pvc期望请求pv的存储大小是2G,期望的pv类型:readwritemany  大小是2G。
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx1
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
          
wq

kubectl apply -f test1.yaml
kubectl get pv

k8s的存储卷---数据卷_第14张图片

k8s的存储卷---数据卷_第15张图片

k8s的存储卷---数据卷_第16张图片

pvc---请求用哪个pv的存储-----pv和物理存储做映射(挂载)---物理设备提供存储卷

只有是Available才是可用被请求

同时,还可以对pv设置回收策略

k8s的存储卷---数据卷_第17张图片

模拟--一个pv匹配多个pod

vim pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv001
  labels:
    name: pv001
spec:
  nfs:
    path: /data/v1
    server: 20.0.0.63
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 1Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv002
  labels:
    name: pv002
spec:
  nfs:
    path: /data/v2
    server: 20.0.0.63
  accessModes: ["ReadWriteOnce"]
  capacity:
    storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv003
  labels:
    name: pv003
spec:
  nfs:
    path: /data/v3
    server: 20.0.0.63
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv004
  labels:
    name: pv004
spec:
  nfs:
    path: /data/v4
    server: 20.0.0.63
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 4Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv005
  labels:
    name: pv005
spec:
  nfs:
    path: /data/v5
    server: 20.0.0.63
  accessModes: ["ReadWriteMany","ReadWriteOnce","ReadOnlyMany"]
  capacity:
    storage: 5Gi








vim pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mypvc
spec:
  accessModes: ["ReadWriteMany"]
  resources:
    requests:
      storage: 2Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx-dir
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
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx-2
  name: nginx-dir1
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx-2
  template:
    metadata:
      labels:
        app: nginx-2
    spec:
      containers:
      - image: nginx:1.22
        name: nginx-2
        volumeMounts:
        - name: html
          mountPath: /usr/share/nginx/html
      volumes:
      - name: html
        persistentVolumeClaim:
          claimName: mypvc

k8s的存储卷---数据卷_第18张图片

总结:

k8s当中存储卷的模式:

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

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

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

pv和pvc:

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

因为NFS支持pvc的所有挂载方式和读写模式

hostPath:仅支持ReadWriteOnce方式。

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

检索挂载方式和读写模式:

检索pv能提供的存储资源的大小。谁合适选谁

资源保留三种方式:

保留:默认可以不写

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

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

你可能感兴趣的:(kubernetes,容器,云原生)