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.1Pod is like
imagePullPolicy: Always
image: "sid_z:$(RELEASE_LEVEL)"
env:
- name: RELEASE_LEVEL
valueFrom:
configMapKeyRef:
name: configmap
key: RELEASE_IDrightnow 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.yamlhere template would be like:
containers:
- name: simple-app
image: <Image>:**RELEASE_LEVEL**
imagePullPolicy: Alwaysand 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.yamlyour yaml should be like
containers:
- name: simple-app
image: <Image>:**$RELEASE_LEVEL**
ports:
- containerPort: 80
name: httpideally 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 imageUpdate 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.0container-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:latestIf 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: 80values.yml
#@data/values
---
image: nginx@sha256:fe2fa7bb1ceb86c6d9c935bc25c3dd8cbd64f2e95ed5b894f93ae7ffbd1e92bbThen 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.