Kubernetes中的emptyDir存儲(chǔ)卷和節(jié)點(diǎn)存儲(chǔ)卷
Kubernetes支持存儲(chǔ)卷類型中,emptyDir存儲(chǔ)卷的生命周期與其所屬的Pod對(duì)象相同,它無(wú)法脫離Pod對(duì)象的生命周期提供數(shù)據(jù)存儲(chǔ)功能,因此emptyDir通常僅用于數(shù)據(jù)緩存或臨時(shí)存儲(chǔ)。不過(guò)基于emptyDir構(gòu)建的gitRepo存儲(chǔ)卷可以在Pod對(duì)象的生命周期起始時(shí)從響應(yīng)的Git倉(cāng)庫(kù)中復(fù)制相應(yīng)的數(shù)據(jù)文件到底層的emptyDir中,從而使得它具有了一定意義上的持久性。
emptyDir存儲(chǔ)卷
emptyDir存儲(chǔ)卷是Pod對(duì)象生命周期中的一個(gè)臨時(shí)目錄,類似于Docker上的docker掛載卷,在Pod對(duì)象啟動(dòng)時(shí)即被創(chuàng)建,而在Pod對(duì)象被移除時(shí)會(huì)被一并刪除。不具有持久能力的emptyDir存儲(chǔ)卷只能用于某些特殊場(chǎng)景中,例如,用一Pod內(nèi)的多個(gè)容器間文件的共享,或者作為容器數(shù)據(jù)的臨時(shí)存儲(chǔ)目錄用于數(shù)據(jù)緩存系統(tǒng)等。
emptyDir存儲(chǔ)卷則定義于.spec.volumes.emptyDir嵌套字段中,可用字段主要包含兩個(gè),具體如下:
?medium:此目錄所在存儲(chǔ)介質(zhì)的類型,可取值為default或Memory,默認(rèn)為default,表示使用節(jié)點(diǎn)的默認(rèn)存儲(chǔ)介質(zhì):Memory 表示基于RAM的臨時(shí)文件系統(tǒng)tmpfs,空間受于內(nèi)存,但性能非常好,通常用于為容器中的應(yīng)用提供緩存空間。
?sizeLimit:當(dāng)前存儲(chǔ)卷的空間限額,默認(rèn)值為 nil,表示不限制;不過(guò)在 medium 字段為Memory時(shí),建議定義此限額。
1.創(chuàng)建Pod對(duì)象配置清單
下面是一個(gè)使用了emptyDir存儲(chǔ)卷的簡(jiǎn)單示例,它保持于vol-emptydir.yaml配置文件:
apiVersion: v1
kind: Pod
metadata:
name: vol-emptydir-pod
spec:
volumes:
- name: html
emptyDir: { }
containers:
- name: nginx
image: nginx:latest
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
- name: pagegen
image: alpine
volumeMounts:
- name: html
mountPath: /html
command: [ "/bin/sh", "-c" ]
args: #定義循環(huán),每10秒向/html/文件中追加寫入當(dāng)前主機(jī)名和時(shí)間
- while true; do
echo $(hostname) $(date) >> /html/index.html;
sleep 10;
done
上面示例中定義的存儲(chǔ)卷名稱為html,掛載于容器nginx的 /usr/share/nginx/html目錄,以及容器pagegen的/html目錄。容器pagegen每隔10秒向存儲(chǔ)卷上的index.html文件中追加一行信息,而容器nginx中的nginx進(jìn)程則以其站點(diǎn)主頁(yè)。如下圖所示:

2.創(chuàng)建Pod對(duì)象
kubectl apply -f vol-emptydir.yaml
3.查看Pod狀態(tài) Pod對(duì)象的詳細(xì)信息中會(huì)顯示存儲(chǔ)卷的相關(guān)狀態(tài),包括其是否創(chuàng)建成功(在Events字段中輸出)、相關(guān)的類型及參數(shù)(在Volumes字段中輸出)以及容器中掛載狀態(tài)等信息(在Containers字段中輸出),如下面命令所示:
kubectl describe pods/vol-emptydir-pod
Containers:
nginx:
Mounts:
/usr/share/nginx/html from html (rw)
/var/run/secrets/kubernetes.io/serviceaccount from default-token-xxqkj (ro)
pagegen:
Command:
/bin/sh
-c
Args:
while true; do echo $(hostname) $(date) >> /html/index.html; sleep 10; done
Mounts:
/html from html (rw)
/var/run/secrets/kubernetes.io/serviceaccount from default-token-xxqkj (ro)
4.訪問(wèn)Pod中Nginx pagegen容器每隔10秒向 html/index.html 追加寫入信息,Nginx容器掛載的也是此臨時(shí)存儲(chǔ),所以Nginx的網(wǎng)頁(yè)文件也是從這里獲取。
curl http://172.20.1.18
vol-emptydir-pod Fri Jun 12 02:47:29 UTC 2020
vol-emptydir-pod Fri Jun 12 02:47:39 UTC 2020
vol-emptydir-pod Fri Jun 12 02:47:49 UTC 2020
vol-emptydir-pod Fri Jun 12 02:47:59 UTC 2020
vol-emptydir-pod Fri Jun 12 02:48:09 UTC 2020
vol-emptydir-pod Fri Jun 12 02:48:19 UTC 2020
5.進(jìn)入容器 以下分別進(jìn)入Nginx容器以及pagegen容器查看其掛載
通過(guò) -c 來(lái)指定容器名稱進(jìn)入指定容器
kubectl exec -it pods/vol-emptydir-pod -c nginx -- /bin/sh
# ls /usr/share/nginx/html
index.html
# head -3 /usr/share/nginx/html/index.html
vol-emptydir-pod Fri Jun 12 02:47:29 UTC 2020
vol-emptydir-pod Fri Jun 12 02:47:39 UTC 2020
vol-emptydir-pod Fri Jun 12 02:47:49 UTC 2020
進(jìn)入pagegen容器
kubectl exec -it pods/vol-emptydir-pod -c pagegen -- /bin/sh
/ # ls /html/
index.html
/ # head -3 /html/index.html
vol-emptydir-pod Fri Jun 12 02:47:29 UTC 2020
vol-emptydir-pod Fri Jun 12 02:47:39 UTC 2020
vol-emptydir-pod Fri Jun 12 02:47:49 UTC 2020
/ # ps aux
PID USER TIME COMMAND
1 root 0:00 /bin/sh -c while true; do echo $(hostname) $(date) >> /html/index.html; sleep 10; done
286 root 0:00 /bin/sh
303 root 0:00 sleep 10
304 root 0:00 ps aux
作為邊車 (sidecar)的容器pagegen,其每隔10秒生成一行信息追加到存儲(chǔ)卷上的index.html文件中,因此,通過(guò)主容器nginx的應(yīng)用訪問(wèn)到文件內(nèi)存也會(huì)處理不停的變動(dòng)中。另外,emptyDir存儲(chǔ)卷也可以基于RAM創(chuàng)建tmpfs文件系統(tǒng)的存儲(chǔ)卷,常用于為容器的應(yīng)用提高高性能緩存,下面是一個(gè)配置示例:
cat vol-emptydir.yaml
apiVersion: v1
kind: Pod
metadata:
name: vol-emptydir-pod
spec:
volumes:
- name: html
emptyDir:
medium: Memory #指定臨時(shí)存儲(chǔ)到內(nèi)存
sizeLimit: 256Mi #給予的內(nèi)存空間大小
containers:
- name: nginx
image: nginx:latest
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
- name: pagegen
image: alpine
volumeMounts:
- name: html
mountPath: /html
command: [ "/bin/sh", "-c" ]
args:
- while true; do
echo $(hostname) $(date) >> /html/index.html;
sleep 10;
done
emptyDir卷簡(jiǎn)單易用,但僅能用于臨時(shí)存儲(chǔ),另外還存在一些類型的存儲(chǔ)卷構(gòu)建在emptyDir之上,并額外提供了emptyDir沒(méi)有的功能。
節(jié)點(diǎn)存儲(chǔ)卷 hostPath
hostPath類型的存儲(chǔ)卷是指將工作節(jié)點(diǎn)上某文件系統(tǒng)的目錄或文件掛載于Pod中的一種存儲(chǔ)卷,它可獨(dú)立于Pod資源的生命周期,因而具有持久性。但它是工作節(jié)點(diǎn)本地的存儲(chǔ)空間,僅適用于特定情況下的存儲(chǔ)卷使用需求,例如,將工作節(jié)點(diǎn)上的文件系統(tǒng)關(guān)聯(lián)為Pod的存儲(chǔ)卷,從而使得容器訪問(wèn)接待您文件系統(tǒng)上的數(shù)據(jù)。這一點(diǎn)在運(yùn)行有管理任務(wù)的系統(tǒng)級(jí)Pod資源需要訪問(wèn)節(jié)點(diǎn)上的文件時(shí)比較有用。
配置hostPath存儲(chǔ)卷的嵌套字段共有兩個(gè):一個(gè)是用于指定工作節(jié)點(diǎn)上的目錄路徑的必須按字段path 一個(gè)是指定存儲(chǔ)卷類型的type,它支持使用的卷類型包含如下幾種:
?DirectoryOrCreate:指定的路徑不存在時(shí)自動(dòng)將其創(chuàng)建為權(quán)限是0755的空目錄,屬主屬組均為kubelet。
?Directory:必須存在的目錄路徑
?FileOrCreate:指定的路徑不存在時(shí)自動(dòng)將其創(chuàng)建為權(quán)限0644的空文件,屬主和屬組同是kubelet。
?File:必須存在的文件路徑
?Socket:必須存在的Socket文件路徑
?CharDevice:必須存在的字符設(shè)備文件路徑
?BlockDevice:必須存在的塊設(shè)備文件路徑

下面是定義在vo-hostpath.yaml配置文件中的Pod資源,它運(yùn)行著日志收集代理應(yīng)用filebeat,負(fù)責(zé)收集工作節(jié)點(diǎn)及容器相關(guān)的日志信息發(fā)往Redis服務(wù)器,它使用了三個(gè)hostPath類型的存儲(chǔ)卷:
1.創(chuàng)建資源配置清單
apiVersion: v1
kind: Pod
metadata:
name: vo-hostpath-pod
spec:
containers:
- name: filebeat
image: ikubernetes/filebeat:5.6.7-alpine
env: #定義變量
- name: REDIS_HOST #變量名
value: redis.ilinux.io:6379 #變量值
- name: LOG_LEVEL #變量明
value: info #變量值
volumeMounts: #卷掛載配置
- name: varlog #掛載名稱為varlog的卷
mountPath: /var/log #掛載到容器中的/var/log目錄中
- name: socket #掛載名稱為socket的卷
mountPath: /var/run/docker.sock#掛載到容器中的/var/run/docker.sock
- name: varlibdockercontainers #掛載名稱為varlibdockercontainers的卷
mountPath: /var/lib/docker/containers#掛載到容器中的/var/lib/docker/containers目錄中
readOnly: true #為只讀掛載
volumes: #卷配置
- name: varlog #自定義的卷名稱
hostPath: #節(jié)點(diǎn)路徑配置
path: /var/log #在節(jié)點(diǎn)上的路徑
type: DirectoryOrCreate #節(jié)點(diǎn)上不存在/var/log目錄時(shí),則自動(dòng)創(chuàng)建權(quán)限為0755的目錄,屬性信息為kubelet用戶
- name: varlibdockercontainers
hostPath:
path: /var/lib/docker/containers
type: Directory
- name: socket
hostPath:
path: /var/run/docker.sock
type: Socket #節(jié)點(diǎn)上必須存在/var/run/docker.sock,否則創(chuàng)建Pod失敗
2.創(chuàng)建Pod對(duì)象
kubectl apply -f vo-hostpath.yaml
3.查看Pod對(duì)象詳細(xì)信息 如下命令可以到Pod的掛載信息
kubectl describe pods/vo-hostpath-pod | grep -A 12 Volumes
Volumes:
varlog:
Type: HostPath (bare host directory volume)
Path: /var/log
HostPathType:
varlibdockercontainers:
Type: HostPath (bare host directory volume)
Path: /var/lib/docker/containers
HostPathType:
socket:
Type: HostPath (bare host directory volume)
Path: /var/run/docker.sock
HostPathType:
如下這臺(tái)Pod運(yùn)行在了Node02節(jié)點(diǎn)之上,那么就會(huì)把Node02上的 /var/log 、/var/lib/docker/containers目錄以及 /var/run/docker.sock文件掛載至我們創(chuàng)建的Pod之中。
kubectl get pods -o wide | grep vo-hostpath-pod
vo-hostpath-pod 1/1 Running 0 3m37s 172.20.2.28 k8s-node02 <none> <none>
4.進(jìn)入Pod查看掛載信息
kubectl exec -it pods/vo-hostpath-pod -- /bin/sh
#查看/var/log
/ # ls /var/log
alternatives.log chrony kern.log syslog.2.gz vmware-vmsvc-root.1.log
alternatives.log.1 cloud-init-output.log kern.log.1 syslog.3.gz vmware-vmsvc-root.2.log
apt cloud-init.log kern.log.2.gz syslog.4.gz vmware-vmsvc-root.3.log
auth.log containers kern.log.3.gz syslog.5.gz vmware-vmsvc-root.log
auth.log.1 dist-upgrade kern.log.4.gz syslog.6.gz vmware-vmtoolsd-root.log
auth.log.2.gz dpkg.log landscape syslog.7.gz wtmp
auth.log.3.gz dpkg.log.1 lastlog tallylog wtmp.1
auth.log.4.gz dpkg.log.2.gz lxd unattended-upgrades
bootstrap.log faillog pods vmware-network.1.log
btmp installer syslog vmware-network.2.log
btmp.1 journal syslog.1 vmware-network.log
#查看/var/lib/docker/containers信息
/ # ls /var/lib/docker/containers/
222ff7ab4b939691d4690ebd353e4dae39782d48dba190f6473d02f65e35e9c5 9b362d8f03d2f87573487a8d6a266c1a77b6e2cfb28654ba5a3016008155564f
2ddb2bd4c2dfd44b48a430502e8f0479651ac2084b14070c7bd6f128907e6d27 d2e2af23b3a406d941a1f19a989c6a529b7cfda32a75579ff171148e3bce771d
2f0c31b8e6fff99953a096af8153b37b572f71a3e98a9e09665486b6ca6d940f e0d8e9913767ef45c700648f20f025440f1313be242b6f0cf3577b1b92d61acb
31baeb1aef75acf16544042add63293e8547008c1ae1d40ab62f8fd24fa203a4 ee09c6588feb6665d24f61a887fe4a9d4df366625f80e9b7b0520c6066b3a754
3dbada0509671af1193b39b86f72d1ed9022914f7ba7886bd975cfa70c554559 ef1fcc1b0de6817b2d2c8b81a187e72a93c960c816ee118bf5ba9d1a07fff7d6
47686a866a3e9f1e0b82bb582072c612b95ea0d1c68951ea44b3f751eb49dbcb f52a7a55801bec13b26f2c02fbc5c32cb758f690de5480ff246f379ebbb3fac7
6bc85638f22115f3479ef025b94159a7d8e5e5988fb508c28d118f510c767e0f f6b5e6bc12ba8121d2aceca137eaf31929d46664648154b45800697a8bd5a23c
9afc7bb18dc7d858f514ec001ad47c6fd6d5ac67f25aa0e777c4762b9ccfaf45
#查看/var/run/docker.sock文件
/ # ls -lrth /var/run/docker.sock
srw-rw---- 1 root ping 0 May 8 03:27 /var/run/docker.sock
/ # exit;
這類Pod資源通常受控于daemonset類型的Pod控制器,它運(yùn)行于集群中的每個(gè)工作節(jié)點(diǎn)之上,負(fù)責(zé)收集工作節(jié)點(diǎn)上系統(tǒng)級(jí)的相關(guān)逐句,因此使用hostPath存儲(chǔ)卷也是理所應(yīng)當(dāng)?shù)摹?/p>
讀者在創(chuàng)建上述Pod資源時(shí),如果有可用的Redis服務(wù)器,則可通過(guò)REDIS_HOST傳遞給Pod資源,待其Ready之后即可通過(guò)Redis服務(wù)器查看到由其發(fā)送的日志信息。在filebeat應(yīng)用架構(gòu)中。這些日志信息會(huì)發(fā)到Elasticsearch,并通過(guò)Kibana進(jìn)行展示。
另外,使用hostPath存儲(chǔ)卷時(shí)需要注意到,不同節(jié)點(diǎn)上的文件或許并不完全相同,于是,那些要求事先必須存在的文件或目錄的滿足狀態(tài)也可能會(huì)有所不同;另外基于資源可用狀態(tài)的調(diào)度器Pod時(shí),hostPath資源的可用性狀態(tài)不會(huì)被考慮在內(nèi);再者,在節(jié)點(diǎn)中創(chuàng)建的文件或目錄默認(rèn)僅有root可寫,若期望容器內(nèi)的進(jìn)程擁有寫權(quán)限,則要么將它們運(yùn)行為特權(quán)容器,要么修改節(jié)點(diǎn)上的目錄權(quán)限。
那些并非執(zhí)行系統(tǒng)級(jí)管理任務(wù)的且不受控于Daemonset控制器的無(wú)狀態(tài)應(yīng)用在Pod資源被重新調(diào)度至其它節(jié)點(diǎn)運(yùn)行時(shí),此前創(chuàng)建的文件或目錄大多數(shù)都不會(huì)存在。因此hostPath存儲(chǔ)卷雖然能持久保存數(shù)據(jù),但對(duì)被調(diào)度器按需調(diào)度的應(yīng)用來(lái)說(shuō)并不適用,這時(shí)需要用到的是獨(dú)立于集群節(jié)點(diǎn)的持久性存儲(chǔ)卷、即網(wǎng)絡(luò)存儲(chǔ)卷。
好啦!今天的分享到這里就結(jié)束了,希望大家持續(xù)關(guān)注馬哥教育官網(wǎng),每天都會(huì)有大量?jī)?yōu)質(zhì)內(nèi)容與大家分享!
文章來(lái)源于網(wǎng)絡(luò),侵刪!