K8s新手系列之Pod的基本存儲(chǔ)
概念
官方文檔:https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/configure-volume-storage/
卷:https://kubernetes.io/zh-cn/docs/concepts/storage/volumes/
容器的生命周期可能很短,會(huì)被頻繁地創(chuàng)建和銷毀。那么容器在銷毀時(shí),保存在容器中的數(shù)據(jù)也會(huì)被清除。這種結(jié)果對(duì)用戶來(lái)說(shuō),在某些情況下是不樂(lè)意看到的。為了持久化保存容器的數(shù)據(jù),kubernetes引入了Volume的概念。
Volume是Pod中能夠被多個(gè)容器訪問(wèn)的共享目錄,它被定義在Pod上,然后被一個(gè)Pod里的多個(gè)容器掛載到具體的文件目錄下,kubernetes通過(guò)Volume實(shí)現(xiàn)同一個(gè)Pod中不同容器之間的數(shù)據(jù)共享以及數(shù)據(jù)的持久化存儲(chǔ)。Volume的生命容器不與Pod中單個(gè)容器的生命周期相關(guān),當(dāng)容器終止或者重啟時(shí),Volume中的數(shù)據(jù)也不會(huì)丟失。
kubernetes的Volume支持多種類型,比較常見的有下面幾個(gè):
- 簡(jiǎn)單存儲(chǔ):EmptyDir、HostPath、NFS
- 高級(jí)存儲(chǔ):PV、PVC
- 配置存儲(chǔ):ConfigMap、Secret
基本存儲(chǔ)之EmptyDir
官方文檔:https://kubernetes.io/zh-cn/docs/concepts/storage/volumes/#emptydir
EmptyDir是在Pod被分配到Node時(shí)創(chuàng)建的,它的初始內(nèi)容為空,并且無(wú)須指定宿主機(jī)上對(duì)應(yīng)的目錄文件,因?yàn)閗ubernetes會(huì)自動(dòng)分配一個(gè)目錄,當(dāng)Pod銷毀時(shí),EmptyDir中的數(shù)據(jù)也會(huì)被永久刪除。使用在臨時(shí)緩存文件、中間計(jì)算結(jié)果(無(wú)需持久化)。

特點(diǎn)
- Pod 創(chuàng)建時(shí)自動(dòng)創(chuàng)建空目錄,Pod 刪除時(shí)數(shù)據(jù)清除。
- 數(shù)據(jù)僅存于 Pod 所在節(jié)點(diǎn)的內(nèi)存或磁盤(可通過(guò)medium參數(shù)指定,默認(rèn)""表示節(jié)點(diǎn)默認(rèn)存儲(chǔ),Memory表示內(nèi)存存儲(chǔ),數(shù)據(jù)易失)。
- 支持 Pod 內(nèi)多個(gè)容器共享數(shù)據(jù)。
EmptyDir使用場(chǎng)景
- 臨時(shí)緩存文件、中間計(jì)算結(jié)果(無(wú)需持久化)
- 例如:filebeat采集日志
EmptyDir實(shí)戰(zhàn)案例
示例:
# 定義清單文件
[root@master01 ~/volumes]# cat empty-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: empty-pod
spec:
# 定義數(shù)據(jù)卷
volumes:
# 數(shù)據(jù)卷名稱
- name: data-volume
# volume的類型
emptyDir: {}
containers:
- name: writer-busybox
image: busybox
command: ["/bin/sh", "-c"]
args:
- |
echo "hello emptyDir" >> /data/hello.txt;
sleep 3600
# 指定掛載的數(shù)據(jù)卷
volumeMounts:
# 要掛載的數(shù)據(jù)卷名稱
- name: data-volume
# 掛載到容器內(nèi)部的路徑
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
基本存儲(chǔ)之HostPath
官方文檔:https://kubernetes.io/zh-cn/docs/concepts/storage/volumes/#hostpath
EmptyDir中數(shù)據(jù)不會(huì)被持久化,它會(huì)隨著Pod的結(jié)束而銷毀,如果想簡(jiǎn)單的將數(shù)據(jù)持久化到主機(jī)中,可以選擇HostPath。
HostPath就是將Node主機(jī)中一個(gè)實(shí)際目錄掛在到Pod中,以供容器使用,這樣的設(shè)計(jì)就可以保證Pod銷毀了,但是數(shù)據(jù)依據(jù)可以存在于Node主機(jī)上。

特點(diǎn)
- 掛載節(jié)點(diǎn)上的本地文件或目錄(如/var/lib/data)到 Pod 中。
- 數(shù)據(jù)隨節(jié)點(diǎn)存在而保留,Pod 刪除后數(shù)據(jù)仍在節(jié)點(diǎn)上,但跨節(jié)點(diǎn)調(diào)度時(shí)無(wú)法共享。
- 需注意節(jié)點(diǎn)路徑權(quán)限(如使用hostPath.type指定路徑類型,如DirectoryOrCreate自動(dòng)創(chuàng)建目錄)。
HostPath實(shí)戰(zhàn)案例
# 定義清單文件
[root@master01 ~/volumes]# cat hostpath-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: hostpath-pod
spec:
volumes:
- name: hostpath
hostPath:
# 節(jié)點(diǎn)上的存儲(chǔ)位置
path: /data/nginx/
# 類型,文件夾不存在時(shí)自動(dòng)創(chuàng)建
type: DirectoryOrCreate
containers:
- name: nginx
image: nginx
volumeMounts:
- name: hostpath
mountPath: /usr/share/nginx/html
# 創(chuàng)建Pod
[root@master01 ~/volumes]# kubectl apply -f hostpath-pod.yaml
pod/hostpath-pod created
# 查看Pod調(diào)度到哪個(gè)節(jié)點(diǎn)上
[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節(jié)點(diǎn)上查看
# 發(fā)現(xiàn)目錄已經(jīng)創(chuàng)建成功了
[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
# 寫入一個(gè)文件進(jìn)行訪問(wèn)測(cè)試
[root@node02 ~]# echo I am huangsir > /data/nginx/index.html
[root@node02 ~]# cat /data/nginx/index.html
I am huangsir
# 訪問(wèn)nginx,發(fā)現(xiàn)綁定成功
[root@node02 ~]# curl 100.95.185.242
I am huangsir
hostPath中type的可用值
-
DirectoryOrCreate:如果在給定路徑上什么都不存在,那么將根據(jù)需要?jiǎng)?chuàng)建空目錄,權(quán)限設(shè)置為 0755,具有與 kubelet 相同的組和屬主信息。
-
Directory:在給定路徑上必須存在的目錄。
-
FileOrCreate:如果在給定路徑上什么都不存在,那么將在那里根據(jù)需要?jiǎng)?chuàng)建空文件,權(quán)限設(shè)置為 0644,具有與 kubelet 相同的組和所有權(quán)。
-
File:在給定路徑上必須存在的文件。
-
Socket:在給定路徑上必須存在的 UNIX 套接字。
-
CharDevice:(僅 Linux 節(jié)點(diǎn)) 在給定路徑上必須存在的字符設(shè)備。
-
BlockDevice:(僅 Linux 節(jié)點(diǎn)) 在給定路徑上必須存在的塊設(shè)備。
基本存儲(chǔ)之NFS
官方文檔:https://kubernetes.io/zh-cn/docs/concepts/storage/volumes/#nfs
HostPath依賴節(jié)點(diǎn),如果Pod重啟之后調(diào)度到另一個(gè)節(jié)點(diǎn)中,那么所依賴數(shù)據(jù)將不存在。
NFS可以解決這個(gè)問(wèn)題,
NFS存儲(chǔ)特點(diǎn)
- 掛載遠(yuǎn)程 NFS 服務(wù)器的共享目錄,支持跨節(jié)點(diǎn)共享數(shù)據(jù)。
- 數(shù)據(jù)持久化存儲(chǔ)在 NFS 服務(wù)器,不依賴 Pod 或節(jié)點(diǎn)生命周期。
使用場(chǎng)景
多 Pod 共享數(shù)據(jù)(如分布式應(yīng)用的共享配置)。
NFS實(shí)戰(zhàn)案例
安裝NFS
首先我們需要安裝NFS,可以參考這篇文章:NFS搭建及使用
master節(jié)點(diǎn)安裝服務(wù)端
apt update -y
apt install -y nfs-kernel-server
# 檢查狀態(tài)
systemctl status nfs-kernel-server
# 創(chuàng)建共享目錄
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節(jié)點(diǎn)安裝客戶端(可以不用操作)
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
# 開機(jī)自啟動(dòng)掛載
echo 10.0.0.30:/data/nfs/nginx /data/nfs/nginx nfs defaults 0 0 >> /etc/fstab
# 檢查是否掛載成功
df -h | grep /data/nfs/nginx
創(chuàng)建Pod測(cè)試
# 定義資源文件
[root@master01 ~/volumes]# cat nfs-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nfs-pod
spec:
# 指定Pod調(diào)度到node01節(jié)點(diǎn)上
nodeName: node01
volumes:
- name: nfs
nfs:
# nfs服務(wù)端的地址
server: 10.0.0.30
# 掛載nfs服務(wù)器的路徑
path: /data/nfs/nginx
containers:
- name: nginx
image: nginx
volumeMounts:
- name: nfs
mountPath: /usr/share/nginx/html
# 創(chuàng)建Pod
[root@master01 ~/volumes]# kubectl apply -f nfs-pod.yaml
pod/nfs-pod created
# 查看pod信息,發(fā)現(xiàn)調(diào)度到node01節(jié)點(diǎn)上,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>
配置測(cè)試內(nèi)容并訪問(wèn)測(cè)試
[root@master01 ~/volumes]# echo nfs-server > index.html
# 訪問(wèn)測(cè)試
[root@master01 ~/volumes]# curl 100.117.144.145
nfs-server
再將Pod調(diào)度到node02節(jié)點(diǎn)上,測(cè)試訪問(wèn)內(nèi)容是否會(huì)發(fā)生變化
[root@master01 ~/volumes]# cat nfs-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nfs-pod
spec:
# 指定Pod調(diào)度到node02節(jié)點(diǎn)上
nodeName: node02
volumes:
- name: nfs
nfs:
# nfs服務(wù)端的地址
server: 10.0.0.30
# 掛載nfs服務(wù)器的路徑
path: /data/nfs/nginx
containers:
- name: nginx
image: nginx
volumeMounts:
- name: nfs
mountPath: /usr/share/nginx/html
# 創(chuàng)建Pod,需要將上一步創(chuàng)建Pod刪除哦~
[root@master01 ~/volumes]# kubectl apply -f nfs-pod.yaml
pod/nfs-pod created
# 查看pod調(diào)度及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>
# 訪問(wèn),發(fā)現(xiàn)內(nèi)容并沒(méi)有發(fā)生變化
[root@master01 ~/volumes]# curl 100.95.185.244
nfs-seerver
配置存儲(chǔ)ConfigMap和Secret
可以參考下面這兩篇文章
本文來(lái)自博客園,作者:huangSir-devops,轉(zhuǎn)載請(qǐng)注明原文鏈接:http://www.rzrgm.cn/huangSir-devops/p/18859111,微信Vac666666,歡迎交流

浙公網(wǎng)安備 33010602011771號(hào)