k8s存储——持久化存储


k8s中为什么要做持久化存储?

在 k8s 中部署的应用都是以 pod 容器的形式运行的。

        假如我们部署 MySQL、Redis 等数据库,需要对 这些数据库产生的数据做备份。因为 Pod 是有生命周期的,如果 pod 不挂载数据卷,那 pod 被删除或重启后这些数据会随之消失,如果想要长久的保留这些数据就要用到 pod 数据持久化存储。

        除了希望数据不在Pod重启后丢失,有时候也需要在Pod间共享文件。因此,Kubernetes抽象出Volume对象来解决这两个问题。

容器在使用Volume时不需要关心后端存储是什么系统,对它来说,所有类型的volume都只是一个目录。

我们想要使用存储卷,需要经历如下步骤

1、定义 pod 的 volume,这个 volume 指明它要关联到哪个存储上的

2、在容器中要使用 volumemounts 挂载对应的存储 经过以上两步才能正确的使用存储卷

Volume类型

k8s中支持的卷类型比较丰富,包括:

 NFS文件系统
Cephfs等分布式存储系统。
awsElasticBlockStore,azureDisk等公有云存储服务。
emptyDir,configMap,HostPath等kubernetes等内置存储类型
ISCSI,FC等....
这里主要讲的就是第四种内置存储类型。

EmptyDir
        emptyDir 类型的 Volume 是在 Pod 分配到 Node 上时被创建,Kubernetes 会在 Node 上自动分配一个目录,因此无需指定宿主机 Node 上对应的目录文件。 这个目录的初始内容为空,当 Pod 从 Node 上移除时, emptyDir 中的数据会被永久删除。emptyDir Volume 主要用于某些应用程序无需永久保存的临时目录,多 个容器的共享目录等。

empttyDir是一种方便但不安全的临时存储解决方案。

创建一个使用EmptyDir的Pod

[root@master tmp]# cat empty-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: emd
spec:
  containers:
  - image: centos7
    name: g-container
    volumeMounts:    //设置volume的挂载点
    - mountPath: /cache  
      name: cache-volume
    args:
    - /bin/sh
    - -c
    - sleep 30000
  volumes:   //配置volume
  - name: cache-volume
    emptyDir: {}  //默认配置
 
————————————————————————————————————————
  volumes:
  - name: cache-volume
    emptyDir:
        sizeLimit: 1Gi     //限制emptyDir容量(1G)

更新文件,查看Pod处于running状态,(正常)。Pod创建在node1节点 

[root@master tmp]# kubectl get pods -o wide
NAME   READY   STATUS    RESTARTS   AGE     IP           NODE    NOMINATED NODE   READINESS GATES
emd    1/1     Running   0          5m20s   10.244.1.3   node1   <none>           <none>

下面步骤都是在node1节点上操作的

登录node1节点,查看运行的容器。找到我们刚刚创建的容器。

[root@node1 ~]# docker ps
CONTAINER ID   IMAGE                               COMMAND                  CREATED         STATUS         PORTS     NAMES
9b55b68c67d1   centos                              "/bin/sh -c 'sleep 3…"   9 minutes ago   Up 9 minutes             k8s_g-container_emd_default_b7765e8a-60ed-4975-9089-d7c8d64d2080_0

 进入容器,在emptyDir挂载目录中创建一个文件

[root@node1 ~]# docker exec -it 9b55b68c67d1  /bin/sh
sh-4.4# ls
bin  cache  dev  etc  home  lib  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  s
sh-4.4# cd cache
sh-4.4# echo "hello.file.emptyDir" >test.txt
sh-4.4# ls
test.txt
sh-4.4# cat test.txt
hello.file.emptyDir
sh-4.4# exit
exit

使用docker inspect 查看对应容器的挂载点可以看到在容器中创建的内容主机目录也有。

[root@node1 ~]# docker inspect 9b55b68c67d1
 
.......
  "Mounts": [      //快速定位Mounts
            {
                "Type": "bind",
                "Source": "/var/lib/kubelet/pods/b7765e8a-60ed-4975-9089-d7c8d64d2080/volumes
                "Destination": "/cache",
                "Mode": "Z",
                "RW": true,
                "Propagation": "rprivate"
            },
......
[root@node1 ~]# cd /var/lib/kubelet/pods/b7765e8a-60ed-4975-9089-d7c8d64d2080/volumes
[root@node1 volumes]# ls
kubernetes.io~empty-dir  kubernetes.io~secret
[root@node1 volumes]# cd kubernetes.io~empty-dir/
[root@node1 kubernetes.io~empty-dir]# ls
cache-volume
[root@node1 kubernetes.io~empty-dir]# cd cache-volume/
[root@node1 cache-volume]# ls
test.txt
[root@node1 cache-volume]# cat test.txt
hello.file.emptyDir
[root@node1 cache-volume]#

 弊端:

 回到master节点删除pod 

[root@master tmp]# kubectl get pods
NAME   READY   STATUS    RESTARTS   AGE
emd    1/1     Running   0          27m
[root@master tmp]# kubectl delete pods emd
pod "emd" deleted

回到node2 节点,发现文件以及目录都不见了

[root@node1 cache-volume]# cd /var/lib/kubelet/pods/b7765e8a-60ed-4975-9089-d7c8d64d2080/volumes
-bash: cd: /var/lib/kubelet/pods/b7765e8a-60ed-4975-9089-d7c8d64d2080/volumes: No such file or directory
[root@node1 cache-volume]# cd /var/lib/kubelet/pods/
[root@node1 pods]# ls
377290eb-fb56-4cc6-b0df-d5b0709a7c22  594ea3fb-cf8b-4c1a-b0da-c3bd5daca320
[root@node1 pods]#
 HostPath(不建议使用)
         HostPath Volume 是指 Pod 挂载宿主机上的目录或文件。 hostPath Volume 使得容器可以使用宿主机 的文件系统进行存储,hostpath(宿主机路径):节点级别的存储卷,在 pod 被删除,这个存储卷还是存在 的,不会被删除,

所以只要同一个 pod 被调度到同一个节点上来,在 pod 被删除重新被调度到这个节点之 后,对应的数据依然是存在的。

hostpath 存储卷缺点: 单节点 pod 删除之后重新创建必须调度到同一个 node 节点,数据才不会丢失 。

hostPath使用时需要确定节点上是否存在对象资源

创建一个使用hostPath的pod 
配置与emptyDir类似

首先在master节点和node节点上创建挂载用的目录

[root@master ~]# mkdir /test-host

 创建pod

[root@master tmp]# cat hostPath-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: hp-pod
spec:
  containers:
  - image: centos
    name: hp-container
    volumeMounts:
    - mountPath: /hp-dir
      name: hp-volume
    args:
    - /bin/sh
    - -c
    - sleep 30000
  volumes:
  - name: hp-volume
    hostPath:            #类型指定为hostPath
      path: /test-host   #path参数需要配置为主机上已经存在的目录
      type: Directory    #type指定为目录
[root@master tmp]#

看到pod创建在node1节点上

[root@master tmp]# kubectl get pods -o wide
NAME     READY   STATUS    RESTARTS   AGE     IP           NODE    NOMINATED NODE   READINESS GATES
hp-pod   1/1     Running   0          6m59s   10.244.1.4   node1   <none>           <none>
[root@node1 ~]# docker ps
CONTAINER ID   IMAGE                               COMMAND                  CREATED          STATUS          PORTS     NAMES
5bba9ab5f6ea   centos                              "/bin/sh -c 'sleep 3…"   17 minutes ago   Up 17 minutes             k8s_hp-container_hp-pod_default_6fd3fdb8-ff05-4705-a812-23267d569325_0

进入容器写入一个文件

[root@node1 ~]# docker exec -it 5bba9ab5f6ea /bin/sh
 
sh-4.4# ls /
bin  etc   hp-dir  lib64       media  opt   root  sbin  sys  usr
dev  home  lib     lost+found  mnt    proc  run   srv   tmp  var
sh-4.4# cd /hp-dir
sh-4.4# echo "hello.test.hostPath">acc.txt
sh-4.4# ls
acc.txt
sh-4.4# cat acc.txt
hello.test.hostPath
sh-4.4# exit
exit

进入对应节点挂载目录,查看文件是否存在。

[root@node1 ~]# cd /test-host/
[root@node1 test-host]# ls
acc.txt
[root@node1 test-host]# cat acc.txt
hello.test.hostPath

回到master节点删除pod,在查看在pod中写入到文件是否存在

[root@master tmp]# kubectl get pods
NAME     READY   STATUS    RESTARTS   AGE
hp-pod   1/1     Running   0          27m
[root@master tmp]# kubectl delete pod hp-pod
pod "hp-pod" deleted

删除pod,发现文件没有随pod的删除而消失 。

[root@node1 /]# cd /test-host/
[root@node1 test-host]# ls
acc.txt
[root@node1 test-host]# cat acc.txt
hello.test.hostPath
[root@node1 test-host]#

PV和PVC

PV和PVC是最常见的使用存储的方式。

 k8s PV 是什么?
         PersistentVolume(PV)是群集中的一块存储,由管理员配置或使用存储类动态配置。 它是集群中的资源,就像 pod 是 k8s 集群资源一样。 PV 是容量插件,如 Volumes,其生命周期独立于使用 PV 的任何单个 pod。

k8s PVC 是什么?
        PersistentVolumeClaim(PVC)是一个持久化存储卷,我们在创建 pod 时可以定义这个类型的存储卷。 它类似于一个 pod。 Pod 消耗节点资源,PVC 消耗 PV 资源。 Pod 可以请求特定级别的资源(CPU 和内存)。 pvc 在申请 pv 的时候也可以请求特定的大小和访问模式(例如,可以一次读写或多次只读)。

创建一个使用PV和PVC的Pod
首先配置nfs服务。

[root@master ~]# yum install nfs-utils rpcbind –y
[root@master ~]# mkdir /pv-pvc
[root@master ~]# vim /etc/exports
-bash: vim: command not found
[root@master ~]# vi /etc/exports
[root@master ~]# cat /etc/exports
/pv-pvc *(rw)
[root@master ~]# systemctl restart rpcbind
[root@master ~]# systemctl restart nfs
[root@master ~]# systemctl restart nfs-server
[root@master ~]# showmount -e 192.168.225.30      #检查nfs是否正常,IP为nfs服务器地址
Export list for 192.168.225.30:
/pv-pvc *
[root@master ~]#

进入挂载目录创建 pv1 目录 

[root@master ~]# cd /pv-pvc/
[root@master pv-pvc]# mkdir pv1
[root@master pv-pvc]# ls
pv1
 

 创建PV

[root@master tmp]# vi pv1.yaml
[root@master tmp]# kubectl apply -f pv1.yaml
persistentvolume/mypv created
[root@master tmp]# cat pv1.yaml
apiVersion: v1
kind: PersistentVolume   #注意类型
metadata:
  name: mypv    #PVC要调用
spec:
  capacity:     #指定PV容量
    storage: 1Gi
  accessModes:     #指定访问模式
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle    #指定回收策略
  nfs:           #配置nfs服务器信息
    path: /pv-pvc/pv1
    server: 192.168.225.30
 
————————————————————————————————————————————————
accessModes
    ReadWriteOnce: 该卷能够以读写模式被加载到一个节点上。
    ReadOnlyMany: 该卷能够以只读模式加载到多个节点上。
    ReadwriteMany: 改卷能够以读写模式加载到多个节点上。
persistentVolumeReclaimPolicy
    Retain(保留) :不删除,需手动回收
    Recycle(回收):基本擦除,类似rm -rf ,使它可供其他PVC申请。
    Delete(删除) :关联存储将被删除。

 查看PV

[root@master tmp]# kubectl get pv
NAME   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
mypv   1Gi        RWO            Recycle          Available                                   22s

创建 PVC

[root@master tmp]# vi pvc1.yaml
[root@master tmp]# kubectl apply -f pvc1.yaml
persistentvolumeclaim/mypvc created
[root@master tmp]# cat pvc1.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mypvc
spec:
  accessModes:
   - ReadWriteOnce
  volumeName: mypv
  resources:
    requests:
      storage: 1Gi

 对比查看PV的状态从Avilable变为Bound,pvc的状态也是Bound。

[root@master tmp]# kubectl get pvc
NAME    STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
mypvc   Bound    mypv     1Gi        RWO                           47s
[root@master tmp]# kubectl get pv
NAME   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM           STORAGECLASS   REASON   AGE
mypv   1Gi        RWO            Recycle          Bound    default/mypvc                           30m

 创建Pod,使用该PVC

[root@master tmp]# vi testpod.yaml
[root@master tmp]# kubectl apply -f testpod.yaml
pod/pvc-pod created
[root@master tmp]# cat testpod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pvc-pod
spec:
  containers:
  - name: pvc-pod
    args:
    - /bin/sh
    - -c
    - sleep 30000;
    image: centos
    volumeMounts:
    - mountPath: /pv-pvc
      name: pvc-volume
  volumes:
    - name: pvc-volume
      persistentVolumeClaim:
        claimName: mypvc
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Kubernetes (K8s) 支持使用 NFS(Network File System)作为持久化存储解决方案。NFS 是一种分布式文件系统协议,允许将远程文件系统挂载到本地服务器上。 要使用 NFS 进行持久化存储,你需要先设置一个 NFS 服务器,并在 Kubernetes 集群中配置一个 NFS 持久卷。以下是一些步骤: 1. 配置 NFS 服务器:你需要设置一个 NFS 服务器并将其配置为共享文件系统。确保你已经安装并配置好了 NFS 服务器软件。 2. 创建 NFS 持久卷:在 Kubernetes 中,你可以使用 PersistentVolume(PV)和 PersistentVolumeClaim(PVC)对象来定义持久卷和持久卷声明。创建一个 PV 来表示 NFS 服务器上的共享目录,并为该 PV 创建一个 PVC。 3. 部署应用程序:使用创建的 PVC,在你的应用程序中声明一个持久卷。你可以通过将 PVC 挂载到应用程序的 Pod 中来实现持久化存储。 以下是一个示例的 YAML 文件,演示了如何在 Kubernetes 中配置一个 NFS 持久卷: ``` apiVersion: v1 kind: PersistentVolume metadata: name: nfs-pv spec: capacity: storage: 5Gi accessModes: - ReadWriteMany nfs: server: <NFS_SERVER_IP> path: /path/to/shared/directory --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: nfs-pvc spec: accessModes: - ReadWriteMany resources: requests: storage: 5Gi storageClassName: "" selector: matchLabels: name: nfs-pv ``` 替换 `<NFS_SERVER_IP>` 和 `/path/to/shared/directory` 为你 NFS 服务器的 IP 地址和共享目录的路径。然后,使用 kubectl apply 命令来部署这个 YAML 文件。 一旦 PVC 和 PV 创建成功,你可以在你的应用程序中使用该 PVC 来挂载 NFS 持久卷,并在 Pod 中进行持久化存储。 这就是使用 NFS 进行持久化存储的基本步骤。希望对你有所帮助!如果还有其他问题,请继续提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值