K8s新手系列之Pod的基本存储
概念
官方文档:https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/configure-volume-storage/
卷:https://kubernetes.io/zh-cn/docs/concepts/storage/volumes/
容器的生命周期可能很短,会被频繁地创建和销毁。那么容器在销毁时,保存在容器中的数据也会被清除。这种结果对用户来说,在某些情况下是不乐意看到的。为了持久化保存容器的数据,kubernetes引入了Volume的概念。
Volume是Pod中能够被多个容器访问的共享目录,它被定义在Pod上,然后被一个Pod里的多个容器挂载到具体的文件目录下,kubernetes通过Volume实现同一个Pod中不同容器之间的数据共享以及数据的持久化存储。Volume的生命容器不与Pod中单个容器的生命周期相关,当容器终止或者重启时,Volume中的数据也不会丢失。
kubernetes的Volume支持多种类型,比较常见的有下面几个:
- 简单存储:EmptyDir、HostPath、NFS
- 高级存储:PV、PVC
- 配置存储:ConfigMap、Secret
基本存储之EmptyDir
官方文档:https://kubernetes.io/zh-cn/docs/concepts/storage/volumes/#emptydir
EmptyDir是在Pod被分配到Node时创建的,它的初始内容为空,并且无须指定宿主机上对应的目录文件,因为kubernetes会自动分配一个目录,当Pod销毁时,EmptyDir中的数据也会被永久删除。使用在临时缓存文件、中间计算结果(无需持久化)。
特点
- Pod 创建时自动创建空目录,Pod 删除时数据清除。
- 数据仅存于 Pod 所在节点的内存或磁盘(可通过medium参数指定,默认""表示节点默认存储,Memory表示内存存储,数据易失)。
- 支持 Pod 内多个容器共享数据。
EmptyDir使用场景
- 临时缓存文件、中间计算结果(无需持久化)
- 例如:filebeat采集日志
EmptyDir实战案例
示例:
# 定义清单文件
[root@master01 ~/volumes]# cat empty-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: empty-pod
spec:
# 定义数据卷
volumes:
# 数据卷名称
- name: data-volume
# volume的类型
emptyDir: {}
containers:
- name: writer-busybox
image: busybox
command: ["/bin/sh", "-c"]
args:
- |
echo "hello emptyDir" >> /data/hello.txt;
sleep 3600
# 指定挂载的数据卷
volumeMounts:
# 要挂载的数据卷名称
- name: data-volume
# 挂载到容器内部的路径
mountPath: /data
# 是否只读,false为可读可写,true为只读
readOnly: false
- name: reader-busybox
image: busybox
command: ["/bin/sh", "-c"]
args:
- |
cat /data/hello.txt;
sleep 3600
volumeMounts:
- name: data-volume
mountPath: /data
readOnly: true
查看pod打印的日志
[root@master01 ~/volumes]# kubectl logs empty-pod reader-busybox
hello emptyDir
基本存储之HostPath
官方文档:https://kubernetes.io/zh-cn/docs/concepts/storage/volumes/#hostpath
EmptyDir中数据不会被持久化,它会随着Pod的结束而销毁,如果想简单的将数据持久化到主机中,可以选择HostPath。
HostPath就是将Node主机中一个实际目录挂在到Pod中,以供容器使用,这样的设计就可以保证Pod销毁了,但是数据依据可以存在于Node主机上。
特点
- 挂载节点上的本地文件或目录(如/var/lib/data)到 Pod 中。
- 数据随节点存在而保留,Pod 删除后数据仍在节点上,但跨节点调度时无法共享。
- 需注意节点路径权限(如使用hostPath.type指定路径类型,如DirectoryOrCreate自动创建目录)。
HostPath实战案例
# 定义清单文件
[root@master01 ~/volumes]# cat hostpath-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: hostpath-pod
spec:
volumes:
- name: hostpath
hostPath:
# 节点上的存储位置
path: /data/nginx/
# 类型,文件夹不存在时自动创建
type: DirectoryOrCreate
containers:
- name: nginx
image: nginx
volumeMounts:
- name: hostpath
mountPath: /usr/share/nginx/html
# 创建Pod
[root@master01 ~/volumes]# kubectl apply -f hostpath-pod.yaml
pod/hostpath-pod created
# 查看Pod调度到哪个节点上
[root@master01 ~/volumes]# kubectl get po hostpath-pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
hostpath-pod 1/1 Running 0 89s 100.95.185.242 node02 <none> <none>
前往node02节点上查看
# 发现目录已经创建成功了
[root@node02 ~]# stat /data/nginx/
File: /data/nginx/
Size: 4096 Blocks: 8 IO Block: 4096 directory
Device: fd00h/64768d Inode: 1441794 Links: 2
Access: (0755/drwxr-xr-x) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2025-05-11 12:52:34.507395315 +0800
Modify: 2025-05-11 12:51:28.658324447 +0800
Change: 2025-05-11 12:51:28.658324447 +0800
Birth: 2025-05-11 12:49:08.272029814 +0800
# 写入一个文件进行访问测试
[root@node02 ~]# echo I am huangsir > /data/nginx/index.html
[root@node02 ~]# cat /data/nginx/index.html
I am huangsir
# 访问nginx,发现绑定成功
[root@node02 ~]# curl 100.95.185.242
I am huangsir
hostPath中type的可用值
DirectoryOrCreate:如果在给定路径上什么都不存在,那么将根据需要创建空目录,权限设置为 0755,具有与 kubelet 相同的组和属主信息。
Directory:在给定路径上必须存在的目录。
FileOrCreate:如果在给定路径上什么都不存在,那么将在那里根据需要创建空文件,权限设置为 0644,具有与 kubelet 相同的组和所有权。
File:在给定路径上必须存在的文件。
Socket:在给定路径上必须存在的 UNIX 套接字。
CharDevice:(仅 Linux 节点) 在给定路径上必须存在的字符设备。
BlockDevice:(仅 Linux 节点) 在给定路径上必须存在的块设备。
基本存储之NFS
官方文档:https://kubernetes.io/zh-cn/docs/concepts/storage/volumes/#nfs
HostPath依赖节点,如果Pod重启之后调度到另一个节点中,那么所依赖数据将不存在。
NFS可以解决这个问题,
NFS存储特点
- 挂载远程 NFS 服务器的共享目录,支持跨节点共享数据。
- 数据持久化存储在 NFS 服务器,不依赖 Pod 或节点生命周期。
使用场景
多 Pod 共享数据(如分布式应用的共享配置)。
NFS实战案例
安装NFS
首先我们需要安装NFS,可以参考这篇文章:NFS搭建及使用
master节点安装服务端
apt update -y
apt install -y nfs-kernel-server
# 检查状态
systemctl status nfs-kernel-server
# 创建共享目录
mkdir -p /data/nfs/nginx
echo '/data/nfs/nginx 10.0.0.0/24(rw,sync,no_root_squash,no_subtree_check)' >> /etc/exports
exportfs -ra
systemctl restart nfs-kernel-server
node节点安装客户端(可以不用操作)
apt update -y
apt install -y nfs-common
mkdir -p /data/nfs/nginx
# 挂载
mount -t nfs 10.0.0.30:/data/nfs/nginx /data/nfs/nginx
# 开机自启动挂载
echo 10.0.0.30:/data/nfs/nginx /data/nfs/nginx nfs defaults 0 0 >> /etc/fstab
# 检查是否挂载成功
df -h | grep /data/nfs/nginx
创建Pod测试
# 定义资源文件
[root@master01 ~/volumes]# cat nfs-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nfs-pod
spec:
# 指定Pod调度到node01节点上
nodeName: node01
volumes:
- name: nfs
nfs:
# nfs服务端的地址
server: 10.0.0.30
# 挂载nfs服务器的路径
path: /data/nfs/nginx
containers:
- name: nginx
image: nginx
volumeMounts:
- name: nfs
mountPath: /usr/share/nginx/html
# 创建Pod
[root@master01 ~/volumes]# kubectl apply -f nfs-pod.yaml
pod/nfs-pod created
# 查看pod信息,发现调度到node01节点上,IP为100.117.144.145
[root@master01 ~/volumes]# kubectl get po nfs-pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nfs-pod 1/1 Running 0 16s 100.117.144.145 node01 <none> <none>
配置测试内容并访问测试
[root@master01 ~/volumes]# echo nfs-server > index.html
# 访问测试
[root@master01 ~/volumes]# curl 100.117.144.145
nfs-server
再将Pod调度到node02节点上,测试访问内容是否会发生变化
[root@master01 ~/volumes]# cat nfs-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nfs-pod
spec:
# 指定Pod调度到node02节点上
nodeName: node02
volumes:
- name: nfs
nfs:
# nfs服务端的地址
server: 10.0.0.30
# 挂载nfs服务器的路径
path: /data/nfs/nginx
containers:
- name: nginx
image: nginx
volumeMounts:
- name: nfs
mountPath: /usr/share/nginx/html
# 创建Pod,需要将上一步创建Pod删除哦~
[root@master01 ~/volumes]# kubectl apply -f nfs-pod.yaml
pod/nfs-pod created
# 查看pod调度及IP
[root@master01 ~/volumes]# kubectl get po nfs-pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nfs-pod 1/1 Running 0 10s 100.95.185.244 node02 <none> <none>
# 访问,发现内容并没有发生变化
[root@master01 ~/volumes]# curl 100.95.185.244
nfs-seerver
配置存储ConfigMap和Secret
可以参考下面这两篇文章
K8s新手系列之Pod的基本存储的更多相关文章
- k8s入门系列之扩展组件(一)DNS安装篇
DNS (domain name system),提供域名解析服务,解决了难于记忆的IP地址问题,以更人性可读可记忆可标识的方式映射对应IP地址. Cluster DNS扩展插件用于支持k8s集群系统 ...
- k8s入门系列之guestbook快速部署
k8s集群以及一些扩展插件已经安装完毕,本篇文章介绍一下如何在k8s集群上快速部署guestbook应用. •实验环境为集群:master(1)+node(4),详细内容参考<k8s入门系列之集 ...
- k8s入门系列之集群安装篇
关于kubernetes组件的详解介绍,请阅读上一篇文章<k8s入门系列之介绍篇> Kubernetes集群安装部署 •Kubernetes集群组件: - etcd 一个高可用的K/V键值 ...
- k8s 入门系列之集群安装篇
关于kubernetes组件的详解介绍,请阅读上一篇文章<k8s入门系列之介绍篇> Kubernetes集群安装部署 •Kubernetes集群组件: - etcd 一个高可用的K/V键值 ...
- k8s之深入解剖Pod(一)
上文说了一下k8s的简单使用,接下来就让我们来具体深入了解一下Pod.为了避免篇幅太长,所以会分成几篇. 目录: Pod定义详解 静态Pod Pod容器共享Volume 一.Pod定义详解 先看一个简 ...
- k8s核心资源之Pod概念&入门使用讲解(三)
目录 1. k8s核心资源之Pod 1.1 什么是Pod? 1.2 Pod如何管理多个容器? 1.3 Pod网络 1.4 Pod存储 1.5 Pod工作方式 1.5.1 自主式Pod 1.5.2 控制 ...
- k8s运维之pod排错
k8s运维之pod排错 K8S是一个开源的,用于管理云平台中多个主机上的容器化应用,Kubernetes的目标是让部署容器化变得简单并且高效 K8S的核心优势: 1,基于yaml文件实现容器的自动创建 ...
- 构建安全的Xml Web Service系列之wse之证书存储位置
原文:构建安全的Xml Web Service系列之wse之证书存储位置 我们在前几天对xml web service的安全性提出了一些建议,大家可以通过以下地址访问: 构建安全的Xml Web Se ...
- JavaScript系列-----对象基于哈希存储(<Key,Value>之Value篇) (3)
JavaScript系列-----Objectj基于哈希存储<Key,Value>之Value 1.问题提出 在JavaScript系列-----Object之基于Hash<Key, ...
- Android新手系列教程(申明:来源于网络)
Android新手系列教程(申明:来源于网络) 地址:http://blog.csdn.net/column/details/androidcoder666.html
随机推荐
- FANUC机器人M-410iB/700电机断轴维修方法
发那科(FANUC)作为电机领域的领袖品牌,其伺服电机广泛应用于各种工业设备中,特别是在机床.自动化控制.机器人等领域.然而,即使是如此高品质的伺服电机,也难免会出现FANUC工业机械手电机故障,其中 ...
- 数据挖掘 | 数据隐私(2) | 差分隐私 | 数据重构化攻击(Reconstruction Attacks)
L2-Reconstruction Attacks 本节课的目的在于正式地讨论隐私,但是我们不讨论算法本身有多隐私,取而代之去讨论一个算法隐私性有多么的不可靠.并且聚焦于 Dinur 与 Nissim ...
- 【由技及道】CI/CD的量子纠缠术:Jenkins与Gitea的自动化交响曲【人工智障AI2077的开发日志】
摘要:当代码提交触发量子涟漪,当构建流水线穿越时空维度--欢迎来到自动化构建的十一维世界.本文记录一个未来AI如何用Jenkins和Gitea搭建量子纠缠式CI/CD管道,让每次代码提交都成为时空交响 ...
- Vue3 值得注意的新特性
Vue3 值得注意的新特性 Vue3 新特性介绍 片段 组合式 API 单文件组件组合式 API 语法糖 (<script setup>) Teleport Suspense 实验性 SF ...
- linux tmux 使用教程
前言 Tmux 是一个终端复用器(terminal multiplexer),非常有用,属于常用的开发工具. 本文介绍如何使用 Tmux. 一.Tmux 是什么? 1.1 会话与进程 命令行的典型使用 ...
- Golang 入门 : 常量
常量 相对于变量而言,常量是在程序使用过程中,不会改变的数据.有些地方你需要将定义好的常量重复使用,代码中你不允许它的值改变.例如 圆周率 在程序执行过程中不会改变. 常量的声明 const Pi f ...
- laradock 更改 mysql 版本
# 修改 .env 文件 MYSQL_VERSION=5.7 # 默认为 latest #停止mysql容器 docker-compose stop mysql # 删除旧数据库数据 rm -rf ~ ...
- Oracle锁表及解锁方法
1. 首先查看数据库中哪些表被锁了,找到session ID: 使用sql: select b.owner,b.object_name,a.session_id,a.locked_modefrom v ...
- [每日算法 - 华为机试] LeetCode 475. 供暖器
入口 力扣https://leetcode.cn/problems/heaters/submissions/ 题目描述 冬季已经来临. 你的任务是设计一个有固定加热半径的供暖器向所有房屋供暖. 在加热 ...
- [框架应用系列:Quartz快速上手] Java定时任务解决方案之Quartz集群
Quartz 是一个开源的作业调度框架,它完全由 Java 写成,并设计用于 J2SE 和 J2EE 应用中.它提供了巨大的灵 活性而不牺牲简单性.你能够用它来为执行一个作业而创建简单的或复杂的调度. ...