我正在寻找一种模式,允许在Kubernetes的同一个pod上运行的两个容器之间共享卷。
我的用例是:
我有一个在docker容器中运行的Ruby on Rails应用程序。
docker镜像包含/app/<app-name>/public
目录中的静态资源,我需要从同一个pod中并行运行的nginx容器中访问这些资源。
香草&#39; docker我会用--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"}
答案 0 :(得分:36)
[update-2016-8] 在最新的Kubernetes版本中,您可以使用名为init-container
的非常好的功能替换下面我的答案中的postStart
部分,将确保集装箱订单。
注意:initContainer仍然是测试版功能,因此此yaml的工作版本实际上是:http://kubernetes.io/docs/user-guide/production-pods/#handling-initialization,请注意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共享到peer容器而不会出现peer peer&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: {}
答案 1 :(得分:9)
答案是 - 现在 - 你做不到。以下是Kubernetes问题的几个讨论主题:
但是,我可以建议您使用可能更好的替代设计吗?
gitRepo
之类的东西
在上线时将其复制到emptyDir
的音量,并且意味着您不必移动内容
所有,只需将其直接下载到共享目录即可。 emptyDir
卷,该卷专为您所寻找的内容而设计(减去缺少的内容)必须复制它。)NFS [1]卷也可以解决您的问题,但可能过于复杂。
此外,我建议这两种服务存在于不同的pod中,因此您可以单独扩展它们。如果需要,您可以创建服务端点以在它们之间进行通信。
[1] https://github.com/GoogleCloudPlatform/kubernetes/blob/master/examples/nfs/nfs-web-pod.yaml
答案 2 :(得分:1)
future 的进一步更新:
现在有一个Docker卷的FlexVol插件:https://github.com/dims/docker-flexvol
在撰写本文时,FlexVol仍然是一个alpha功能,因此需要注意。
答案 3 :(得分:1)
Kubernetes具有自己的卷类型,这些是最常用的卷类型:
您可以在此处找到有关kubernets卷的更多信息-https://kubernetes.io/docs/concepts/storage/volumes/
主机路径卷的示例:
for i in range(0,4):
while(x < 8):
attempt = attempt + 1
x = np.random.uniform(low=0, high=10, size=1)
hostpath会将主机/节点目录挂载到容器目录中。一个容器中的多个容器可以使用不同或相同的卷。您需要在每个容器中提及它。 hostPath卷与pod生命周期无关,但是它会在node和pod之间建立紧密的耦合,因此应避免使用hostPath。
答案 4 :(得分:0)
如果您使用的是Docker v17.0.5或更高版本,则可以在构建期间使用多阶段构建将文件从一个容器复制到另一个容器。这是https://medium.com/@tonistiigi/advanced-multi-stage-build-patterns-6f741b852fae
上高级功能的重要入门将静态资产从后端容器复制到Nginx代理中的方式是
ARG API_BACKEND_CONTAINER="api:backend"
FROM $API_BACKEND_CONTAINER as source
FROM nginx:mainline-alpine
ARG NGINX_ROOT=/usr/share/nginx/html/
COPY --from=source /var/share/api/static/ ${NGINX_ROOT}
很棒的是,因为API_BACKEND_CONTAINER
是一个构建参数,所以我可以传递最新API构建的标签。