<p>I'm looking for a pattern that allows to share volumes between two containers running on the same pod in Kubernetes.</p>

<p>My use case is:
I have a Ruby on Rails application running inside a docker container.
The docker image contains static assets in <code>/app/&lt;app-name&gt;/public</code> directory, and I need to access those assets from the nginx container running alongside in the same pod.</p>

<p>In 'vanilla' docker I would have used <code>--volumes-from</code> flag to share this directory:</p>

<pre><code>docker run --name app -v /app/&lt;app-dir&gt;/public &lt;app-image&gt;
docker run --volumes-from app nginx
</code></pre>

<p>After reading this doc: <a href="https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/volumes.md" rel="noreferrer">https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/volumes.md</a>
I tried this (only relevant entries presented):</p>

<pre><code>spec:
  containers:
    - image: &lt;app-image&gt;
      name: &lt;app-name&gt;
      volumeMounts:
        - mountPath: /app/&lt;app-name&gt;/public
          name: assets
    - image: nginx
      name: nginx
      volumeMounts:
        - mountPath: /var/www/html
          name: assets
          readOnly: true
    volumes:
      - name: assets
        hostPath:
          path: /tmp/assets
</code></pre>

<p>But:</p>

<ul>
<li>Even though <code>/tmp/assets</code> on the node exists, it's empty</li>
<li><code>/app/&lt;app-name&gt;/public</code> inside the app container is also empty</li>
</ul>

<p>As a workaround I'm gonna try to populate the shared directory when the application container is up (simply <code>cp /app/&lt;app-name&gt;/public/*</code> to shared directory), but I really dislike this idea.</p>

<p><strong>Question:</strong> how to mimic <code>--volumes-from</code> in Kubernetes, or if there is no direct counterpart, how can I share files from one container to other running in the same pod ?</p>

<p><code>apiVersion: v1beta3</code></p>

<pre><code>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"}
</code></pre>

<p><strong>[update-2016-8]</strong> In latest Kubernetes release, you can use a very nice feature named <code>init-container</code> to replace the <code>postStart</code> part in my answer below, which will make sure the container order.</p>

<pre><code>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: {}
</code></pre>

<p><strong>NOTE</strong>: initContainer is still a <strong>beta feature</strong> so the work version of this yaml is actually like: <a href="http://kubernetes.io/docs/user-guide/production-pods/#handling-initialization" rel="noreferrer">http://kubernetes.io/docs/user-guide/production-pods/#handling-initialization</a>, please notice the <code>pod.beta.kubernetes.io/init-containers</code> part.</p>

<p><em>---original answer begin---</em></p>

<p>Actually, you can. You need to use container life cycle handler to control what files/dirs you want to share with other containers. Like:</p>

<pre><code>---
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
</code></pre>

<p>Please check my gist for more details:</p>

<p><a href="https://gist.github.com/resouer/378bcdaef1d9601ed6aa" rel="noreferrer">https://gist.github.com/resouer/378bcdaef1d9601ed6aa</a></p>

<p>And of course you can use emptyDir. Thus, war container can share its /sample.war to peer container without mess peer's /app directory.</p>

<p>If we can tolerate /app been overridden, it will be much simpler:</p>

<pre><code>---
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: {}
</code></pre>
