[K8S系列七]存储-PV、PVC与Storage Class

本质上说,一个volume(卷)就是一个目录,从容器内部可以访问这个目录中的内容,而这个目录是怎么来的,它背后的媒介是什么以及它里面的内容,都是由volume的类型来决定的;而使用volume,只需要在pod上指定使用哪种类型的volume,以及mount到容器中的什么位置即可。K8S支持的存储类型如下所示,这里主要介绍HostPath和Persistent Volume。

K8S 目前支持的存储

1. hostPath

hostPath 类型的volume是映射Pod所在的节点的文件或者目录到 pod 里。在使用 hostPath 类型的存储卷时,也可以设置 type 字段,支持的类型有文件、目录、File、Socket、CharDevice 和 BlockDevice。

1.1 示例

根据附录1的volume-pod.yaml创建一个pod,使用hostPath类型的volume

# kubectl apply -f volume-pod.yaml
# kubectl get pods -o wide
volume-pod                          2/2     Running   0              11m    10.244.80.226   w2     <none>           <none>

部署后查看pods详情, 发现volume-pod位于w2节点,登录到w2 尝试在pods的容器中创建文件

# docker ps  |grep volume
d8524ebeb2d0        busybox                                                         "sh -c 'echo The app…"   38 seconds ago      Up 37 seconds                           k8s_busybox-container_volume-pod_default_eb751f47-59eb-4541-986f-fb009d137bb7_46
02791634ee65        nginx                                                           "/docker-entrypoint.…"   46 hours ago        Up 46 hours                             k8s_nginx-container_volume-pod_default_eb751f47-59eb-4541-986f-fb009d137bb7_0
637ddb8efe45        registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.6   "/pause"                 46 hours ago        Up 46 hours                             k8s_POD_volume-pod_default_eb751f47-59eb-4541-986f-fb009d137bb7_0

# 在busybox容器的/busybox-volume目录下创建busybox文件
# docker exec d8524ebeb2d0 touch /busybox-volume/busybox
# docker exec d8524ebeb2d0 ls /busybox-volume/
busybox

# 在nginx容器的/nginx-volume目录下创建nginx文件,可以同时看到busybox文件和nginx文件
# docker exec  02791634ee65  touch /nginx-volume/nginx
# docker exec  02791634ee65  ls /nginx-volume/
busybox  nginx

# 在宿主机的 /tmp/volume-pod 目录下也同时可以看到busybox和nginx文件
# ls /tmp/volume-pod/
busybox  nginx

# 删除volume-pod之后,w2节点/tmp/volume-pod/下的busybox和nginx依然存在
# master节点执行
# kubectl delete pod volume-pod
pod "volume-pod" deleted

# w2 节点执行
# ls /tmp/volume-pod/
busybox  nginx

2. PV、PVC与静态分配

2.1 PV与PVC

因为hostPath类型的volume只映射pod所在的节点的文件或目录到pod中,如果pod因为重启被调度到其他节点时,将会看不到原来节点保存的数据,因此有了网络存储+pv+pvc的方式。
通过PersistentVolume(PV)与PersistentVolumeClaim(PVC)将提供存储与消费存储分离:

  1. PV由管理员负责创建,它如同cpu、mem一样属于集群资源,为满足不同用户需求,一般管理员会在集群创建很多种类的PV,而用户不关心这些pv的实现细节;

2.PVC由用户创建来消费存储,如同通过创建pod来消费cpu、mem资源。

2.2 PV与PVC绑定

PVC与PV是通过PersistentVolume Controller 进行绑定的。PV Controller 会不断地循环去查看每一个 PVC,是不是已经处于 Bound(已绑定)状态。如果不是,那它就会遍历所有的、可用的 PV,并尝试将其与未绑定的 PVC 进行绑定,这样,Kubernetes 就可以保证用户提交的每一个 PVC,只要有合适的 PV 出现,它就能够很快进入绑定状态。而所谓将PV 与 PVC 进行“绑定”,其实就是将这个 PV 对象的名字,填在了 PVC 对象的 spec.volumeName 字段上 。


PVC与PV运作过程(图片来自《Kubernetes in Action》)
2.3 PV、PVC示例

这里以NFS+PV+PVC为例进行说明, NFS搭建过程请参考附录2,根据考附录3 nginx-pv-pvc.yaml,创建nginx(deployment)、nginx-pv(pv)、nginx-pvc(pvc)。nginx-pv挂载在/nfs/data/nginx 下。在/nfs/data/nginx下创建文件1.html,pod中也可以访问,并且pod的重新创建不影响1.html。

# 01 创建deployment、pv、pvc
# kubectl apply -f nginx-pv-pvc.yaml

# 02 查看pv、pvc,pv和pvc的状态都是Bound,nginx-pvc的volume指向nginx-pv
# kubectl get pv,pvc
NAME                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM               STORAGECLASS   REASON   AGE
persistentvolume/nginx-pv   2Gi        RWX            Retain           Bound    default/nginx-pvc                           39m

NAME                              STATUS   VOLUME     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/nginx-pvc   Bound    nginx-pv   2Gi        RWX                           39m

# kubectl get pods -o wide
NAME                                READY   STATUS    RESTARTS         AGE    IP              NODE   NOMINATED NODE   READINESS GATES
nginx-7d7959d89b-tr7jj              1/1     Running   0                38m    10.244.80.227   w2     <none>           <none>

# 03 创建文件,演示pv和pvc的效果
# echo  "Hello kubernetes." > /nfs/data/nginx/1.html

# kubectl get pods -o wide
NAME                                READY   STATUS    RESTARTS       AGE    IP              NODE   NOMINATED NODE   READINESS GATES
nginx-7d7959d89b-tr7jj              1/1     Running   0              85m    10.244.80.227   w2     <none>           <none>

# curl 10.244.80.227/1.html
Hello kubernetes.

# kubectl delete pod nginx-7d7959d89b-tr7jj
pod "nginx-7d7959d89b-tr7jj" deleted

# kubectl get pods -o wide
NAME                                READY   STATUS    RESTARTS        AGE    IP              NODE   NOMINATED NODE   READINESS GATES
nginx-7d7959d89b-p99k5              1/1     Running   0               113s   10.244.190.89   w1     <none>           <none>

# curl 10.244.190.89/1.html
Hello kubernetes.

# docker exec 9cef89890c56 cat /usr/share/nginx/html/1.html
Hello kubernetes.
deployment、pvc、pv、nfs

3.基于StorageClass的动态分配

上节说的PV和PVC方法虽然能实现屏蔽底层存储,但是PV创建比较复杂,通常都是由集群管理员管理,这非常不方便。
利用StorageClass实现,可以根据PVC需求,自动构建相对应的PV持久化存储卷,进一步简化运维管理成本。
StorageClass对象会定义下面两部分内容:

  1. PV的属性。比如,存储类型,Volume的大小等;
  2. 创建这种PV需要用到的存储插。


    StorageClass 运作过程(图片来自《Kubernetes in Action》)
3.1 示例

示例部分参考nfs-subdir-external-provisioner。 相关文件来源于deploy,需要略作修改。

# 01 搭建NFS服务,参考附录2

# 02 配置account及授权, 如果不修改rbac.yaml会使用默认的命名空间
# kubectl apply -f rbac.yaml

# 03 修改deployment.yaml中nfs服务的配置:NFS_SERVER和NFS_PATH。
# kubectl apply -f deployment.yaml

# kubectl get deployment
NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
nfs-client-provisioner   1/1     1            1           78s

# 04 部署Storage Class
# kubectl apply -f class.yaml
storageclass.storage.k8s.io/nfs-client created
# kubectl get storageClass
NAME         PROVISIONER                                   RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
nfs-client   k8s-sigs.io/nfs-subdir-external-provisioner   Delete          Immediate           false                  4s

# 05 部署PVC,发现PV也被自动创建
# kubectl apply -f test-claim.yaml
persistentvolumeclaim/test-claim created
# kubectl get pv,pvc
NAME                                                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                STORAGECLASS   REASON   AGE
persistentvolume/pvc-f2ec97fc-5b67-4d33-87a4-7344ceb8f522   1Mi        RWX            Delete           Bound    default/test-claim   nfs-client              25s

NAME                               STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/test-claim   Bound    pvc-f2ec97fc-5b67-4d33-87a4-7344ceb8f522   1Mi        RWX            nfs-client     25s

# 06 创建pod使用存储
# kubectl apply -f test-pod.yaml
pod/test-pod created
[root@master storageclass-nfs]# kubectl get pv,pvc
NAME                                                        CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                STORAGECLASS   REASON   AGE
persistentvolume/pvc-f2ec97fc-5b67-4d33-87a4-7344ceb8f522   1Mi        RWX            Delete           Bound    default/test-claim   nfs-client              76s

NAME                               STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/test-claim   Bound    pvc-f2ec97fc-5b67-4d33-87a4-7344ceb8f522   1Mi        RWX            nfs-client     76s

[root@master ~]# ls /nfs/data/default-test-claim-pvc-f2ec97fc-5b67-4d33-87a4-7344ceb8f522/
SUCCESS

参考文献

1.Volumes
2.《kubernetes权威指南》
3.Kubernetes 存储设计

附录

1.volume-pod.yaml
kind: Pod
metadata:
  name: volume-pod
spec:
  containers:
  - name: nginx-container
    image: nginx
    ports:
    - containerPort: 80
    volumeMounts:
    - name: volume-pod
      mountPath: /nginx-volume
  - name: busybox-container
    image: busybox
    command: ['sh', '-c', 'echo The app is running! && sleep 3600']
    volumeMounts:
    - name: volume-pod
      mountPath: /busybox-volume
  volumes:
  - name: volume-pod
    hostPath:
      path: /tmp/volume-pod

2. NFS搭建流程

NFS(Network File System)网络文件系统,是FreeBSD支持的文件系统中的一种,允许网络中的计算机之间通过TCP/IP网络共享资源。

# 01 master节点搭建nfs
# 安装nfs
yum install -y nfs-utils

# 创建nfs目录
mkdir -p /nfs/data/

# 授予权限
chmod -R 777 /nfs/data
# 编辑export文件
vi /etc/exports
/nfs/data *(rw,no_root_squash,sync)

# 使配置生效
exportfs -r

# 查看是否生效
exportfs
# 显示 /nfs/data      <world>

# 启动rpcbind、nfs服务
systemctl restart rpcbind && systemctl enable rpcbind
systemctl restart nfs && systemctl enable nfs

# 查看rpc服务的注册情况
rpcinfo -p localhost
# showmount测试, 192.168.0.51 为master ip
# showmount -e 192.168.0.51
Export list for 192.168.0.51:
/nfs/data *


# 02 所有node上安装客户端
yum -y install nfs-utils
systemctl start nfs && systemctl enable nfs
3 nginx-pv-pvc.yaml
# 定义PV
apiVersion: v1
kind: PersistentVolume
metadata:
  name: nginx-pv
spec:
  accessModes:
    - ReadWriteMany
  capacity:
    storage: 2Gi
  nfs:
    path: /nfs/data/nginx
    server: 192.168.0.51

---
# 定义PVC,用于消费PV
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: nginx-pvc
spec:
  accessModes:
    - ReadWriteMany
  resources:
    requests:
      storage: 2Gi

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

推荐阅读更多精彩内容