How to cp data from one container to another using kubernetes

7/2/2019

Say we have a simple deployment.yml file:

apiVersion: apps/v1 
kind: Deployment
metadata:
  namespace: ikg-api-demo
  name: ikg-api-demo
spec:
  selector:
    matchLabels:
      app: ikg-api-demo
  replicas: 3 
  template:
    metadata:
      labels:
        app: ikg-api-demo
    spec:
      containers:
        - name: ikg-api-demo
          imagePullPolicy: Always
          image: 913xxx371.dkr.ecr.us-west-2.amazonaws.com/main_api:c56cefbd0c81142558cf814cba7d7cd75d7cb6a7
          ports:
            - containerPort: 80

the problem is that this image/container depends on another image/container - it needs to cp data from the other image, or use some shared volume.

How can I tell kubernetes to download another image, run it as a container, and then copy data from it to the container declared in the above file?

It looks like this article explains how.

but it's not 100% clear how it works. It looks like you create some shared volume, launch the two containers, using that shared volume?

so I according to that link, I added this to my deployment.yml:

spec:

  volumes:
    - name: shared-data
      emptyDir: {}

  containers:

    - name: ikg-api-demo
      imagePullPolicy: Always
      volumeMounts:
        - name: shared-data
          mountPath: /nltk_data
      image: 913617820371.dkr.ecr.us-west-2.amazonaws.com/nltk_data:latest

    - name: ikg-api-demo
      imagePullPolicy: Always
      volumeMounts:
        - name: shared-data
          mountPath: /nltk_data
      image: 913xxx371.dkr.ecr.us-west-2.amazonaws.com/main_api:c56cefbd0c81142558cf814cba7d7cd75d7cb6a7
      ports:
        - containerPort: 80

my primary hesitation is that mounting /nltk_data as a shared volume will overwrite what might be there already.

So I assume what I need to do is mount it at some other location, and then make the ENTRYPOINT for the source data container:

ENTRYPOINT ['cp', '-r', '/nltk_data_source', '/nltk_data']

so that will write it to the shared volume, once the container is launched.

So I have two questions:

  1. How to run one container and finish a job, before another container starts using kubernetes?

  2. How to write to a shared volume without having that shared volume overwrite what's in your image? In other words, if I have /xyz in the image/container, I don't want to have to copy /xyz to /shared_volume_mount_location if I don't have to.

-- Alexander Mills
amazon-eks
docker-copy
docker-volume
eks
kubernetes

1 Answer

7/3/2019

How to run one container and finish a job, before another container starts using kubernetes?

Use initContainers - updated your deployment.yml, assuming 913617820371.dkr.ecr.us-west-2.amazonaws.com/nltk_data:latest is your data image

How to write to a shared volume without having that shared volume overwrite?

As you know what is there in your image, you need to select an appropriate mount path. I would use /mnt/nltk_data

Updated deployment.yml with init containers

spec:
  volumes:
    - name: shared-data
      emptyDir: {}
  initContainers:
    - name: init-ikg-api-demo
      imagePullPolicy: Always
      # You can use command, if you don't want to change the ENTRYPOINT
      command: ['sh', '-c', 'cp -r /nltk_data_source /mnt/nltk_data']
      volumeMounts:
        - name: shared-data
          mountPath: /mnt/nltk_data
      image: 913617820371.dkr.ecr.us-west-2.amazonaws.com/nltk_data:latest
  containers:
    - name: ikg-api-demo
      imagePullPolicy: Always
      volumeMounts:
        - name: shared-data
          mountPath: /nltk_data
      image: 913xxx371.dkr.ecr.us-west-2.amazonaws.com/main_api:c56cefbd0c81142558cf814cba7d7cd75d7cb6a7
      ports:
        - containerPort: 80
-- Prakash Krishna
Source: StackOverflow