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主要用于某些应用程序无需永久保存的临时目录,多个容器的共享目录等。

1apiVersion: v1 2kind: Pod 3metadata: 4 name: test-pd 5spec: 6 containers: 7 - image: gcr.io/google_containers/test-webserver 8 name: test-container 9 volumeMounts: 10 - mountPath: /cache 11 name: cache-volume 12 volumes: 13 - name: cache-volume 14 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目录

1apiVersion: v1 2kind: Pod 3metadata: 4 name: test-pd 5spec: 6 containers: 7 - image: k8s.gcr.io/test-webserver 8 name: test-container 9 # 指定在容器中挂接路径 10 volumeMounts: 11 - mountPath: /test-pd 12 name: test-volume 13 # 指定所提供的存储卷 14 volumes: 15 - name: test-volume 16 hostPath: 17 # 宿主机上的目录 18 path: /data 19 # this field is optional 20 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_的值确定所使用的存储卷

1# for versions before 1.9.0 use apps/v1beta2 2apiVersion: apps/v1 3kind: Deployment 4metadata: 5 name: redis 6spec: 7 selector: 8 matchLabels: 9 app: redis 10 revisionHistoryLimit: 2 11 template: 12 metadata: 13 labels: 14 app: redis 15 spec: 16 containers: 17 # 应用的镜像 18 - image: redis 19 name: redis 20 imagePullPolicy: IfNotPresent 21 # 应用的内部端口 22 ports: 23 - containerPort: 6379 24 name: redis6379 25 env: 26 - name: ALLOW_EMPTY_PASSWORD 27 value: "yes" 28 - name: REDIS_PASSWORD 29 value: "redis" 30 # 持久化挂接位置,在docker中 31 volumeMounts: 32 - name: redis-persistent-storage 33 mountPath: /data 34 volumes: 35 # 宿主机上的目录 36 - name: redis-persistent-storage 37 nfs: 38 path: /k8s-nfs/redis/data 39 server: 192.168.8.150

persistentVolumeClaim

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

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

1# This mounts the nfs volume claim into /mnt and continuously 2# overwrites /mnt/index.html with the time and hostname of the pod. 3apiVersion: v1 4kind: Deployment 5metadata: 6 name: busybox-deployment 7spec: 8 replicas: 2 9 selector: 10 name: busybox-deployment 11 template: 12 metadata: 13 labels: 14 name: busybox-deployment 15 spec: 16 containers: 17 - image: busybox 18 command: 19 - sh 20 - -c 21 - 'while true; do date > /mnt/index.html; hostname >> /mnt/index.html; sleep $(($RANDOM % 5 + 5)); done' 22 imagePullPolicy: IfNotPresent 23 name: busybox 24 volumeMounts: 25 # name must match the volume name below 26 - name: nfs 27 mountPath: "/mnt" 28 volumes: 29 - name: nfs 30 persistentVolumeClaim: 31 claimName: nfs-pvc

subPath

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

1apiVersion: v1 2kind: Pod 3metadata: 4 name: my-lamp-site 5spec: 6 containers: 7 - name: mysql 8 image: mysql 9 volumeMounts: 10 - mountPath: /var/lib/mysql 11 name: site-data 12 subPath: mysql 13 - name: php 14 image: php 15 volumeMounts: 16 - mountPath: /var/www/html 17 name: site-data 18 subPath: html 19 volumes: 20 - name: site-data 21 persistentVolumeClaim: 22 claimName: my-lamp-site-data

secret(信息数据卷)

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

yaml示例如下:

1apiVersion: v1 2kind: Secret 3metadata: 4 name: mysecret 5type: Opaque 6data: 7 username: emhlbnl1 8 password: eWFvZGlkaWFv 9-- 10apiVersion: v1 11kind: Pod 12metadata: 13 labels: 14 name: test-secret 15 role: master 16 name: test-secret 17spec: 18 containers: 19 - name: test-secret 20 image: registry:5000/back_demon:1.0 21 volumeMounts: 22 - name: secret 23 mountPath: /home/laizy/secret 24 readOnly: true 25 command: 26 - /run.sh 27 volumes: 28 - name: secret 29 secret: 30 secretName: mysecret

参考:

Kubernetes中的Volume介绍

Kubernetes-存储卷Volume

Kubernetes volumes简介

点赞
收藏

评论区

加载中...

相关推荐

MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1

文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s

Oracle 分组与拼接字符串同时使用

SELECTT.,ROWNUMIDFROM(SELECTT.EMPLID,T.NAME,T.BU,T.REALDEPART,T.FORMATDATE,SUM(T.S0)S0,MAX(UPDATETIME)CREATETIME,LISTAGG(TOCHAR(

MySQL部分从库上面因为大量的临时表tmp_table造成慢查询

背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_

皕杰报表之UUID

​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为

手写Java HashMap源码

HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22

2020年前端实用代码段,为你的工作保驾护航

有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )

Kubernetes Pod的数据卷Volume - HelloWorld