kubernetes share non-empty volume

1/24/2020

In my application with docker-compose I have 2 container, 1 nginx and 1 python script crontab that update some files in nginx/html folder. With docker-compose when I declare

volumes:
    - shared-volume:/usr/share/nginx/html/assets/xxx:ro

the initial files in the nginx images are copied to the shared volume.

Now I'm trying to move the application to k8s, but when I use shared volume I see that initial files in nginx/html are missing.

So the question is, is it possible to copy initial files from my nginx images to the shared volume? How?

____________________________EDIT______________________________________

To clarify, I'm new to k8s, With VM we usually run script that update an nginx assets folder. With docker-compose I use something like this:

version: '3.7'
services:
  site-web:
    build: .
    image: "site-home:1.0.0"
    ports:
    - "80:80"
    volumes:
    - v_site-home:/usr/share/nginx/html/assets/:ro
  site-cron:
    build: ./cronScript
    image: "site-home-cron:1.0.0"
    volumes:
    - v_site-home:/app/my-assets
volumes:
  v_site-home:
    name: v_site-home

Now I'm starting to write a deployment (with persistent volume? Because as I understand even if there is a persistent volume a stateful set is not useful in this case) to convert my docker-compose to k8s. Actually we cannot use any public cloud for security policy (data must be in our country and now there's no big company with this option). So the idea is to run vanilla k8s in multiple bare metal server and start migration with very simple application like this. I tried with the 2 docker, replica:1 and an empty volume in a single pod. In this case I see that initially the application has the nginx folder empty, and I need to wait the crontab update to see my results. So this is the first problem.

Now I read your answer and obviously I've other doubts. Is it better to split the pod, so 1 pod for container? A deployment with persistent volume is the way? In this case, I've the old problem, how to see initial nginx assets files? Thank you so much for the help!

-- Davide
kubernetes
nginx
volume

2 Answers

1/24/2020

This generally requires an initContainer which runs cp. it’s not a great solution but it gets the job done.

-- coderanger
Source: StackOverflow

1/25/2020

Kubernetes doesn't have the Docker feature that copies content into volumes when the container is first started.

The two straightforward answers to this are:

  1. Build a custom Nginx image that contains the static assets. You can use the Dockerfile COPY --from=other/image:tag construct to copy them from your application container into the proxy container.

  2. Store the assets somewhere outside container space altogether. If you're deploying this to AWS, you can publish them to S3, and even directly serve them from a public S3 bucket. Or if you have something like an NFS mount accessible to your cluster, have your overall build process copy the static assets there.

The Docker feature has many corner cases that are frequently ignored, most notably that content is only copied when the container is first started. If you're expecting the volume to contain static assets connected to your application, and you update the application container, the named volume will not update. As such you need some other solution to manage the shared content anyways, and I wouldn't rely on that Docker feature as a solution to this problem.

In Kubernetes you have the additional problem that you typically will want to scale HTTP proxies and application backends separately, which means putting them in different Deployments. Once you have three copies of your application, which one provides "the" static assets? You need to use something like a persistent volume to share contents, but most of the persistent volume types that are easy to get access to don't support multiple mounts.

-- David Maze
Source: StackOverflow