tl; dr:我们如何将 pods 中的现有目录安装到PV,从而使我们能够持久化将要生成的数据?
目前,我们正在运行具有Azure Disk和Azure File集成的K8s 1.16.7。我们有一个镜像,其中包含一些我们希望存储在PV上以保持持久性的目录。在Docker中,这很容易处理,因为容器会将数据写入主机安装中。有谁知道如何在Kubernetes中解决此问题?现在,当我们执行此操作时,容器将启动,但是目录(例如:/etc/nginx/conf.d/作为装入PV的目录)为空,并且pod崩溃了。
例:
在下面的容器中,/ usr / src / app充满了hello-world应用程序。在下面的文件部署之后,容器由于无法在/ usr / src / app中找到任何内容而崩溃(由于PV安装,目录为空)。
---
apiVersion: v1
kind: Namespace
metadata:
name: testwebsite
labels:
environment: development
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: normal
namespace: testwebsite
provisioner: disk.csi.azure.com
parameters:
storageaccounttype: Standard_LRS
kind: Managed
resourceGroup: resourcegroup
cachingmode: None
mountOptions:
- dir_mode=0777
- file_mode=0777
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-azurefile
namespace: testwebsite
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: normal
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-kubernetes
namespace: testwebsite
spec:
replicas: 1
selector:
matchLabels:
app: hello-kubernetes
template:
metadata:
labels:
app: hello-kubernetes
spec:
containers:
- name: hello-kubernetes
image: paulbouwer/hello-kubernetes:1.8
ports:
- containerPort: 8080
volumeMounts:
- name: azurefile01
mountPath: "/usr/src/app"
volumes:
- name: azurefile01
persistentVolumeClaim:
claimName: pvc-azurefile
目标:将容器内/ usr / src / app中的数据写入PV。提前谢谢!
最佳答案
据我了解,您的要求是,每次创建Pod
时,您都希望它的/usr/src/app
包含应用程序到目前为止生成并永久存储在PersistentVolume
中的数据,以及/usr/src/app
的原始内容是您的paulbouwer/hello-kubernetes:1.8
图片,可在/usr/src/app
目录下找到。
您可以使用init container在 kubernetes 中实现该功能,该操作会将/usr/src/app
启动过程中Pod
目录的原始内容复制到可能已经包含某些数据的PersistentVolume
中,该数据先前由您的应用生成。在进行这样的卷初始化之后,主容器将挂载PersistentVolume
,其中包含您的应用先前生成的数据(如果有)以及镜像中/usr/src/app
目录的原始内容。
您的Deployment
可能如下所示:
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-kubernetes
namespace: testwebsite
spec:
replicas: 1
selector:
matchLabels:
app: hello-kubernetes
template:
metadata:
labels:
app: hello-kubernetes
spec:
initContainers:
- name: init-hello-kubernetes
image: paulbouwer/hello-kubernetes:1.8
command: ['sh', '-c', 'cp -a /usr/src/app/* /mnt/pv-content/']
volumeMounts:
- name: azurefile01
mountPath: "/mnt/pv-content"
containers:
- name: hello-kubernetes
image: paulbouwer/hello-kubernetes:1.8
ports:
- containerPort: 8080
volumeMounts:
- name: azurefile01
mountPath: "/usr/src/app"
volumes:
- name: azurefile01
persistentVolumeClaim:
claimName: pvc-azurefile
为了从/usr/src/app/
图像的paulbouwer/hello-kubernetes:1.8
获取原始数据,您的init容器也必须基于该图像。一个警告:
paulbouwer/hello-kubernetes:1.8
图像必须包含cp
二进制文件才能执行该操作。如您所见,这不是一个非常“优雅”的解决方案。好吧,实际上不是。这就是为什么不建议将
PersistentVolume
挂载在已经包含一些重要文件的目录下,应用程序需要该文件才能正常运行。但是无法将卷安装在特定的安装点下并同时保留其原始内容。在Linux或其他基于nix的系统中,它根本无法通过这种方式工作。您要么装载整个卷,要么根本不装载它,并保留特定目录的原始内容。原始内容甚至都不会被覆盖。它仍然在那里。当此特定路径用作其他卷的安装点时,它仍然完全不可用。
关于kubernetes - K8s 1.16:将镜像中的现有目录挂载到pv,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62997427/