環(huán)境說明:
創(chuàng)新互聯(lián)是一家專注于網(wǎng)站建設(shè)、成都網(wǎng)站制作與策劃設(shè)計(jì),巴東網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)10余年,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:巴東等地區(qū)。巴東做網(wǎng)站價(jià)格咨詢:18982081108
主機(jī)名 | 操作系統(tǒng)版本 | ip | docker version | kubelet version | 配置 | 備注 |
---|---|---|---|---|---|---|
master | Centos 7.6.1810 | 172.27.9.131 | Docker 18.09.6 | V1.14.2 | 2C2G | master主機(jī) |
node01 | Centos 7.6.1810 | 172.27.9.135 | Docker 18.09.6 | V1.14.2 | 2C2G | node節(jié)點(diǎn) |
node02 | Centos 7.6.1810 | 172.27.9.136 | Docker 18.09.6 | V1.14.2 | 2C2G | node節(jié)點(diǎn) |
centos7 | Centos 7.3.1611 | 172.27.9.181 | × | × | 1C1G | nfs服務(wù)器 |
?
k8s集群部署詳見:Centos7.6部署k8s(v1.14.2)集群
k8s學(xué)習(xí)資料詳見:基本概念、kubectl命令和資料分享
k8s高可用集群部署詳見:Centos7.6部署k8s v1.16.4高可用集群(主備模式)
?
??Kubernetes的卷是pod的一個(gè)組成部分,因此像容器一樣在pod的規(guī)范中就定義了。它們不是獨(dú)立的Kubernetes對(duì)象,也不能單獨(dú)創(chuàng)建或刪除。pod中的所有容器都可以使用卷,但必須先將它掛載在每個(gè)需要訪問它的容器中。在每個(gè)容器中,都可以在其文件系統(tǒng)的任意位置掛載卷。
??容器磁盤上的文件的生命周期是短暫的,這就使得在容器中運(yùn)行重要應(yīng)用時(shí)會(huì)出現(xiàn)一些問題。首先,當(dāng)容器崩潰時(shí),kubelet會(huì)重啟它,但是容器中的文件將丟失——容器以干凈的狀態(tài)(鏡像最初的狀態(tài))重新啟動(dòng)。其次,在 Pod 中同時(shí)運(yùn)行多個(gè)容器時(shí),這些容器之間通常需要共享文件。Kubernetes 中的 Volume 抽象就很好的解決了這些問題。
目前,Kubernetes支持以下Volume 類型:
本文將對(duì)emptyDir,hostPath,共享存儲(chǔ)NFS,PV及PVC分別進(jìn)行測試實(shí)踐。
??emptyDir是最基礎(chǔ)的Volume類型,用于存儲(chǔ)臨時(shí)數(shù)據(jù)的簡單空目錄。如果Pod設(shè)置了emptyDir類型Volume,Pod被分配到Node上時(shí)候,會(huì)創(chuàng)建emptyDir,只要Pod運(yùn)行在Node上,emptyDir都會(huì)存在(容器掛掉不會(huì)導(dǎo)致emptyDir丟失數(shù)據(jù)),但是如果Pod從Node上被刪除(Pod被刪除,或者Pod發(fā)生遷移),emptyDir也會(huì)被刪除,并且永久丟失。
?
??下面將用emptyDir卷實(shí)現(xiàn)在同一pod中兩個(gè)容器之間的文件共享
[root@master ~]# more emptyDir-pod.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
app: prod #pod標(biāo)簽
name: emptydir-fortune
spec:
containers:
- image: loong576/fortune
name: html-generator
volumeMounts: #名為html的卷掛載至容器的/var/htdocs目錄
- name: html
mountPath: /var/htdocs
- image: nginx:alpine
name: web-server
volumeMounts: #掛載相同的卷至容器/usr/share/nginx/html目錄且設(shè)置為只讀
- name: html
mountPath: /usr/share/nginx/html
readOnly: true
ports:
- containerPort: 80
protocol: TCP
volumes:
- name: html #卷名為html的emptyDir卷同時(shí)掛載至以上兩個(gè)容器
emptyDir: {}
[root@master ~]# kubectl apply -f emptyDir-pod.yaml
pod/emptydir-fortune created
[root@master ~]# kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
emptydir-fortune 2/2 Running 0 9s 10.244.2.140 node02 <none> <none>
創(chuàng)建pod emptydir-fortune,該pod有兩個(gè)容器,同時(shí)掛載emptyDir卷,容器html-generator向卷中寫入隨機(jī)內(nèi)容,通過訪問容器web-server驗(yàn)證是否實(shí)現(xiàn)文件的共享。
root@master ~]# more Dockerfile
[root@master ~]# more fortune/Dockerfile
FROM ubuntu:latest
RUN apt-get update ; apt-get -y install fortune
ADD fortuneloop.sh /bin/fortuneloop.sh
E*TRYPOINT /bin/fortuneloop.sh
該鏡像的base鏡像為ubuntu,鏡像啟動(dòng)時(shí)會(huì)執(zhí)行fortuneloop.sh腳本
?
fortuneloop.sh腳本:
[root@master ~]# more fortuneloop.sh
#!/bin/bash
trap "exit" SIGINT
mkdir /var/htdocs
while :
do
echo $(date) Writing fortune to /var/htdocs/index.html
/usr/games/fortune > /var/htdocs/index.html
sleep 10
done
該腳本主要是每10秒鐘輸出隨機(jī)短語至index.html文件中。
[root@master ~]# more service-fortune.yaml
apiVersion: v1
kind: Service
metadata:
name: my-service #service名
spec:
type: NodePort
selector:
app: prod #pod標(biāo)簽,由此定位到pod emptydir-fortune
ports:
- protocol: TCP
nodePort: 30002 #節(jié)點(diǎn)監(jiān)聽端口,暴露靜態(tài)端口30002對(duì)外提供服務(wù)
port: 8881 #ClusterIP監(jiān)聽的端口
targetPort: 80 #容器端口
sessionAffinity: ClientIP #是否支持Session,同一個(gè)客戶端的訪問請(qǐng)求都轉(zhuǎn)發(fā)到同一個(gè)后端Pod
[root@master ~]# kubectl apply -f service-fortune.yaml
service/my-service created
[root@master ~]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 3d17h
my-service NodePort 10.102.191.57 <none> 8881:30002/TCP 9s
[root@master ~]# curl 10.102.191.57:8881
Writing is easy; all you do is sit staring at the blank sheet of paper until
drops of blood form on your forehead.
-- Gene Fowler
[root@master ~]# curl 172.27.9.135:30002
Don't Worry, Be Happy.
-- Meher Baba
結(jié)論:
容器nginx成功的讀取到了容器fortune寫入存儲(chǔ)的內(nèi)容,emptyDir卷可以實(shí)現(xiàn)容器間的文件共享。
??hostPath允許掛載Node上的文件系統(tǒng)到Pod里面去。如果Pod需要使用Node上的文件,可以使用hostPath。在同一個(gè)節(jié)點(diǎn)上運(yùn)行并在其hostPath卷中使用相同路徑的pod可以看到相同的文件。
在node節(jié)點(diǎn)上創(chuàng)建掛載目錄,master和各node上分別執(zhí)行如下操作
[root@master ~]# mkdir /data && cd /data && echo `hostname` > index.html
[root@master ~]# more hostPath-pod.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
app: prod
name: hostpath-nginx
spec:
containers:
- image: nginx
name: nginx
volumeMounts:
- mountPath: /usr/share/nginx/html #容器掛載點(diǎn)
name: nginx-volume #掛載卷nginx-volume
volumes:
- name: nginx-volume #卷名
hostPath:
path: /data #準(zhǔn)備掛載的node上的文件系統(tǒng)
[root@master ~]# kubectl apply -f hostPath-pod.yaml
pod/hostpath-nginx created
[root@master ~]# kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
emptydir-fortune 2/2 Running 0 40m 10.244.2.140 node02 <none> <none>
hostpath-nginx 1/1 Running 0 16s 10.244.1.140 node01 <none> <none>
[root@master ~]# curl 10.244.1.140
node01
結(jié)論:
pod運(yùn)行在node01上,訪問的內(nèi)容為'node01',為掛載的文件系統(tǒng)/data下index.html內(nèi)容,容器成功讀取到掛載的節(jié)點(diǎn)文件系統(tǒng)里的內(nèi)容。
僅當(dāng)需要在節(jié)點(diǎn)上讀取或?qū)懭胂到y(tǒng)文件時(shí)才使用hostPath , 切勿使用它們來持久化跨pod的數(shù)據(jù)。
??NFS是Network File System的縮寫,即網(wǎng)絡(luò)文件系統(tǒng)。Kubernetes中通過簡單地配置就可以掛載NFS到Pod中,而NFS中的數(shù)據(jù)是可以永久保存的,同時(shí)NFS支持同時(shí)寫操作。
??emptyDir可以提供不同容器間的文件共享,但不能存儲(chǔ);hostPath可以為不同容器提供文件的共享并可以存儲(chǔ),但受制于節(jié)點(diǎn)限制,不能跨節(jié)點(diǎn)共享;這時(shí)需要網(wǎng)絡(luò)存儲(chǔ) (NAS),即既可以方便存儲(chǔ)容器又可以從任何集群節(jié)點(diǎn)訪問,本文以NFS為例做測試。
nfs搭建詳見:Centos7下NFS服務(wù)器搭建及客戶端連接配置
?
完成nfs服務(wù)器搭建和客戶端nfs軟件安裝安裝后,可在master和各node節(jié)點(diǎn)檢查nfs服務(wù)是否正常
[root@master ~]# showmount -e 172.27.9.181
Export list for 172.27.9.181:
/backup 172.27.9.0/24
master和node01、node02節(jié)點(diǎn)都執(zhí)行showmount命令,用于驗(yàn)證nfs服務(wù)是否正常,/backup為nfs服務(wù)器對(duì)外提供的共享目錄。
本文測試的NFS內(nèi)容:
[root@master ~]# more mongodb-pod-nfs.yaml
apiVersion: v1
kind: Pod
metadata:
name: mongodb-nfs
spec:
containers:
- image: mongo
name: mongodb
volumeMounts:
- name: nfs-data #掛載的卷名,與上面的mongodb-data保持一致
mountPath: /data/db #MongoDB數(shù)據(jù)存放的路徑
ports:
- containerPort: 27017
protocol: TCP
volumes:
- name: nfs-data #卷名
nfs:
server: 172.27.9.181 #nfs服務(wù)器ip
path: /backup #nfs服務(wù)器對(duì)外提供的共享目錄
[root@master ~]# kubectl apply -f mongodb-pod-nfs.yaml
pod/mongodb-nfs created
[root@master ~]# kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mongodb-nfs 1/1 Running 0 23s 10.244.2.142 node02 <none> <none>
注意此時(shí)pod的ip為10.244.2.142
[root@master ~]# kubectl exec -it mongodb-nfs mongo
> use loong
switched to db loong
> db.foo.insert({name:'loong576'})
WriteResult({ "nInserted" : 1 })
切換至db loong,插入JSON文檔(name:'loong576')
> db.foo.find()
{ "_id" : ObjectId("5d6e17b018651a21e0063641"), "name" : "loong576" }
[root@master ~]# kubectl delete pod mongodb-nfs
pod "mongodb-nfs" deleted
[root@master ~]# kubectl apply -f mongodb-pod-nfs.yaml
pod/mongodb-nfs created
[root@master ~]# kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mongodb-nfs 1/1 Running 0 22s 10.244.2.143 node02 <none> <none>
刪除pod mongodb-nfs并重建,此時(shí)podip變?yōu)?0.244.2.143,再次訪問MongoDB驗(yàn)證之前寫入的文檔是否還存在。
[root@master ~]# kubectl exec -it mongodb-nfs mongo
> use loong
switched to db loong
> db.foo.find()
{ "_id" : ObjectId("5d6e17b018651a21e0063641"), "name" : "loong576" }
即使pod被刪除重建仍然能訪問共享數(shù)據(jù)。
結(jié)論:
?? PersistentVolume (持久卷, 簡稱 PV)和Persistent VolumeClaim(持久卷聲明,簡稱 PVC)使得K8s集群具備了存儲(chǔ)的邏輯抽象能力,使得在配置Pod的邏輯里可以忽略對(duì)實(shí)際后臺(tái)存儲(chǔ)技術(shù)的配置,而把這項(xiàng)配置的工作交給PV的配置者,即集群的管理者。存儲(chǔ)的PV和PVC的這種關(guān)系,跟計(jì)算的Node和Pod的關(guān)系是非常類似的;PV和Node是資源的提供者,根據(jù)集群的基礎(chǔ)設(shè)施變化而變化,由K8s集群管理員配置;而PVC和Pod是資源的使用者,根據(jù)業(yè)務(wù)服務(wù)的需求變化而變化,由K8s集群的使用者即服務(wù)的管理員來配置。
?
??當(dāng)集群用戶需要在其pod中使用持久化存儲(chǔ)時(shí),他們首先創(chuàng)建PVC清單,指定所需要的最低容量要求和訪問模式,然后用戶將待久卷聲明清單提交給Kubernetes API服務(wù)器,Kubernetes將找到可匹配的PV并將其綁定到PVC。PVC可以當(dāng)作pod中的一個(gè)卷來使用,其他用戶不能使用相同的PV,除非先通過刪除PVC綁定來釋放。
nfs服務(wù)器共享目錄配置:
[root@centos7 ~]# exportfs
/backup/v1 172.27.9.0/24
/backup/v2 172.27.9.0/24
/backup/v3 172.27.9.0/24
master和各node節(jié)點(diǎn)檢查nfs配置:
[root@master ~]# showmount -e 172.27.9.181
Export list for 172.27.9.181:
/backup/v3 172.27.9.0/24
/backup/v2 172.27.9.0/24
/backup/v1 172.27.9.0/24
[root@master ~]# more pv-nfs.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv001
spec:
capacity:
storage: 2Gi #指定PV容量為2G
volumeMode: Filesystem #卷模式,默認(rèn)為Filesystem,也可設(shè)置為'Block'表示支持原始?jí)K設(shè)備
accessModes:
- ReadWriteOnce #訪問模式,該卷可以被單個(gè)節(jié)點(diǎn)以讀/寫模式掛載
persistentVolumeReclaimPolicy: Retain #回收策略,Retain(保留),表示手動(dòng)回收
storageClassName: nfs #類名,PV可以具有一個(gè)類,一個(gè)特定類別的PV只能綁定到請(qǐng)求該類別的PVC
nfs: #指定NFS共享目錄和IP信息
path: /backup/v1
server: 172.27.9.181
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv002
spec:
capacity:
storage: 2Gi #指定PV容量為2G
volumeMode: Filesystem #卷模式,默認(rèn)為Filesystem,也可設(shè)置為'Block'表示支持原始?jí)K設(shè)備
accessModes:
- ReadOnlyMany #訪問模式,該卷可以被多個(gè)節(jié)點(diǎn)以只讀模式掛載
persistentVolumeReclaimPolicy: Retain #回收策略,Retain(保留),表示手動(dòng)回收
storageClassName: nfs #類名,PV可以具有一個(gè)類,一個(gè)特定類別的PV只能綁定到請(qǐng)求該類別的PVC
nfs: #指定NFS共享目錄和IP信息
path: /backup/v2
server: 172.27.9.181
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv003
spec:
capacity:
storage: 1Gi #指定PV容量為1G
volumeMode: Filesystem #卷模式,默認(rèn)為Filesystem,也可設(shè)置為'Block'表示支持原始?jí)K設(shè)備
accessModes:
- ReadWriteOnce #訪問模式,該卷可以被單個(gè)節(jié)點(diǎn)以讀/寫模式掛載
persistentVolumeReclaimPolicy: Retain #回收策略,Retain(保留),表示手動(dòng)回收
storageClassName: nfs #類名,PV可以具有一個(gè)類,一個(gè)特定類別的PV只能綁定到請(qǐng)求該類別的PVC
nfs: #指定NFS共享目錄和IP信息
path: /backup/v3
server: 172.27.9.181
[root@master ~]# kubectl apply -f pv-nfs.yaml
persistentvolume/pv001 created
persistentvolume/pv002 created
persistentvolume/pv003 created
[root@master ~]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLA*S REASON AGE
pv001 2Gi RWO Retain Available nfs 26s
pv002 2Gi ROX Retain Available nfs 26s
pv003 1Gi RWO Retain Available nfs 26s
創(chuàng)建pv001、pv002、pv003,分別對(duì)應(yīng)nfs的共享目錄/backup/v1、/backup/v2、/backup/v2。
卷可以處于以下的某種狀態(tài):
?
PV的訪問模式有三種:
PV不屬于任何命名空間, 它跟節(jié)點(diǎn)一樣是集群層面的資源,區(qū)別于pod和PVC。
[root@master ~]# more pvc-nfs.yaml
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: mypvc #聲明的名稱,當(dāng)做pod的卷使用時(shí)會(huì)用到
spec:
accessModes:
- ReadWriteOnce #訪問卷模式,篩選PV條件之一
volumeMode: Filesystem #卷模式,與PV保持一致,指示將卷作為文件系統(tǒng)或塊設(shè)備使用
resources: #聲明可以請(qǐng)求特定數(shù)量的資源,篩選PV條件之一
requests:
storage: 2Gi
storageClassName: nfs #請(qǐng)求特定的類,與PV保持一致,否則無法完成綁定
[root@master ~]# kubectl apply -f pvc-nfs.yaml
persistentvolumeclaim/mypvc created
[root@master ~]# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
mypvc Bound pv001 2Gi RWO nfs 22s
創(chuàng)建PVC mypvc,訪問卷模式為ReadWriteOnce,大小為2G;WO、ROX、RWX、RWO表示可以同時(shí)使用卷的工作節(jié)點(diǎn)的數(shù)量而并非pod的數(shù)量。
PVC篩選條件:
PV | accessModes | storage |
---|---|---|
pv001 | √ | √ |
pv002 | × | √ |
pv003 | √ | × |
PV查看:
[root@master ~]# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLA*S REASON AGE
pv001 2Gi RWO Retain Bound default/mypvc nfs 12m
pv002 2Gi ROX Retain Available nfs 12m
pv003 1Gi RWO Retain Available nfs 12m
pv001被選中,符合PVC定義,pv002訪問模式不匹配,pv003大小不匹配。
[root@master ~]# more mongodb-pod-pvc.yaml
apiVersion: v1
kind: Pod
metadata:
name: mongodb-pvc
spec:
containers:
- image: mongo
name: mongodb
volumeMounts:
- name: pvc-data
mountPath: /data/db
ports:
- containerPort: 27017
protocol: TCP
volumes:
- name: pvc-data
persistentVolumeClaim:
claimName: mypvc #與pvc中聲明的name保持一致
[root@master ~]# kubectl apply -f mongodb-pod-pvc.yaml
pod/mongodb-pvc created
[root@master ~]# kubectl get po -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
mongodb-pvc 1/1 Running 0 16s 10.244.2.144 node02 <none> <none>
創(chuàng)建pod mongodb-pvc,使用PVC mypvc,測試同四-4中的nfs共享存儲(chǔ)測試,不再贅述。
?
?
本文所有腳本和配置文件已上傳:k8s實(shí)踐(七):存儲(chǔ)卷和數(shù)據(jù)持久化(Volumes and Persistent Storage)
?
?
我的博客即將同步至騰訊云+社區(qū),邀請(qǐng)大家一同入駐:https://cloud.tencent.com/developer/support-plan?invite_code=1xq751tgzgk0m
?
?
分享名稱:k8s實(shí)踐(七):存儲(chǔ)卷和數(shù)據(jù)持久化(VolumesandPersistentStorage)
當(dāng)前鏈接:http://jinyejixie.com/article28/podscp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App開發(fā)、網(wǎng)站策劃、營銷型網(wǎng)站建設(shè)、外貿(mào)建站、標(biāo)簽優(yōu)化、小程序開發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)