Kubernetes - Trying to create pod with init container

3/25/2019

I am trying to play with init pods. I want to use init container to create file and default container to check if file exist and sleep for a while.

my yaml:

apiVersion: v1
kind: Pod
metadata:
  name: init-test-pod
spec:
  containers:
  - name: myapp-container
    image: alpine
    command: ['sh', '-c', 'if [ -e /workdir/test.txt ]; then sleep 99999; fi']
  initContainers:
  - name: init-myservice
    image: busybox:1.28
    command: ['sh', '-c', 'mkdir /workdir; echo>/workdir/test.txt']

When I am trying to debug from alpine image I use the command to create:

kubectl run alpine --rm -ti --image=alpine /bin/sh

If you don't see a command prompt, try pressing enter.
/ # if [ -e /workdir/test.txt ]; then sleep 3; fi
/ # mkdir /workdir; echo>/workdir/test.txt
/ # if [ -e /workdir/test.txt ]; then sleep 3; fi
/ *here shell sleeps for 3 seconds
/ #

And it seems like commands working as expected.

But on my real k8s cluster I have only CrashLoopBackOff for main container.

kubectl describe pod init-test-pod

Shows me only that error:

Containers:
  myapp-container:
    Container ID:  docker://xxx
    Image:         alpine
    Image ID:      docker-pullable://alpine@sha256:xxx
    Port:          <none>
    Host Port:     <none>
    Command:
      sh
      -c
      if [ -e /workdir/test.txt ]; then sleep 99999; fi
    State:          Waiting
      Reason:       CrashLoopBackOff
    Last State:     Terminated
      Reason:       Completed
      Exit Code:    0
    Ready:          False
    Restart Count:  3
    Environment:    <none>
-- golang
docker
kubernetes

2 Answers

3/25/2019

The problem here is that your main container is not finding the folder you create. When your initial container completes running, the folder gets wiped with it. You will need to use a Persistent Volume to be able to share the folder between the two containers:

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: mypvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
---
apiVersion: v1
kind: Pod
metadata:
  name: init-test-pod
spec:
  volumes:
  - name: mypvc
    persistentVolumeClaim:
      claimName: mypvc
  containers:
  - name: myapp-container
    image: alpine
    command: ['sh', '-c', 'if [ -f /workdir/test.txt ]; then sleep 99999; fi']
    volumeMounts:
    - name: mypvc
      mountPath: /workdir
  initContainers:
  - name: init-myservice
    image: busybox:1.28
    command: ['sh', '-c', 'mkdir /workdir; echo>/workdir/test.txt']
    volumeMounts:
    - name: mypvc
      mountPath: /workdir

You can as well look at emptyDir, so you won't need the PVC:

apiVersion: v1
kind: Pod
metadata:
  name: init-test-pod
spec:
  volumes:
  - name: mydir
    emptyDir: {}
  containers:
  - name: myapp-container
    image: alpine
    command: ['sh', '-c', 'if [ -f /workdir/test.txt ]; then sleep 99999; fi']
    volumeMounts:
    - name: mydir
      mountPath: /workdir
  initContainers:
  - name: init-myservice
    image: busybox:1.28
    command: ['sh', '-c', 'mkdir /workdir; echo>/workdir/test.txt']
    volumeMounts:
    - name: mydir
      mountPath: /workdir
-- cookiedough
Source: StackOverflow

3/25/2019

That's because your 2 containers have separate filesystems. You need to share this file using an emtyDir volume:

apiVersion: v1
kind: Pod
metadata:
  name: init-test-pod
spec:
  containers:
  - name: myapp-container
    image: alpine
    command: ['sh', '-c', 'if [ -e /workdir/test.txt ]; then sleep 99999; fi']
    volumeMounts:
    - mountPath: /workdir
      name: workdir
  initContainers:
  - name: init-myservice
    image: busybox:1.28
    command: ['sh', '-c', 'mkdir /workdir; echo>/workdir/test.txt']
    volumeMounts:
    - mountPath: /workdir
      name: workdir
  volumes:
  - name: workdir
    emptyDir: {}
-- Grigory Ignatyev
Source: StackOverflow