kubenetes入门学习-十二-存储卷1

最近学习k8s遇到很多问题,建了一个qq群:153144292,交流devops、k8s、docker等

存储卷

=========================
应用分类:
   有状态、有存储
   有状态,无存储
   无状态,有存储
   无状态,无存储

当pod故障被删除或者用户被删除,从新被编排到其他node上运行,数据随之pod结束就结束了,pod是有生命周期的,这里就需要存储了,持久化存储数据。

基于以上原因就k8s提供了存储卷,存储卷不属于k8s,属于pod,创建pod的是基于pause基础架构容器,都是基于他的网络名称空间。

如果是宿主机的存储卷,node宕机就有问题了。这样就需要跨node的存储卷了
=========================
一、存储卷的概念和类型
    emptyDir(Pod删除,数据也会被清除、用于数据的临时存储)
    hostPath(docker之前学的)
    传统意义的san(iscsi..)设备或者nas(nfs、cifs..)
    分布式存储(glusterfs、rbd、cephfs)
    云存储(aws ebs、Azure Disk...)

    为了保证数据的持久性,必须保证数据在外部存储在docker容器中,为了实现数据的持久性存储,在宿主机和容器内做映射,可以保证在容器的生命周期结束,数据依旧可以实现持久性存储。但是在k8s中,由于pod分布在各个不同的节点之上,并不能实现不同节点之间持久性数据的共享,并且,在节点故障时,可能会导致数据的永久性丢失。为此,k8s就引入了外部存储卷的功能。

k8s支持的类型:
    kubectl explain pod.spec.volumes
    发现很多种类型的存储
    pvc(persistentVolumeClaim):pod上定义一个pvc类型,关联到ns,这个是申请,申请跟pv建立关联关系。pv才是存储上的存储空间。
         公有云的情况是在存储之上抽象一层,当用户申请的时候,自动帮助用户分配匹配的存储空间大小。

k8s要使用存储卷,需要2步:
    1、在pod定义volume,并指明关联到哪个存储设备
    2、在容器使用volume mount进行挂载,然后才能使用
========================
二、emptyDir实验
    一个emptyDir 第一次创建是在一个pod被指定到具体node的时候,并且会一直存在在pod的生命周期当中,
正如它的名字一样,它初始化是一个空的目录,pod中的容器都可以读写这个目录,这个目录可以被挂在到各
个容器相同或者不相同的的路径下。当一个pod因为任何原因被移除的时候,这些数据会被永久删除。

注意:一个容器崩溃了不会导致数据的丢失,因为容器的崩溃并不移除pod

emptyDir 磁盘的作用:
(1)普通空间,基于磁盘的数据存储
(2)作为从崩溃中恢复的备份点
(3)存储那些那些需要长久保存的数据,例web服务中的数据

默认的,emptyDir 磁盘会存储在主机所使用的媒介上,可能是SSD,或者网络硬盘,这主要取决于你的环境。
当然,我们也可以将emptyDir.medium的值设置为Memory来告诉Kubernetes 来挂在一个基于内存的目录tmpfs,
因为tmpfs速度会比硬盘块度了,但是,当主机重启的时候所有的数据都会丢失。

kubectl explain pod.spec.volumes.emptyDir  #查看emptyDir存储定义
kubectl explain pod.spec.containers
kubectl explain pod.spec.containers.volumeMounts #查看容器挂载方式

[root@master ~]# cd manifests/
[root@master manifests]# mkdir volumes
[root@master manifests]# cd volumes/
[root@master volumes]# ls
[root@master volumes]# cp ../pod-demo.yaml ./
[root@master volumes]# ll
total 4
-rw-r--r--. 1 root root 408 Mar 14 11:53 pod-demo.yaml
[root@master volumes]# mv pod-demo.yaml pod-vol-demo.yaml
[root@master volumes]# cat pod-vol-demo.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-demo
  namespace: default
  labels:
    app: myapp
    tier: frontend
  annotations:
    magedu.com/create-by:"cluster admin"
spec:
  containers:
  - name: myapp
    image: nginx
    ports:
    - name: http
      containerPort: 80
    volumeMounts:                #在容器内定义挂载存储名称和挂载路径
    - name: html
      mountPath: /usr/share/nginx/html/  
  - name: busybox
    image: busybox:latest
    volumeMounts:                #在容器内定义挂载存储名称和挂载路径
    - name: html
      mountPath: /data/
    command: ['/bin/sh','-c','while true;do echo $(date) >> /data/index.html;sleep 2;done']
  volumes:                      #定义存储卷     
  - name: html                   #定义存储卷名称 
    emptyDir: {}                 #定义存储卷类型

[root@master volumes]# kubectl apply -f pod-vol-demo.yaml 
pod/pod-demo created
[root@master volumes]# kubectl get pods
NAME                                 READY   STATUS    RESTARTS   AGE
liveness-httpget-pod                 1/1     Running   1          9d
myapp-backend-pod-69dc8c7655-pqwk8   1/1     Running   0          24h
myapp-backend-pod-69dc8c7655-sgpw6   1/1     Running   0          24h
myapp-backend-pod-69dc8c7655-v4jvx   1/1     Running   0          24h
myapp-deploy-69dc8c7655-jkkwv        1/1     Running   0          4d8h
myapp-deploy-69dc8c7655-q97jc        1/1     Running   0          4d8h
myapp-deploy-69dc8c7655-sldk8        1/1     Running   0          4d8h
myapp-deploy-69dc8c7655-v9dvc        1/1     Running   0          4d8h
myapp-deploy-69dc8c7655-x5qth        1/1     Running   0          4d8h
nginx-7849c4bbcd-dscjr               1/1     Running   0          12d
nginx-7849c4bbcd-vdd45               1/1     Running   0          12d
nginx-7849c4bbcd-wrvks               1/1     Running   0          12d
nginx-deploy-84cbfc56b6-mjcw5        1/1     Running   0          13d
pod-demo                             2/2     Running   0          7s  这里下面两个容器
tomcat-backed-64d5bc78f7-b9tlh       1/1     Running   0          24h
tomcat-backed-64d5bc78f7-lv844       1/1     Running   0          24h
tomcat-backed-64d5bc78f7-s62j8       1/1     Running   0          24h
[root@master volumes]# kubectl get pods -o wide
NAME                                 READY   STATUS    RESTARTS   AGE    IP            NODE     NOMINATED NODE   READINESS GATES
liveness-httpget-pod                 1/1     Running   1          9d     10.244.2.17   node02            
myapp-backend-pod-69dc8c7655-pqwk8   1/1     Running   0          24h    10.244.1.27   node01            
myapp-backend-pod-69dc8c7655-sgpw6   1/1     Running   0          24h    10.244.1.28   node01            
myapp-backend-pod-69dc8c7655-v4jvx   1/1     Running   0          24h    10.244.2.30   node02            
myapp-deploy-69dc8c7655-jkkwv        1/1     Running   0          4d8h   10.244.1.24   node01            
myapp-deploy-69dc8c7655-q97jc        1/1     Running   0          4d8h   10.244.2.25   node02            
myapp-deploy-69dc8c7655-sldk8        1/1     Running   0          4d8h   10.244.2.27   node02            
myapp-deploy-69dc8c7655-v9dvc        1/1     Running   0          4d8h   10.244.2.28   node02            
myapp-deploy-69dc8c7655-x5qth        1/1     Running   0          4d8h   10.244.1.25   node01            
nginx-7849c4bbcd-dscjr               1/1     Running   0          12d    10.244.1.13   node01            
nginx-7849c4bbcd-vdd45               1/1     Running   0          12d    10.244.2.15   node02            
nginx-7849c4bbcd-wrvks               1/1     Running   0          12d    10.244.1.14   node01            
nginx-deploy-84cbfc56b6-mjcw5        1/1     Running   0          13d    10.244.2.9    node02            
pod-demo                             2/2     Running   0          117s   10.244.2.33   node02              这里
tomcat-backed-64d5bc78f7-b9tlh       1/1     Running   0          24h    10.244.1.29   node01            
tomcat-backed-64d5bc78f7-lv844       1/1     Running   0          24h    10.244.2.32   node02            
tomcat-backed-64d5bc78f7-s62j8       1/1     Running   0          24h    10.244.2.31   node02            
在上面,我们定义了2个容器,其中一个容器是输入日期到index.html中,然后验证访问nginx的html是否可以获取日期。
以验证两个容器之间挂载的emptyDir实现共享。如下访问验证:
[root@master volumes]# curl 10.244.2.33
Thu Mar 14 15:59:22 UTC 2019
Thu Mar 14 15:59:24 UTC 2019
Thu Mar 14 15:59:26 UTC 2019
Thu Mar 14 15:59:28 UTC 2019
Thu Mar 14 15:59:30 UTC 2019
Thu Mar 14 15:59:32 UTC 2019
Thu Mar 14 15:59:34 UTC 2019
Thu Mar 14 15:59:36 UTC 2019
Thu Mar 14 15:59:38 UTC 2019

========================
三、gitRepo
    把git仓库当作存储卷使用,宿主机必须有git命令,他也是在emptyDir之上。
说明:
    克隆仓库的内容
    修改不会同步git仓库
    如果pod运行过程,git仓库发生改变,不会从新同步新数据,当然如果想同步,可以做个辅助容器定时同步,实现同步。
[root@master volumes]# vim vol-gitrepo-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: vol-gitrepo-pod
  namespace: default
  labels:
    app: wolf
    tier: frontend
spec:
  containers:
  - name: wolf
    image: nginx:1.12-alpine
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html/
  volumes:
  - name: html
    gitRepo:
      repository: https://github.com/iKubernetes/k8s_book.git
      directory: .
      revision: "master"
这里创建失败,回头找原因
=======================
四、hostPath
    hostPath宿主机路径,就是把pod所在的宿主机之上的脱离pod中的容器名称空间的之外的宿主机的文件
系统的某一目录和pod建立关联关系,在pod删除时,存储数据不会丢失。

1、查看hostPath存储类型定义
[root@master ~]#kubectl explain pods.spec.volumes.hostPath 
[root@master ~]#kubectl explain pods.spec.volumes.hostPath.type

https://kubernetes.io/docs/concepts/storage/volumes#hostpath
type:
DirectoryOrCreate  宿主机上不存在创建此目录  
Directory 必须存在挂载目录  
FileOrCreate 宿主机上不存在挂载文件就创建  
File 必须存在文件
[root@master volumes]# vim pod-hostpath--vol.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-vol-hostpath
  namespace: default
spec:
  containers:
  - name: myapp
    image: nginx
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
  volumes:
  - name: html
    hostPath:
      path: /data/pod/volume1
      type: DirectoryOrCreate
为了显示效果,去node1和node2上建立/data/pod/volume1,并创建index.html文件,分别写入node1和node2
[root@master volumes]# kubectl apply -f pod-hostpath--vol.yaml 
pod/pod-vol-hostpath created
[root@master volumes]# kubectl get pod
NAME                                 READY   STATUS    RESTARTS   AGE
pod-vol-hostpath                     1/1     Running   0          22s
[root@master volumes]# kubectl get pod -o wide
NAME                                 READY   STATUS    RESTARTS   AGE    IP            NODE     NOMINATED NODE   READINESS GATES
pod-vol-hostpath                     1/1     Running   0          36s    10.244.2.35   node02            

[root@master volumes]# kubectl get pod -o wide
NAME                                 READY   STATUS    RESTARTS   AGE    IP            NODE     NOMINATED NODE   READINESS GATES
pod-vol-hostpath                     1/1     Running   0          4s     10.244.2.37   node02            

[root@master volumes]# curl 10.244.2.37
node02

[root@master volumes]# kubectl delete -f pod-hostpath--vol.yaml 
pod "pod-vol-hostpath" deleted
[root@master volumes]# kubectl apply -f pod-hostpath--vol.yaml 
pod/pod-vol-hostpath created
[root@master volumes]# kubectl get pod -o wide
NAME                                 READY   STATUS              RESTARTS   AGE    IP            NODE     NOMINATED NODE   READINESS GATES
pod-vol-hostpath                     0/1     ContainerCreating   0          3s            node02            

[root@master volumes]# kubectl get pod -o wide
NAME                                 READY   STATUS    RESTARTS   AGE    IP            NODE     NOMINATED NODE   READINESS GATES
pod-vol-hostpath                     1/1     Running   0          6s     10.244.2.38   node02            

[root@master volumes]# curl 10.244.2.38
node02

hostPath可以实现持久存储,但是在node节点故障时,也会导致数据的丢失

========================
五、nfs共享存储卷
  nfs使的我们可以挂在已经存在的共享到的我们的Pod中,和emptyDir不同的是,emptyDir会被删除
当我们的Pod被删除的时候,但是nfs不会被删除,仅仅是解除挂在状态而已,这就意味着NFS能够允许
我们提前对数据进行处理,而且这些数据可以在Pod之间相互传递.并且,nfs可以同时被多个pod挂在并
进行读写。

[root@master volumes]# kubectl explain pv      #查看pv的定义方式
FIELDS:
    apiVersion
    kind
    metadata
    spec

[root@master volumes]# kubectl explain pv.spec       #查看pv定义的规格
spec:
  nfs(定义存储类型)
    path(定义挂载卷路径)
    server(定义服务器名称)
  accessModes(定义访问模型,有以下三种访问模型,以列表的方式存在,也就是说可以定义多个访问模式)
    ReadWriteOnce(RWO)  单节点读写
    ReadOnlyMany(ROX)  多节点只读
    ReadWriteMany(RWX)  多节点读写
  capacity(定义PV空间的大小)
    storage(指定大小)    


[root@master volumes]# kubectl explain pvc   #查看PVC的定义方式
KIND:     PersistentVolumeClaim
VERSION:  v1
FIELDS:
   apiVersion  
   kind  
   metadata
   spec
[root@master volumes]# kubectl explain pvc.spec
spec:
  accessModes(定义访问模式,必须是PV的访问模式的子集)
  resources(定义申请资源的大小)
    requests:
      storage: 
    
注意:必须先报纸NFS服务器正常运行在我们进行挂在nfs的时候

在master节点上安装nfs,并配置nfs服务
[root@master volumes]#yum install nfs-utils -y
[root@master volumes]# mkdir /data/volumes -pv
[root@master data]# cat /etc/exports
/data/wolf 10.249.6.0/24(rw,no_root_squash)
[root@master volumes]# systemctl start nfs
[root@master data]# showmount -e
Export list for master:
/data/wolf 10.249.6.0/24

在node01和node02节点上安装nfs-utils,并测试挂载

[root@node01 ~]# yum install -y nfs-utils
[root@node01 ~]# mount -t nfs master:/data/wolf /tmp
[root@node01 ~]# mount
master:/data/wolf on /tmp type nfs4 (rw,relatime,vers=4.1,rsize=1048576,wsize=1048576,namlen=255,hard,proto=tcp,port=0,timeo=600,retrans=2,sec=sys,clientaddr=10.249.6.101,local_lock=none,addr=10.249.6.100)
[root@node01 ~]# umount /tmp

[root@node02 ~]# yum install -y nfs-utils
[root@node02 ~]# mount -t nfs master:/data/wolf /tmp
[root@node02 ~]# umount /tmp

创建nfs存储卷的使用清单
[root@master volumes]# cp pod-hostpath--vol.yaml pod-nfs-vol.yaml
[root@master volumes]# vi pod-nfs-vol.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-vol-nfs
  namespace: default
spec:
  containers:
  - name: myapp
    image: nginx
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
  volumes:
  - name: html
    nfs:
      path: /data/wolf
      server: master
[root@master volumes]# kubectl apply -f pod-nfs-vol.yaml 
pod/pod-vol-nfs created
[root@master volumes]# kubectl get pods -o wide
NAME                                 READY   STATUS    RESTARTS   AGE    IP            NODE     NOMINATED NODE   READINESS GATES
pod-vol-nfs                          1/1     Running   0          9s     10.244.2.39   node02            

在nfs服务器上创建index.html
[root@master wolf]# vi index.html
[root@master wolf]# cat index.html 

wolf nfs


[root@master wolf]# curl 10.244.2.39

wolf nfs


[root@master wolf]# curl 10.244.2.39

wolf nfs


[root@master wolf]# curl 10.244.2.39

wolf nfs

删除pod,重建,可以看出数据持久化
[root@master volumes]# kubectl delete -f pod-nfs-vol.yaml 
pod "pod-vol-nfs" deleted
[root@master volumes]# kubectl apply -f pod-nfs-vol.yaml 
pod/pod-vol-nfs created
[root@master volumes]# kubectl get pods -o wide
NAME                                 READY   STATUS    RESTARTS   AGE    IP            NODE     NOMINATED NODE   READINESS GATES
pod-vol-nfs                          1/1     Running   0          15s    10.244.2.40   node02            
[root@master volumes]# curl 10.244.2.40

wolf nfs


========================
========================
PVC和PV的概念
    我们前面提到kubernetes提供那么多存储接口,但是首先kubernetes的各个Node节点能管理这些存储,但是各
种存储参数也需要专业的存储工程师才能了解,由此我们的kubernetes管理变的更加复杂的。由此kubernetes提出
了PV和PVC的概念,这样开发人员和使用者就不需要关注后端存储是什么,使用什么参数等问题。

PersistentVolume(PV)是集群中已由管理员配置的一段网络存储。 集群中的资源就像一个节点是一个集群资源。 
PV是诸如卷之类的卷插件,但是具有独立于使用PV的任何单个pod的生命周期。 该API对象捕获存储的实现细节,
即NFS,iSCSI或云提供商特定的存储系统。

PersistentVolumeClaim(PVC)是用户存储的请求。PVC的使用逻辑:在pod中定义一个存储卷(该存储卷类型为PVC)
,定义的时候直接指定大小,pvc必须与对应的pv建立关系,pvc会根据定义去pv申请,而pv是由存储空间创建出来的
。pv和pvc是kubernetes抽象出来的一种存储资源。

虽然PersistentVolumeClaims允许用户使用抽象存储资源,但是常见的需求是,用户需要根据不同的需求去创建PV,
用于不同的场景。而此时需要集群管理员提供不同需求的PV,而不仅仅是PV的大小和访问模式,但又不需要用户了解
这些卷的实现细节。 对于这样的需求,此时可以采用StorageClass资源。这个在前面就已经提到过此方案。

PV是集群中的资源。 PVC是对这些资源的请求,也是对资源的索赔检查。 PV和PVC之间的相互作用遵循这个生命周期:
Provisioning(配置)---> Binding(绑定)--->Using(使用)---> Releasing(释放) ---> Recycling(回收)

Provisioning
   这里有两种PV的提供方式:静态或者动态

静态-->直接固定存储空间:
    集群管理员创建一些 PV。它们携带可供集群用户使用的真实存储的详细信息。 它们存在于Kubernetes API中,可
用于消费。

动态-->通过存储类进行动态创建存储空间:
    当管理员创建的静态 PV 都不匹配用户的 PVC 时,集群可能会尝试动态地为 PVC 配置卷。此配置基于 
StorageClasses:PVC 必须请求存储类,并且管理员必须已创建并配置该类才能进行动态配置。 要求该类的声明有
效地为自己禁用动态配置。

Binding
    在动态配置的情况下,用户创建或已经创建了具有特定数量的存储请求和特定访问模式的PersistentVolumeClaim。
主机中的控制回路监视新的PVC,找到匹配的PV(如果可能),并将 PVC 和 PV 绑定在一起。 如果为新的PVC动态配置
PV,则循环将始终将该PV绑定到PVC。 否则,用户总是至少得到他们要求的内容,但是卷可能超出了要求。 一旦绑定,
PersistentVolumeClaim绑定是排他的,不管用于绑定它们的模式。

    如果匹配的卷不存在,PVC将保持无限期。 随着匹配卷变得可用,PVC将被绑定。 例如,提供许多50Gi PV的集群将
不匹配要求100Gi的PVC。 当集群中添加100Gi PV时,可以绑定PVC。

Using
    Pod使用PVC作为卷。 集群检查声明以找到绑定的卷并挂载该卷的卷。 对于支持多种访问模式的卷,用户在将其声
明用作pod中的卷时指定所需的模式。

    一旦用户有声明并且该声明被绑定,绑定的PV属于用户,只要他们需要它。 用户通过在其Pod的卷块中包含
PersistentVolumeClaim来安排Pods并访问其声明的PV。


Releasing
    当用户完成卷时,他们可以从允许资源回收的API中删除PVC对象。 当声明被删除时,卷被认为是“释放的”,但是它
还不能用于另一个声明。 以前的索赔人的数据仍然保留在必须根据政策处理的卷上.

Reclaiming
    PersistentVolume的回收策略告诉集群在释放其声明后,该卷应该如何处理。 目前,卷可以是保留,回收或删除。 
保留可以手动回收资源。 对于那些支持它的卷插件,删除将从Kubernetes中删除PersistentVolume对象,以及删除外部
基础架构(如AWS EBS,GCE PD,Azure Disk或Cinder卷)中关联的存储资产。 动态配置的卷始终被删除

Recycling
    如果受适当的卷插件支持,回收将对卷执行基本的擦除(rm -rf / thevolume / *),并使其再次可用于新的声明。

========================
六、NFS使用PV和PVC
pod--pvc--pv-nfs

[root@master volumes]# kubectl explain pv        #查看pv的定义方式

[root@master volumes]# kubectl explain pv.spec   #查看pv定义的规格
spec:
  nfs(定义存储类型)
    path(定义挂载卷路径)
    server(定义服务器名称)
  accessModes(定义访问模型,有以下三种访问模型,以列表的方式存在,也就是说可以定义多个访问模式)
    ReadWriteOnce(RWO)  单节点读写
    ReadOnlyMany(ROX)  多节点只读
    ReadWriteMany(RWX)  多节点读写
  capacity(定义PV空间的大小)
    storage(指定大小)

[root@master volumes]# kubectl explain pvc   #查看PVC的定义方式
KIND:     PersistentVolumeClaim
VERSION:  v1
FIELDS:
   apiVersion  
   kind  
   metadata
   spec
[root@master volumes]# kubectl explain pvc.spec
spec:
  accessModes(定义访问模式,必须是PV的访问模式的子集)
  resources(定义申请资源的大小)
    requests:
      storage:
      
1、配置nfs存储
[root@master volumes]# mkdir -p /data/wolf{1,2,3,4,5}
[root@master volumes]# ll /data/
total 0
drwxr-xr-x. 3 root root 21 Mar 15 10:27 pod
drwxr-xr-x. 2 root root  6 Mar 16 03:51 volumes
drwxr-xr-x. 2 root root 24 Mar 16 13:12 wolf
drwxr-xr-x. 2 root root  6 Mar 16 13:25 wolf1
drwxr-xr-x. 2 root root  6 Mar 16 13:25 wolf2
drwxr-xr-x. 2 root root  6 Mar 16 13:25 wolf3
drwxr-xr-x. 2 root root  6 Mar 16 13:25 wolf4
drwxr-xr-x. 2 root root  6 Mar 16 13:25 wolf5
[root@master volumes]# cat /etc/exports
/data/wolf 10.249.6.0/24(rw,no_root_squash)

echo "/data/wolf1 10.249.6.0/24(rw,no_root_squash)" >>/etc/exports
echo "/data/wolf2 10.249.6.0/24(rw,no_root_squash)" >>/etc/exports
echo "/data/wolf3 10.249.6.0/24(rw,no_root_squash)" >>/etc/exports
echo "/data/wolf4 10.249.6.0/24(rw,no_root_squash)" >>/etc/exports
echo "/data/wolf5 10.249.6.0/24(rw,no_root_squash)" >>/etc/exports

[root@master volumes]# cat /etc/exports
/data/wolf 10.249.6.0/24(rw,no_root_squash)
/data/wolf1 10.249.6.0/24(rw,no_root_squash)
/data/wolf2 10.249.6.0/24(rw,no_root_squash)
/data/wolf3 10.249.6.0/24(rw,no_root_squash)
/data/wolf4 10.249.6.0/24(rw,no_root_squash)
/data/wolf5 10.249.6.0/24(rw,no_root_squash)

[root@master volumes]# exportfs -arv
exporting 10.249.6.0/24:/data/wolf5
exporting 10.249.6.0/24:/data/wolf4
exporting 10.249.6.0/24:/data/wolf3
exporting 10.249.6.0/24:/data/wolf2
exporting 10.249.6.0/24:/data/wolf1
exporting 10.249.6.0/24:/data/wolf
[root@master volumes]# showmount -e
Export list for master:
/data/wolf5 10.249.6.0/24
/data/wolf4 10.249.6.0/24
/data/wolf3 10.249.6.0/24
/data/wolf2 10.249.6.0/24
/data/wolf1 10.249.6.0/24
/data/wolf  10.249.6.0/24

2、定义PV
这里定义5个PV,并且定义挂载的路径以及访问模式,还有PV划分的大小。
[root@master volumes]# kubectl explain pv
[root@master volumes]# kubectl explain pv.spec.nfs
[root@master volumes]# vim pv-demo.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv001
  labels:
    name: pv001
spec:
  nfs:
    path: /data/wolf1
    server: master
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 1Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv002
  labels:
    name: pv002
spec:
  nfs:
    path: /data/wolf2
    server: master
  accessModes: ["ReadWriteOnce"]
  capacity:
    storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv003
  labels:
    name: pv003
spec:
  nfs:
    path: /data/wolf3
    server: master
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 2Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv004
  labels:
    name: pv004
spec:
  nfs:
    path: /data/wolf4
    server: master
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 4Gi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: pv005
  labels:
    name: pv005
spec:
  nfs:
    path: /data/wolf5
    server: master
  accessModes: ["ReadWriteMany","ReadWriteOnce"]
  capacity:
    storage: 5Gi
    
[root@master volumes]# kubectl apply -f pv-demo.yaml 
persistentvolume/pv001 created
persistentvolume/pv002 created
persistentvolume/pv003 created
persistentvolume/pv004 created
persistentvolume/pv005 created
[root@master volumes]# kubectl get pv
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
pv001   1Gi        RWO,RWX        Retain           Available                                   8s
pv002   2Gi        RWO            Retain           Available                                   8s
pv003   2Gi        RWO,RWX        Retain           Available                                   8s
pv004   4Gi        RWO,RWX        Retain           Available                                   8s
pv005   5Gi        RWO,RWX        Retain           Available                                   8s

3、定义PVC
    这里定义了pvc的访问模式为多路读写,该访问模式必须在前面pv定义的访问模式之中。定义PVC申请的大小为2Gi,
此时PVC会自动去匹配多路读写且大小为2Gi的PV,匹配成功获取PVC的状态即为Bound

[root@master volumes]#vi pod-vol-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mypvc
  namespace: default
spec:
  accessModes: ["ReadWriteMany"]
  resources:
    requests:
      storage: 2Gi
---
apiVersion: v1
kind: Pod
metadata:
  name: pod-vol-pvc
  namespace: default
spec:
  containers:
  - name: myapp
    image: nginx
    volumeMounts:
    - name: html
      mountPath: /usr/share/nginx/html
  volumes:
    - name: html
      persistentVolumeClaim:
        claimName: mypvc

[root@master volumes]# kubectl apply -f pv-demo.yaml 
persistentvolume/pv001 created
persistentvolume/pv002 created
persistentvolume/pv003 created
persistentvolume/pv004 created
persistentvolume/pv005 created
[root@master volumes]# kubectl get pv
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
pv001   1Gi        RWO,RWX        Retain           Available                                   8s
pv002   2Gi        RWO            Retain           Available                                   8s
pv003   2Gi        RWO,RWX        Retain           Available                                   8s
pv004   4Gi        RWO,RWX        Retain           Available                                   8s
pv005   5Gi        RWO,RWX        Retain           Available                                   8s
[root@master volumes]# kubectl get pvv
error: the server doesn't have a resource type "pvv"
[root@master volumes]# kubectl get pvc
No resources found.
[root@master volumes]# vi pod-vol-pvc.yaml
[root@master volumes]# kubectl apply -f pod-vol-pvc.yaml 
persistentvolumeclaim/mypvc created
pod/pod-vol-pvc created
[root@master volumes]# kubectl get pv
NAME    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM           STORAGECLASS   REASON   AGE
pv001   1Gi        RWO,RWX        Retain           Available                                           2m27s
pv002   2Gi        RWO            Retain           Available                                           2m27s
pv003   2Gi        RWO,RWX        Retain           Bound       default/mypvc                           2m27s
pv004   4Gi        RWO,RWX        Retain           Available                                           2m27s
pv005   5Gi        RWO,RWX        Retain           Available                                           2m27s
[root@master volumes]# kubectl get pvc
NAME    STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
mypvc   Bound    pv003    2Gi        RWO,RWX                       18s

4、测试访问
在存储服务器上创建index.html,并写入数据,通过访问Pod进行查看,可以获取到相应的页面。
[root@master data]# ls
pod  volumes  wolf  wolf1  wolf2  wolf3  wolf4  wolf5
[root@master data]# cd wolf3
[root@master wolf3]# ls
[root@master wolf3]# echo "use pv3" >index.html
[root@master wolf3]# kubectl get pods -o wide
NAME                                 READY   STATUS    RESTARTS   AGE     IP            NODE     NOMINATED NODE   READINESS GATES
pod-vol-pvc                          1/1     Running   0          2m40s   10.244.2.41   node02            

[root@master wolf3]# curl 10.244.2.41
use pv

========================

k8s支持的类型
[root@master ~]# kubectl explain pod.spec.volumes
KIND:     Pod
VERSION:  v1

RESOURCE: volumes <[]Object>

DESCRIPTION:
     List of volumes that can be mounted by containers belonging to the pod.
     More info: https://kubernetes.io/docs/concepts/storage/volumes

     Volume represents a named volume in a pod that may be accessed by any
     container in the pod.

FIELDS:
   awsElasticBlockStore        这里是aws ebs
     AWSElasticBlockStore represents an AWS Disk resource that is attached to a
     kubelet's host machine and then exposed to the pod. More info:
     https://kubernetes.io/docs/concepts/storage/volumes#awselasticblockstore

   azureDisk      微软云
     AzureDisk represents an Azure Data Disk mount on the host and bind mount to
     the pod.

   azureFile     微软云
     AzureFile represents an Azure File Service mount on the host and bind mount
     to the pod.

   cephfs      这个不说了撒 ceph
     CephFS represents a Ceph FS mount on the host that shares a pod's lifetime

   cinder      
     Cinder represents a cinder volume attached and mounted on kubelets host
     machine More info:
     https://releases.k8s.io/HEAD/examples/mysql-cinder-pd/README.md

   configMap    
     ConfigMap represents a configMap that should populate this volume

   downwardAPI    
     DownwardAPI represents downward API about the pod that should populate this
     volume

   emptyDir    
     EmptyDir represents a temporary directory that shares a pod's lifetime.
     More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir

   fc    
     FC represents a Fibre Channel resource that is attached to a kubelet's host
     machine and then exposed to the pod.

   flexVolume    
     FlexVolume represents a generic volume resource that is
     provisioned/attached using an exec based plugin.

   flocker    
     Flocker represents a Flocker volume attached to a kubelet's host machine.
     This depends on the Flocker control service being running

   gcePersistentDisk    
     GCEPersistentDisk represents a GCE Disk resource that is attached to a
     kubelet's host machine and then exposed to the pod. More info:
     https://kubernetes.io/docs/concepts/storage/volumes#gcepersistentdisk

   gitRepo    
     GitRepo represents a git repository at a particular revision. DEPRECATED:
     GitRepo is deprecated. To provision a container with a git repo, mount an
     EmptyDir into an InitContainer that clones the repo using git, then mount
     the EmptyDir into the Pod's container.

   glusterfs    
     Glusterfs represents a Glusterfs mount on the host that shares a pod's
     lifetime. More info:
     https://releases.k8s.io/HEAD/examples/volumes/glusterfs/README.md

   hostPath    
     HostPath represents a pre-existing file or directory on the host machine
     that is directly exposed to the container. This is generally used for
     system agents or other privileged things that are allowed to see the host
     machine. Most containers will NOT need this. More info:
     https://kubernetes.io/docs/concepts/storage/volumes#hostpath

   iscsi    
     ISCSI represents an ISCSI Disk resource that is attached to a kubelet's
     host machine and then exposed to the pod. More info:
     https://releases.k8s.io/HEAD/examples/volumes/iscsi/README.md

   name     -required-
     Volume's name. Must be a DNS_LABEL and unique within the pod. More info:
     https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names

   nfs    
     NFS represents an NFS mount on the host that shares a pod's lifetime More
     info: https://kubernetes.io/docs/concepts/storage/volumes#nfs

   persistentVolumeClaim    
     PersistentVolumeClaimVolumeSource represents a reference to a
     PersistentVolumeClaim in the same namespace. More info:
     https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistentvolumeclaims

   photonPersistentDisk    
     PhotonPersistentDisk represents a PhotonController persistent disk attached
     and mounted on kubelets host machine

   portworxVolume    
     PortworxVolume represents a portworx volume attached and mounted on
     kubelets host machine

   projected    
     Items for all in one resources secrets, configmaps, and downward API

   quobyte    
     Quobyte represents a Quobyte mount on the host that shares a pod's lifetime

   rbd    
     RBD represents a Rados Block Device mount on the host that shares a pod's
     lifetime. More info:
     https://releases.k8s.io/HEAD/examples/volumes/rbd/README.md

   scaleIO    
     ScaleIO represents a ScaleIO persistent volume attached and mounted on
     Kubernetes nodes.

   secret    
     Secret represents a secret that should populate this volume. More info:
     https://kubernetes.io/docs/concepts/storage/volumes#secret

   storageos    
     StorageOS represents a StorageOS volume attached and mounted on Kubernetes
     nodes.

   vsphereVolume    
     VsphereVolume represents a vSphere volume attached and mounted on kubelets
     host machine

[root@master ~]# kubectl explain pod.spec.volumes.emptyDir
KIND:     Pod
VERSION:  v1

RESOURCE: emptyDir

DESCRIPTION:
     EmptyDir represents a temporary directory that shares a pod's lifetime.
     More info: https://kubernetes.io/docs/concepts/storage/volumes#emptydir

     Represents an empty directory for a pod. Empty directory volumes support
     ownership management and SELinux relabeling.

FIELDS:
   medium      媒介类型  
     What type of storage medium should back this directory. The default is ""
     which means to use the node's default medium. Must be an empty string
     (default) or Memory. More info: 
     https://kubernetes.io/docs/concepts/storage/volumes#emptydir

   sizeLimit    
     Total amount of local storage required for this EmptyDir volume. The size
     limit is also applicable for memory medium. The maximum usage on memory
     medium EmptyDir would be the minimum value between the SizeLimit specified
     here and the sum of memory limits of all containers in a pod. The default
     is nil which means that the limit is undefined. More info:
     http://kubernetes.io/docs/user-guide/volumes#emptydir
     
[root@master ~]#  kubectl explain pods.spec.volumes.hostPath 
KIND:     Pod
VERSION:  v1

RESOURCE: hostPath

DESCRIPTION:
     HostPath represents a pre-existing file or directory on the host machine
     that is directly exposed to the container. This is generally used for
     system agents or other privileged things that are allowed to see the host
     machine. Most containers will NOT need this. More info:
     https://kubernetes.io/docs/concepts/storage/volumes#hostpath

     Represents a host path mapped into a pod. Host path volumes do not support
     ownership management or SELinux relabeling.

FIELDS:
   path     -required-               #指定宿主机的路径
     Path of the directory on the host. If the path is a symlink, it will follow
     the link to the real path. More info:
     https://kubernetes.io/docs/concepts/storage/volumes#hostpath

   type    
     Type for HostPath Volume Defaults to "" More info:
     https://kubernetes.io/docs/concepts/storage/volumes#hostpath
     
[root@master volumes]# kubectl explain pv      #查看pv的定义方式
KIND:     PersistentVolume
VERSION:  v1

DESCRIPTION:
     PersistentVolume (PV) is a storage resource provisioned by an
     administrator. It is analogous to a node. More info:
     https://kubernetes.io/docs/concepts/storage/persistent-volumes

FIELDS:
   apiVersion  
     APIVersion defines the versioned schema of this representation of an
     object. Servers should convert recognized schemas to the latest internal
     value, and may reject unrecognized values. More info:
     https://git.k8s.io/community/contributors/devel/api-conventions.md#resources

   kind
     Kind is a string value representing the REST resource this object
     represents. Servers may infer this from the endpoint the client submits
     requests to. Cannot be updated. In CamelCase. More info:
     https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds

   metadata    
     Standard object's metadata. More info:
     https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata

   spec
     Spec defines a specification of a persistent volume owned by the cluster.
     Provisioned by an administrator. More info:
     https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistent-volumes

   status      
     Status represents the current information/status for the persistent volume.
     Populated by the system. Read-only. More info:
     https://kubernetes.io/docs/concepts/storage/persistent-volumes#persistent-volumes
 

你可能感兴趣的:(devops,kubenetes,kubenetes)