zoukankan      html  css  js  c++  java
  • Kubernetes Pod的数据卷Volume

    概述

    由于容器本身是非持久化的,因此需要解决在容器中运行应用程序遇到的一些问题。首先,当容器崩溃时,kubelet将重新启动容器,但是写入容器的文件将会丢失,容器将会以镜像的初始状态重新开始;第二,在通过一个Pod中一起运行的容器,通常需要共享容器之间一些文件。Kubernetes通过存储卷解决上述的两个问题。

    在Docker有存储卷的概念卷,但Docker中存储卷只是磁盘的或另一个容器中的目录,并没有对其生命周期进行管理。Kubernetes的存储卷有自己的生命周期,它的生命周期与使用的它Pod生命周期一致。因此,相比于在Pod中运行的容器来说,存储卷的存在时间会比的其中的任何容器都长,并且在容器重新启动时会保留数据。当然,当Pod停止存在时,存储卷也将不再存在。在Kubernetes支持多种类型的卷,而Pod可以同时使用各种类型和任意数量的存储卷。

    在Pod中通过指定下面的字段来使用存储卷:

    • spec.volumes:通过此字段提供指定的存储卷
    • spec.containers.volumeMounts:通过此字段将存储卷挂接到容器中

    存储卷类型

    emptryDir (本地数据卷)

    emptyDir类型的Volume在Pod分配到Node上时被创建,Kubernetes会在Node上自动分配一个目录,因此无需指定宿主机Node上对应的目录文件。 这个目录的初始内容为空,当Pod从Node上移除时,emptyDir中的数据会被永久删除。

    emptyDir Volume主要用于某些应用程序无需永久保存的临时目录,多个容器的共享目录等。

    apiVersion: v1
    kind: Pod
    metadata:
      name: test-pd
    spec:
      containers:
      - image: gcr.io/google_containers/test-webserver
        name: test-container
        volumeMounts:
        - mountPath: /cache
          name: cache-volume
      volumes:
      - name: cache-volume
        emptyDir: {}
    

    hostPath (本地数据卷)

    hostPath类型的存储卷用于将宿主机的文件系统的文件或目录挂接到Pod中,除了需要指定path字段之外,在使用hostPath类型的存储卷时,也可以设置type,type支持的枚举值由下表。另外在使用hostPath时,

    需要注意下面的事项:

    • 具有相同配置的Pod(例如:从同一个podTemplate创建的),可能会由于Node的文件不同,而行为不同。
    • 在宿主机上创建的文件或目录,只有root用户具写入的权限。您要么在容器中以root身份运行进程,要么在主机上修改的文件或目录的权限,以便具备写入内容到hostPath的存储卷中。
    行为
    空字符串(默认)是用于向后兼容,这意味着在挂接主机路径存储卷之前不执行任何检查。
    DirectoryOrCreate 如果path指定目录不存在,则会在宿主机上创建一个新的目录,并设置目录权限为0755,此目录与kubelet拥有一样的组和拥有者。
    Directory path指定的目标必需存在
    FileOrCreate 如果path指定的文件不存在,则会在宿主机上创建一个空的文件,设置权限为0644,此文件与kubelet拥有一样的组和拥有者。
    File path指定的文件必需存在
    Socket path指定的UNIX socket必需存在
    CharDevice path指定的字符设备必需存在
    BlockDevice 在path给定路径上必须存在块设备。

    下面是使用hostPath作为存储卷的YAML文件,此YAML文件定义了一个名称为test-pd的Pod资源。它通过hostPath类型的存储卷,将Pod宿主机上的/data挂接到容器中的/teset-pd目录

    apiVersion: v1
    kind: Pod
    metadata:
      name: test-pd
    spec:
      containers:
      - image: k8s.gcr.io/test-webserver
        name: test-container
        # 指定在容器中挂接路径
        volumeMounts:
        - mountPath: /test-pd
          name: test-volume
      # 指定所提供的存储卷
      volumes:
      - name: test-volume
        hostPath:
          # 宿主机上的目录
          path: /data
          # this field is optional
          type: Directory
    

    nfs (网络数据卷)

    在Kubernetes中,可以通过nfs类型的存储卷将现有的NFS(网络文件系统)到的挂接到Pod中。在移除Pod时,NFS存储卷中的内容被不会被删除,只是将存储卷卸载而已。这意味着在NFS存储卷总可以预先填充数据,并且可以在Pod之间共享数据。NFS可以被同时挂接到多个Pod中,并能同时进行写入。需要注意的是:在使用nfs存储卷之前,必须已正确部署和运行NFS服务器,并已经设置了共享目录。

    下面是一个redis部署的YAML配置文件,redis在容器中的持久化数据保存在/data目录下;存储卷使用nfs,nfs的服务地址为:192.168.8.150,存储路径为:/k8s-nfs/redis/data。容器通过volumeMounts.name的值确定所使用的存储卷

    # for versions before 1.9.0 use apps/v1beta2
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: redis
    spec:
      selector:
        matchLabels:
          app: redis
      revisionHistoryLimit: 2
      template:
        metadata:
          labels:
            app: redis
        spec:
          containers:
          # 应用的镜像
          - image: redis
            name: redis
            imagePullPolicy: IfNotPresent
            # 应用的内部端口
            ports:
            - containerPort: 6379
              name: redis6379
            env:
            - name: ALLOW_EMPTY_PASSWORD
              value: "yes"
            - name: REDIS_PASSWORD
              value: "redis"   
            # 持久化挂接位置,在docker中 
            volumeMounts:
            - name: redis-persistent-storage
              mountPath: /data
          volumes:
          # 宿主机上的目录
          - name: redis-persistent-storage
            nfs:
              path: /k8s-nfs/redis/data
              server: 192.168.8.150
    

    persistentVolumeClaim

    persistentVolumeClaim类型存储卷将PersistentVolume挂接到Pod中作为存储卷。使用此类型的存储卷,用户并不知道存储卷的详细信息。

    此处定义名为busybox-deployment的部署YAML配置文件,使用的镜像为busybox。基于busybox镜像的容器需要对/mnt目录下的数据进行持久化,在YAML文件指定使用名称为nfs的PersistenVolumeClaim对容器的数据进行持久化。

    # This mounts the nfs volume claim into /mnt and continuously
    # overwrites /mnt/index.html with the time and hostname of the pod. 
    apiVersion: v1
    kind: Deployment
    metadata:  
      name: busybox-deployment
    spec:  
      replicas: 2  
      selector:    
        name: busybox-deployment
      template:    
        metadata:      
          labels:        
            name: busybox-deployment    
        spec:      
          containers:      
          - image: busybox        
            command:          
            - sh          
            - -c          
            - 'while true; do date > /mnt/index.html; hostname >> /mnt/index.html; sleep $(($RANDOM % 5 + 5)); done'        
            imagePullPolicy: IfNotPresent        
            name: busybox        
            volumeMounts:          
            # name must match the volume name below          
            - name: nfs            
              mountPath: "/mnt"     
         volumes:      
         - name: nfs        
           persistentVolumeClaim:          
             claimName: nfs-pvc
    

    subPath

    有时,可以在一个pod中,将同一个卷共享,使其有多个用处。volumeMounts.subPath特性可以用来指定卷中的一个子目录,而不是直接使用卷的根目录。
    这里有一个使用LAMP栈(Linux Apache Mysql PHP)的pod示例,该pod使用了一个共享的卷。HTML内容映射在它的html子目录,而数据库则保存在它的mysql目录

    apiVersion: v1
    kind: Pod
    metadata:
      name: my-lamp-site
    spec:
        containers:
        - name: mysql
          image: mysql
          volumeMounts:
          - mountPath: /var/lib/mysql
            name: site-data
            subPath: mysql
        - name: php
          image: php
          volumeMounts:
          - mountPath: /var/www/html
            name: site-data
            subPath: html
        volumes:
        - name: site-data
          persistentVolumeClaim:
            claimName: my-lamp-site-data
    

    secret(信息数据卷)

    Kubemetes提供了Secret来处理敏感数据,比如密码、Token和密钥,相比于直接将敏感数据配置在Pod的定义或者镜像中,Secret提供了更加安全的机制(Base64加密),防止数据泄露。Secret的创建是独立于Pod的,以数据卷的形式挂载到Pod中,Secret的数据将以文件的形式保存,容器通过读取文件可以获取需要的数据。

    yaml示例如下:

    apiVersion: v1
    kind: Secret
    metadata:
     name: mysecret
    type: Opaque
    data:
     username: emhlbnl1
     password: eWFvZGlkaWFv
    --
    apiVersion: v1
    kind: Pod
    metadata:
      labels:
        name: test-secret
        role: master
      name: test-secret
    spec:
      containers:
        - name: test-secret
          image: registry:5000/back_demon:1.0
          volumeMounts:
           - name: secret
             mountPath: /home/laizy/secret
             readOnly: true
          command:
          - /run.sh
      volumes:
      - name: secret
        secret:
         secretName: mysecret
    

    参考:

    Kubernetes中的Volume介绍

    Kubernetes-存储卷Volume

    Kubernetes volumes简介

  • 相关阅读:
    Codeforces Round #632 (Div. 2) D-Challenges in school №41(模拟好题)
    余数求和
    B. 齐心抗疫
    MyBatis源码分析
    关于Idea中右边的maven projects窗口找不到了如何调出来
    IDEA java类文件左下角出现红色的J标识,解决方法
    Postman Tests脚本的使用
    JSONPath解析json
    Postman + Newman 生成测试报告
    TestNG 多线程测试
  • 原文地址:https://www.cnblogs.com/hongdada/p/11586514.html
Copyright © 2011-2022 走看看