Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to mimic '--volumes-from' in Kubernetes

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

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

In 'vanilla' docker I would have used --volumes-from flag to share this directory:

docker run --name app -v /app/<app-dir>/public <app-image> docker run --volumes-from app nginx 

After reading this doc: https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/volumes.md I tried this (only relevant entries presented):

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 

But:

  • Even though /tmp/assets on the node exists, it's empty
  • /app/<app-name>/public inside the app container is also empty

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

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

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"} 
like image 324
cthulhu Avatar asked May 29 '15 20:05

cthulhu


People also ask

How do I view volumes in Kubernetes?

You can get the volumes mounted on the pod using the output of kubectl describe pod which has the Mounts section in each container's spec . You can then exec into the pod using kubectl exec and the cd to the directory you want to write data to.

What is Kubernetes emptyDir?

The Kubernetes emptyDir is defined as, the emptyDir in Kubernetes are volumes that can obtain empty when a pod is generated, the pod is running in its emptyDir which it exists, if the container in a pod has collision the emptyDir then the content of them will not get affected, if we try to delete a pod, then it can ...

Where are volumes stored Kubernetes?

For any kind of volume in a given pod, data is preserved across container restarts. At its core, a volume is a directory, possibly with some data in it, which is accessible to the containers in a pod.

How do volumes work in Kubernetes?

A Volume in Kubernetes represents a directory with data that is accessible across multiple containers in a Pod. The container data in a Pod is deleted or lost when a container crashes or restarts, but when you use a volume, the new container can pick up the data at the state before the container crashes.


1 Answers

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

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: initContainer is still a beta feature so the work version of this yaml is actually like: http://kubernetes.io/docs/user-guide/production-pods/#handling-initialization, please notice the pod.beta.kubernetes.io/init-containers part.

---original answer begin---

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

--- 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 

Please check my gist for more details:

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

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

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

--- 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: {} 
like image 170
harryz Avatar answered Oct 06 '22 14:10

harryz