欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  科技

kubernetes系列10—存储卷详解

程序员文章站 2022-05-02 13:45:08
本文收录在容器技术学习系列文章总目录 1、认识存储卷 1.1 背景 默认情况下容器中的磁盘文件是非持久化的,容器中的磁盘的生命周期是短暂的,这就带来了一系列的问题:第一,当一个容器损坏之后,kubelet 会重启这个容器,但是文件会丢失-这个容器会是一个全新的状态;第二,当很多容器在同一Pod中运行 ......

本文收录在

1、认识存储卷

1.1 背景

  默认情况下容器中的磁盘文件是非持久化的,容器中的磁盘的生命周期是短暂的,这就带来了一系列的问题:第一,当一个容器损坏之后,kubelet 会重启这个容器,但是文件会丢失-这个容器会是一个全新的状态;第二,当很多容器在同一pod中运行的时候,很多时候需要数据文件的共享。kubernete volume解决了这个问题。

 

1.2 介绍

  docker有一个volumes的概念,虽然这个volume有点宽松和管理性比较小。在docker中,一个 volume 是一个简单的所在主机的一个目录或者其它容器中的。生命周期是没有办法管理,直到最近才有 local-disk-backed 磁盘。docker现在提供了磁盘驱动,但是功能非常有限(例如docker1.7只能挂在一个磁盘每个容器,并且无法传递参数)

  从另外一个方面讲,kubernetes volume,拥有明确的生命周期,与所在的pod的生命周期相同。因此,kubernetes volume独立与任何容器,与pod相关,所以数据在重启的过程中还会保留,当然,如果这个pod被删除了,那么这些数据也会被删除。更重要的是,kubernetes volume 支持多种类型,任何容器都可以使用多个kubernetes volume

  它的核心,一个 volume 就是一个目录,可能包含一些数据,这些数据对pod中的所有容器都是可用的,这个目录怎么使用,什么类型,由什么组成都是由特殊的volume 类型决定的。

  要使用volumepod需要指定volume的类型和内容(spec.volumes字段),和映射到容器的位置(spec.containers.volumemounts字段)。

  容器中的进程可以看成由docker镜像和卷组成的文件系统视图。docker镜像位于文件系统层次结构的根目录下,任何卷都安装在图像中的指定路径上。卷无法装入其他卷或具有到其他卷的硬链接。pod中的每个容器必须独立指定每个卷的安装位置。

 

1.3 存储卷常用类型

  •  非持久性存储
    •  emptydir
    •  hostpath
  •  网络连接性存储
    •  saniscsi
    •  nfsnfscfs
  •  分布式存储
    •  glusterfsrbdcephfs
  •  云端存储
    •  ebsazure disk、阿里云、gitrepo
$ kubectl explain pod.spec.volumes 查询k8s支持的所有类型存储卷

 

2、emptydir存储卷

2.1 emptydir介绍

  使用emptydir,当pod分配到node上时,将会创建emptydir,并且只要node上的pod一直运行,volume就会一直存。当pod(不管任何原因)从node上被删除时,emptydir也同时会删除,存储的数据也将永久删除。

  常用于作为临时目录、或缓存使用。

 

2.2 演示:创建emptydir存储卷

1)编写yaml文件,并创建

先创建一个名为html的存储卷;再由2pod都挂载此存储卷;

pod1基于此存储卷作为nginx的主目录;pod2向此存储卷目录写入东西;

[root@master volumes]# vim vol-emptydir-demo.yaml
apiversion: v1
kind: pod
metadata:
  name: pod-vol-demo
  namespace: default
  labels:
    app: myapp
    tier: frontend
  annotations:
    along.com/created-by: "cluster admin"
spec:
  volumes:
  - name: html
    emptydir: {}
  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"
[root@master volumes]# kubectl apply -f vol-emptydir-demo.yaml
pod/pod-vol-demo created

  

2)验证

---pod创建成功
[root@master ~]# kubectl get pods -o wide
name           ready     status    restarts   age       ip             node
pod-vol-demo   2/2       running   0          13s       10.244.1.106   node1
---访问业务,输出是pod2的输入
[root@master ~]# curl 10.244.1.106
tue jan 29 07:19:13 utc 2019
tue jan 29 07:19:15 utc 2019
tue jan 29 07:19:17 utc 2019
tue jan 29 07:19:19 utc 2019
tue jan 29 07:19:21 utc 2019
tue jan 29 07:19:23 utc 2019
tue jan 29 07:19:25 utc 2019
tue jan 29 07:19:27 utc 2019
tue jan 29 07:19:29 utc 2019

  

3、hostpath存储卷

3.1 emptydir介绍

  hostpath允许挂载node(宿主机)上的文件系统到pod里面去。如果pod需要使用node上的文件,可以使用hostpath

 

3.2 hostpath类型

行为
空字符串(默认)用于向后兼容,这意味着在安装hostpath卷之前不会执行任何检查。
directoryorcreate 如果给定路径中不存在任何内容,则将根据需要创建一个空目录,权限设置为0755,与kubelet具有相同的组和所有权。
directory 目录必须存在于给定路径中
fileorcreate 如果给定路径中不存在任何内容,则会根据需要创建一个空文件,权限设置为0644,与kubelet具有相同的组和所有权。
file 文件必须存在于给定路径中
socket unix套接字必须存在于给定路径中
chardevice 字符设备必须存在于给定路径中
blockdevice 块设备必须存在于给定路径中

 

3.2 演示:创建hostpath存储卷

1)编写yaml文件,并创建

创建存储卷,使用directoryorcreate类型,node节点不存在会自动创建

[root@master volumes]# vim vol-hostpath-demo.yaml
apiversion: v1
kind: pod
metadata:
  name: vol-hostpath
  namespace: default
spec:
  volumes:
  - name: html
    hostpath:
      path: /data/pod/volume1/
      type: directoryorcreate
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    volumemounts:
    - name: html
      mountpath: /usr/share/nginx/html/
[root@master volumes]# kubectl apply -f vol-hostpath-demo.yaml
pod/vol-hostpath created

  

2)查询验证

[root@master volumes]# kubectl get pods -o wide
name           ready     status    restarts   age       ip             node
vol-hostpath   1/1       running   0          3s        10.244.1.111   node1
---在node1上查询是否生产目录
[root@node1 ~]# ll -d /data/pod/volume1/index.html 
-rw-r--r-- 1 root root 17 sep 21 14:44 /data/pod/volume1/index.html

  

3)验证存储卷功能

---在node1上生成文件
[root@node1 ~]# echo "node01.along.com" > /data/pod/volume1/index.html
---访问pod内服务,显示成功
[root@master volumes]# curl 10.244.1.111
node01.along.com

  

4)就算pod被删除再重建,只要node还在,存储卷就还在

[root@master volumes]# kubectl delete -f vol-hostpath-demo.yaml
pod "vol-hostpath" deleted
[root@master volumes]# kubectl apply -f vol-hostpath-demo.yaml
pod/vol-hostpath created
[root@master volumes]# kubectl get pods -o wide
name           ready     status    restarts   age       ip             node
vol-hostpath   1/1       running   0          3s        10.244.1.112   node1
[root@master volumes]# curl 10.244.1.112
node01.along.com

  

4、共享存储nfs存储卷

4.1 nfs存储卷介绍

  nfs network file system的缩写,即网络文件系统。kubernetes中通过简单地配置就可以挂载nfspod中,nfs中的数据是可以永久保存的,同时nfs支持同时写操作。pod被删除时,volume被卸载,内容被保留。这就意味着nfs能够允许我们提前对数据进行处理,而且这些数据可以在pod之间相互传递。

 

4.2 演示:创建nfs存储卷

4.2.1 在一台服务器搭建nfs

1)事前准备

修改k8s集群服务的hosts文件,使之能解析nfs服务器

[root@master volumes]# vim /etc/hosts
192.168.130.103 master
192.168.130.104 node1
192.168.130.105 node2
192.168.130.106 nfs

k8s集群服务器,安装nfs-utils 工具

$ yum -y install nfs-utils

  

2)在106服务器上提供nfs服务

[root@nfs ~]# yum -y install nfs-utils
[root@nfs ~]# mkdir /data/volumes -p
[root@nfs ~]# vim /data/volumes/index.html
<h1>nfs stor</h1>
[root@nfs ~]# vim /etc/exports
/data/volumes	192.168.130.0/24(rw,no_root_squash)
[root@nfs ~]# systemctl start nfs

  

4.2.1 创建nfs存储卷

1)编写yaml文件,并创建

[root@master volumes]# vim vol-nfs-demo.yaml 
apiversion: v1
kind: pod
metadata:
  name: vol-nfs
  namespace: default
spec:
  volumes:
  - name: html
    nfs:
      path: /data/volumes
      server: nfs
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    volumemounts:
    - name: html
      mountpath: /usr/share/nginx/html/
[root@master volumes]# kubectl apply -f vol-nfs-demo.yaml
pod/vol-nfs created

  

2)验证,访问服务成功

[root@master ~]# kubectl get pods -o wide
name      ready     status    restarts   age       ip             node
vol-nfs   1/1       running   0          9s        10.244.1.115   node1
[root@master ~]# curl 10.244.1.115
<h1>nfs stor</h1>

删除pod,再创建,也还存在数据。

 

5、一些不常用的存储卷

5.1 gitrepo

1)介绍

gitrepo volumegit代码下拉到指定的容器路径中

 

2)示例

apiversion: v1
kind: pod
metadata:
  name: server
spec:
  volumes:
  - name: git-volume
    gitrepo:
      repository: "git@github.com:alonghub/my-git-repository.git"
     revision: "22f1d8406d464b0c0874075539c1f2e96c253775"
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    imagepullpolicy: ifnotpresent
    ports:
    - name: http
      containerport: 80
    volumemounts:
    - name: git-volume
      mountpath: /usr/share/nginx/html/

  

5.2 glusterfs

  glusterfs,允许将glusterfs(一个开源网络文件系统)volume安装到pod中。不同于emptydirpod被删除时,volume只是被卸载,内容被保留。味着glusterfs能够允许我们提前对数据进行处理,而且这些数据可以在pod之间切换

  注意::必须先运行自己的glusterfs安装,然后才能使用它。

  有关更多详细信息,请参阅glusterfs示例

 

5.3 rbd

  rbd允许rados block device格式的磁盘挂载到pod中,同样的,当pod被删除的时候,rbd也仅仅是被卸载,内容保留,rbd能够允许我们提前对数据进行处理,而且这些数据可以在pod之间切换

  有关更多详细信息,请参阅rbd示例

 

5.4 cephfs

  cephfs volume可以将已经存在的cephfs volume挂载到pod中,与emptydir特点不同,pod被删除的时,cephfs仅被被卸载,内容保留。cephfs能够允许我们提前对数据进行处理,而且这些数据可以在pod之间切换

  提示:可以使用自己的ceph服务器运行导出,然后在使用cephfs

  有关更多详细信息,请参阅cephfs示例