Skip to content

Manifest (kubernetes part)

Creating a Manifest for a Python Application

The first step in creating a manifest is to open Visual Studio Code and create a new file, for example, app-pod.yml. Next, you need to specify the apiVersion and kind of this manifest and add a metadata section with name (pod name) and namespace fields (for logical and sometimes physical separation of pods and other resources).

One example of using namespaces is the "one development team — one namespace" approach. This way, if different development teams can only create resources in designated namespaces, it allows you to clearly distinguish which resources are responsible for what. Also, the namespace name can indicate its purpose. For example, kube-system contains pods needed by the cluster itself. Resources within a namespace must have unique names, but names can be duplicated if they belong to different namespaces.

Limits on CPU, Disk Memory, and other resource usage can be imposed on namespaces. Such limits will prevent, for example, one team from consuming all cluster resources.

Alright, now let's get back to the manifest! You can also add a labels field — a collection of key-value pairs that helps organize pods. Other resources can reference pods using this field.

You also need to describe the container specification. To do this, add a new spec section and within it a containers section. Containers is the section where one or more containers belonging to this pod are described. The first container will include the following description:

  • name — the container name;
  • image — the full path to the image including the repository name. By default, Kubernetes will use Docker Hub to search for the specified images.

So our file will look like this:

apiVersion: v1
kind: Pod
metadata:
  name: kube2py
  namespace: mateapp
  labels:
    app: kube2py
spec:
  containers:
    - name: kube2py
      image: semorgana/kube2py-repo:1.0.0
      ports:
        - containerPort: 8080

Now it's time to deploy the application. To do this, run the command kubectl apply -f app-pod.yml from the terminal:

As you can see, something went wrong. Let's try to figure it out! The ErrImagePull status indicates that Kubernetes could not download the image. You can find out details using the command kubectl describe pod kube2py -n mateapp:

Events:
  Type     Reason     Age                  From               Message
  ----     ------     ----                 ----               -------
  Normal   Scheduled  2m16s                default-scheduler  Successfully assigned mateapp/kube2py to docker-desktop
  Normal   Pulling    42s (x4 over 2m15s)  kubelet            Pulling image "kulyk404/kub2py"
  Warning  Failed     39s (x4 over 2m13s)  kubelet            Failed to pull image "kulyk404/kub2py": Error response from daemon: pull access denied for kulyk404/kub2py, repository does not exist or may require 'docker login': denied: requested access to the resource is denied
  Warning  Failed     39s (x4 over 2m13s)  kubelet            Error: ErrImagePull
  Warning  Failed     28s (x6 over 2m13s)  kubelet            Error: ImagePullBackOff
  Normal   BackOff    17s (x7 over 2m13s)  kubelet            Back-off pulling image "kulyk404/kub2py"

The Events section shows that the scheduler successfully chose a worker node for the pod, then kubelet started downloading the image, but an error occurred: the repository does not exist or you need to log in. The reason in this case is a missing letter i in the repository name ikulyk404/kub2py, and this can be fixed by editing the manifest that has already been sent to the API server.

To do this, run the command kubectl edit pod kube2py -n mateapp, after which the Vim editor will open. To start editing, press the English i, find the line that needs to be edited, and add the letter i to the repository name in the container image description section. Then press ESC, type wq, and press Enter. wq means write and quit:

kubectl edit pod kube2py -n mateapp         1 ✘  docker-desktop ⎈  21:01:36
pod/kube2py edited

Let's check all pods in the namespace again. The error that occurred this time: ikulyk404/kub2py:latest not found. This means that kubelet could not find an image with the latest tag. So you need to specify the exact image version you intend to use. Run the command kubectl edit pod kube2py -n mateapp, add the version, and save the changes.

Upon re-checking the pods in the namespace, the Running status will confirm that everything is in order:

kubectl get pods -n mateapp             ✔  23s   docker-desktop ⎈  21:11:40
NAME      READY   STATUS    RESTARTS          AGE
busybox   1/1     Running   172 (5m57s ago)   7d6h
kube2py   1/1     Running   0                 18m
nginx     1/1     Running   0                 7d6h

Testing can be done through the additional busybox pod that is already in the namespace. To see IPs, run the command kubectl get pods -o wide -n mateapp, and then enter busybox:

kubectl -n mateapp exec -it busybox -- sh and execute the curl command:

 root@busybox:/ ]$ curl 10.1.0.9:8080

    Docker is Awesome!
<pre>                   ##        .</pre>
<pre>             ## ## ##       ==</pre>
<pre>          ## ## ## ##      ===</pre>
<pre>      /""""""""""""""""\___/ ===</pre>
<pre> ~~~ (~~ ~~~~ ~~~ ~~~~ ~~ ~ /  ===-- ~~~</pre>
<pre>      \______ o          __/</pre>
<pre>        \    \        __/</pre>
<pre>         \____\______/</pre>

Another important command is kubectl port-forward, which allows you to redirect traffic from one or more local ports to a pod. This command can be useful during troubleshooting or testing and looks like this: kubectl port-forward pod/kube2py 8081:8080 -n mateapp, where pod/kube2py indicates that we are doing a port-forward to a pod, followed by the specific pod. Then you specify which local port and which pod port the traffic will be redirected to.

kubectl port-forward pod/kube2py 8081:8080 -n mateapp  ✔  30sdocker-desktop ⎈  21:24:05
Forwarding from 127.0.0.1:8081 -> 8080
Forwarding from [::1]:8081 -> 8080

The localhost:8081 page in the browser will look like this: