数据存储

容器的生命周期可能会很短,会被频繁的创建和销毁。那么容器在销毁的时候,保存在容器中的数据也会被清除。这种结果对于用户来说,在某些情况下是不愿意看到的。为了持久化保存容器中的数据,K8s 引入了Volume 的概念。

Volume 是Pod 中能够被多个容器访问的共享目录,它被定义在Pod 上,然后被一个pod 里面的多个容器挂载在具体的文件目录下,K8s 通过Volume 实现同一个Pod 中不同容器之间的数据共享以及数据的持久化存储。

Volume 的生命容器不与pod 中单个容器的生命周期相关,当容器终止或重启时,Volume 中的数据也不会丢失。

k8s 的Volume 支持多种类型,常见的有下面几种:

  • 简单存储: EmptyDir, HostPath,NFS
  • 高级存储: PV, PVS
  • 配置存储 : ConfigMap, Secret
基本存储
EmptyDir

EmptyDir 是最基础的Volume 类型,一个EmptyDir 就是Host 上的一个空目录。

EmptyDir 是在Pod 被分配到Node 的时候被创建的。它的初始内容为空,并且无需指定宿主机上的对应的目录文件。因为K8s 会自动分配一个目录,当pod 被销毁时,EmptyDir 中的数据也会被永久删除。 EmptyDir 用途如下。

  • 临时空间,例如用于某些应用程序运行时所需的临时目录(存放临时文件),且无需永久保存
  • 一个容器需要从另一个容器中获取数据的目录(多容器共享目录)

举例:容器之间文件共享案例

在这里插入图片描述

在一个pod 中准备两个容器nginx 和busybox, 然后声明一个Volume 分别挂载到两个容器的目录中,然后nginx 容器负责向Volume 中写日志,busybox 中通过命令将日志内容读到控制台。

创建volume-emptydir.yaml

apiVersion: v1 #固定的,可以查看
kind: Pod
metadata:
  name: volume-emptydir
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    ports:
    - containerPort: 80
    volumeMounts: # 将logs-volume 挂载在nginx 容器中,对应的目录为 /var/log/nginx
    - name: logs-volume
      mountPath: /var/log/nginx
  - name: busybox
    image: busybox:1.30
    command: ["bin/sh","-c","tail -f /logs/access.log"]  #初始化命令,动态读取指定文件中的内容
    volumeMounts:
    - name: logs-volume
      mountPath: /logs  # 挂载到 /logs 文件下
  volumes:  # 声明volume,name 为logs-volume, 类型为emptyDir
    - name: logs-volume
      emptyDir: {}


在这里插入图片描述

在这里插入图片描述

访问nginx 容器

在这里插入图片描述

使用 kubectl logs 命令查看指定容器的标准输出

kubectl  logs -f volume-emptydir -n dev -c busybox

在这里插入图片描述

HostPath

主机路径

EmptyDir 中的数据不会被持久化,它会随着pod 的结束而销毁。如果想简单的数据持久化到主机上,就可以选择HostPath。

HostPath 就是将 Node 主机中一个实际目录挂载到pod 中,以供容器使用,这样的设计就可以保证pod 被销毁了,但数据依旧存在与Node 主机上。

在这里插入图片描述

创建一个 volume-hostpath.yaml

apiVersion: v1 #固定的,可以查看
kind: Pod
metadata:
  name: volume-hostpath
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    ports:
    - containerPort: 80
    volumeMounts: # 将logs-volume 挂载在nginx 容器中,对应的目录为 /var/log/nginx
    - name: logs-volume
      mountPath: /var/log/nginx
  - name: busybox
    image: busybox:1.30
    command: ["bin/sh","-c","tail -f /logs/access.log"]  #初始化命令,动态读取指定文件中的内容
    volumeMounts:
    - name: logs-volume
      mountPath: /logs   # 挂载到 /logs 文件下
  volumes:  # 声明volume,name 为logs-volume, 类型为emptyDir
    - name: logs-volume
      hostPath:
        path: /root/logs #主机path 路径
        type: DirectoryOrCreate

type 类型说明:

在这里插入图片描述

在这里插入图片描述

查看详细信息

在这里插入图片描述
在这里插入图片描述

在minikube 节点查看路径 /root/logs 可以看到生成了两个nginx 相关的文件。
访问nginx,可以看到产生了一条记录。
在这里插入图片描述

使用 下列命令删除该pod

kubectl delete -f volume-hostpath.yaml

在这里插入图片描述

删除了该pod ,其对应的文件还在。

NFS

HostPath 也存在一些缺陷,一旦Node 节点故障了,Pod 如果转移到别的节点,就无法读取到故障节点上存储的文件。 这个时候需要准备单独的网络存储系统,常见的有NFS,CIFS

NFS 是一个网络文件存储系统,可以搭建一台NFS 服务器,然后将pod 中的存储直接连接到NFS 系统上。这样的话,无论pod 在节点上怎么转移。只要Node 跟NFS 的对接没有问题,数据就可以成功访问。

在这里插入图片描述

1 准备nfs 服务器

1 安装nfs 服务
apt install nfs-common
2 准备一个共享目录
mkdir /root/data/nfs -pv
3 将共享目录以读写权限暴露给网段中的所有主机
vim /etc/exports
更改为
/root/data/nfs 172.18.0.0/16(rw,no_root_squash)
4 重启nfs 服务
systemctl start nfs

2 创建volume-nfs.yaml 文件

apiVersion: v1 #固定的,可以查看
kind: Pod
metadata:
  name: volume-nfs
  namespace: dev
spec:
  containers:
  - name: nginx
    image: nginx:1.17.1
    ports:
    - containerPort: 80
    volumeMounts: # 将logs-volume 挂载在nginx 容器中,对应的目录为 /var/log/nginx
    - name: logs-volume
      mountPath: /var/log/nginx
  - name: busybox
    image: busybox:1.30
    command: ["bin/sh","-c","tail -f /logs/access.log"]  #初始化命令,动态读取指定文件中的内容
    volumeMounts:
    - name: logs-volume
      mountPath: /logs   # 挂载到 /logs 文件下
  volumes:  # 声明volume,name 为logs-volume, 类型为emptyDir
    - name: logs-volume
      nfs:
        server: 172.0.18.100 #nfs 服务器地址
        path: /root/data/nfs #共享文件路径




PV 和PVC

由于K8s支持的存储系统有很多,要求客户全部掌握显然不是很显示,为了屏蔽底层存储的实现细节,方便用户使用,K8s 引入了PV 和 PVC 两种资源对象。

PV(Persistent Volume) 是持久化卷的意思,是对底层共享存储的一种抽象,一般情况下,PV由K8s 管理员进行创建和配置。它与底层具体的共享存储技术有关。并通过插件完成与共享存储的对接 。

PVC(Persistent Volume Claim)持久卷声明的意思,是用户对存储需求的一种说明。PVC 其实就是用户向K8s 系统发出的一种 组员需求申请。

在这里插入图片描述

存储 :存储工程师维护

PV:K8s 管理员维护

PVC: K8s 用户进行维护

PV

PV 资源清单文件

apiVersion: v1 #固定的,可以查看
kind: PersistentVolume
metadata:
  name: pv2
spec:
  nfs: #存储类型,与底层真正存储对应
  capacity: # 存储能力,目前只支持存储空间设置
    storage: 2Gi
  accessModes: # 访问模式
  storageClassName: #存储类别
  persistentVolumeReclaimPolicy: # 回收策略
  

PV 关键配置说明:

在这里插入图片描述

在这里插入图片描述

使用NFS 作为存储,演示PV 的使用,创建3个PV,对应NFS 中3个暴露的路径

创建pv.yaml

apiVersion: v1 #固定的,可以查看
kind: PersistentVolume
metadata:
  name: pv1
spec:
  capacity: # 存储能力,目前只支持存储空间设置
    storage: 1Gi
  accessModes: # 访问模式
  - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain # 回收策略
  nfs: #存储类型,与底层真正存储对应
    path: /root/data/pv1
    server: 192.168.109.100

---
apiVersion: v1 #固定的,可以查看
kind: PersistentVolume
metadata:
  name: pv2
spec:
  capacity: # 存储能力,目前只支持存储空间设置
    storage: 2Gi
  accessModes: # 访问模式
  - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain # 回收策略
  nfs: #存储类型,与底层真正存储对应
    path: /root/data/pv2
    server: 192.168.109.100
---
apiVersion: v1 #固定的,可以查看
kind: PersistentVolume
metadata:
  name: pv3
spec:
  capacity: # 存储能力,目前只支持存储空间设置
    storage: 2Gi
  accessModes: # 访问模式
  - ReadWriteMany
  persistentVolumeReclaimPolicy: Retain # 回收策略
  nfs: #存储类型,与底层真正存储对应
    path: /root/data/pv3
    server: 192.168.109.100

PVC

PVC 是资源的申请,用来声明对存储空间,访问模式,存储类别需求信息,下面是资源清单。

通过PVC 申请PV,然后在Pod 中使用PVC

PVC 资源清单文件

apiVersion: v1 #固定的,可以查看
kind: PersistentVolumeClaim
metadata:
  name: pvc
  namespace: dev  # 注意PV 是跨namespace 的,但是pvc不跨namespace
spec:
  accessModes: # 访问模式
  selector: # 采用标签对PV选择
  storageClassName: #存储类别
  resource: #请求空间
    requests:
      storage: 5Gi

在这里插入图片描述

创建pvc.yaml,申请pv

apiVersion: v1 #固定的,可以查看
kind: PersistentVolumeClaim
metadata:
  name: pvc1
  namespace: dev
spec:
  accessModes: # 访问模式
  - ReadWriteMany
  resource: #请求空间
    requests:
      storage: 1Gi
ConfigMap

ConfigMap 是一种比较特殊的存储卷,它的主要作用是来存储配置信息的。

创建configmap.yaml

apiVersion: v1 #固定的,可以查看
kind: ConfigMap
metadata:
  name: configmap
  namespace: dev
data:
  info: |
    username:admin
    password:123456

创建configmap:

kubectl create -f configmap.yaml

在这里插入图片描述

查看configmap 详情:

kubectl describe cm configmap -n dev

在这里插入图片描述

创建一个pod-configmap.yaml, 将上面创建的 configmap 挂载上去。

apiVersion: v1 # API版本号,注意:具有多个,不同的对象可能会使用不同API
kind: Pod  # 对象类型,pod
metadata:  # 元数据
  name: pod-configmap # POD名称
  namespace: dev # 所属的命名空间
spec: # specification of the resource content(资源内容的规范)
  containers: # 容器列表
  - name: nginx # 容器名称
    image: nginx:1.17.1 # 容器镜像
    volumeMounts: #将configmap 挂载到目录
    - name: config
      mountPath: /configmap/config
  volumes: #引用configmap
  - name: config
    configMap:
      name: configmap

1 创建pod

在这里插入图片描述

2 查看pod

在这里插入图片描述

3 进入容器查看是否挂载成功

kubectl exec -it pod-configmap -n dev /bin/sh

在这里插入图片描述

可以看到映射已经生效,每个configmap 都可以映射成一个目录

key 对应文件名, value 对应文件中的内容

如果此时更新 configmap 的内容,容器中的值也会动态更新

password 后面添加一个7,使用kubectl apply 进行更新

在这里插入图片描述

挂载的文件也进行了更新

Secret

在K8s 中,还存在一种和ConfigMap 非常类似的对象,称为Secret 对象,ConfigMap 是用明文进行存储,而Secret 对象主要用来存储敏感信息,例如密码,密钥,证书等。

1 首先使用base64 对数据进行编码

echo -n "admin" | base64
echo -n "123456" | base64

在这里插入图片描述

2 编写secret.yaml, 并创建secret

apiVersion: v1 #固定的,可以查看
kind: ConfigMap
metadata:
  name: configmap
  namespace: dev
data:
  info: |
    username:YWRtaW4=
    password:MTIzNDU2
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐