k8s基本存儲(EmptyDir、HostPath、NFS)
數據存儲
在前面已經提到,容器的生命周期可能很短,會被頻繁地創建和銷毀。那么容器在銷毀時,保存在容器中的數據也會被清除。
這種結果對用戶來說,在某些情況下是不樂意看到的。為了持久化保存容器的數據,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@master ~]# kubectl create -f volume-emptydir.yaml # 查看Pod [root@master ~]# kubectl get pods volume-emptydir -n dev -o wide # 通過PodIp訪問nginx,產生日志 [root@master ~]# curl 10.244.1.92 # 通過kubectl logs命令查看指定容器的標準輸出,實時讀取日志 [root@master ~]# 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: - 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@master ~]# kubectl create -f volume-hostpath.yaml # 查看Pod [root@master ~]# kubectl get pods volume-hostpath -n dev -o wide #訪問nginx [root@master ~]# curl 10.244.2.75 [root@master ~]# kubectl logs -f volume-hostpath -n dev -c busybox # 接下來就可以去host的/root/logs目錄下查看存儲的文件了 ### 注意: 下面的操作需要到Pod所在的節點運行(我的是node2)


[root@node2 ~]# ls /root/logs/ access.log error.log 刪除pod后,node2上的目錄文件仍存在 # 同樣的道理,如果在此目錄下創建一個文件,到容器中也是可以看到的

NFS
HostPath可以解決數據持久化的問題,但是一旦Node節點故障了,Pod如果轉移到了別的節點,又會出現問題了,此時需要準備單獨的網絡存儲系統,比較常用的用NFS、CIFS。
NFS是一個網絡文件存儲系統,可以搭建一臺NFS服務器,然后將Pod中的存儲直接連接到NFS系統上,這樣的話,無論Pod在節點上怎么轉移,只要Node跟NFS的對接沒問題,數據就可以成功訪問。

案例
1)首先要準備nfs的服務器,這里為了簡單,直接是master節點做nfs服務器
# 在master上安裝nfs服務 [root@master ~]# yum install -y nfs-utils rpcbind # 準備一個共享目錄 [root@nfs ~]# mkdir -p /root/data/nfs # 將共享目錄以讀寫權限暴露給192.168.5.0/24網段中的所有主機 [root@master ~]# vim /etc/exports [root@master ~]# cat /etc/exports /root/data/nfs 192.168.1.0/24(rw,no_root_squash) 建議修改權限 chmod 777 -R /root/data/nfs exportfs -r # 啟動nfs服務 [root@master ~]# systemctl enable rpcbind --now [root@master ~]# systemctl enable nfs --now 在Master節點(NFS服務器)測試是否掛載成功: [root@master ~]# showmount -e 192.168.1.50

2)接下來,要在的每個node節點上都安裝下nfs,這樣的目的是為了node節點可以驅動nfs設備
# 在node上安裝nfs服務,注意不需要啟動 [root@node1 ~]# yum install nfs-utils -y [root@node2 ~]# 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.1.50 #nfs服務器地址 path: /root/data/nfs #共享文件路徑
4)最后,運行下pod,觀察結果
# 創建Pod [root@master ~]# kubectl create -f volume-nfs.yaml pod/volume-nfs created # 查看Pod [root@master ~]# kubectl get pods volume-nfs -n dev -o wide NAME READY STATUS RESTARTS AGE volume-nfs 2/2 Running 0 2m9s # 查看nfs服務器上的共享目錄,發現已經有文件了 [root@master ~]# ls /root/data/ [root@master ~]# tail -f data/nfs/access.log [root@master ~]# curl 10.244.1.93

參考
黑馬B站k8s課程https://www.bilibili.com/video/BV1Qv41167ck/
https://gitee.com/yooome/golang/blob/main/k8s%E8%AF%A6%E7%BB%86%E6%95%99%E7%A8%8B-%E8%B0%83%E6%95%B4%E7%89%88/k8s%E8%AF%A6%E7%BB%86%E6%95%99%E7%A8%8B.md
https://www.yuque.com/fairy-era/yg511q/xyqxge
浙公網安備 33010602011771號