2020-03-28 Kubernetes—volume (上)

说起存储卷和docker的存储卷有几分相似的地方,数据不会跟随Pod的停止或删除而消失,从而实现数据的持久性,但是由于K8s的独特,K8s面对的是集群,如果要实现数据的持久性,Pod会分布到各个节点之上,所以引入了外部存储卷。

① · 常见的存储卷类型有:

  • emptyDir :当Pod生命周期结束后,存储卷会被一并删除,这种通常会存放一些临时数据。
  • hostPath:宿主机目录映射
  • 本地的SAN(iSCSI,FC)、NAS(nfs,cifs,http)存储
  • 分布式存储(glusterfs,rbd,cephfs)
  • 云存储(EBS,Azure Disk)
    种类繁多的存储无疑会提高K8s的使用门槛,这意味着你不仅要懂K8s还要懂存储的结构、用法、参数、使用场景等等等...
    所以K8s又引入了一个概念叫做PVC 全称 persistentVolumeClaim -->PVC(存储卷创建申请)
    当你需要一个存储空间的时候,只要进行对应的申请即可,灵魂图: ↓
image.png

在Pod 上定义一个PVC,但该PVC只是一个申请,他需要和PV进行关联,PV是属于存储设备上的一部分空间,so申请之前我们应该创建好对应大小的pv等待使用,那么就造成了每次用户需要存储卷的时候都要想K8s的管理员申请,等管理员建立好他才能进行PVC的申请,这听起来比较麻烦,于是又有了另一个方案。

image.png

不要pv层,把所有存储资源抽象成一个存储类,当用户申请PVC到达存储类的时候,会根据申请大小,自动创建出相应的存储空间,实现动态供给。

emptydir类型示例:

emptydir具体操作步骤: ↓
① · 在Pod层定义volume,并指明关联到哪个存储设备
② · 在容器中层使用 volume mount 进行挂载
emptydir:
是一个临时的空目录,在pod之上的每个容器都可以挂载到相同或不同的目录上,并且共享里面的内容,当Pod因为任何原因被删除时,存储卷会被一并删除,无法保留数据。但是容器崩溃的时候,不会影响数据,因为一个容器崩溃不会导致Pod被删除。
默认情况下emptydir是一个普通磁盘提供的存储空间,但是也可以定义为memory,意为使用node的内存来提供存储功能,因为内存性能强大,但是要注意当node重启的时候,内存内的数据会丢失,emptydir的数据也会随之消失。
清单示例:

apiVersion: v1
kind: Pod
metadata: 
  name: Pod-demo
  namespace: default
  labels:
    app: myapp
    tier: frontend
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: {}
  

上述清单定义了一个类型为emptydir的存储卷,并且创建了两个容器共同挂载,由后端的busybox不停的向目录中注入内容,通过从前端访问显示内容,实现两个容器之间的存储共享。

[root@k8s-master volumes]# kubectl apply -f pod-vol-demo.yaml 
pod/pod-vol-demo created 
[root@k8s-master volumes]# kubectl get pods
NAME                                 READY     STATUS    RESTARTS   AGE
pod-vol-demo                         2/2       Running   0          27s
[root@k8s-master volumes]# kubectl get pods -o wide
NAME                      READY     STATUS    RESTARTS   AGE       IP            NODE
......
pod-vol-demo              2/2       Running   0          16s       10.244.2.34   k8s-node02
......

[root@k8s-master volumes]# curl 10.244.2.34  #访问验证
Tue Oct 9 03:56:53 UTC 2018
Tue Oct 9 03:56:55 UTC 2018
Tue Oct 9 03:56:57 UTC 2018
Tue Oct 9 03:56:59 UTC 2018
Tue Oct 9 03:57:01 UTC 2018
Tue Oct 9 03:57:03 UTC 2018
Tue Oct 9 03:57:05 UTC 2018
Tue Oct 9 03:57:07 UTC 2018
Tue Oct 9 03:57:09 UTC 2018
Tue Oct 9 03:57:11 UTC 2018
Tue Oct 9 03:57:13 UTC 2018
Tue Oct 9 03:57:15 UTC 2018

另外一种比较特殊类型的存储类型叫做gitrepo,就是利用github仓库作为外部持久存储,但是他的基础仍然是emptydir来实现的,并且要确保node之上有Git工具,因为这是通过node 来驱动的git,具体实现方式就是通过sidecar容器将gitrepo clone到容器上,然后不停的往GitHub之上push数据来实现。

hostPath类型示例:

hostPath是将宿主机上的某个目录与Pod中的容器建立关联关系,数据不属于container,所以当Pod生命周期结束的时候,数据不会丢失。但是当node节点发生故障的时候,数据也会丢失。

apiVersion: v1
kind: Pod
metadata:
  name: pod-hostPath
  namespace: default
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    imagePullPolicy: IfNotPresent
    volumeMonts: 
    - name: html
      mountPath: /usr/share/nginx/html
  volumes:
  - name: html
    hostPath:
      path: /data/pod/volume1
      type: DirectoryOrCreate

# type:
#DirectoryOrCreate  宿主机上不存在创建此目录  
#Directory 必须存在挂载目录  
#FileOrCreate 宿主机上不存在挂载文件就创建  
#File 必须存在文件  

在node节点上创建挂载目录
[root@k8s-node01 ~]# mkdir -p /data/pod/volume1
[root@k8s-node01 ~]# vim /data/pod/volume1/index.html
node01.magedu.com
[root@k8s-node02 ~]# mkdir -p /data/pod/volume1
[root@k8s-node02 ~]# vim /data/pod/volume1/index.html
node02.magedu.com
[root@k8s-master volumes]# kubectl apply -f pod-hostpath-vol.yaml 
pod/pod-vol-hostpath created

(4)访问测试
[root@k8s-master volumes]# kubectl get pods -o wide
NAME                                 READY     STATUS    RESTARTS   AGE       IP            NODE
......
pod-vol-hostpath                     1/1       Running   0          37s       10.244.2.35   k8s-node02
......
[root@k8s-master volumes]# curl 10.244.2.35
node02.magedu.com
[root@k8s-master volumes]# kubectl delete -f pod-hostpath-vol.yaml  #删除pod,再重建,验证是否依旧可以访问原来的内容
[root@k8s-master volumes]# kubectl apply -f pod-hostpath-vol.yaml 
pod/pod-vol-hostpath created
[root@k8s-master volumes]# curl  10.244.2.37 
node02.magedu.com

NFS类型示例:

NFS挂载是在其中一个node之上将共享的目录发布出来,并且在各个node之上都安装好nfs-utils工具,只要在创建Pod的时候指定要挂载的文件系统为nfs,和挂载点、权限即可自动完成挂载操作,并且能实现数据同步。
在创建Pod之前要做好nfs的配置

在stor01节点上安装nfs,并配置nfs服务
[root@stor01 ~]# yum install -y nfs-utils                 ##  192.168.56.14
[root@stor01 ~]# mkdir /data/volumes -pv
[root@stor01 ~]# vim /etc/exports
/data/volumes 192.168.56.0/24(rw,no_root_squash)
[root@stor01 ~]# systemctl start nfs
[root@stor01 ~]# showmount -e
Export list for stor01:
/data/volumes 192.168.56.0/24
在node2上测试连接,成功后即可创建Pod

[root@k8s-node02 ~]# yum install -y nfs-utils
[root@k8s-node02 ~]# mount -t nfs stor01:/data/volumes /mnt
[root@k8s-node02 ~]# mount
......
stor01:/data/volumes on /mnt type nfs4 (rw,relatime,vers=4.1,rsize=131072,wsize=131072,namlen=255,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=192.168.56.13,local_lock=none,addr=192.168.56.14)
[root@k8s-node02 ~]# umount /mnt/

清单示例:

apiVersion: v1
kind: Pod
metadata: 
  name: Pod-nfs
  namespace: default
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
  volumes:
  - name: html
    nfs:
      path: /data/volumes  # 共享出来的目录
      server: stor01   #要提前做好解析
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,470评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,393评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,577评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,176评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,189评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,155评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,041评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,903评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,319评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,539评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,703评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,417评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,013评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,664评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,818评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,711评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,601评论 2 353

推荐阅读更多精彩内容