kubernetes之K8s核心原理--第二篇(五)

六、 共享存储原理

  Kubernetes对有状态或者对数据需要持久化的应用,不仅需要将容器内的目录挂载到宿主机的目录或者empDir临时存储卷,而且需要更加可靠的存储来保存应用产生的重要数据,以便于容器应用重建以后,仍然可以使用之前的数据。为了能够屏蔽底层存储实现的细节,让用户方便使用,同时能让管理员方便管理,kubernetes从v1.0版本就引入了persistentVolume和persistentVolumeCliam两个资源对象来实现对存储的管理。
  persistentVolume(PV)是对底层网络共享存储的抽象,将共享存储定义为一种“资源”,比如节点也是一种容器应用可以消费的资源。PV由管理员进行创建和配置,它与共享存储的具体实现直接相关,例如:GlusterFS、iSCSI、RBD或者GEC/AWS公有云提供的共享存储,通过插件式的机制完成与共享存储的对接,以供应用访问和使用。  persistentVolumeCliam(PVC)则是用户对于存储资源的一个“申请”。就像Pod“消费”node的资源一样,PVC会“消费”PV资源。PVC可以申请特定的存储空间访问模式
  使用PVC“申请”到一定的存储空间仍然不足以满足应用对于存储设备的各种需求。通常应用程序都会对存储设备的特性和性能有不同的要求。包括读写速度、并发性能、数据冗余等更高的要求,kubernetes从v1.4开始引入了一个新的资源对象storageClass,用于标记存储资源的特性和性能。到v1.6版本时,storageClass和动态资源应用机制得到了完善,实现了存储卷的按需创建。
那么下面小编将对PV、PVC、storageClass和动态资源供应等共享存储管理机制进行详细说明。

创新互联是一家以网络技术公司,为中小企业提供网站维护、成都网站设计、成都做网站、网站备案、服务器租用、域名注册、软件开发、微信小程序开发等企业互联网相关业务,是一家有着丰富的互联网运营推广经验的科技公司,有着多年的网站建站经验,致力于帮助中小企业在互联网让打出自已的品牌和口碑,让企业在互联网上打开一个面向全国乃至全球的业务窗口:建站欢迎咨询:13518219792

1. PV详解介绍

  PV作为存储资源,主要包括存储能力、访问模式、存储类型、回收策略、后端存储类型等关键信息的设置。以下面配置为例:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv1
spec:
  capacity:
    storage: 5Gi
  accessModes:
    - ReadWriteOnce
  persistentVolumeReclaimPolicy: Recycle
  storageClassName: slow
  nfs:
    path: /tmp
    server: 172.17.0.2

上面这个例子就创建了一个5G空间,访问模式为ReadWriteOnce,存储类型为”slow”(这里需要要求系统已经创建了名为slow的storageClass 资源对象),回收策略为“recycle”,并且后端存储类型为nfs(并设置了NFS server的IP和路径)
Kubernetes支持的PV的类型如下:
  GCEPersistentDisk #GEC公有云提供的PersistentDisk
  AWSElasticBlockStore #AWS公有云提供的ElasticBlockStore
  AzureFile #Azure公有云提供的File
  Azuredisk #AzureDisk提供的Disk
  FC (Fibre Channel)
  Flexvolume
  Flocker
  NFS #网络文件系统
  iSCSI
  RBD (Ceph Block Device) #Ceph存储块
  CephFS
  Cinder (OpenStack block storage) #openStack Cinder块存储
  Glusterfs
  VsphereVolume
  Quobyte Volumes
  HostPath #宿主机目录,仅用于单机测试
  Portworx Volumes
  ScaleIO Volumes
  StorageOS

(1) PV的关键配置参数

① 存储能力(capacity)
 描述存储设备具备的能力,目前仅支持对存储空间的设置(storage:xxx)

② 访问模式(Access Modes)
 对PV进行访问模式的设置,用于描述用户应用对存储资源的访问权限。访问模式如下:
   ReadWriteOnce:读写权限,并且只能被单个node挂载
   ReadOnlyMany:只读权限,可以被多个node挂载
   ReadWriteMany:读写权限,可以被多个node挂载
注意:PV可以可能支持多种访问模式,但PV在挂载时只能使用一种访问模式,多种访问模式不能同时生效。
对于不同类型的PV有不同的访问模式,在PV的定义时需要与他们匹配:
kubernetes之K8s核心原理--第二篇(五)

③ 存储类别(class)
 PV可以设定其存储的类别,通过storageClassName参数指定一个storageClass资源对象的名称。具有特定“类别”的PV只能与请求了该“类别”的PVC进行绑定。未设定“类别”的PV则只能与不请求任何“类别”的PVC进行绑定。storageClass资源对象会在后面的动态资源供应中大展神威。

④ 回收策略(Reclaim Policy)
 目前支持以下三种回收策略:
   保留(Retain):保留数据,需要手工处理
   回收空间(Recycle):简单清除文件的操作(例如执行rm -rf /xx/*)
   删除(Delete):与PV相连的后端存储完成volume的删除操作(如AWS EBS、GCE PD、Azure Disk、OpenStack Cinder等设备的内部volume清理)
注意:目前只有NFS和hostPath支持“Recycle”,AWS EBS、GCE PD、Azure Disk、OpenStack Cinder支持“Delete”。

(2) PV的生命周期

 某个PV在生命周期中,可能处于以下4个节点之一:
   Available:可用状态,还与某个PVC绑定
   Bound:已经与某个PVC绑定
   Released:绑定的PVC已经删除,资源已经释放,但没有被集群回收
   Failed:自动资源回收失败

(3) PV挂载参数

 在将一个PV挂载到一个node上时,根据后端存储的特点,可能需要设置额外的挂载参数,目前可以通过在PV的定义中,设置一个名为“volume.beta.kubernetes.io/mount/options”的annotation来实现。下面小编通过一个gcePersistentDisk设置挂载参数为例:

apiVersion: "v1"
kind: PersistentVolume
metadata:
  name: gce-disk-1
  annotations:
    volume.beta.kubernetes.io/mount/options: discard
sepc:
  capacity: 
    storage: 10Gi
  accessModes:
   - ReadWriteOnce
   gcePersistentDisk:
     fsType: ext4
     pdName: gce-disk-1

2. PVC详细介绍

  上面我们了解了PV的定义,这里我们就使用它,这时就需要PVC了。PVC作为用户对存储资源的需求申请,主要包括存储空间申请、访问模式。PV选择条件和存储类别等信息的设置。
 接下来小编也是通过一个例子,向大家介绍如果定义PVC去使用PV:

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: myclaim
sepc:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 8Gi
  storageClassName: slow
  selector:
    matchLabels:
      release: "stable"
    matchExpressions:
      - {key: environment, operator: In, values: [dev]}

 申请8G空间,访问模式为“ReadWriteOnce”、PV选择条件包括标签为“release=stable”并且包含条件为“environment in dev”的标签,存储类别为slow(系统中已经存在)。
 其中对PVC的关键配置详细介绍:
   资源请求(resources):仅支持存储空间大小请求
   资源请求(resources):仅支持存储空间大小请求
   PV的选择条件:通过label selector去筛选可以使用的PV,系统将根据标签找到合适得到PV,并且将PV与PVC绑定
   存储类别:PVC在定义时可以设定需要的后端存储的类别,以降低对后端存储特性的依赖。只有设置了该class的PV才能被系统筛选出来,并且与该PVC绑定
 这里针对PVC是否设置class需求,小编进行详细的说明一下:
  这里分为两种情况:
    系统启用了defaultStorageClass
     如果启用了defaultStorageClass但是,系统中不存在默认的storageClass,那么等效于不启用defaultStorageClass的情况
     如果启用了defaultStorageClass并且系统中有默认的storageClass,则系统自动的为PVC创建一个PV(使用默认的defaultStorageClass),并将它们绑定
    系统未启用defaultStorageClass
     如果设置了storageClass为“”或者没有设置storageClass字段,那么只能选择未设定storageclass的PV与之进行匹配和绑定
 设置默认的storageClass的方法是,在storageClass上定义一个annotation“storageclass.kubernetes.io/is-default-class=true”,但是不能给多个storageClass都设置annotation,如果这样的话由于不唯一,系统无法为PVC创建相应的PV。
使用PV与PVC绑定的注意项
 PV和PVC都受namespace的 限制,只有相同namespace中的PV和PVC才能绑定,并只有相同namespace下pod才能挂载PVC。
 当在PVC定义中同时设置了selector和storageClassName,只有二者同时满足条件才能将PV和PVC绑定。

3. PV和PVC的生命周期

PV可以看做可用的存储资源,PVC则是对存储资源的请求,PV和PVC的相互关系如下图所示:

kubernetes之K8s核心原理--第二篇(五)
接下来由图我们逐一介绍:

(1) 资源供应(provisioning)

 Kubernetes支持两种资源供应模式:静态模式动态模式。资源供应的结果就是创建好的PV。
   静态模式:集群管理员手工创建许多PV,在定义PV时需要将后端存储的特性进行设置。
   动态模式:集群管理员无须手动创建PV,而是通过storageClass的设置对后端存储进行描述,标记为某种“类型”。此时要求PVC对存储的类型进行声明,系统将自动完成PV的创建于PVC的绑定。

(2) 资源绑定(binding)

 在用户定义好PVC之后,系统将根据PVC对存储资源的请求在已经存在的PV中选择一个满足PVC要求的PV,一旦找到,就将该PV与用户定义的PVC进行绑定,然后用户的应用就可以使用这个PVC。如果系统中没有满足PVC要求的PV,PVC则会无限期的处于pending状态,直到等待系统管理员创建了一个符合其要求的PV。PV一旦绑定到某个PVC上,就被这个PVC独占,不能与其他的PVC进行绑定了。这样的话容易造成资源的浪费,如果使用的是动态模式,则系统在为PVC找到合适的storageClass后将自动创建一个PV并完成与PVC的绑定。

(3) 资源使用(Using)

 Pod使用volume的定义,将PVC挂载到容器内的某个路径进行使用。Volume的类型为“persistentVolumeClaim”,在后面的示例中再进行详细的说明。在容器应用挂载了一个PVC之后,就能被持续独占使用。不过,多个pod可以挂载同一个PVC。

(4) 资源释放

 当用户对存储资源使用完毕之后,用户可以删除PVC,与该PVC绑定的PV将会被标价为“已释放”,但还不能立刻与其他PVC进行绑定。通过之前PVC写入的数据可能还留在存储设备上,只有在清除之后该PV才能再次使用。

(5) 资源回收

 对于PV,管理员可以设置回收策略,用于设置与之绑定的PVC释放资源之后,对于遗留数据如何处理。只有PV的存储空间完成回收,才能供新的PVC绑定和使用。

 最后小编通过两幅图,来介绍一下静态资源供应模式和动态资源供应模式的原理,为下面一节内容做铺垫:
      kubernetes之K8s核心原理--第二篇(五)
               静态模式下的PV和PVC原理

      kubernetes之K8s核心原理--第二篇(五)
              动态模式下storageClass、PV、PVC原理

4. StorageClass详细介绍

(1) StorageClass介绍以及简单定义

  StorageClass作为对存储资源的抽象定义,对用户设置的PVC申请屏蔽后端存储的细节,一方面减轻用户对于存储资源细节的关注,另一方面也减轻了管理员手工管理PV的工作,由系统自动完成PV的创建和绑定,实现了动态的资源供应。
  对于StorageClass的定义主要包括:名称、后端存储的提供者和后端存储的相关参数配置。StorageClass一旦被创建出来,将无法修改。如需要修改,只能删除原先创建的StorageClass重新构建。下面是一个定义StorageClass的例子:

kind: storageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: standard
provisioner: kubernetes.io/aws-ebs
parameters:
  type:  gp2

上面的例子就定义了一个名为“standard”,提供者为“aws-ebs”,其参数为gp2的StorageClass。
其中定义StorageClass中有两个重点参数:
 provisioner(提供者):描述存储资源的提供者,也可以看做是后端存储驱动。目前provisioner都是以“Kubernetes.io/”为开头
 parameters(参数):后端资源提供者的参数设置,不同的provisioner包括不同的参数设置

(2)几种常见的provisioner对StorageClass的定义:

①AWS EBS存储卷

kind: storageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: slow
provisioner:
  kubernetes.io/aws-ebs
parameters:
  type: io1
  zone: us-east-1d
  iopsPerGB: "10"

参数说明
 type:可选有:io1、gp2、sc1、st1,默认是gp2
 zone:AWS zone名称
 iopPerGB:仅用于io1类型的volume,意为每秒每G的I/O操作数量
 encrypted:是否加密
 kmsKeyId:加密时的Amazon Resource Name
② GCE PD存储卷

kind: storageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: slow
provisioner: kubernetes.io/gce-pd
parameters:
  type: pd-standard
  zone: us-centrall-a

参数说明
 type:可选项有:pd-standard、pd-ssd,默认是pd-standard
 zone:GCE zone名称
③ GlusterFS存储卷

apiVersion: storage.k8s.io/v1
kind: storageClass
metadata:
  name: slow
provisioner: kubernetes.io/glusterfs
parameters:
  resturl:  "http://127.0.0.1:8081"
  clusterid: 44ad5as1fd5ae1fde1fwe1d5we1d5
  restauthenabled: "true"
  restuser: "admin"
  secreNamespace: "default"
      secreName: "heketi-sercret"
  gidMin: "40000"
  gidMax: "50000"
  volumetype: "replicate:3"

参数说明
 resturl:Gluster REST服务(Heketi)URL地址,用于自动完成GlusterFSvolume的设置
 restauthenabled:访问Gluster REST服务启用安全机制
 restuser:访问Gluster REST服务的用户名
 secretNamespace和secretName:保存访问Gluster REST服务密码的Secret的资源对象名
 clustered:GlusterFS 的cluster ID
 gidMin和gidMax:storageClass的GID的范围,用于动态创建资源供应时PV设置的GID
 volumetype:GlusterFS的volume类型设置,例如:replicate:3表示replicate类型3个副本
④ OpenStack Cinder存储卷

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: gold
provisioner: kubernetes.io/cinder
parameters:
  type: fast
  availability: nova

参数说明
 type:cinder的volumetype,默认为空
 availability:availability zone ,默认为空

(3) 设置默认的storageClass

  要在系统中设置一个默认的storageClass,首先需要启动名为“DefaultStorageClass”的admission controller,即在kube-apiserver的命令参数中的--admission-control中增加:DefaultStorageClass
:--admission-control=“xxx,xxx,xxx, DefaultStorageClass”

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: gold
  annotations: storageclass.beta.kubernetes.io/is-default-class="true"
provisioner: kubernetes.io/gce-pd
parameters:
  type: pd-ssd

然后创建这个storageClass,此时我们在通过命令可查看:

[::root]kubelet get sc -n=xxx

注意:默认的storageClass只能设置一个,否则系统会因为多个default引起冲突,而不知道筛选哪一个为默认的,最终导致默认的storageClass不生效。

5. 动态存储管理实战,GlusterFS

  这个案例从定义storageClass、创建storageFS和Heketi服务、用户申请PVC到创建Pod使用存储资源,对storageClass和动态资源分配进行详细说明,进一步分析kubernetes的存储机制。
  这里的案例是参考至:
https://www.cnblogs.com/xiaoqshuo/p/10096682.html 和《kubernetes权威指南》

(1) 概念介绍

1) 分布式文件系统-GlusterFS概述

  GlusterFS是Scale-Out存储解决方案Gluster的核心,它是一个开源的分布式文件系统,具有强大的横向扩展能力,通过扩展能够支持数PB存储容量和处理数千客户端。GlusterFS借助TCP/IP或InfiniBand RDMA网络将物理分布的存储资源聚集在一起,使用单一全局命名空间来管理数据。GlusterFS基于可堆叠的用户空间设计,可为各种不同的数据负载提供优异的性能。
  GlusterFS支持运行在任何标准IP网络上标准应用程序的标准客户端,用户可以在全局统一的命名空间中使用NFS/CIFS等标准协议来访问应用数据。GlusterFS使得用户可摆脱原有的独立、高成本的封闭存储系统,能够利用普通廉价的存储设备来部署可集中管理、横向扩展、虚拟化的存储池,存储容量可扩展至TB/PB级。
  GlusterFS以原始数据格式(如EXT3、EXT4、XFS、ZFS)储存数据,并实现多种数据自动修复机制。
架构图:
kubernetes之K8s核心原理--第二篇(五)
这里只是带大家了解一下GlusterFS,便于理解后面PVC挂载的内容,无需过多深入。

2) Heketi服务

  Heketi服务是一个提供REST ful API管理GlusterFS卷框架,并能够在kubernetes、openstack等云平台上实现动态存储资源供应,支持GlusterFS多集群管理,便于管理员对GlusterFS进行操作,如下图简单介绍了Heketi服务的作用:
kubernetes之K8s核心原理--第二篇(五)

(2) 实战搭建

① 在各个计划用于GlusterFS的node上安装GlusterFS客户端

#yum install glusterfs glusterfs-fuse -y

② 在master的kube-apiserver服务和待启动GlusterFS的各个node上的kubelet服务的启动参数中入:--allow-privileged=true
③ 载入指定的个别模块

modprobe dm_snapshot 
modprobe dm_mirror 
modprobe dm_thin_pool

④ 为要部署GlusterFS的node打上标签,为了将GlusterFS容器定向部署到安装了GlusterFS的node上

[root@k8s-master01 ~]# kubectl label node k8s-node-1 storagenode=glusterfs 
node/k8s-node-1 labeled 
[root@k8s-master01 ~]# kubectl label node k8s-node-2 storagenode=glusterfs 
node/k8s-node-2 labeled 
[root@k8s-master01 ~]# kubectl label node k8s-node-3 storagenode=glusterfs 
node/k8s-node-3 labeled

⑤ 创建GlusterFS管理服务容器集群
#glusterfs-daemonset.yaml:

kind: DaemonSet
apiVersion: extensions/v1beta1
metadata:
  name: glusterfs
  labels:
    glusterfs: daemonset
  annotations:
    description: GlusterFS DaemonSet
    tags: glusterfs
spec:
  template:
    metadata:
      name: glusterfs
      labels:
        glusterfs-node: pod
    spec:
      nodeSelector:
        storagenode: glusterfs
      hostNetwork: true
      containers:
      - image: gluster/gluster-centos:latest
        name: glusterfs
        volumeMounts:
        - name: glusterfs-heketi
          mountPath: "/var/lib/heketi"
        - name: glusterfs-run
          mountPath: "/run"
        - name: glusterfs-lvm
          mountPath: "/run/lvm"
        - name: glusterfs-etc
          mountPath: "/etc/glusterfs"
        - name: glusterfs-log
          mountPath: "/var/log/glusterfs"
        - name: glusterfs-config
          mountPath: "/var/lib/glusterd"
        - name: glusterfs-dev
          mountPath: "/dev"
        - name: glusterfs-misc
          mountPath: "/var/lib/misc/glusterfsd"
        - name: glusterfs-cgroup
          mountPath: "/sys/fs/cgroup"
          readOnly: true
        - name: glusterfs-ssl
          mountPath: "/etc/ssl"
          readOnly: true
        securityContext:
          capabilities: {}
          privileged: true
        readinessProbe:
          timeoutSeconds: 3
          initialDelaySeconds: 60
          exec:
            command:
            - "/bin/bash"
            - "-c"
            - systemctl status glusterd.service
        livenessProbe:
          timeoutSeconds: 3
          initialDelaySeconds: 60
          exec:
            command:
            - "/bin/bash"
            - "-c"
            - systemctl status glusterd.service
      volumes:
      - name: glusterfs-heketi
        hostPath: 
         path: "/var/lib/heketi"
      - name: glusterfs-run
      - name: glusterfs-lvm
        hostPath:
          path: "/run/lvm"
      - name: glusterfs-etc
        hostPath:
          path: "/etc/glusterfs"
      - name: glusterfs-log
        hostPath:
          path: "/var/log/glusterfs"
      - name: glusterfs-config
        hostPath:
          path: "/var/lib/glusterd"
      - name: glusterfs-dev
        hostPath:
          path: "/dev"
      - name: glusterfs-misc
        hostPath:
          path: "/var/lib/misc/glusterfsd"
      - name: glusterfs-cgroup
        hostPath:
          path: "/sys/fs/cgroup"
      - name: glusterfs-ssl
        hostPath:
          path: "/etc/ssl"
#kubelet create -f glusterfs-daemonset.yaml #创建
#kubectl get pods #查看
NAME READY STATUS RESTARTS AGE 
glusterfs-fvxh7 1/1 Running 0 47m 
glusterfs-jjw7b 1/1 Running 0 47m 
glusterfs-td875 1/1 Running 0 47m

⑥创建Heketi服务
在部署Heketi之前,需要为他创建一个ServiceAccount对象:
#heketi-service-account.yaml

apiVersion: v1
kind: ServiceAccount
metadata:
  name: heketi-service-account
#kubelet create -f heketi-service-account.yaml

#heketi-deployment-svc.yaml

kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: deploy-heketi
  labels:
    glusterfs: heketi-deployment
    deploy-heketi: heketi-deployment
  annotations:
    description: Defines how to deploy Heketi
spec:
  relicas: 1
  template:
    metadata:
      name: deploy-heketi
      labels:
        glusterfs: heketi-pod
    spec:
      ServiceAccountName: heketi-service-account
      containers:
      - image: heketi/heketi:dev
        name: deploy-heketi
        env:
        - name: HEKETI_EXECUTOR
          value: kubernetes
        - name: HEKETI_FSTAB
          value: "/var/lib/heketi/fstab"
        - name: HEKETI_SNAPSHOT_LIMIT
          value: "14"
        - name: HEKETI_KUBE_GLUSTER_DAEONSET
          value: "y"
        ports:
        - containerPort: 8080
        volumeMounts:
        - name: db
          mountPath: "/var/lib/heketi"
        readinessProbe:
          timeoutSeconds: 3
          initialDelaySeconds: 3
          httpGet:
            path: "/hello"
            port: 8080
        livenessProbe:
          timeoutSeconds: 3
          initialDelaySeconds: 30
          httpGet:
            path: "/hello"
            port: 8080
    volumes:
    - name: db
      hostPath:
        path: "/heketi-data"
--- 
kind: Service
apiVersion: v1
metadata:
  name: deploy-heketi
  labels:
    glusterfs: heketi-service
    deploy-heketi: support
  annotations: 
    description: Exposes Heketi Service 
spec:
  selector:
    name: deploy-heketi
  ports:
  - name: deploy-heketi
    port: 8080
    targetPort: 8080
#kubelete create -f heketi-deployment-svc.yaml

⑦ 为Heketi设置GlusterFS集群
在Heketi能管理GlusterFS集群之前,需要为其设置GlusterFS集群信息。可以使用json配置文件传入,并且Heketi要求一个GlusterFS集群至少有3各节点。
#topology.json

{
    "clusters": [
        {
            "nodes": [
                {
                    "node": {
                        "hostnames": {
                            "manage": [
                                "k8s-node-1"
                            ],
                            "storage": [
                                "192.168.2.100"
                            ]
                        },
                        "zone": 1
                    },
                    "devices": [
                        {
                            "name": "/dev/sdb"
                        }
                    ]
                },
                {
                    "node": {
                        "hostnames": {
                            "manage": [
                                "k8s-node-2"
                            ],
                            "storage": [
                                "192.168.2.101"
                            ]
                        },
                        "zone": 1
                    },
                    "devices": [
                        {
                            "name": "/dev/sdc"
                        }
                    ]
                },
                {
                    "node": {
                        "hostnames": {
                            "manage": [
                                "k8s-node-3"
                            ],
                            "storage": [
                                "192.168.2.102"
                            ]
                        },
                        "zone": 1
                    },
                    "devices": [
                        {
                            "name": "/dev/sdb"
                        }
                    ]
                }
            ]
        }
    ]
}

然后进入Heketi的容器中,执行:

#export HEKETI_CLI_SERVER=http://localhost:8080
#heketi-cli topology load –json= topology.json

完成以上操作,Heketi就完成了GlusterFS集群的创建,同时在GlusterFS集群的各个节点上的/dev/sdb盘上成功创建了PV和VG。
注意:/dev/sdb一定要是未创建文件系统的裸设备。
#查看GFS信息

[root@k8s-node-1 kubernetes]# heketi-cli topology info

(3) 测试

集群创建成功之后,当然我们要试试,storageClass的功能能不能用啊:
① 定义storageClass
#storageclass-gluster-heketi.yaml

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: gluster-heketi
provisioner: kubernetes-io/glusterfs
parameters:
  resturl: "http://172.17.2.2:8080"
  restauthenabled: "false"

② 定义PVC
#pvc-gluster-heketi.yaml(使用动态资源供应模式)

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: pvc-gluster-heketi
spec:
  storageClassName: gluster-heketi
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

#可以通过命令查看pv,和自动创建的PVC

#kubelet get pvc
#kubelet get pv

③ 使用pod挂载PVC
#pod-use-pvc.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod-use-pvc
spec:
  containers:
  - name: pod-use-pvc
    image: busybox
    command:
    - sleep
    - "3600"
    volumeMounts:
    - name: gluster-volume
      mountPath: "/pv-data"
      readOnly: false
  volumes:
  - name: gluster-volume
    persistentVolumeClaim:
      claimName: pvc-gluster-heketi
#kubelet create -f pod-use-pvc.yaml #创建这个pod

然后进入容器:

#kubelet exec -it pod-use-pvc /bin/sh

在其中的/pv-data 目录创建文件,然后验证文件在GlusterFS集群中是否生效!

文章内容参考至《kubernetes权威指南》


网页题目:kubernetes之K8s核心原理--第二篇(五)
网站链接:http://ybzwz.com/article/gccjco.html