k8s 学习笔记之数据存储——基础存储
在前面已经提到,容器的生命周期可能很短,会被频繁地创建和销毁。那么容器在销毁时,保存在容器中的数据也会被清除。这种结果对用户来说,在某些情况下是不乐意看到的。为了持久化保存容器的数据,kubernetes 引入了 Volume 的概念。
Volume 是 Pod 中能够被多个容器访问的共享目录,它被定义在 Pod 上,然后被一个 Pod 里的多个容器挂载到具体的文件目录下,kubernetes 通过 Volume 实现同一个 Pod 中不同容器之间的数据共享以及数据的持久化存储。Volume 的生命容器不与 Pod 中单个容器的生命周期相关,当容器终止或者重启时,Volume 中的数据也不会丢失。
kubernetes 的 Volume 支持多种类型,比较常见的有下面几个:
- 简单存储:EmptyDir、HostPath、NFS
- 高级存储:PV、PVC
- 配置存储:ConfigMap、Secret
基本存储
EmptyDir
EmptyDir 是最基础的 Volume 类型,一个 EmptyDir 就是 Host 上的一个空目录。
EmptyDir 是在 Pod 被分配到 Node 时创建的,它的初始内容为空,并且无须指定宿主机上对应的目录文件,因为 kubernetes 会自动分配一个目录,当 Pod 销毁时,EmptyDir 中的数据也会被永久删除。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: # 将 logs-volume 挂在到 busybox 容器中,对应的目录为 /logs - name: logs-volume mountPath: /logs volumes: # 声明 volume, name 为 logs-volume,类型为 emptyDir - name: logs-volume emptyDir: {}
# 创建 Pod [root@k8s-master01 ~]# kubectl create -f volume-emptydir.yaml pod/volume-emptydir created # 查看 pod [root@k8s-master01 ~]# kubectl get pods volume-emptydir -n dev -o wide NAME READY STATUS RESTARTS AGE IP NODE ...... volume-emptydir 2/2 Running 0 97s 10.42.2.9 node1 ...... # 通过 pod Ip 访问 nginx [root@k8s-master01 ~]# curl 10.42.2.9 ...... # 通过 kubectl logs 命令查看指定容器的标准输出 [root@k8s-master01 ~]# kubectl logs -f volume-emptydir -n dev -c busybox 10.42.1.0 - - [27/Jun/2021:15:08:54 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-"
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: - 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 volumes: - name: logs-volume hostPath: path: /root/logs type: DirectoryOrCreate # 目录存在就使用,不存在就先创建后使用
关于 type 的值的一点说明: DirectoryOrCreate 目录存在就使用,不存在就先创建后使用 Directory 目录必须存在 FileOrCreate 文件存在就使用,不存在就先创建后使用 File 文件必须存在 Socket unix套接字必须存在 CharDevice 字符设备必须存在 BlockDevice 块设备必须存在
# 创建 Pod [root@k8s-master01 ~]# kubectl create -f volume-hostpath.yaml pod/volume-hostpath created # 查看 Pod [root@k8s-master01 ~]# kubectl get pods volume-hostpath -n dev -o wide NAME READY STATUS RESTARTS AGE IP NODE ...... pod-volume-hostpath 2/2 Running 0 16s 10.42.2.10 node1 ...... #访问 nginx [root@k8s-master01 ~]# curl 10.42.2.10 # 接下来就可以去 host 的 /root/logs 目录下查看存储的文件了 ### 注意: 下面的操作需要到 Pod 所在的节点运行(案例中是 node1) [root@node1 ~]# ls /root/logs/ access.log error.log # 同样的道理,如果在此目录下创建一个文件,到容器中也是可以看到的
NFS
HostPath 可以解决数据持久化的问题,但是一旦 Node 节点故障了,Pod 如果转移到了别的节点,又会出现问题了,此时需要准备单独的网络存储系统,比较常用的用 NFS、CIFS。
NFS 是一个网络文件存储系统,可以搭建一台 NFS 服务器,然后将 Pod 中的存储直接连接到 NFS 系统上,这样的话,无论 Pod 在节点上怎么转移,只要 Node 跟 NFS 的对接没问题,数据就可以成功访问。
1)首先要准备 nfs 的服务器,这里为了简单,直接是 master 节点做 nfs 服务器
# 在 nfs 上安装 nfs 服务 [root@nfs ~]# yum install nfs-utils -y # 准备一个共享目录 [root@nfs ~]# mkdir /root/data/nfs -pv # 将共享目录以读写权限暴露给 192.168.5.0/24 网段中的所有主机 [root@nfs ~]# vim /etc/exports [root@nfs ~]# more /etc/exports /root/data/nfs 192.168.5.0/24(rw,no_root_squash) # 启动 nfs 服务 [root@nfs ~]# systemctl restart nfs
2)接下来,要在的每个 node 节点上都安装下 nfs,这样的目的是为了 node 节点可以驱动 nfs 设备
# 在 node 上安装 nfs 服务,注意不需要启动 [root@k8s-master01 ~]# yum install nfs-utils -y
3)接下来,就可以编写 pod 的配置文件了,创建 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: - 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 volumes: - name: logs-volume nfs: server: 192.168.5.6 #nfs 服务器地址 path: /root/data/nfs #共享文件路径
4)最后,运行下 pod,观察结果
# 创建 pod [root@k8s-master01 ~]# kubectl create -f volume-nfs.yaml pod/volume-nfs created # 查看 pod [root@k8s-master01 ~]# kubectl get pods volume-nfs -n dev NAME READY STATUS RESTARTS AGE volume-nfs 2/2 Running 0 2m9s # 查看 nfs 服务器上的共享目录,发现已经有文件了 [root@k8s-master01 ~]# ls /root/data/ access.log error.log
本文作者:三眠
本文链接:https://www.cnblogs.com/sanmian/p/17610361.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步