Kubernetes useful tricks: Creating a secret from a file in an image

Recently I had an interesting problem. The product I was working on needed to create a secret from a file. Now on one hand this is an easy thing as you can just have a job run within an image

kubectl create secret generic mysecret --from-file=./file.txt

Ah… However Kubernetes command line client is only compatible within one minor version of the Kubernetes api server. So if you want to support all major version for Redhat Openshift currently supported you have to support Kubernetes 1.11 to 1.21. So to get around this problem you have to curl against the kubapi server directly. Here is a sample script I created to demonstrate this method.

apiVersion: batch/v1
kind: Job
metadata:
  name: readfiletosecret
  description: "Example of reading a file to a kubernetes secret."
spec:
  template:
    spec:
      serviceAccountName: account-with-secret-create-priv
      volumes:
      - name: local
        emptyDir: {}
      initContainers:
      - name: get-file
        image: registry.access.redhat.com/ubi8/ubi-minimal:latest
        command:
        - "/bin/sh"
        - "-c"
        env:
        - name: UPLOAD_FILE_PATH
          value: "/root/buildinfo/content_manifests/ubi8-minimal-container*.json"
        args:
        - |
          cat $UPLOAD_FILE_PATH
          cp -vf $UPLOAD_FILE_PATH /work/
        volumeMounts:
        - name: local
          mountPath: /work
      containers:
      - name: create-secret
        image: registry.access.redhat.com/ubi8/ubi-minimal:latest
        command:
        - "/bin/sh"
        - "-c"
        args:
        - |
          ls /work/
          i#
          export CONTENT=$(cat /work/* | base64 )
          echo $CONTENT
          #Set auth info
          export SERVICEACCOUNT=/var/run/secrets/kubernetes.io/serviceaccount
          export NAMESPACE=$(cat ${SERVICEACCOUNT}/namespace)
          export TOKEN=$(cat ${SERVICEACCOUNT}/token)
          export CACERT=${SERVICEACCOUNT}/ca.crt
          export APISERVER="https://kubernetes.default.svc"
          # Explore the API with TOKEN
          curl --cacert ${CACERT} --header "Authorization: Bearer ${TOKEN}" -X POST -H 'Accept: application/json' -H 'Content-Type: application/json' -d @-  ${APISERVER}/api/v1/namespaces/$NAMESPACE/secrets <<EOF
          {
            "kind": "Secret",
            "apiVersion": "v1",
            "metadata": {
              "name": "example"
            },
            "data": {
              "file": "$CONTENT"
            }
          }
          EOF
          rm /work/*
        volumeMounts:
        - name: local
          mountPath: /work
      restartPolicy: Never
  backoffLimit: 4

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s