【云原生 | Kubernetes 实战】13、K8s 常见的存储方案及具体应用场景分析(上)

news2024/11/18 8:44:38

目录

K8s 持久化存储

一、k8s 持久化存储:emptyDir

二、k8s 持久化存储:hostPath

三、k8s 持久化存储:nfs

3.1 搭建 nfs 服务

3.2 创建Pod,挂载 NFS 共享出来的目录

3.3 测试 pod 挂载 nfs 是否成功


 

K8s 持久化存储

        在 k8s 中为什么要做持久化存储?k8s 中部署的应用都是以 pod 容器的形式运行的,假如我们部署 MySQL 、 Redis 等数据库需要对这些数据库产生的数据做备份 。因为 Pod 是有生命周期的,如果 pod 不挂载数据卷,那 pod 被删除或重启后这些数据会随之消失,如果想要长久的保留这些数据就要用到 pod 数据持久化存储。

查看 k8s 支持哪些存储类型:

[root@k8s-master01 ~]# kubectl explain pods.spec.volumes

常用的如下:

  • emptyDir
  • hostPath
  • nfs
  • persistentVolumeClaim
  • glusterfs
  • cephfs
  • configMap
  • secret

我们想要使用存储卷,需要经历如下步骤:

  1. 定义 pod 的 volume ,这个 volume 指明它要关联到哪个存储上的;
  2. 在容器中要使用 volumemounts 挂载对应的存储 。

一、k8s 持久化存储:emptyDir

        emptyDir 类型的 Volume 是在 Pod 分配到 Node 上时被创建, Kubernetes 会在 Node 上自动分配一个目录,因此无需指定宿主机 Node 上对应的目录文件。 这个目录的初始内容为空,当 Pod 从 Node 上移除时, emptyDir 中的数据会被永久删除。 emptyDir Volume 主要用于某些应用程序无需永久保存的临时目录,多个容器的共享目录等 。

emptyDir 的一些用途:

  • 缓存空间,例如基于磁盘的归并排序。
  • 为耗时较长的计算任务提供检查点,以便任务能方便地从崩溃前状态恢复执行。
  • 在 Web 服务器容器服务数据时,保存内容管理器容器获取的文件。
# 创建个存放此次实验 yaml 文件的目录
[root@k8s-master01 ~]# mkdir volumes
[root@k8s-master01 ~]# cd volumes/

# 查看帮助命令
[root@k8s-master01 volumes]# kubectl explain pods
[root@k8s-master01 volumes]# kubectl explain pods.metadata
[root@k8s-master01 volumes]# kubectl explain pods.spec
[root@k8s-master01 volumes]# kubectl explain pods.spec.containers
[root@k8s-master01 volumes]# kubectl explain pods.spec.volumes
[root@k8s-master01 volumes]# kubectl explain pods.spec.volumes.emptyDir
[root@k8s-master01 volumes]# kubectl explain pods.spec.containers.volumeMounts

# 创建一个 pod,挂载临时目录 emptyDir
[root@k8s-master01 volumes]# vim emptydir.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-empty
spec:
  containers:
  - name: container-empty
    image: nginx
    imagePullPolicy: IfNotPresent
    volumeMounts:
    - mountPath: /cache
      name: cache-volume    # 必须与 emptyDir.name 同名
  volumes:
  - emptyDir: {}
    name: cache-volume


[root@k8s-master01 volumes]# kubectl apply -f emptydir.yaml
pod/pod-empty created

# pod 调度到 node2 节点了
[root@k8s-master01 volumes]# kubectl get pods -o wide 
NAME        READY   STATUS    RESTARTS   AGE   IP               NODE        NOMINATED NODE   READINESS GATES
pod-empty   1/1     Running   0          17s   10.244.169.157   k8s-node2   <none>           <none>

# 查看 pod 的 uid
[root@k8s-master01 volumes]# kubectl get pods pod-empty -o yaml | grep uid
  uid: b8bf8521-cd8d-4085-8ae0-328fa6241879

# 在 node2 查看临时目录
[root@k8s-node2 ~]# tree /var/lib/kubelet/pods/b8bf8521-cd8d-4085-8ae0-328fa6241879
[root@k8s-node2 ~]# cd /var/lib/kubelet/pods/b8bf8521-cd8d-4085-8ae0-328fa6241879/volumes/kubernetes.io~empty-dir/cache-volume/

# 在 master 节点进入容器内部,在挂载目录创建文件
[root@k8s-master01 volumes]# kubectl exec -it pod-empty -- bash
root@pod-empty:/# cd cache/
root@pod-empty:/cache# touch 1.txt

# 在 node2 本地挂载目录可以同步看到
[root@k8s-node2 cache-volume]# ls
1.txt

# 而在 node2 本地挂载目录下创建文件,也能同步到容器中
[root@k8s-node2 cache-volume]# touch 2.txt
root@pod-empty:/cache# ls
1.txt  2.txt

# 如果删除了 pod,那么 node2 本地挂载目录及数据也会被删除
[root@k8s-master01 volumes]# kubectl delete -f emptydir.yaml 
pod "pod-empty" deleted

[root@k8s-node2 cache-volume]# ls
[root@k8s-node2 cache-volume]# cd ../
cd: 获取当前目录时出错: getcwd: 无法访问父目录: 没有那个文件或目录

        由上可知,临时目录在被调度到的 node2 节点本地的 /var/lib/kubelet/pods/b8bf8521-cd8d-4085-8ae0-328fa6241879/volumes/kubernetes.io~empty-dir/cache-volume/ 下。

官方参考文档:卷 | Kubernetes 

二、k8s 持久化存储:hostPath

        hostPath Volume 是指 Pod 挂载宿主机上的目录或文件。 hostPath Volume 使得容器可以使用宿主机的文件系统进行存储 hostpath (宿主机路径):节点级别的存储卷,在 pod 被删除,这个存储卷还是存在的,不会被删除,但要同一个 pod 被调度到同一个节点上来,在 pod 被删除重新被调度到这个节点之后,对应的数据依然是存在的。

# 查看 hostPath 存储卷的用法
[root@k8s-master01 volumes]#  kubectl explain pods.spec.volumes.hostPath

# 创建一个 pod ,挂载 hostPath 存储卷
[root@k8s-master01 volumes]# vim hostpath.yaml
apiVersion: v1
kind: Pod
metadata:
  name: test-hostpath
spec:
  containers:
  - image: nginx
    imagePullPolicy: IfNotPresent
    name: test-nginx
    volumeMounts:
    - mountPath: /test-nginx
      name: test-volume
  - image: billygoo/tomcat8-jdk8
    imagePullPolicy: IfNotPresent
    name: test-tomcat
    volumeMounts:
    - mountPath: /test-tomcat
      name: test-volume
  volumes:
  - name: test-volume
    hostPath:
      path: /data1
      type: DirectoryOrCreate     # DirectoryOrCreate 表示本地有 data1 目录,就用本地的,本地没有就会在 pod 调度到的节点自动创建一个。
# 更新资源清单文件
[root@k8s-master01 volumes]# kubectl apply -f hostpath.yaml 
pod/test-hostpath created

# 查看 pod 调度 到了哪个物理节点
[root@k8s-master01 volumes]# kubectl get pods -o wide 
NAME            READY   STATUS    RESTARTS   AGE   IP               NODE        NOMINATED NODE   READINESS GATES
test-hostpath   2/2     Running   0          8s    10.244.169.158   k8s-node2   <none>           <none>

支持的 type 值如下:

        由上面可以知道 pod 调度到了node2 上,登录到 node2 机器,查看是否在这台机器创建了存储目录:

# data1 目录权限为 755
[root@k8s-node2 ]# cd /
[root@k8s-node2 /]# ll | grep data1
drwxr-xr-x    2 root root    6 12月 15 21:16 data1

# 在本地挂载目录下创建文件
[root@k8s-node2 /]# cd data1/
[root@k8s-node2 data1]# touch 1.txt

# 测试存储卷是否可以正常使用,登录到 nginx 容器
[root@k8s-master01 volumes]# kubectl exec -it test-hostpath -c test-nginx -- bash               
root@test-hostpath:/# cd test-nginx/
root@test-hostpath:/test-nginx# ls
1.txt
root@test-hostpath:/test-nginx# touch 2.txt

# 登录到 tomcat 容器
[root@k8s-master01 volumes]# kubectl exec -it test-hostpath -c test-tomcat -- bash
root@test-hostpath:/usr/local/tomcat# cd /test-tomcat/
root@test-hostpath:/test-tomcat# ls
1.txt  2.txt

        通过上面测试可以看到, 同一个 pod 里的 test nginx 和 test tomcat 这两个容器是共享存储卷
的 。

# 删除 pod ,并使其调度到 node1
[root@k8s-master01 volumes]# vim hostpath.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: test-hostpath
spec:
  nodeName: k8s-node1    # 调度到 node1
  containers:

[root@k8s-master01 volumes]# kubectl delete -f hostpath.yaml 
pod "test-hostpath" deleted

[root@k8s-master01 volumes]# kubectl apply -f hostpath.yaml 
pod/test-hostpath created

[root@k8s-master01 volumes]# kubectl get pods -o wide 
NAME            READY   STATUS    RESTARTS   AGE     IP             NODE        NOMINATED NODE   READINESS GATES
test-hostpath   2/2     Running   0          2m42s   10.244.36.67   k8s-node1   <none>           <none>

        重新进入两个容器内部,会发现原来的(数据)两个文件没有了,本地 node1 节点挂载目录下也没有数据,只有把 pod 重新调度到 node2 节点数据才能恢复!

        hostpath 存储卷缺点:单节点,pod 删除之后重新创建必须调度到同一个 node 节点,数据才不会丢失。

官方参考文档:卷 | Kubernetes

三、k8s 持久化存储:nfs

        NFS:网络文件系统,英文 Network File System(NFS) NFS),是由 SUN 公司研制的 UNIX 表示层 协议(presentation layer protocol),能使使用者访问网络上别处的文件就像在使用自己的计算机一样。

        在 k8s 中,nfs 卷能将 NFS (网络文件系统) 挂载到你的 Pod 中。 不像 emptyDir 那样会在删除 Pod 的同时也会被删除,nfs 卷的内容在删除 Pod 时会被保存,卷只是被卸载。 这意味着 nfs 卷可以被预先填充数据,并且这些数据可以在 Pod 之间共享。

3.1 搭建 nfs 服务

#1. 搭建 nfs 服务。所有节点都安装 nfs,以 k8s 的控制节点作为 NFS 服务端,工作节点为客户端
yum install -y nfs-utils

#2. 在宿主机创建 NFS 需要的共享目录
[root@k8s-master01 ~]# mkdir /data/volumes -pv

#3. 所有节点启动 nfs 并设置开机自启
systemctl enable nfs --now

#4. 配置 nfs 共享服务器上的 /data/volumes 目录
[root@k8s-master01 ~]# vim /etc/exports
/data/volumes *(rw,no_root_squash)

# * :所有客户端都可以访问
# rw:该主机对该共享目录有读写权限
# no_root_squash:登入 NFS 主机使用分享目录的使用者,如果是 root 的话,那么对于这个分享的目录来说,他就具有 root 的权限

#5. 使 NFS 配置生效
[root@k8s-master01 ~]# exportfs -arv
exporting *:/data/volumes

#6. 在 node1 上手动挂载试试
[root@k8s-node1 ~]# mkdir /test 

# 控制节点的宿主机 ip
[root@k8s-node1 ~]# mount 192.168.78.133:/data/volumes /test/

# 说明 nfs 搭建成功
[root@k8s-node1 ~]# df -Th |grep nfs
192.168.78.133:/data/volumes nfs4       27G  7.9G   20G   29% /test

# 卸载目录
[root@k8s-node1 ~]# umount /test 
[root@k8s-node1 ~]# df -Th |grep nfs

3.2 创建Pod,挂载 NFS 共享出来的目录

# 查看帮助命令
[root@k8s-master01 ~]# kubectl explain deployment
[root@k8s-master01 ~]# kubectl explain deployment.spec
[root@k8s-master01 ~]# kubectl explain deployment.spec.selector
[root@k8s-master01 ~]# kubectl explain deployment.spec.template
[root@k8s-master01 ~]# kubectl explain deployment.spec.template.spec
[root@k8s-master01 ~]# kubectl explain deployment.spec.template.spec.containers
[root@k8s-master01 ~]# kubectl explain deployment.spec.template.spec.containers.ports
[root@k8s-master01 ~]# kubectl explain deployment.spec.template.spec.volumes
[root@k8s-master01 ~]# kubectl explain deployment.spec.template.spec.volumes.nfs

[root@k8s-master01 volumes]# vim nfs.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
 name: nfs-test
spec:
  replicas: 3
  selector:
    matchLabels:
      cunchu: nfs
  template:
    metadata:
      labels:
        cunchu: nfs
    spec:
       containers:
       - name: test-nfs
         image: nginx
         imagePullPolicy: IfNotPresent
         ports:
         - containerPort: 80
           protocol: TCP
         volumeMounts:
         - name: nfs-volumes
           mountPath: /usr/share/nginx/html
       volumes:
       - name: nfs-volumes
         nfs:
           path: /data/volumes
           server: 192.168.78.133

# 删除前面创建的 pod
[root@k8s-master01 volumes]# kubectl delete -f hostpath.yaml 
pod "test-hostpath" deleted

# 更新资源清单文件
[root@k8s-master01 volumes]# kubectl apply -f nfs.yaml 
deployment.apps/nfs-test created

# 查看 pod 信息
[root@k8s-master01 volumes]# kubectl get pods -o wide 
NAME                        READY   STATUS    RESTARTS   AGE   IP               NODE        NOMINATED NODE   READINESS GATES
nfs-test-6bcdf5f5d6-4g7fk   1/1     Running   0          65s   10.244.169.161   k8s-node2   <none>           <none>
nfs-test-6bcdf5f5d6-g5lsj   1/1     Running   0          65s   10.244.169.162   k8s-node2   <none>           <none>
nfs-test-6bcdf5f5d6-hfwqc   1/1     Running   0          65s   10.244.36.74     k8s-node1   <none>           <none>

3.3 测试 pod 挂载 nfs 是否成功

# 登录到 nfs 服务器,在共享目录创建一个 index.html
[root@k8s-master01 volumes]# cd /data/volumes/
[root@k8s-master01 volumes]# vim index.html
hello sky

# 请求任意 pod,查看结果
[root@k8s-master01 ~]# curl 10.244.169.161
hello sky

# 通过上面可以看到,在共享目录创建的 index.html 已经被 pod 挂载了

# 登录到 pod 验证下
[root@k8s-master01 volumes]# kubectl exec -it nfs-test-6bcdf5f5d6-4g7fk -- bash
root@nfs-test-6bcdf5f5d6-4g7fk:/# cat /usr/share/nginx/html/index.html 
hello sky

        上面说明挂载 nfs 存储卷成功了,nfs 支持多个客户端挂载,可以创建多个 pod,挂载同一个nfs 服务器共享出来的目录;但是 nfs 如果宕机了,数据也就丢失了,所以需要使用分布式存储,常见的分布式存储有 glusterfs 和 cephfs(后面会讲到)。

pod 挂载 nfs 官方参考文档:卷 | Kubernetes  

上一篇文章:【云原生 | Kubernetes 实战】12、K8s 四层代理 Service 入门到企业实战应用(下)_Stars.Sky的博客-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/96216.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

[附源码]Nodejs计算机毕业设计基于框架的在线问答平台Express(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置&#xff1a; Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分…

[附源码]Python计算机毕业设计公租房管理系统Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置&#xff1a; Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术&#xff1a; django python Vue 等等组成&#xff0c;B/S模式 pychram管理等…

ASPICE详细介绍-1.什么是ASPICE?

什么是ASPICE&#xff1f; ASPICE全称是“Automotive Software Process Improvement and Capacity dEtermination”&#xff0c;即汽车软件过程改进及能力评定&#xff0c;简称A-SPICE或ASPICE。 属于过程模型&#xff0c;由过程和能力度两个维度构成&#xff0c;用于评价汽车…

DBeaver连接hive(详细图解)

文章目录DBeaver 简介使用DBeaver连接hive&#xff08;1&#xff09;配置Maven仓库&#xff08;2&#xff09;配置hive驱动&#xff08;3&#xff09;创建hive连接&#xff08;4&#xff09;连接测试DBeaver 简介 dbeaver是免费和开源&#xff08;GPL&#xff09;为开发人员和数…

RK3588平台开发系列讲解(AUDIO篇)Linux音频调试--alsa-utils 工具

平台内核版本安卓版本RK3588Linux 5.10Android 12文章目录 一、工具介绍二、工具的使用2.1 aplay2.2 arecord2.3 amixer2.4 aplay | arecord沉淀、分享、成长,让自己和他人都能有所收获!😄 📢本篇将介绍Linux下audio调试工具alsa-utils的使用方法。 一、工具介绍 RK平台…

[ 数据结构 -- 手撕排序算法第一篇 ] 插入排序

文章目录前言一、常见的排序算法二、插入排序的实现2.1 基本思想2.2 直接插入排序2.2.1 单趟排序的代码实现三、插入排序代码实现四、插入排序测试五、插入排序的时间复杂度5.1 最坏的情况下5.2 最好的情况下六、直接插入排序特性总结总结前言 手撕排序算法第一篇&#xff1a;…

HashSet源码解析

HashSet源码解析 问题 &#xff08;1&#xff09;集合&#xff08;Collection&#xff09;和集合&#xff08;Set&#xff09;有什么区别&#xff1f; &#xff08;2&#xff09;HashSet 怎么保证添加元素不重复&#xff1f; &#xff08;3&#xff09;HashSet 是否允许 nu…

基于nodejs大学生宿舍管理系统的设计与实现.zip(论文+源码+ppt文档+视频录制)

相关资料下载地址&#xff1a;请点击下载》》》 1 绪论 3 1.1 项目开发背景和意义 3 1.2 项目研究现状 3 1.3 项目主要的内容 4 2 相关技术介绍及环境开发条件 4 2.1相关技术介绍 4 2.1.1 nodejs开发框架 4 2.1.2 MySQL数据库 5 2.1.3VSCODE开发工具 6 2.2环境开发条件 6 3 系…

C51——震动控制喇叭

通过继电器使得喇叭稍微的带一点点智能的感觉&#xff1a; 当振动传感器模块 感受到震动的时候让喇叭响起来&#xff0c;这喇叭之后两根线来供电&#xff0c;这便少不了继电器的作用 震动模块&#xff0c;继电器和单片机的连接方式在前面已经提到了 这里我们先让电源的负极和…

就是收藏,不解释。Jmeter接口测试数据库断言的实现与设计

接口测试大部分都使用接口的响应值作为接口验证的依据&#xff0c;但在与数据库有交互的接口中这种结果判断不足以判断接口的正确性&#xff0c;本文将以jmeter作为接口测试的工具来实现接口的数据库断言 一、总体思路概述 使用jmeter发起接口请求使用json提取器获取接口响应结…

双指针算法(尺取法)

目录 一 算法简介 1&#xff09;算法解释 2&#xff09;概述 3&#xff09;分类 4&#xff09;前提 5&#xff09;算法模板 6&#xff09;常见问题 二 算法实践 1&#xff09;反向扫描 1&#xff09;反转字符串&#xff08;一&#xff09; 题目描述 思路 解法 2&…

fiddler抓包 - Android 虚拟机

导出fiddler 证书 将Fiddler的证书导出到电脑&#xff0c;点击Tools -> Options -> HTTPS -> Actions -> Export Root Certificate to Desktop 下载和安装openssl 添加一下path :C:\Program Files\OpenSSL-Win64\bin 证书格式转换与重命名 1、将Fiddler cer证书转…

CS61A Proj 3

更好的阅读体验 Project 3: Ants Vs. SomeBees ants.zip The bees are coming! Create a better soldier With inherit-ants. Introduction Important submission note: For full credit, Submit with Phase 1 complete by Thursday, March 3 (worth 1 pt).Submit with Phase …

【Flink】Flink 1.13 版本 KafkaSource 代码解读

文章目录 1.概述2. 案例3.源码解读3.1 build3.2 handleOperatorEvent3.3 addSplits3.4 createSplitFetcher3.5 创建SplitFetcher2.6 运行2.7 启动 SplitFetcher2.8 runOnce2.9 fetchTask.run2.9 fetch1.概述 因为最近看到新版本的kafka source进行改版了,于是就想测试一下看看…

Gradle学习笔记之任务

文章目录任务入门任务行为任务的依赖方式参数依赖内部依赖外部依赖多种依赖方式的混合跨项目依赖任务执行gradle run命令演示gradle projects演示gradle tasks演示gradle tasks --all演示查看指定的任务组任务查看某一任务的详细信息查看项目的依赖关系查看项目的属性信息任务类…

RCNN网络源码解读(Ⅱ) --- 使用IOU计算正负样本用于finetune训练

目录 1.预训练二分类器Alexnet 1.1 code&#xff08;finetune.py&#xff09; 2.二分类数据集处理 2.1 code&#xff08;cerate_classifier_data.py&#xff09; 1.预训练二分类器Alexnet 1.1 code&#xff08;finetune.py&#xff09; 1.引入头文件 import os import c…

阿里是如何使用分布式架构的,阿里内部学习手册分享

为什么要使用分布式架构&#xff1f;分布式架构解决了互联网应用的两大难题&#xff1a;高并发和高可用。高并发指服务器并发处理客户端请求的数量大&#xff0c;而高可用指后端服务能始终处于可用状态。 提高系统容量 随着业务越来越复杂&#xff0c;服务也会变得越来越复杂…

CS61A Proj 2

更好的阅读体验 Project 2: CS 61A Autocorrected Typing Software cats.zip Programmers dream of Abstraction, recursion, and Typing really fast. Introduction Important submission note: For full credit: Submit with Phase 1 complete by Thursday, February 17, wo…

ADI Blackfin DSP处理器-BF533的开发详解55:CVBS输入-DSP和ADV7180的应用详解(含源码)

硬件准备 ADSP-EDU-BF533&#xff1a;BF533开发板 AD-HP530ICE&#xff1a;ADI DSP仿真器 软件准备 Visual DSP软件 硬件链接 CVBS IN 视频输入 硬件实现原理 CVBS_IN 子卡板连接在 ADSP-EDU-BF53x 开发板的扩展端口 PORT3 和 PORT4 上&#xff0c;板卡插入时&#xff0c;…

[内网渗透]—域外向域内信息收集、密码喷洒

前言 当我们与目标内网建立了socks5隧道后,就可以从域外对域内机器进行信息搜集了,很多工具不用上传到目标机器,也就不易被AV检测到,但是有可能会被一些流量检测设备发现有大量socks5流量。 接下来介绍下如何通过域外对域内进⾏更深的信息搜集:枚举域⽤户、查看域内⽤户…