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
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.
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)
--local
, more on that on the example bellow.Examples:
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: {}
$ 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
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
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
If you have any questions let me know in the comments.
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 -
You would want to look at tools like Kustomize and Helm instead.