我正在寻找一种模式,该模式允许在Kubernetes中在同一容器上运行的两个容器之间共享卷。
我的用例是:我有一个在Docker容器中运行的Ruby on Rails应用程序。docker映像在/app/<app-name>/public
目录中包含静态资产,我需要从在同一容器中并排运行的nginx容器访问这些资产。
在'vanilla'泊坞窗中,我将使用--volumes-from
标志来共享此目录:
docker run --name app -v /app/<app-dir>/public <app-image>
docker run --volumes-from app nginx
阅读此文档后:https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/volumes.md我尝试了此操作(仅显示了相关条目):
spec:
containers:
- image: <app-image>
name: <app-name>
volumeMounts:
- mountPath: /app/<app-name>/public
name: assets
- image: nginx
name: nginx
volumeMounts:
- mountPath: /var/www/html
name: assets
readOnly: true
volumes:
- name: assets
hostPath:
path: /tmp/assets
但是:
/tmp/assets
存在,也为空/app/<app-name>/public
]也为空作为一种解决方法,我将尝试在应用程序容器启动时填充共享目录(仅将cp /app/<app-name>/public/*
共享目录),但我真的不喜欢这个想法。
问题:如何在Kubernetes中模拟--volumes-from
,或者如果没有直接对应的文件,如何共享文件从一个容器到同一容器中运行的另一个容器?
apiVersion: v1beta3
Client Version: version.Info{Major:"0", Minor:"17", GitVersion:"v0.17.0", GitCommit:"82f8bdac06ddfacf493a9ed0fedc85f5ea62ebd5", GitTreeState:"clean"}
Server Version: version.Info{Major:"0", Minor:"17", GitVersion:"v0.17.0", GitCommit:"82f8bdac06ddfacf493a9ed0fedc85f5ea62ebd5", GitTreeState:"clean"}
[[update-2016-8]在最新的Kubernetes版本中,您可以使用名为init-container
的非常好用的功能替换下面我的答案中的postStart
部分,这将确保容器顺序。 >
:initContainer仍然是beta功能,因此此Yaml的工作版本实际上如下:http://kubernetes.io/docs/user-guide/production-pods/#handling-initialization,请注意apiVersion: v1 kind: Pod metadata: name: javaweb-2 spec: initContainers: - name: war image: resouer/sample:v2 command: ["cp", "/sample.war", "/app"] volumeMounts: - mountPath: /app name: app-volume containers: - name: tomcat image: resouer/mytomcat:7.0 command: ["sh","-c","/root/apache-tomcat-7.0.42-v2/bin/start.sh"] volumeMounts: - mountPath: /root/apache-tomcat-7.0.42-v2/webapps name: app-volume ports: - containerPort: 8080 hostPort: 8001 volumes: - name: app-volume emptyDir: {}
NOTE
pod.beta.kubernetes.io/init-containers
部分。---原始答案开始---
实际上,可以。您需要使用容器生命周期处理程序来控制要与其他容器共享的文件/目录。喜欢:
--- apiVersion: v1 kind: Pod metadata: name: server spec: restartPolicy: OnFailure containers: - image: resouer/sample:v2 name: war lifecycle: postStart: exec: command: - "cp" - "/sample.war" - "/app" volumeMounts: - mountPath: /app name: hostv1 - name: peer image: busybox command: ["tail", "-f", "/dev/null"] volumeMounts: - name: hostv2 mountPath: /app/sample.war volumes: - name: hostv1 hostPath: path: /tmp - name: hostv2 hostPath: path: /tmp/sample.war
请查看我的要点以获取更多详细信息:
https://gist.github.com/resouer/378bcdaef1d9601ed6aa
当然,您可以使用emptyDir。因此,war容器可以将其/sample.war共享给对等容器,而不会陷入对等方的/ app目录。
如果我们可以容忍/ app被覆盖,那就简单得多:
---
apiVersion: v1
kind: Pod
metadata:
name: javaweb-2
spec:
restartPolicy: OnFailure
containers:
- image: resouer/sample:v2
name: war
lifecycle:
postStart:
exec:
command:
- "cp"
- "/sample.war"
- "/app"
volumeMounts:
- mountPath: /app
name: app-volume
- image: resouer/mytomcat:7.0
name: tomcat
command: ["sh","-c","/root/apache-tomcat-7.0.42-v2/bin/start.sh"]
volumeMounts:
- mountPath: /root/apache-tomcat-7.0.42-v2/webapps
name: app-volume
ports:
- containerPort: 8080
hostPort: 8001
volumes:
- name: app-volume
emptyDir: {}
答案是-现在-您不能。这是来自Kubernetes问题的一些讨论线程:
来自未来
如果您使用的是Docker v17.0.5或更高版本,则可以在构建期间使用多阶段构建将文件从一个容器复制到另一个容器。这是https://medium.com/@tonistiigi/advanced-multi-stage-build-patterns-6f741b852fae
Kubernetes具有自己的卷类型,这些是最常用的卷类型: