zoukankan      html  css  js  c++  java
  • Kubernetes学习笔记(五):卷

    简介

    卷是Pod的一部分,与Pod共享生命周期。它不是独立的Kubernetes对象,因此不能单独创建。

    卷提供的存储功能不但可以解决容器重启后数据丢失的问题,还可以使数据在容器间共享。

    一些卷的类型:

    • emptyDir:用于存储临时数据的空目录
    • hostPath:用于将目录从工作节点挂载到pod
    • gitRepo:通过检出Git仓库的内容来初始化的卷
    • nfs:挂载到pod中的nfs共享卷
    • configMap、secret、downwardAPI:用于将Kubernetes部分资源和集群信息公开给pod的特殊类型的卷
    • persistentVolumeClaim:一种使用预置或者动态配置的持久存储类型

    单个容器可以同时使用不同类型的多个卷。

    emptyDir

    emptyDir卷对于在同一个pod中运行的容器之间共享文件特别有用。但也可以被单个容器用于将数据临时写入磁盘。

    下面的例子中,Pod包含两个容器,这个两个容器分别将卷html挂载到容器内的不同路径,实现了文件共享。html-generator每隔一秒写入当前时间到index.html,web-server提供web服务使index.html可以被访问。

    # volume-share-pod.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: volume-share
    spec:
      containers:
        - image: alpine		# 容器镜像一
          name: html-generator
          volumeMounts:		# 将名为html的卷挂载到容器的/var/html
          - name: html
            mountPath: /var/html
          command: ["sh","-c","mkdir /var/html; while :; do echo $(date) > /var/html/index.html;sleep 1;done"]
        - image: nginx:alpine	#容器镜像二
          name: web-server
          volumeMounts:		# 与上面相同的卷卷挂载到容器的/usr/share/nginx/html
          - name: html
            mountPath: /usr/share/nginx/html
            readOnly: true
          ports:
          - containerPort: 80
      volumes:			# 创建一个名为html的卷
      - name: html
        emptyDir: {}
    

    创建pod,设置端口转发

    -> [root@kube0.vm] [~] k create -f volume-share-pod.yaml
    pod/volume-share created
    
    -> [root@kube0.vm] [~] k port-forward volume-share 80:80
    Forwarding from 127.0.0.1:80 -> 80
    Forwarding from [::1]:80 -> 80
    

    发出请求

    -> [root@kube0.vm] [~] curl http://localhost
    Sun May 24 01:14:48 UTC 2020
    -> [root@kube0.vm] [~] curl http://localhost
    Sun May 24 01:14:49 UTC 2020
    

    如果进行下面的改动,emptyDir的内容会存在内存中

      volumes:
      - name: html
        emptyDir: 
          medium: Memory
    

    gitRepo

    gitRepo卷基本上也是一个emptyDir卷,它在容器启动前从git仓库检出填充数据。

    当git仓库内容发生改变时,对已存在的Pod内的gitRepo卷是不可见的。但启动新的Pod时会检出最新的。

    下面的例子中,该pod创建了一个名为html的gitRepo卷的,创建一个提供web服务的容器web-server,并将卷html挂载到web-server的/usr/share/nginx/html。

    # volume-gitrepo-pod.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: volume-gitrepo
    spec:
      containers:
        - image: nginx:alpine
          name: web-server
          volumeMounts:
          - name: html
            mountPath: /usr/share/nginx/html
            readOnly: true
          ports:
          - containerPort: 80
      volumes:		# 创建一个名为html的gitRepo卷
      - name: html
        gitRepo:
          repository: https://github.com/orccn/kube-dockerfile.git	# 仓库地址
          revision: master	# 分支
          directory: .	# 检出到卷的根目录
    

    创建pod,设置端口转发

    -> [root@kube0.vm] [~] k create -f volume-gitrepo-pod.yaml
    pod/volume-gitrepo created
    
    -> [root@kube0.vm] [~] k port-forward volume-gitrepo 80:80
    Forwarding from 127.0.0.1:80 -> 80
    Forwarding from [::1]:80 -> 80
    

    发出请求

    -> [root@kube0.vm] [~] curl http://localhost/etcd/Dockerfile
    FROM k8s.gcr.io/etcd:3.4.3-0
    

    hostPath

    hostPath卷提供的是映射到工作节点本地持久存储。所以应仅当需要在工作节点上读写文件时才使用hostPath

    下例中,Pod中创建一个名为html的hostPath卷挂载到工作节点的 /tmp/html,容器volume-hostpath将卷html挂载到/var/html,并且向其中写入文件。

    # volume-hostpath-pod.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: volume-hostpath
    spec:
      containers:
        - image: alpine
          name: volume-hostpath
          command: ["sh","-c","mkdir /var/html; while :; do echo $(date) > /var/html/index.html;sleep 1;done"]
          volumeMounts:
          - name: html
            mountPath: /var/html
      volumes:
      - name: html
        hostPath:
          path: /tmp/html
    

    创建volume-hostpath,查看其部署在哪个节点。

    -> [root@kube0.vm] [~] k create -f volume-hostpath-pod.yaml
    pod/volume-hostpath created
    
    -> [root@kube0.vm] [~] k get po -o wide
    NAME              READY   STATUS    RESTARTS   AGE     IP            NODE       NOMINATED NODE   READINESS GATES
    volume-hostpath   1/1     Running   0          9m32s   10.244.1.11   kube1.vm   <none>           <none>
    

    进入节点kube1.vm

    -> [root@kube1.vm] [~] cat /tmp/html/index.html
    Sun May 24 02:26:14 UTC 2020
    

    PV与PVC

    PV(PersistentVolume持久卷)也是一种资源,并且不属于任何命名空间。它的功能与卷类似,但是它的生命周期是独立于Pod的。PV由集群管理员创建,并被Pod通过PVC(PersistentVolumeClaim,持久卷声明)使用。

    在创建PV时,管理员可以指定其大小和支持的访问模式:

    • ReadWriteOnce(RWO):仅允许单个节点挂载读写
    • ReadOnlyMany(ROX):允许多个节点挂载只读
    • ReadWriteMany(RWX):允许多个节点挂载读写

    一个卷不论支持多少种访问模式,同时只能以一种访问模式加载。

    创建PV

    管理员在创建PV时需要指定,PV的大小、访问模式、实际存储类型、路径等。

    # pv.yaml
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      name: mypv
    spec:
      capacity:
        storage: 10Mi	# 定义大小
      accessModes:	# 支持单个客户端挂在为读写模式或者多个客户端只读模式
      - ReadWriteOnce
      - ReadOnlyMany
      persistentVolumeReclaimPolicy: Retain	# 当声明被释放后,PV将被保留
      hostPath:
        path: /tmp/pv
    

    条件有限,所以存储类型只能先选hostPath用着,接下来创建pv并查看

    -> [root@kube0.vm] [~] k create -f pv.yaml
    persistentvolume/volume-pv created
    
    -> [root@kube0.vm] [~] k get pv
    NAME   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE
    mypv   10Mi       RWO,ROX        Retain           Available                                   4s
    

    创建PVC

    假设要部署一个需要持久化存储的Pod,将要用到持久卷,但是不能在Pod中直接使用,需要先声明一个。

    # pvc.yaml
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: mypvc
    spec:
      resources:
        requests:
          storage: 10Mi
      accessModes:
      - ReadWriteOnce
      storageClassName: ""
    

    PVC创建好后,Kubernetes会寻找适当的PV将其绑定到PVC。持久卷必须要足够大,并且包含声明中指定的访问模式。

    -> [root@kube0.vm] [~] k create -f pvc.yaml
    persistentvolumeclaim/mypvc created
    
    -> [root@kube0.vm] [~] k get pv,pvc
    NAME                    CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM           STORAGECLASS   REASON   AGE
    persistentvolume/mypv   10Mi       RWO,ROX        Retain           Bound    default/mypvc                           7m11s
    
    NAME                          STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
    persistentvolumeclaim/mypvc   Bound    mypv     10Mi       RWO,ROX                       9s
    

    可以看到持久卷被绑定到default/mypvc声明上,default是mypvc的命名空间。PV不存在命名空间的概念,但是PVC只能在特定命名空间创建。

    Pod中使用PVC

    # use-pvc-pod.yaml
    apiVersion: v1
    kind: Pod
    metadata:
      name: use-pvc
    spec:
      containers:	# 这里的内容与volume-share.yaml的一样,所以功能不再赘叙,
        - image: alpine
          name: html-generator
          volumeMounts:
          - name: html
            mountPath: /var/html
          command: ["sh","-c","mkdir /var/html; while :; do echo $(date) > /var/html/index.html;sleep 1;done"]
      volumes:
      - name: html
        persistentVolumeClaim:	# 这里使用了PVC类型,制定了PVC的名字
          claimName: mypvc
    

    创建Pod

    -> [root@kube0.vm] [~] k create -f use-pvc-pod.yaml
    pod/use-pvc created
    
    -> [root@kube0.vm] [~] k get po -o wide
    NAME      READY   STATUS    RESTARTS   AGE    IP            NODE       NOMINATED NODE   READINESS GATES
    use-pvc   1/1     Running   0          4m1s   10.244.1.12   kube1.vm   <none>           <none>
    

    与kube1.vm查看是否写入了内容

    -> [root@kube1.vm] [~] cat /tmp/pv/index.html
    Sun May 24 06:43:02 UTC 2020
    

    回收PV

    删除PVC后,查看PV,可以看到此时的状态是Released,而不是之前的Available。

    -> [root@kube0.vm] [~] k delete pvc mypvc
    persistentvolumeclaim "mypvc" deleted
    
    -> [root@kube0.vm] [~] k get pv
    NAME   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS     CLAIM           STORAGECLASS   REASON   AGE
    mypv   10Mi       RWO,ROX        Retain           Released   default/mypvc                           35s
    

    这时候在创建PVC,会发现mypvc的状态一直是Pending,因为没有可用的PV。所以,persistentVolumeReclaimPolicy设置为Retain的PV需要手动删除重建才能恢复可用。

    -> [root@kube0.vm] [~] k create -f  pvc.yaml
    persistentvolumeclaim/mypvc created
    
    -> [root@kube0.vm] [~] k get pvc
    NAME    STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
    mypvc   Pending                                                     16s
    

    persistentVolumeReclaimPolicy用来设置回收策略,其他两种是Recycle和Delete。可以在现有的PV上更改卷回收策略,比如开始设置为Delete,可以改为Retain。

    PV与PVC的声明周期,以及在Pod中的使用

    StorageClass

    使用PV与PVC可以使开发人员不用关心实际的存储技术,但是仍然需要集群管理人员来支持实际的存储。可以通过创建StorageClass资源解决此问题。

    StorageClass的作用是:为引用它的PVC在创建的时候通过置备程序创建一个PV。

    工作流程简介:

    • 集群管理员根据不同性能及特性创建若干个StorageClass
    • 开发人员创建一个引用StorageClass的PVC
    • Kubernetes查找引用的StorageClass置备程序,并按照PVC的访问模式和存储大小置备新的PV

    因为环境问题,下面的例子使用minikube运行。

    创建StorageClass

    # storageclass-fast.yaml
    apiVersion: storage.k8s.io/v1
    kind: StorageClass
    metadata:
      name: fast
    provisioner: k8s.io/minikube-hostpath
    parameters:
      type: pd-ssd
    

    运行查看

    -> [feifei@ffmac.local] [~/work/k8s] kubectl create -f storageclass-fast.yaml
    storageclass.storage.k8s.io/fast created
    
    -> [feifei@ffmac.local] [~/work/k8s] kubectl get sc
    NAME                 PROVISIONER                RECLAIMPOLICY   VOLUMEBINDINGMODE   ALLOWVOLUMEEXPANSION   AGE
    fast                 k8s.io/minikube-hostpath   Delete          Immediate           false                  114m
    standard (default)   k8s.io/minikube-hostpath   Delete          Immediate           false                  117m
    

    创建PVC引用StorageClass

    # pvc-storageclass.yaml
    apiVersion: v1
    kind: PersistentVolumeClaim
    metadata:
      name: pvc-sc
    spec:
      resources:
        requests:
          storage: 10Mi
      accessModes:
      - ReadWriteOnce
      storageClassName: fast	# 引用了上面名为fast的StorageClass
    

    可以看到,成功创建了一个名为pvc-be95fa9c-0666-4e3b-a2e2-a68c0bbea6f6的持久卷,绑定的持久卷声明是default/pvc-sc。访问模式与存储大小与pvc-sc的都一致。

    -> [feifei@ffmac.local] [~/work/k8s] kubectl create -f pvc-storageclass.yaml
    persistentvolumeclaim/pvc-sc created
    
    -> [feifei@ffmac.local] [~/work/k8s] kubectl get pv
    NAME                                       CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM            STORAGECLASS   REASON   AGE
    pvc-be95fa9c-0666-4e3b-a2e2-a68c0bbea6f6   10Mi       RWO            Delete           Bound    default/pvc-sc   fast                    3m36s
    
    -> [feifei@ffmac.local] [~/work/k8s] kubectl get pvc
    NAME     STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
    pvc-sc   Bound    pvc-be95fa9c-0666-4e3b-a2e2-a68c0bbea6f6   10Mi       RWO            fast           3m40s
    

    不指定存储类的动态配置

    如果将PVC配置中的storageClassName设置为空,那么创建PVC时将优先绑定到预先配置的PV,而不是由StorageClass配置新的PV。

    流程图

    小结

    • 卷是Pod的一部分,与Pod共享生命周期。它不是独立的Kubernetes对象,因此不能单独创建。
    • 卷提供的存储功能不但可以解决容器重启后数据丢失的问题,还可以使数据在容器间共享。
    • gitRepo卷基本上相当于emptyDir,它在容器启动前从git仓库检出填充数据。但git仓库与gitRepo的内容并不保持同步。
    • hostPath卷提供的是映射到工作节点本地持久存储
    • PV是一种资源,并且不属于任何命名空间。它的功能与卷类似,但是它的生命周期是独立于Pod的。PV由集群管理员创建,并被Pod通过PVC使用。
    • PVC创建好后,Kubernetes会寻找适当的PV将其绑定到PVC。持久卷必须要足够大,并且包含声明中指定的访问模式。
    • 可以在现有的PV上更改卷回收策略,比如开始设置为Delete,可以改为Retain。
    • StorageClass为引用它的PVC在创建的时候通过置备程序创建一个PV
    • 如果将PVC配置中的storageClassName设置为空,那么创建PVC时将优先绑定到预先配置的PV,而不是由StorageClass配置新的PV。
  • 相关阅读:
    LeetCode.152
    python
    python
    python
    python
    python
    python
    python
    PyCharm2020.1激活码破解教程
    Python GUI编程(Tkinter)17、Menu鼠标右键菜单
  • 原文地址:https://www.cnblogs.com/flhs/p/12945406.html
Copyright © 2011-2022 走看看