# Lab\_01 - Running Workloads Imperatively

## Lab 01: Running Workloads Imperatively

In this lab, you will begin to run actual workloads on our Kubernetes cluster.

### Enabling Bash Completion <a href="#enabling-bash-completion" id="enabling-bash-completion"></a>

#### Bash Completion <a href="#bash-completion" id="bash-completion"></a>

While not technically necessary, this step will help you a lot while working with Kubernetes. Enable k8s command completion for the current session using the following command:

```
source <(kubectl completion bash)
```

#### Persistent Bash Completion <a href="#persistent-bash-completion" id="persistent-bash-completion"></a>

To enable bash completion for all future sessions, add the command to your .bashrc file:

```
echo "source <(kubectl completion bash)" >> ~/.bashrc
```

#### Test Bash Completion <a href="#test-bash-completion" id="test-bash-completion"></a>

Try it out - list all pods in all namespaces, this time using tab completion.

Examples:

```
kubectl get po[TAB] # gets completed to "pod"
```

```
kubectl get pods --all[TAB][TAB] # lists all available options starting with "–all"
```

### Taking a Look Around <a href="#taking-a-look-around" id="taking-a-look-around"></a>

List all the namespaces in your cluster.

Hint

Namespaces are a resource just like everything else in k8s.

```
kubectl get ...
```

Solution

```
kubectl get namespaces
```

List all the pods in each namespace.

Solution

```
kubectl get pods -n kube-public
```

```
kubectl get pods -n default
```

```
kubectl get pods -n kube-system
```

Right now, the only running pods are inside the `kube-system` namespace. List the pods, including the node on which every pod is currently running.

Hint

The `-o wide` option for `kubectl get pods` will help.

Solution

```
kubectl get pods -n kube-system -o wide
```

Do you notice a pattern in the pod-to-node distribution?

Solution

There are actually several patterns:

* Some pods (like the kube-proxy ones) run a copy of the pod on each node in the cluster. These are part of so-called DaemonSets.
* Other pods (like the controller-manager) only run on the master
* Yet other pods (like the user workloads, which we will soon see) are not normally scheduled on the master - only on the worker nodes.

### Running a Simple Pod <a href="#running-a-simple-pod" id="running-a-simple-pod"></a>

Run a simple pod based on the alpine image (a very small, very lightweight, Linux image). Use the following options, without specifying anything else:

* pod name: alpine1
* image name: alpine
* interactive mode, keep tty open (`-it`)
* command to run: sh

Hint

```
kubectl run ...
```

Solution

```
kubectl run -it alpine1 --image=alpine sh
```

You should end up at a command-line prompt inside the pod. Verify this by checking the hostname of the machine you are now on.

Note

Keep in mind that connecting and running commands directly inside a container is NOT a best practice! We are just using it in the lab to illustrate various behaviours (also, it can be very useful for troubleshooting container issues).

Solution

```
hostname
```

What is the IP address of this pod?

Solution

```
ifconfig
```

Exit the interactive session, leaving the pod running

Hint

Press `Ctrl-P Ctrl-Q`.

Display a list of pods. What is the status of the pod? On which host is the pod running?

Solution

```
kubectl get pod
```

```
kubectl get pod -o wide
```

Get the IP address of the pod, as it is known by Kubernetes.

Hint

```
kubectl describe ...
```

Solution

```
kubectl describe pod alpine1
```

Ping the pod’s IP address. Can you reach it? (Optional: also try to ping it from another node).

Note

We will get back to this in a future lesson, but this is the „magic” of Kubernetes networking - all pods are reachable from all nodes, on the same (private) IP address!

Solution

```
ping POD_IP
```

### Running `nginx` <a href="#running-nginx" id="running-nginx"></a>

Run a new pod, with the following settings:

* name: nginx1
* image name: nginx

Hint

This is a „normal” pod - there is no need to run it in interactive mode. Also, since the nginx image will automatically start the nginx daemon, there is no need to specify a command to run.

Solution

```
kubectl run nginx1 --image=nginx
```

Check that the pod is running. On what host has it been scheduled?

Note

Chances are it has been scheduled on the other node (not the one on which the alpine pod is running). Kubernetes does its best to balance the workload among worker nodes.

Solution

```
kubectl get pod
```

```
kubectl get pod -o wide
```

What is the IP address of the pod?

Hint

```
kubectl describe ...
```

Solution

```
kubectl describe pod nginx1
```

Connect to the IP address by using `curl`. You should see the default `nginx` welcome page.

Solution

curl POD\_IP

### Getting Inside a Running Pod <a href="#getting-inside-a-running-pod" id="getting-inside-a-running-pod"></a>

Run a bash shell inside the nginx pod.

Hint

kubectl exec -it POD\_NAME -- COMMAND

Solution

```
kubectl exec -it nginx1 bash
```

Change the contents of the default nginx `index.html` file: `/usr/share/nginx/html/index.html`.

Hint

You could use a text editor or the following command:

```
echo "new content" > /path/to/desired/file.html
```

Exit the shell (type exit or press Ctrl-D). Is the pod still running? Why or why not?

Note

When the main process inside a container is stopped, the entire container stops. However, the shell was not the main process inside the container - the main process was (and still is) `nginx`!

Solution

From *inside the pod*:

```
exit
```

From the host (node):

```
kubectl get pod
```

Using `curl`, connect to the web server once again. You should receive the new contents of the `index.html` file.

### Deleting a Pod <a href="#deleting-a-pod" id="deleting-a-pod"></a>

Time to do some cleanup… delete the `alpine1` pod.

Solution

```
kubectl get pod
```

```
kubectl delete pod alpine1
```

```
kubectl delete pod nginx1
```
