Lab_02 - The Declarative Model
Lab 02: The Declarative Model
In this lab, we will switch from imperative to declarative. We are no longer telling Kubernetes what to do (and in what order) - we are simply telling it „this is the desired end state”, and K8s will implement the required changes in order to reach it.
Running a Pod
Connect to the master node with your user credentials. Make sure that there are no pods already running on the system (in the default namespace).
Create a simple pod YAML file in your home directory - let’s call it s01-pod.yaml
.
Note
You can use any text editor you wish for this task. If you do not have a favorite, I would recommend nano:
nano ~/01-pod.yaml
Populate the file with the necessary information in order to create an nginx pod. The name of the pod should be nginx01
, and the image used should be nginx
. Remember that you will need:
apiVersion (pods exist since v1)
kind (Pod) (the kind is PascalCase)
metadata, with a field called name (mandatory)
spec, listing at least one container, with a name and an image
Here is a starting point:
apiVersion: v1
kind: ...
metadata:
name: ...
spec:
containers:
- image: ...
name: ...
Solution
apiVersion: v1
kind: Pod
metadata:
name: nginx01
spec:
containers:
- image: nginx
name: nginx
Run the pod on the cluster.
Hint
You can use kubectl apply
or kubectl create
, with the -f
argument specifying the file to use.
Solution
kubectl apply -f 01-pod.yaml
Verify that the pod has been created and is running. On which host has the pod been scheduled?
Solution
kubectl get pod
Get the IP address of the pod. Connect to the IP address using curl
to verify that the web server is serving content.
Hint
You could use kubectl describe
to get the IP address, but it is also included in the output of kubectl get pod -o wide
.
Solution
kubectl get pod -o wide
curl IP_ADDRESS
Getting Possible Options
There are many possible options that could be used in the YAML file. The easiest way to take a look at them is to see the actual configuration of your pod (the way Kubernetes sees it). Display the pod configuration in YAML format.
Hint
kubectl get pod -o yaml
Note
The status section is dynamically populated by Kubernetes at runtime (so it cannot be part of the original YAML file, used to create the pod). Focus on the spec section.
Solution
kubectl get pod nginx01 -o yaml
What is the restart policy of the pod?
Hint
Look for restartPolicy
.
Note
Since we did not specify this field as part of the original YAML file, it has been populated with the default value.
For a full list of configuration options, try the following command:
kubectl explain pod --recursive
Note
It is strongly recommended to pipe it to the less command - there are many pages of possible options…
Print out the pod configuration in JSON format.
Not as easy to read by a human, is it? (although the fact that k8s pretty-prints it by default does help) However, it is much easier to parse by machines - including command-line tools such as jq
.
Solution
kubectl get pod nginx01 -o json
Challenge: Speaking of jq - can you write a single command that prints out only the IP address of a specific pod?
Note
This is not easy in the beginning (it requires you to look up and understand the syntax used by jq to extract specific fields). However, it is a very useful thing to master if you ever need to deal with JSON-formatted data.
Solution
kubectl get pod nginx01 -o json | jq -r .status.podIP
Create another file (02-alpine.yaml) that starts an alpine pod. The name of the pod should be alpine01, and the image used should be alpine. Create the pod based on this file.
Solution
02-alpine.yaml
:
apiVersion: v1
kind: Pod
metadata:
name: alpine01
spec:
containers:
- image: alpine
name: alpine
kubectl apply -f 02-alpine.yaml
Verify that the pod is running. What do you see?
Solution
You will see that the pod continuously crashes and is automatically restarted.
kubectl get pod
Check the details of the pod. What is the reason for this behavior?
Hint
kubectl describe pod
By default, the alpine image will try to run sh
, which is a shell, and expects to receive input…
Solution
kubectl describe pod alpine01
Actually, the describe command is not that helpful - you will see that the container keeps crashing, but you will not see the actual reason…
Delete the pod. Edit the 02-alpine.yaml
to fix the problem.
Hint
When running a shell (or any other type of program that expects input on stdin) inside a container, you need to use -it
on the command line. The equivalent in YAML is to set stdin: true
(-i) and tty: trues
(-t) for the container (.spec.containers)
Solution
kubectl delete pod alpine01
apiVersion: v1
kind: Pod
metadata:
name: alpine01
spec:
containers:
- image: alpine
name: alpine
stdin: true # <---
tty: true # <---
Create a pod based on the new file, and verify that the pod starts correctly.
Solution
kubectl apply -f 02-alpine.yaml
kubectl get pod
Attach to the running shell on the alpine container.
Hint
In a previous lab, we have used kubectl exec to run a new process inside an existing container. This time, we want to attach to the existing, main process inside the container. For this, we will use kubectl attach.
You need to specify -it
on the command line!
Solution
kubectl attach -it alpine01
Exit the shell (type exit
or press Ctrl-D
).
What happens?
Note
If you have attached to the main process inside the container, and then stopped that process, the container is stopped. However, Kubernetes automatically restarts it - you will see the number of restarts incrementing.
kubectl get pod
Optional: RestartPolicy
Let’s explore the possible restart policies… The status of the container is dictated by its exit code - 0 means „success”, a non-zero code means „error”. To simulate this, we will attach to the container and use the commands exit 0
(for success), or exit 1
(for failure).
Attach to the running alpine container. Type exit 0
. What happens?
Hint
this is a „success”. The container status will briefly change to „Completed”, and then the pod will be restarted.
Solution
kubectl attach -it alpine01
exit 0
kubectl get pod
Once the pod is running again, reattach to it. This time, type exit 1
. What happens?
Hint
This is „exit with an error”. The container status will change to „Error”, and then the pod will be restarted.
Solution
kubectl attach -it alpine01
Delete the pod. Change the YAML file so that restartPolicy
(under spec
) is set to OnFailure
.
Solution
kubectl delete pod alpine01
apiVersion: v1
kind: Pod
metadata:
name: alpine01
spec:
containers:
- image: alpine
name: alpine
stdin: true
tty: true
restartPolicy: OnFailure # <---
Create a new pod based on the changed file.
Solution
kubectl apply -f 02-alpine.yaml
Attach to the running alpine container again. Type exit 0
. What is different this time?
Solution
kubectl attach -it alpine01
exit 0
kubectl get pod
This time the pod is restarted only when it exits due to an error. Once the pod completes execution successfully, it remains stopped.
Optional: Running Multiple Pods
Create a single file ( 03-pods.yaml
) that starts both an alpine and an nginx pod.
Hint
The easiest way to do this is to simply use two yaml documents (separated by ---
) inside a single file.
Solution
03-pods.yaml
:
apiVersion: v1
kind: Pod
metadata:
name: nginx02
spec:
containers:
- image: nginx
name: nginx
---
apiVersion: v1
kind: Pod
metadata:
name: alpine02
spec:
containers:
- image: alpine
name: alpine
stdin: true
tty: true
Apply the file and verify that the two pods get created correctly.
Solution
kubectl apply -f 03-pods.yaml
kubectl get pod
Cleaning Up
Delete all pods.
Solution
kubectl delete pods --all
Last updated