數據卷-掛載
掛載是指將定義在 Pod 中的數據卷關聯到容器,同一個 Pod 中的同一個數據卷可以被掛載到該 Pod 中的多個容器上。
數據卷內子路徑
有時候我們需要在同一個 Pod 的不同容器間共享數據卷。使用 volumeMounts.subPath
屬性,可以使容器在掛載數據卷時指向數據卷內部的一個子路徑,而不是直接指向數據卷的根路徑。
下面的例子中,一個 LAMP(Linux Apache Mysql PHP)應用的 Pod 使用了一個共享數據卷,HTML 內容映射到數據卷的 html
目錄,數據庫的內容映射到了 mysql
目錄:
apiVersion: v1
kind: Pod
metadata:
name: my-lamp-site
spec:
containers:
- name: mysql
image: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: "rootpasswd"
volumeMounts:
- mountPath: /var/lib/mysql
name: site-data
subPath: mysql
readOnly: false
- name: php
image: php:7.0-apache
volumeMounts:
- mountPath: /var/www/html
name: site-data
subPath: html
readOnly: false
volumes:
- name: site-data
persistentVolumeClaim:
claimName: my-lamp-site-data
通過環境變量指定數據卷內子路徑
FEATURE STATE: Kubernetes v1.15
beta
使用 volumeMounts.subPathExpr
字段,可以通過容器的環境變量指定容器內路徑。使用此特性時,必須啟用 VolumeSubpathEnvExpansion
feature gate
(自 Kubernetes v1.15 開始,是默認啟用的。)
同一個 volumeMounts 中 subPath
字段和 subPathExpr
字段不能同時使用。
如下面的例子,該 Pod 使用 subPathExpr
在 hostPath 數據卷 /var/log/pods
中創建了一個目錄 pod1
(該參數來自於Pod的名字)。此時,宿主機目錄 /var/log/pods/pod1
掛載到了容器的 /logs
路徑:
apiVersion: v1
kind: Pod
metadata:
name: pod1
spec:
containers:
- name: container1
env:
- name: POD_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
image: busybox
command: [ "sh", "-c", "while [ true ]; do echo 'Hello'; sleep 10; done | tee -a /logs/hello.txt" ]
volumeMounts:
- name: workdir1
mountPath: /logs
subPathExpr: $(POD_NAME)
readOnly: false
restartPolicy: Never
volumes:
- name: workdir1
hostPath:
path: /var/log/pods
# 容器內路徑
mountPath 數據卷被掛載到容器的路徑,不能包含 :
# 權限
容器對掛載的數據卷是否具備讀寫權限,如果 readOnly
為 true
,則只讀,否則可以讀寫(為 false
或者不指定)。默認為 false
# 掛載傳播
數據卷的掛載傳播(Mount Propagation)由 Pod 的 spec.containers[*].volumeMounts.mountPropagation
字段控制。可選的取值有:
- None: 默認值。在數據卷被掛載到容器之后,此數據卷不會再接受任何后續宿主機或其他容器掛載到該數據卷對應目錄下的子目錄的掛載。同樣的,在容器中向該數據卷對應目錄掛載新目錄時,宿主機也不能看到。對應 Linux 的
private
mount propagation 選項 Linux內核文檔
- HostToContainer:在數據卷被掛載到容器之后,宿主機向該數據卷對應目錄添加掛載時,對容器是可見的。對應 Linux 的
rslave
mount propagation 選項 Linux內核文檔
- Bidirectional:在數據卷被掛載到容器之后,宿主機向該數據卷對應目錄添加掛載時,對容器是可見的;同時,從容器中向該數據卷創建掛載,同樣也對宿主機可見。對應 Linux 的
rshared
mount propagation 選項 Linux內核文檔
WARNING
Bidirectional mount propagation 選項隱藏風險。如果在容器內進行不合適的掛載,可能影響宿主機的操作系統正常執行,因此,只有 privileged 容器才可以使用該選項。使用此選項時,建議對 Linux 內核的行為有所熟悉。此外,使用 Bidirectional 選項時,任何由 Pod 中容器在對應數據卷目錄創建的掛載必須在容器終止時銷毀(umounted)。
額外配置
在部分系統中(CoreOS、RedHat/Centos、Ubuntu),Docker 的 mount share 選項必須事先配置好,步驟如下:
使用yum方式安裝的docker,默認的docker.service路徑是:/usr/lib/systemd/system/docker.service
或者使用這個方法查看:systemctl status docker.service
- 編輯 Docker 的 systemd service 文件,將
MountFlags
設定如下:
MountFlags=shared
或者移除 MountFlags=slave
重啟 Docker 守護進程:
sudo systemctl daemon-reload
sudo systemctl restart docker