大家好,我是小菜,一個渴望在互聯網行業做到蔡不菜的小菜。可柔可剛,點贊則柔,白嫖則剛!
死鬼~看完記得給我來個三連哦!
本文主要介紹
K8s中數據存儲的使用
如有需要,可以參考
如有幫助,不忘 點贊 ❥
微信公眾號已開啟,小菜良記,沒關注的同學們記得關注哦!
k8s 的進程到這里我們已經完成了 Namespace、Pod、PodController 幾種資源的使用方式,已經過大半了哦~這篇文章我們就繼續來了解一下在k8s 中怎么進行數據存儲!
kubernetes的最小控制單元,容器都是運行在 pod 中的,一個pod中可以有 1 個或多個容器
這個概念我們早已了解,不難明白容器的生命周期會很短暫,當pod出現問題的時候,pod控制器會頻繁的創建和銷毀,而每個pod都是獨立的,因此存儲在容器中的數據也會被清除,這種結果無疑是致命打擊。這時,可能就會有小伙伴說了,docker 中存在數據掛載,k8s 肯定也存在,我們可以利用數據掛載來解決該問題~那么,恭喜你答對了,k8s 中不僅支持數據掛載,而且支持的功能還相當強大,話不多說,我們接下來就進入數據世界~
數據存儲
k8s中有個 Volume 的概念,Volumn 是 Pod 中能夠被多個容器訪問的共享目錄,K8s 的 Volume 定義在 pod 上,然后被一個 pod里的多個容器掛載到具體的文件目錄下,k8s通過 Volume 實現同一個 pod 中不同容器之間的數據共享以及數據的持久化存儲,Volume的生命周期不與pod中單個容器的生命周期相關,當容器終止或重啟的時候,Volume中的數據也不會被丟失。
Volume 支持常見的類型如下:
除了上面列出來的這些,還有 gcePersistentDisk、awsElasticBlockStore、azureFileVolume、azureDisk 這些存儲,但是因為使用較少,所以不做過多了解。下面我們就來詳細看看每個存儲該如何使用!
一、基本存儲
1)EmptyDir
這是個最基礎的 Volume類型,一個 EmptyDir 就是 Host 上的一個空目錄。
概念:
它是在 Pod 被分配到 Node 節點上時才會被創建,初始內容為空,並且無需指定宿主機上對應的目錄文件,它會自動在宿主機上分配一個目錄。
值得關注的是:
Pod 銷毀時,EmptyDir 中的數據也會被永久刪除!
用處:
- 用作臨時空間,比如 Web 服務器寫日志或者 tmp 文件需要的臨時目錄。
- 用作多容器之間的共享目錄(一個容器需要從另一個容器中獲取數據的目錄)
實戰:
我們以nginx為例,准備一份資源清單
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: cbuc-test
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.14-alpine
ports:
- containerPort: 80
volumeMounts: # 將 nginx-Log 掛載到nginx容器中,容器內目錄為/var/log/nginx
- name: nginx-log
mountPath: /var/log/nginx
volumes: #在此聲明volume
- name: nginx-log
emptyDir: {}
然后我們創建后可以看看emptyDir存儲卷在宿主機的位置。默認情況下宿主機中聲明volume的目錄位置是在 /var/lib/kubelet/pods/<Pod 的 ID>/volumes/kubernetes.io~<Volume 類型 >/<Volume 名字 >
中。
2)HostPath
概念:
HostPath 就是將 Node 節點上一個實際目錄掛載到pod中,供容器使用,這種好處就是在 pod 銷毀后,該目錄下的數據依然存在!
實戰:
我們以 nginx 為例,准備一份資源清單:
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: cbuc-test
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: nginx:1.14-alpine
ports:
- containerPort: 80
volumeMounts:
- name: nginx-log
mountPath: /var/log/nginx
volumes:
- name: nginx-log
hostPath: # 指定宿主機目錄為 /data/nginx/log
path: /data/nginx/log
type: DirectoryOrCreate # 創建類型
spec.volumes.hostPath.type
(創建類型):
- DirectoryOrCreate:目錄存在就是用,不存在就先創建后使用
- Directory: 目錄必須存在
- FileOrCreate: 文件存在就是用,不存在就創建后使用
- File: 文件必須存在
- Socket: unix 套接字必須存在
- CharDevice: 字符設備必須存在
- BlockDevice: 塊設備必須存在
我們根據該資源清單可以創建出一個 pod,然后通過 podIp 訪問該pod,再查看 /data/nginx/log
下的日志文件,發現已有日志產生
3)NFS
HostPath 是我們日常中比較經常使用到的存儲方式了,已經可以滿足基本的使用場景。目前為止我們小小的總結一下:EmptyDir 是針對 pod
,如果 pod 被銷毀了,那么改數據就會丟失。針對該問題,HostPath 進行了改進,存儲變成是針對 Node ,但是如果 Node 宕機了,那么數據還是會丟失。這個時候就需要准備單獨的網絡存儲系統了,而比較常用的便是 NFS、CIFS
概念:
NFS 是一個網絡存儲系統,可以搭建一台 NFS 服務器,然后將 Pod 中的存儲直接連接到 NFS 系統上,這樣的話,無論pod在節點上如何轉移,只要 Node 節點和 NFS服務器對接沒問題,數據就不會出現問題。
實戰:
既然需要 NFS 服務器,那肯定需要自己搭建一個。我們選取 master 節點來安裝NFS 服務器
# 安裝 nfs 服務器
yum install -y nfs-utils
# 准備共享目錄
mkdir -p /data/nfs/nginx
# 將共享目錄以讀寫權限暴露給 192.168.108.0/24 網段的所有主機
vim /etc/exports
# 添加以下內容
/data/nfs/nginx 192.168.108.0/24(rw,no_root_squash)
# 啟動 nfs 服務器
systemctl start nfs
然后我們在各個節點上同樣安裝 NFS,以供驅動 NFS 設備
yum install -y nfs-utils
做好以上准備后我們就可以准備資源清單文件了:
apiVersion: v1
kind: Pod
metadata:
name: nginx
namespace: cbuc-test
labels:
app: nginx
spec:
containers:
- name: nginx-pod
image: nginx:1.14-alpine
ports:
- containerPort: 80
volumeMounts:
- name: nginx-log
mountPath: /var/log/nginx
volumes:
- name: nginx-log
nfs:
server: 192.168.108.100 # NFS服務器地址,也就是master地址
path: /data/nfs/nginx # 共享文件路徑
創建完pod后,我們可以進入到 /data/nfs
目錄下查看到兩個日志文件了
二、高級存儲
管理存儲是管理計算的一個明顯問題,該部分需要抽象出如何根據消費方式來提供存儲的詳細信息。而 k8s 也很好的支持了,引入了兩個新的 API 資源:PersistenVolume 和 PersistentVolumeClaim
PersistenVolume(PV)是持久化卷的意思,是對底層共享存儲的一種抽象,一般情況下PV由 k8s 管理員進行創建和配置,它與底層具體的共享存儲技術有關,並通過插件完成與共享存儲的對象。
PersistentVolumeClaim(PVC)是持久卷聲明的意思,是用戶對存儲需求的一種聲明,換句話說,PVC其實就是用戶向 k8s 系統發出的一種資源需求申請。
1)PV
PV 是集群中由管理員配置的一段網絡存儲,它也是集群中的一種資源,資源清單模板如下:
apiVersion: v1
kind: PersistentVolume
meatadata:
name: pv
spec:
nfs: # 存儲類型,可以是 CIFS、GlusterFS
capacity: # 存儲空間的設置
storage: 2Gi
accessModes: # 訪問模式
storageClassName: # 存儲類別
persistentVolumeReclaimPolicy: # 回收策略
每個屬性真的是又長又難記,我們先來看看每個屬性的含義:
- 存儲類型
底層實際存儲的類型,k8s 支持多種存儲類型,每種存儲類型的配置都有所差異
- 存儲能力(capacity)
目前只支持存儲空間的設置,未來可能會加入 IOPS、吞吐量等指標的設置
- 訪問模式(accessModes)
用於描述用戶應用對存儲資源的訪問權限,有以下幾種訪問權限:
- ReadWriteOnce(RWO):讀寫權限,但是只能被單個節點掛載
- ReadOnlyMany(ROM):只讀權限,可以被多個節點掛載
- ReadWriteMany(RWM):讀寫權限,可以被多個節點掛載
- 存儲類別
PV 可以通過storageClassName參數指定一個存儲類別
- 具有特定類別的PV只能與請求了該類別的PVC進行綁定
- 未設定類別的PV則只能與不請求任何類別的PVC進行綁定
- 回收策略(persistentVolumeReclaimPolicy)
當PV沒有再被使用的時候,需要對其處理的方式(不同的存儲類型支持的策略也會不同),有以下幾種回收策略:
-
Retain(保留):保留數據。需要管理員手動清理數據
-
Recycle(回收):清除PV中的數據,效果相當於
rm -rf
-
Delete(刪除):與 PV 相連的后端存儲完成 volume 的刪除操作,常見於雲服務商的存儲服務
生命周期:
一個 PV 的生命周期可能會處於4種不同的階段:
- Available(可用): 表示可用狀態,還未被任何PVC綁定
- Bound(已綁定): 表示PV已經被PVC綁定
- Released(已釋放): 表示PVC已被刪除,但是資源還未被集群重新聲明
- Failed(失敗): 表示該PV的自動回收失敗
實戰:
我們前面已經認識了NFS存儲服務器,因此我們這里也依然使用 NFS 服務器做底層存儲。首先我們需要創建1個PV,也對應着NFS中1個需要暴露的路徑。
# 創建目錄
mkdir /data/pv1 -pv
# 向NFS暴露路徑
vim /etc/exports
/data/pv1 192.168.108.0/24(rw,no_root_squash)
完成以上步驟后我們就需要創建1個 PV:
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv01
namespace: cbuc-test
labels:
app: pv
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteMany
persistentVolumeReclaimPolicy: Retain
nfs:
path: /data/pv1
server: 192.168.108.100
通過創建后我們可以查看到PV:
2)PVC
PVC是資源的申請,用來聲明對存儲空間,訪問模式,存儲類別的需求信息,資源清單模板如下:
apiVersion: v1
kind: persistentVolumeClaim
metadata:
name: pvc
namespace: cbuc-test
labels:
app: pvc
spec:
accessModes: # 訪問模式
selector: # 采用標簽對PV選擇
storageClassName: # 存儲類別
resources: # 請求空間
request:
storage: 1Gi
很多屬性我們在PV中已經了解到了,這里我們簡單過一下~
- 訪問模式(accessModes)
用於描述用戶應用對存儲資源的訪問權限
- 選擇條件(selector)
通過 Labels Selector的設置,對於系統中已經存在的PV進行篩選管理
- 資源類別(storageClassName)
pvc在定義時可以設定需要的后端存儲的類別,只有設置了該class的pv才能被系統選出
- 資源請求(resources)
描述對存儲資源的請求
實戰:
准備1份PVC的資源清單模板:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc01
namespace: cbuc-test
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Gi
創建后我們先查看PVC是否創建成功
然后再查看pv是否已經被pvc綁定上
3)實際使用
上面我們已經成功創建了 PV 和 PVC,但是還沒說明如何使用,接下來我們就准備一份pod清單:
apiVersion: v1
kind: Pod
metadata:
name: pod-pvc
namespace: cbuc-test
spec:
containers:
- name: nginx01
image: nginx:1.14-alpine
volumeMounts:
- name: test-pv
mountPath: /var/log/nginx
volumes:
- name: test-pv
persistentVolumeClaim:
claimName: pvc01
readOnly: true
4)生命周期
萬物皆有生命周期,PV與PVC也不例外,生命周期如下:
- 資源供應
管理員手動創建底層存儲和PV
- 資源綁定
用戶創建PVC,k8s負責根據PVC的聲明去尋找PV,並綁定。
- 如果找到,則會成功進行綁定,用戶的應用就可以使用這個PVC了
- 如果找不到,PVC則會無限處於Pending的狀態,直到等到系統管理員創建了一個符合其要求的PV
PV一旦綁定到某個PVC上,就會被這個PVC獨占,不能再與其他PVC進行綁定了
- 資源使用
用戶可在Pod中想 volume 一樣使用pvc
- 資源釋放
用戶通過刪除PVC來釋放PV,當存儲資源使用完畢后,用戶可以刪除PVC,與該PVC綁定的PV將會標記為 已釋放
,但還不能立刻與其他PVC進行綁定,通過之前PVC寫入的數據可能還留在存儲設備上,只有在清除之后該PV才能再次使用
- 資源回收
k8s 會根據pv設置的回收策略進行資源的回收
上面列出了 PV和PVC 的生命周期,與其說是生命周期,但不如是PV和PVC的使用過程!
三、配置存儲
配置存儲,顧名思義就是用來存儲配置的,其中包括了兩種配置存儲,分別是 ConfigMap
和 Secret
1)ConfigMap
ConfigMap 是一種比較特殊的存儲卷,它的主要作用是用來存儲配置信息的。資源清單模板如下:
apiVersion: v1
kind: ConfigMap
metadata:
name: cmp
namespace: cbuc-test
data:
info:
username:cbuc
sex:male
使用方式很簡單,少了 spec
,多了 data.info
,只需在 info
下級以 key: value
的方式存儲自己想要配置的配置文件即可
通過kubectl create -f configMap.yaml
命令可創建出一個 ConfigMap
具體使用如下,我們需要創建一個Pod:
apiVersion: v1
kind: Pod
metadata:
name: test-pod
namespace: cbuc-test
spec:
containers:
- name: nginx
image: nginx:1.14-apline
volumeMounts: # 將 configMap 掛載到目錄中
- name: config
mountPath: /var/configMap/config
volumes:
- name: config
configMap:
name: cmp # 上面我們創建 configMap 的名稱
然后通過命令kubectl create -f pod-cmp.yaml
創建出測試Pod,然后可查看pod中的配置文件:
2)Secret
在 k8s 中,還存在一種和 ConfigMap 非常類似的對象,稱之為 Secret 對象。它主要用於存儲敏感信息,例如密碼、秘鑰、證書等信息。
我們首先對想要配置的數據進行 base64 加密:
# 加密用戶名
[root@master test]# echo -n 'cbuc' | base64
Y2J1Yw==
# 加密密碼
[root@master test]# echo -n '123456' | base64
MTIzNDU2
然后准備 Secret 資源清單文件
apiVersion: v1
kind: Secret
metadata:
name: secret
namespace: cbuc-test
type: Opaque # 表示base64編碼格式的Secret
data:
username: Y2J1Yw==
password: MTIzNDU2
通過命令kubectl create -f secret.yaml
創建 Secret,然后我們再准備一份Pod資源清單:
apiVersion: v1
kind: Pod
metadata:
name: pod-secret
namespace: cbuc-test
spec:
containers:
- name: nginx
image: nginx:1.14-apline
volumeMounts:
- name: config
mountPath: /var/secret/config
volumes:
- name: config
secret:
secretName: secret
創建后我們進入pod查看配置文件,可以發現配置文件的信息已經是解碼后的
END
這篇我們就介紹了 k8s 的數據存儲,篇幅較短,是不是意猶未盡,我們下篇再見(Server和Ingress)!路漫漫,小菜與你一同求索~
今天的你多努力一點,明天的你就能少說一句求人的話!
我是小菜,一個和你一起學習的男人。
💋
微信公眾號已開啟,小菜良記,沒關注的同學們記得關注哦!