kubernetes use env variables to pull the images

6/4/2020

in the yaml file can we use something like below to pull the image? or is there a better way?

I want to pull an image but the may vary depending on the releases.

configmap is like

kind: ConfigMap
apiVersion: v1
metadata:
  name: configmap
  namespace: rel
data:
  # Configuration values can be set as key-value properties
  RELEASE_ID: 1.1.1

Pod is like

    imagePullPolicy: Always
    image: "sid_z:$(RELEASE_LEVEL)"
    env:
      - name: RELEASE_LEVEL
        valueFrom:
          configMapKeyRef:
            name: configmap
            key: RELEASE_ID

rightnow it gives me an error invalid reference format Error: InvalidImageName

-- user2511126
kubernetes

4 Answers

6/4/2020

Here when you use env it means the when the pod is created and then you utilize those environment variables.

Below is from the kubernetes site https://kubernetes.io/docs/concepts/configuration/configmap/

A ConfigMap is an API object used to store non-confidential data in key-value pairs. Pods can consume ConfigMaps as environment variables, command-line arguments, or as configuration files in a volume.

In order to use the tag name for your image you would have to define it in the environment where you are running the kubernetes resource.

A simple way would be run export RELEASE_LEVEL=1.1.1 from a shell script and then in the image use it like image: sid_z:$RELEASE_LEVEL

Edited: Indeed like @willrof mentioned to substitute to yaml you can either use sed command where you save actual yaml in a kind of template and then substitute it with the value of environment variable like so

sed  s/RELEASE_LEVEL/$RELEASE_LEVEL/ deployment.yaml.template > deployment.yaml

here template would be like:

containers:
  - name: simple-app
    image: <Image>:**RELEASE_LEVEL**
    imagePullPolicy: Always

and apply the yaml or use envsubst (update environment variable in the file) like so. Note here you have to copy it to a different file and then rename it to the actual file. envsubst do not update in place. In the below example when you feed the file to envsubst and you have exported the environment variable like explained above, it will replace the variable with actual value.

envsubst deployment.yaml deployment.yaml.out
mv deployment.yaml.out deployment.yaml

your yaml should be like

containers:
    - name: simple-app
      image: <Image>:**$RELEASE_LEVEL**
      ports:
        - containerPort: 80
          name: http

ideally it would be a part of shell script or individual commands in order.

-- Atishay
Source: StackOverflow

6/5/2020
  • You can't use Environment variables, because they are made available inside the container, as mentioned in the other answer.

  • using linux variables would not be processed as well because is the server who processes the yaml, not the terminal itself.

  • My suggestion is to use Kubectl set image:

kubectl set image Update existing container image(s) of resources like:

pod (po), replicationcontroller (rc), deployment (deploy), daemonset (ds), replicaset (rs)

  • You can even see the processed yaml locally, before hitting the server with the parameter --local, more on that on the example bellow.

Examples:

  • Print result in yaml format of updating the image of the container named container-1 from local file, without hitting the server, neither changing the file:
$ cat hello.yaml 
apiVersion: v1
kind: Pod
metadata:
 name: hello
spec:
  containers:
  - name: container-1
    image: gcr.io/google-samples/hello-app:1.0
    ports:
    - name: http
      containerPort: 8080

$ kubectl set image -f hello.yaml container-1=gcr.io/google-samples/hello-app:2.0 --local -o yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  name: hello
spec:
  containers:
  - image: gcr.io/google-samples/hello-app:2.0
    name: container-1
    ports:
    - containerPort: 8080
      name: http
    resources: {}
status: {}
  • You can pipe the output to directly create the pod with the changed image:
$ kubectl set image -f hello.yaml container-1=gcr.io/google-samples/hello-app:2.0 --local -o yaml | kubectl apply -f -
pod/hello created

$ kubectl get pods
NAME    READY   STATUS    RESTARTS   AGE
hello   1/1     Running   0          22s

$ kubectl describe pod hello | grep Image:
    Image:          gcr.io/google-samples/hello-app:2.0
  • Changing the image of container-1 on the deployed pod hello:
$ kubectl set image pod/hello container-1=gcr.io/google-samples/hello-app:1.0
pod/hello image updated

$ kubectl describe pod hello | grep Image:
    Image:          gcr.io/google-samples/hello-app:1.0
  • Update images of all containers from deployment hello-2:
$ kubectl apply -f hello-2-deploy.yaml 
deployment.apps/hello-2 created

$ kubectl get deployment hello-2
NAME      READY   UP-TO-DATE   AVAILABLE   AGE
hello-2   3/3     3            3           6s

$ kubectl describe deploy hello-2 | grep Image:
    Image:        gcr.io/google-samples/hello-app:2.0

$ kubectl set image deployment hello-2 *=nginx:latest
deployment.apps/hello-2 image updated

$ kubectl describe deploy hello-2 | grep Image:
    Image:        nginx:latest
  • All updates were made without modifying the original yaml file.

If you have any questions let me know in the comments.

-- Will R.O.F.
Source: StackOverflow

7/25/2020

The container runtime needs to know what image to use to start the container to even have a process running that has environment variables.

In short, you need to select the image prior to applying the Pod manifest to the cluster.

When I know that there's a part of my YAML that will be variable, I reach for ytt and slip in a little templating:

pod.yml

#@ load("@ytt:data", "data")
---
apiVersion: v1
kind: Pod
metadata:
  name: guestbook
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: #@ data.values.image
    ports:
    - containerPort: 80

values.yml

#@data/values
---
image: nginx@sha256:fe2fa7bb1ceb86c6d9c935bc25c3dd8cbd64f2e95ed5b894f93ae7ffbd1e92bb

Then ytt will substitute in the image ref and you can pipe that right to kubectl:

$ ytt -f pod.yml -f values.yml | kubectl apply -f -

And I typically use ytt's cousin, kapp for deploying to K8s clusters. It's a near drop-in replacement for most of what I use kubectl for...

$ ytt -f pod.yml -f values.yml | kapp deploy -a guestbook -f -
-- JTigger
Source: StackOverflow

6/4/2020

You would want to look at tools like Kustomize and Helm instead.

-- coderanger
Source: StackOverflow