一、前言
新建具有兩個節(jié)點的k8s集群,主節(jié)點(master節(jié)點/m節(jié)點)的ip地址是192.168.100.150,從節(jié)點(w1節(jié)點)的ip地址是192.168.100.151。
本文操作如何將pod中的container容器中的目錄映射到宿主機(包括pod所在宿主機和其他任意宿主機),分為三個部分:volumes的使用、pv/pvc的使用、storageClass的使用。
三者的關(guān)系是:volumes映射Pod只能映射到自己所在node(實際機器)的目錄上;pv/pvc映射通過配置 NFS 服務(wù)器可以保證無論Pod在哪個node節(jié)點上都映射到 NFS 服務(wù)器上,下次無論 Pod 被分配到哪個節(jié)點,都從 NFS 服務(wù)器加載;storageClass解決的是 pv/pvc 一對一的關(guān)系,如果有 N 個pvc,這運維人員需要新建 N 個pv,但是有了storageClass,運維人員只需要建立好一個storageClass,就算有 N 個pvc,這個storageClass 也會自動創(chuàng)建 N個 pv 來給 N個 pvc使用。
本文資源地址:https://www.syjshare.com/res/JF7S1RQU
二、volumes實現(xiàn)本地持久化存儲
2.1 K8S各個Pod之間可以存儲和網(wǎng)絡(luò)的共享
Pod中的各個container,可以實現(xiàn) 共享網(wǎng)絡(luò) 和 共享存儲(即volume)

2.2 volumes實現(xiàn)本地持久化存儲
(1)創(chuàng)建資源
kubectl apply -f volume-pod.yaml
(2)查看pod的運行情況
kubectl get pods -o wide
(3) 進入pod里面的container
# 根據(jù)pod名稱進入
kubectl exec -it pod-name -- /bin/bash


注意:使用這種volumes目錄映射,只能映射到pod所在的物理機器的目錄,這是volumes映射的局限,需要部署一個 NFS 服務(wù)器,然后通過 PV/PVC 來連接這個 NFS 服務(wù)器,解決這個問題。
三、遠程服務(wù)器持久化存儲
3.1 PersistentVolume
官網(wǎng):https://kubernetes.io/docs/concepts/storage/persistent-volumes/
apiVersion: v1
kind: PersistentVolume # PV是一個Kind,volume不是一種kind
metadata:
name: my-pv
spec:
capacity:
storage: 5Gi # 需要使用的遠端服務(wù)器的存儲空間大小(修改)
volumeMode: Filesystem
accessModes:
- ReadWriteOnce # 只允許一個Pod進行獨占式讀寫操作
persistentVolumeReclaimPolicy: Recycle
storageClassName: slow
mountOptions:
- hard
- nfsvers=4.1
nfs: # host是k8s集群內(nèi),nfs是k8s集群外
path: /tmp # 遠端服務(wù)器的目錄(修改)
server: 172.17.0.2 # 遠端的服務(wù)器(修改)
說白了,PV是K8s中的資源,volume的plugin實現(xiàn),生命周期獨立于Pod,封裝了底層存儲卷實現(xiàn)的細節(jié)。
pv的生命周期是獨立于pod的
注意:PV的維護通常是由運維人員、集群管理員進行維護的。
3.2 PersistentVolumeClaim
官網(wǎng):https://kubernetes.io/docs/concepts/storage/persistent-volumes/#persistentvolumeclaims
有了PV,那Pod如何使用呢?為了方便使用,我們可以設(shè)計出一個PVC來綁定PV,然后把PVC交給Pod來使用即可,且聽下面的分析。pod中想要使用這個pv,就是通過pvc來和pv綁定的 pod - pvc - pv - 遠端服務(wù)器
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: myclaim
spec:
accessModes: # 匹配
- ReadWriteOnce
volumeMode: Filesystem
resources:
requests:
storage: 8Gi # 匹配
storageClassName: slow
selector:
matchLabels:
release: "stable"
matchExpressions:
- {key: environment, operator: In, values: [dev]}
說白了,PVC會匹配滿足要求的PV[是根據(jù)size和訪問模式進行匹配的],進行一一綁定,然后它們的狀態(tài)都會變成Bound。
也就是PVC負責(zé)請求PV的大小和訪問方式,然后Pod中就可以直接使用PVC咯。
注意:PVC通常由開發(fā)小伙伴維護,開發(fā)小伙伴無需關(guān)注與存儲細節(jié)。
3.3 Pod中如何使用PVC (Pod綁定PVC)
官網(wǎng):https://kubernetes.io/docs/concepts/storage/persistent-volumes/#claims-as-volumes
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: myfrontend
image: nginx
volumeMounts:
- mountPath: "/var/www/html" # ok 不變
name: mypd # ok 不變
volumes:
- name: mypd # ok 不變 volumes 和 pod 綁定,通過name
persistentVolumeClaim:
claimName: myclaim # pod 和 pvc 綁定,通過claimName
3.4 遠程服務(wù)器持久化存儲實踐與測試
背景:使用nginx持久化存儲演示
(1)共享存儲使用nfs,比如選擇在m節(jié)點
(2)創(chuàng)建pv和pvc
(3)nginx pod中使用pvc
3.4.1 啟動前的配置(配置NFS服務(wù)器)
nfs(network file system)網(wǎng)絡(luò)文件系統(tǒng),是FreeBSD支持的文件系統(tǒng)中的一種,允許網(wǎng)絡(luò)中的計算機之間通過TCP/IP網(wǎng)絡(luò)共享資源。
隨便找一個機器搭建NFS服務(wù)器(用來作為遠程服務(wù)器存放),可以是k8s集群內(nèi)的節(jié)點,也可以是k8s集群外的節(jié)點。這里在master節(jié)點上搭建一個NFS服務(wù)器,目錄為/nfs/data,然后
01 選擇master節(jié)點作為nfs的server,所以在master節(jié)點上,執(zhí)行以下命令
# 第一步,啟動nfs和rpcbind
# 啟動nfs
systemctl status nfs (如果存在就開啟 systmctl start nfs ,不過不存在就安裝 yum -y install nfs-utils 并 systemctl start nfs)
systemctl status nfs (啟動后再次查看狀態(tài),狀態(tài)成功就是表示啟動成功了)
systemctl enable nfs (設(shè)置為為開機自啟動)
# 啟動rpcbind
systemctl restart rpcbind (重啟)
systemctl enable rpcbind (設(shè)置為開機自啟動)
systemctl status rpcbind (查看狀態(tài),驗證重啟成功)
# 第二步,創(chuàng)建nfs目錄并授予權(quán)限 /nfs/data/ 這個目錄就是nfs ip那個目錄
# 創(chuàng)建nfs目錄
mkdir -p /nfs/data/
# 授予權(quán)限
chmod -R 777 /nfs/data
# 第三步,編輯export文件并保存
# 編輯export文件 對于/nfs/data目錄,授予可讀可寫權(quán)限、根目錄權(quán)限、同步數(shù)據(jù)權(quán)限
vi /etc/exports
/nfs/data *(rw,no_root_squash,sync)
/nfs/data *(rw,no_root_squash,sync,no_subtree_check) # 新版nfs
# 使得配置生效
exportfs -r
# 查看生效
exportfs
# 第四步,驗證rpcbind、nfs
# 查看rpc服務(wù)的注冊情況
rpcinfo -p localhost
# showmount測試
# showmount命令用于查詢NFS服務(wù)器的相關(guān)信息 -e或--exports 顯示NFS服務(wù)器的輸出清單。
showmount -e master-ip
showmount -e 192.168.100.150
02 所有node上安裝客戶端 ps -ef|grep nfs
# 啟動nfs
systemctl status nfs (如果存在就開啟 systmctl start nfs ,不過不存在就安裝 yum -y install nfs-utils 并 systemctl start nfs)
systemctl status nfs (啟動后再次查看狀態(tài),狀態(tài)成功就是表示啟動成功了)
systemctl enable nfs (設(shè)置為為開機自啟動)
# 啟動rpcbind
systemctl restart rpcbind (重啟)
systemctl enable rpcbind (設(shè)置為開機自啟動)
systemctl status rpcbind (查看狀態(tài),驗證重啟成功)
注意1:nfs主節(jié)點判斷nfs是否安裝成功了三條
exportfs 或者 cat /etc/exports
rpcinfo -p localhost
showmount -e 192.168.100.150
注意2:nfs主節(jié)點和從節(jié)點配置的區(qū)別
從節(jié)點:啟動好nfs和rpcbind
主節(jié)點:啟動好nfs和rpcbind、新建/nfs/data目錄、vi /etc/exports、showmount -e 192.168.100.150 測試
注意3:pod - nfs 和 pod - pvc - pv - nfs 兩種方式等效,增加了 pvc - pv 這一層只是為了開發(fā)和運維解耦,pod - pvc 由開發(fā)負責(zé),pv - nfs 由運維負責(zé),如果都是一個人干,可以直接 pod - nfs,不要中間 pvc-pv 這一層
3.4.2 啟動并測試
(1)在nfs服務(wù)器創(chuàng)建所需要的目錄(數(shù)據(jù)存放目錄 因為pvc文件需要這個目錄 在宿主機上)
mkdir -p /nfs/data/nginx
(2)定義PV,PVC和Nginx的yaml文件 (三個yaml文件 就是合并為一個yaml文件 nginx-pv-demo.yaml)
網(wǎng)盤中:課堂源碼/nginx-pv-demo.yaml
(3)根據(jù)yaml文件創(chuàng)建資源并查看資源
# 創(chuàng)建三個
kubectl apply -f nginx-pv-demo.yaml
# 查看三個
kubectl get pv,pvc
kubectl get pods -o wide
測試:遠程服務(wù)器持久化存儲


四、遠程服務(wù)器持久化存儲的另一種方式(StorageClass自動創(chuàng)建PV)
4.1 StorageClass
上面手動管理PV的方式還是有點low,能不能更加靈活一點呢?
官網(wǎng):https://kubernetes.io/docs/concepts/storage/storage-classes/
nfs github:github:https://github.com/kubernetes-incubator/external-storage/tree/master/nfs
Introduction
A StorageClass provides a way for administrators to describe the “classes” of storage they offer.Different classes might map to quality-of-service levels, or to backup policies, or to arbitrary policies determined by the cluster administrators. Kubernetes itself is unopinionated about what classes represent. This concept is sometimes called “profiles” in other storage systems.
StorageClass 為管理員提供了描述存儲 “類” 的方法。不同的類型可能會映射到不同的服務(wù)質(zhì)量等級或備份策略,或是由集群管理員制定的任意策略(即可以自定義)。Kubernetes 本身并不清楚各種類代表的什么(這種類是k8s不識別的)。這個類的概念在其他存儲系統(tǒng)中有時被稱為 “配置文件”。
The StorageClass Resource
Each StorageClass contains the fields provisioner, parameters, and reclaimPolicy, which are used when a PersistentVolume belonging to the class needs to be dynamically provisioned. The name of a StorageClass object is significant, and is how users can request a particular class. Administrators set the name and other parameters of a class when first creating StorageClass objects, and the objects cannot be updated once they are created.
每個 StorageClass 都包含 provisioner、parameters 和 reclaimPolicy 字段,這些字段會在 StorageClass 需要動態(tài)分配 PersistentVolume 時會使用到(就是說StorageClass的目的是自動生成pv)。StorageClass 對象的命名很重要,用戶使用這個命名來請求生成一個特定的類。當創(chuàng)建 StorageClass 對象時,管理員設(shè)置 StorageClass 對象的命名和其他參數(shù),一旦創(chuàng)建了對象就不能再對其更新。
小結(jié):StorageClass聲明存儲插件,用于自動創(chuàng)建PV。說白了就是創(chuàng)建PV的模板,其中有兩個重要部分:PV屬性和創(chuàng)建此PV所需要的插件。這樣PVC就可以按“Class”來匹配PV。可以為PV指定storageClassName屬性,標識PV歸屬于哪一個Class。
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: standard
# 這里加上體現(xiàn)了 "每個 StorageClass 都包含 provisioner、parameters 和 reclaimPolicy 字段"
#(provisioner是指定插件)
provisioner: kubernetes.io/aws-ebs
parameters:
type: gp2
reclaimPolicy: Retain
allowVolumeExpansion: true
mountOptions:
- debug
volumeBindingMode: Immediate
01 對于PV或者StorageClass只能對應(yīng)一種后端存儲
02 對于手動的情況,一般我們會創(chuàng)建很多的PV,等有PVC需要使用的時候就可以直接使用了
03 對于自動的情況,那么就由StorageClass來自動管理創(chuàng)建
04 如果Pod想要使用共享存儲,一般會在創(chuàng)建PVC,PVC中描述了想要什么類型的后端存儲、空間等,K8s從而會匹配對應(yīng)的PV,
如果沒有匹配成功,Pod就會處于Pending狀態(tài)。Pod中使用只需要像使用volumes一樣,指定名字就可以使用了
05 一個Pod可以使用多個PVC,一個PVC也可以給多個Pod使用 (pod和pvc的對應(yīng)關(guān)系是多對多,直接 claimName 匹配)
06 一個PVC只能綁定一個PV,一個PV只能對應(yīng)一種后端存儲 (pv和pvc的對應(yīng)關(guān)系是一對一,通過 accessModes 和 storage 匹配)
07 一個PV只能綁定一個NFS,但是一個NFS可以綁定多個PV
正是因為 “一個PVC只能綁定一個PV”,所以有了storageClass,storageClass解決的是 pv/pvc 一對一的關(guān)系,如果有 N 個pvc,這運維人員需要新建 N 個pv,但是有了storageClass,運維人員只需要建立好一個storageClass,就算有 N 個pvc,這個storageClass 也會自動創(chuàng)建 N個 pv 來給 N個 pvc使用。
有了StorageClass之后的PVC可以變成這樣 (新的pvc)
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: test-claim1
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 1Mi
storageClassName: nfs
StorageClass之所以能夠動態(tài)供給PV,是因為Provisioner,也就是Dynamic Provisioning,通過 storageClass 來關(guān)聯(lián) pv ,所以需要一個provisioner的鏡像,并將其作為deployment運行到k8s中。但是NFS這種類型,K8s中默認是沒有Provisioner插件的,需要自己創(chuàng)建,在github上現(xiàn)成的。
4.2 StorageClass實踐
這里準備了五個文件,如下:

一個圖看懂五個文件的關(guān)聯(lián)關(guān)系

好了,開始實踐 storageClass 根據(jù)pvc的連接自動創(chuàng)建pv(可以承受N個pvc的連接,因為可以自動創(chuàng)建N個pv),開始!!!
(1)準備好NFS服務(wù)器[并且確保nfs可以正常工作],創(chuàng)建持久化需要的目錄
mkdir -p /nfs/data/jack (這個目錄是pv要使用的 )
(2)根據(jù)rbac.yaml文件創(chuàng)建資源 【apply第一個yaml文件,是一個身份憑證】
kubectl apply -f rbac.yaml
(3)根據(jù)deployment.yaml文件創(chuàng)建資源 【apply第二個yaml文件,是一個來自github的插件 (第一步和第二步就是準備好這兩個插件)】
kubectl apply -f deployment.yaml
注意,需要修改deployment.yaml文件中的server,我這里NFS服務(wù)器部署在master節(jié)點上,所以部署
path: /nfs/data/jack
server: 192.168.100.150 (就是master節(jié)點 nfs服務(wù)器部署在m節(jié)點上)
(4)根據(jù)class.yaml創(chuàng)建資源 【apply第三個yaml文件,是storageClass,可以根據(jù)pvc的需要自動生成pv】
kubectl apply -f class.yaml
(5)根據(jù)pvc.yaml創(chuàng)建資源 【apply第四個yaml文件,是具體的pvc,因為storageClass已經(jīng)啟動了,所以現(xiàn)在可以啟動pvc】
kubectl apply -f my-pvc.yaml
kubectl get pvc
(6)根據(jù)nginx-pod創(chuàng)建資源 【apply第五個yaml文件,是具體的消費者pod,使用pv/pvc打通好的連接,直接通過claimName連接到pvc,就可以從 NFS服務(wù)器 取到數(shù)據(jù)】
kubectl apply -f nginx-pod.yaml
遠程服務(wù)器持久化存儲的另一種方式,通過StorageClass自動創(chuàng)建PV,啟動(五個配置文件)

測試 pod/nginx 取到了 NFS 服務(wù)器的文件
# 進行同步數(shù)據(jù)測試,進入容器檢查
kubectl exec -it nginx bash
cd /usr/jack


4.3 PV的狀態(tài)和回收策略
Available:表示當前的pv沒有被綁定
Bound:表示已經(jīng)被pvc掛載
Released:pvc沒有在使用pv, 需要管理員手工釋放pv
Failed:資源回收失敗
沒有被使用可以被使用 已經(jīng)被使用 沒有被使用不可以被使用 狀態(tài)失敗
Retain:表示刪除PVC的時候,PV不會一起刪除,而是變成Released狀態(tài)等待管理員手動清理
Recycle:在Kubernetes新版本就不用了,采用動態(tài)PV供給來替代
Delete:表示刪除PVC的時候,PV也會一起刪除,同時也刪除PV所指向的實際存儲空間NFS
注意:目前只有NFS和HostPath支持Recycle策略。AWS EBS、GCE PD、Azure Disk和Cinder支持Delete策略
五、小結(jié)
Kubernetes第六篇:k8s持久化存儲(親測可用),完成了。
天天打碼,天天進步!!