k8s-存储卷

一,简介

我们知道默认情况下容器的数据都是非持久化的,在容器消亡以后数据也跟着丢失,所以 Docker 提供了 Volume 机制以便将数据持久化存储。类似的,Kubernetes 提供了更强大的 Volume 机制和丰富的插件,解决了容器数据持久化和容器间共享数据的问题。
与 Docker 不同,Kubernetes Volume 的生命周期与 Pod 绑定容器挂掉后 Kubelet 再次重启容器时,Volume 的数据依然还在而 Pod 删除时,Volume 才会清理。数据是否丢失取决于具体的 Volume 类型,比如 emptyDir 的数据会丢失,而 PV 的数据则不会丢

1,volume类型

目前kubernetes支持一下volume类型:


image.png

注意,这些 volume 并非全部都是持久化的,比如 emptyDir、secret、gitRepo 等,这些 volume 会随着 Pod 的消亡而消失。

二,示例

1,emptyDir
概念:

emptyDir是最基础的Volume类型,用于存储临时数据的简单空目录。如果Pod设置了emptyDir类型Volume,Pod被分配到Node上时候,会创建emptyDir,只要Pod运行在Node上,emptyDir都会存在(容器挂掉不会导致emptyDir丢失数据),但是如果Pod从Node上被删除(Pod被删除,或者Pod发生迁移),emptyDir也会被删除,并且永久丢失。

面将用emptyDir卷实现在同一pod中两个容器之间的文件共享


image.png
[root@k8s-master volumes]# cat pod-volume.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-volume
  namespace: default
  labels:
    app: myapp
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: {}

查看pod

[root@k8s-master volumes]# kubectl get pods -o wide
NAME                            READY   STATUS    RESTARTS   AGE     IP            NODE        NOMINATED NODE   READINESS GATES
pod-volume                      2/2     Running   0          2m13s   10.244.1.74   k8s-node1   <none>           <none>
#使用curl 命令查看我们重定向到网页文件的内容
[root@k8s-master volumes]# curl 10.244.1.74
Thu Mar 18 08:26:58 UTC 2021
Thu Mar 18 08:27:00 UTC 2021
Thu Mar 18 08:27:02 UTC 2021
Thu Mar 18 08:27:04 UTC 2021

2,hostPath
概念:

hostPath允许挂载Node上的文件系统到Pod里面去。如果Pod需要使用Node上的文件,可以使用hostPath。在同一个节点上运行并在其hostPath卷中使用相同路径的pod可以看到相同的文件。


image.png

hostPath指定的type:


image.png
#在node 上创建存储目录
mkdir -p /data/volume 
echo "hello" >/data/volume/index.html
[root@k8s-master volumes]# cat pod-volume-hostpath.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-volume-hostpath
  namespace: default
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
      containerPort: 80 
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
  volumes:
  - name: html
    hostPath:
      path: /data/volume
      type: DirectoryOrCreate
#创建pod
kubectl apply -f pod-volume-hostpath.yaml

[root@k8s-master volumes]# kubectl get pods  -o wide
NAME                            READY   STATUS    RESTARTS   AGE    IP            NODE        NOMINATED NODE   READINESS GATES
pod-volume-hostpath             1/1     Running   0          10s    10.244.1.75   k8s-node1   <none>           <none>
#访问网页文件
[root@k8s-master volumes]# curl 10.244.1.75
hello
#hostpath类型删除pod后重新创建pod被调度到该node节点上数据依然不会变,如果node节点宕了则存储卷也会删除,数据会消失,

3,NFS
概念:

NFS是Network File System的缩写,即网络文件系统。Kubernetes中通过简单地配置就可以挂载NFS到Pod中,而NFS中的数据是可以永久保存的,同时NFS支持同时写操作。
 emptyDir可以提供不同容器间的文件共享,但不能存储;hostPath可以为不同容器提供文件的共享并可以存储,但受制于节点限制,不能跨节点共享;这时需要网络存储 (NAS),即既可以方便存储容器又可以从任何集群节点访问,本文以NFS为例做测试

首先准备一台机器同一局域网的机器做为nfs-server(关闭firewalld.service和selinux)
安装nfs软件

[root@docker-ce ~]# yum install -y nfs-utils

创建共享目录:

mkdir -p /data/volumes
[root@docker-ce ~]# cat /etc/exports
/data/volumes 10.0.0.0/24(rw,no_root_squash)

在node节点上安装nfs-utils

[root@k8s-node2 ~]# yum install -y nfs-utils

创建NFS的pods

[root@k8s-master volumes]# cat volume-nfs.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-nfs
  namespace: default
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
      containerPort: 80
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html/
  volumes:
  - name: html
    nfs:
      path: /data/volumes
      server: 10.0.0.100
创建pod
[root@k8s-master volumekubectl apply -f volume-nfs.yaml 
[root@k8s-master volumes]# kubectl get pods -o wide
NAME                            READY   STATUS    RESTARTS   AGE    IP            NODE        NOMINATED NODE   READINESS GATES
pod-nfs                         1/1     Running   0          9s     10.244.1.77   k8s-node1   <none>           <none>

去存储节点创建文件:

[root@docker volumes]# cat /data/volumes/index.html 
<h1>NFS docker</h1
#然后去访问pod的文件
[root@k8s-master volumes]# curl 10.244.1.77
<h1>NFS docker</h1
#删掉pod后在重建pod后数据依然在但是如果nfs宕了数据依然会丢失。
4,pv && pvc
概念:

PersistentVolume (持久卷, 简称 PV)和Persistent VolumeClaim(持久卷声明,简称 PVC)使得K8s集群具备了存储的逻辑抽象能力,使得在配置Pod的逻辑里可以忽略对实际后台存储技术的配置,而把这项配置的工作交给PV的配置者,即集群的管理者。存储的PV和PVC的这种关系,跟计算的Node和Pod的关系是非常类似的;PV和Node是资源的提供者,根据集群的基础设施变化而变化,由K8s集群管理员配置;而PVC和Pod是资源的使用者,根据业务服务的需求变化而变化,由K8s集群的使用者即服务的管理员来配置。
当集群用户需要在其pod中使用持久化存储时,他们首先创建PVC清单,指定所需要的最低容量要求和访问模式,然后用户将待久卷声明清单提交给Kubernetes API服务器,Kubernetes将找到可匹配的PV并将其绑定到PVC。PVC可以当作pod中的一个卷来使用,其他用户不能使用相同的PV,除非先通过删除PVC绑定来释放。

image.png
1,创建pv

准备环境
在nfs存储机器上创建目录

[root@docker ~]# mkdir /data/volumes/v{1..5}

[root@docker ~]# cat /etc/exports
/data/volumes/v1 10.0.0.0/24(rw,no_root_squash)
/data/volumes/v2 10.0.0.0/24(rw,no_root_squash)
/data/volumes/v3 10.0.0.0/24(rw,no_root_squash)
/data/volumes/v4 10.0.0.0/24(rw,no_root_squash)
/data/volumes/v5 10.0.0.0/24(rw,no_root_squash)

显示正常导出:
[root@docker ~]# exportfs -avr
exporting 10.0.0.0/24:/data/volumes/v5
exporting 10.0.0.0/24:/data/volumes/v4
exporting 10.0.0.0/24:/data/volumes/v3
exporting 10.0.0.0/24:/data/volumes/v2
exporting 10.0.0.0/24:/data/volumes/v1
#
[root@docker ~]# showmount -e
Export list for docker:
/data/volumes/v5 10.0.0.0/24
/data/volumes/v4 10.0.0.0/24
/data/volumes/v3 10.0.0.0/24
/data/volumes/v2 10.0.0.0/24
/data/volumes/v1 10.0.0.0/24

定义一个nfs的pv

定义pv不能定义在namespace中,应为pv是属于集群级别的资源,同样创建namespace是也不能指定名称空间,这两都是属于集群级别的资源

#创建了5个pv
[root@k8s-master volumes]# cat pv-deom.yaml 
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv001
spec:
  capacity:
    storage: 5Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
    - ReadWriteMany
  nfs:
    path: /data/volumes/v1
    server: 10.0.0.100
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv002
spec:
  capacity:
    storage: 8Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
    - ReadWriteMany
  nfs:
    path: /data/volumes/v2
    server: 10.0.0.100
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv003
spec:
  capacity:
    storage: 10Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
    - ReadWriteMany
  nfs:
    path: /data/volumes/v3
    server: 10.0.0.100
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv004
spec:
  capacity:
    storage: 15Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
    - ReadWriteMany
  nfs:
    path: /data/volumes/v4
    server: 10.0.0.100
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv005
spec:
  capacity:
    storage: 20Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
    - ReadWriteMany
  nfs:
    path: /data/volumes/v5
    server: 10.0.0.100

查看pv

[root@k8s-master volumes]# kubectl get pv 
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
pv001   5Gi        RWO,RWX        Retain           Available                                   89s
pv002   8Gi        RWO,RWX        Retain           Available                                   89s
pv003   10Gi       RWO,RWX        Retain           Available                                   89s
pv004   15Gi       RWO,RWX        Retain           Available                                   89s
pv005   20Gi       RWO,RWX        Retain           Available                                   89s

创建pvc
[root@k8s-master volumes]# cat pvc-demo.yaml 
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mypvc
  namespace: default
spec:
  accessModes: 
  - ReadWriteMany
  resources:
    requests:
      storage: 8Gi
---
apiVersion: v1
kind: Pod
metadata:
  name: pvc-pod
  namespace: default
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    imagePullPolicy: IfNotPresent
    ports:
    - name: http
      containerPort: 80
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html/
  volumes:
  - name: html
    persistentVolumeClaim:
      claimName: mypvc
#创建pvc
[root@k8s-master volumes]# kubectl apply -f pvc-demo.yaml 
#查看pvc
[root@k8s-master volumes]# kubectl get pvc
NAME    STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
mypvc   Bound    pv002    8Gi        RWO,RWX                       18s
[root@k8s-master volumes]# kubectl get pv
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM           STORAGECLASS   REASON   AGE
pv001   5Gi        RWO,RWX        Retain           Available                                           74m
pv002   8Gi        RWO,RWX        Retain           Bound       default/mypvc                           74m
pv003   10Gi       RWO,RWX        Retain           Available                                           74m
pv004   15Gi       RWO,RWX        Retain           Available                                           74m
pv005   20Gi       RWO,RWX        Retain           Available                                           74m

spec:
  capacity:
    storage: 5Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
#access modes 使用参考:
https://v1-19.docs.kubernetes.io/docs/concepts/storage/persistent-volumes/
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容