如何在Kubernetes中模仿'--volumes-from'

cth*_*lhu 44 docker kubernetes google-kubernetes-engine

我正在寻找一种模式,允许在Kubernetes的同一个pod上运行的两个容器之间共享卷.

我的用例是:我在docker容器中运行了一个Ruby on Rails应用程序.docker镜像包含/app/<app-name>/public目录中的静态资源,我需要从同一pod中运行的nginx容器访问这些资源.

在"vanilla"docker中,我会用--volumes-fromflag来共享这个目录:

docker run --name app -v /app/<app-dir>/public <app-image>
docker run --volumes-from app nginx
Run Code Online (Sandbox Code Playgroud)

阅读此文档后: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
Run Code Online (Sandbox Code Playgroud)

但:

  • 即使/tmp/assets节点存在,它也是空的
  • /app/<app-name>/public app容器内部也是空的

作为一种解决方法,我将尝试在应用程序容器启动时填充共享目录(仅限cp /app/<app-name>/public/*于共享目录),但我真的不喜欢这个想法.

问题:如何模仿--volumes-fromKubernetes,或者如果没有直接对应物,我如何将文件从一个容器共享到另一个容器中运行?

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"}
Run Code Online (Sandbox Code Playgroud)

har*_*ryz 39

[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: 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: {}
Run Code Online (Sandbox Code Playgroud)

请查看我的要点以获取更多详细信息:

https://gist.github.com/resouer/378bcdaef1d9601ed6aa

当然你可以使用emptyDir.因此,war容器可以将其/sample.war共享到peer容器而不会出现mess peer's/app目录.

如果我们可以容忍/ app被覆盖,那将更简单:

---
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
Run Code Online (Sandbox Code Playgroud)


aro*_*ick 9

答案是 - 现在 - 你做不到.以下是Kubernetes问题的几个讨论主题:

但是,我可以建议您使用可能更好的替代设计吗?

  1. 如果您的资产被锁定在容器上线的位置,您可以使用诸如gitRepo 卷之类的东西,将其复制到emptyDir上线点,并且意味着您根本不必移动内容,只是将其直接下载到共享目录.
  2. 如果您的资产被锁定在正在构建的容器的位置,那么最好使用Docker COPY命令将它们复制到该点.
  3. 如果你真的想坚持你的方式,你必须将内容复制到emptyDir卷,这是专为你正在寻找的东西而设计的(减去不必复制它).

NFS [1]卷也可以解决您的问题,但可能过于复杂.

另外,我建议这两种服务存在于不同的pod中,因此您可以单独扩展它们.如果需要,您可以创建服务端点以在它们之间进行通信.

[1] https://github.com/GoogleCloudPlatform/kubernetes/blob/master/examples/nfs/nfs-web-pod.yaml