kubernetes copy a file/volume mount is not working in init-container

12/7/2021

I have a service which needs secret to be available before the pod starts. I added a volume for secret

    - name: cert
      secret:
        secretName: service-bhr-proxy-certificate

This volume is mounted in init-container.

        image: gaming-nginx-ssl-proxy:1.0.0
        imagePullPolicy: IfNotPresent
        name: service-bhr-proxy-certificate
        volumeMounts:
        - mountPath: /etc/nginx/certs_intermit
          name: cert

My understanding is secret file will available under /etc/nginx/certs_intermit before container starts. I even tried creating a another empty volume and mounting it on init-container and copying the secret to it. No luck. Any kind of help is appreciated.

-- Kavya Rudrappa
kubernetes

2 Answers

12/7/2021

Did you tried mounting the volume to main container also ?

Please refer this:

spec:
  template:
    spec:
      containers:
      - image: "my-image:latest"
        name: my-app
        ...
        volumeMounts:
          - mountPath: "/var/my-app"
            name: ssh-key
            readOnly: true
     initContainers:
     - command:
     - sh
     - -c
     - chown -R 1000:1000 /var/my-app #if any changes required
     image: busybox:1.29.2
     name: set-dir-owner
     securityContext:
       privileged: true
     volumeMounts:
     - mountPath: /var/my-app
       name: ssh-key
    volumes:
        - name: ssh-key
          secret:
            secretName: ssh-key

Full example

apiVersion: apps/v1
kind: Deployment
metadata:
  name: secret-manager
  labels:
    app: my-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      volumes:
      - name: secret-volume
        emptyDir: {}
      initContainers:
      - name: init-secret
        image: <Imagename>:latest
        imagePullPolicy: Always
        env:
        - name: SECRET_FILE_PATH
          value: "/secret/secret.env"
        volumeMounts:
          - mountPath: /secret
            name: secret-volume
      containers:
      - name: main-app
        image: busybox
        imagePullPolicy: Always
        command: ["/bin/sh", "-c"]
        args:
          - "source /secret/secret.env && while true; do echo '\n\n$DB_PASSWORD = '$DB_PASSWORD; echo '\nContents of secret.env file:'; cat /secret/secret.env;  sleep 2; done"
        env:
          - name: SECRET_FILE_PATH
            value: "/secret/secret.env"
        volumeMounts:
          - mountPath: /secret
            name: secret-volume
-- Harsh Manvar
Source: StackOverflow

12/7/2021

In your case, you need to use a shared volume. And you need to Mount this volume both in the init-container and main container. Then data or file will be in main-container of the pod. you can read more about shared volume here.

Lets discuss a example here:

step-1: First we need create a secret. Lets create a dummy one.

secret.yaml

apiVersion: v1
kind: Secret
metadata:
  name: server-secert
  namespace: demo
type: Opaque
stringData:
  # You can include additional key value pairs as you do with Opaque Secrets
  hello.txt: "hello from secret"
  demo.txt: "this is a demo"

let's apply this one:

kubectl apply -f secret.yaml

step-2 Now, Lets create a pod with shared volume mount in init-container and also on main container.

apiVersion: v1
kind: Pod
metadata:
  name: shared-demo
  namespace: demo
spec:
  initContainers:
  - name: init-secret
    image: alpine
    imagePullPolicy: Always
    volumeMounts:
      - mountPath: /shared
        name: shared-volume
  containers:
  - name: main-app
    image: busybox
    imagePullPolicy: IfNotPresent
    command: ["/bin/sh", "-c"]
    args:
      - "ls /shared; cat /shared/hello.txt; sleep 3600;"
    volumeMounts:
      - mountPath: /shared
        name: shared-volume
  volumes: 
    - name: shared-volume
      secret:
        secretName: server-secert

Now let's apply this one:

kubectl apply -f pod.yaml

then you can see the log:

kubectl logs -n demo shared-demo

you can also check with exec into pod:

kubectl exec -it -n demo shared-demo -c main-app -- sh

let's ls /shared path.

ls /shared
$ cat /shared/demo.txt
this is a demo
-- Emon46
Source: StackOverflow