Try   HackMD

Chapter 4 : Basic of Kubernetes

4.1 Node

Node is a worker point in Kubernetes, previously called minion. Actually, Node is in the form of Virtual Machine or Physical Machine (Bare Metal), but there is additional management by Kubernetes.

Like the previous material, nodes already have kubelet, kube-proxy, and container-manager. You can see the picture below :

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

Well, as explained earlier, there is no need to know where Kubernetes places the node, because it is already the task of Kubernetes, only need to determine how many nodes are working on Kubernetes. If for example 2 nodes have been run, it turns out to be almost full or high traffic, then simply add a node without having to bother with manual settings.

To see the nodes that have been added to minukube Type the following command after starting Minikube :

$ kubectl get node

For details, just type the command:

$ kubectl describe node (nodename)

Replace (nodename) with the existing node name without any brackets.

And then it will outputed like this :

NAME       STATUS   ROLES           AGE   VERSION
minikube   Ready    control-plane   47m   v1.30.0

4.2 Pod

4.2.1 About Pod

Pod is the smallest unit that can be deployed in Kubernetes Cluster. Similar to deploying an application in Docker that is placed in a Container, the difference is deploying in Kubernetes will be deployed into a Pod, why is that? because in Kubernetes Pod can be filled with 1 or more containers. Yes, simply put, Pod contains applications that are run in Kubernetes Cluster.

The picture is like this :

Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

As seen in the picture in Pod can be 2 containers. Kubernetes uses a different layer called pod to run 2 or more containers directly.

How to view all Pods :

$ kubectl get pod

To view Pod details:

$ kubectl describe pod (podname)

Replace (podname) with the existing node name without any brackets.

So, it will outputed like this :

hilmi@minkube:~$ kubectl get pod
No resources found in default namespace.

Yeah, because i didn't make Pod it will outputed No resources found in default namespace.

4.2.2 Making Pod

To create a pod, make sure you do it in the following steps:

  1. Creating a Configuration File

    The first step to take to create a Pod is to use a yaml file, as below:

    4.2.2.1-template-pod.yaml

    ​​​ apiVersion: v1
    ​​​ kind: Pod
    ​​​ metadata:
    ​​​   name: pod-name
    ​​​ spec:
    ​​​   containers:
    ​​​     - name: container-name
    ​​​       image: image-name
    ​​​       ports:
    ​​​         - containerPort: 80
    

    With the explanation below:

    • apiVersion: v1; determines the pod API version used.
    • kind: Pod; determines the type to be created (of course Pod).
    • metadata; adds metadata for pods
    • metadata: mame; adds metadata to what the pod will be named.
    • spec; determines the configuration to be created.
    • containers; creates the containers themselves. (You can also create more than one in one configuration file).
    • containers: name; determines the name of the container.
    • containers: image; determines what image/application will be used in the container.
    • ports: containerPort: 80; determines the port that will run in the container.

    For example, here we will try with the nginx application, a lightweight web service application that runs on port 80.

    4.2.2.2-nginx-pod.yaml

    ​​​​apiVersion: v1
    ​​​​kind: Pod
    ​​​​metadata:
    ​​​​  name: test-pod
    ​​​​spec:
    ​​​​  containers:
    ​​​​    - name: nginx
    ​​​​      image: nginx
    ​​​​      ports:
    ​​​​        - containerPort: 80
    
  2. Create a Pod with the .yaml file that has been created

    After creating the .yaml file, run it in the terminal with the command as below :

    ​​​​$ kubectl create -f (podfile).yaml
    

    Replace (podfile) with the existing node name without any brackets.
    If you use a file created like the example, it will look like this :

    ​​​​$ kubectl create -f 4.2.2.2-nginx-pod.yaml 
    

    So it produces the output :

    ​​​​pod/nginx created
    
  3. Check the installed Pod

    Just like before to check the list of installed pods, use the command :

    ​​​​$ kubectl get pod
    

    So it will produce output :

    ​​​​NAME        READY   STATUS              RESTARTS   AGE
    ​​​​nginx-pod   0/1     ContainerCreating   0          16s
    

    If you see, in that example Pod status is creating just wait and BOOM, like this :

    ​​​​NAME        READY   STATUS    RESTARTS   AGE
    ​​​​nginx-pod   1/1     Running   0          15m 
    

    You can also get more details from the pod list with the command :

    ​​​​$ kubectl get pod -o wide
    

    So it will produce output :

    ​​​​NAME        READY   STATUS    RESTARTS   AGE   IP           NODE       NOMINATED NODE   READINESS GATES
    ​​​​nginx-pod   1/1     Running   0          23m   10.244.0.3   minikube   <none>           <none>
    

    And, for details of a single pod, you can type in the command :

    ​​​​$ kubectl describe pod (podname)
    

    Replace (podname) with the existing node name without any brackets.

    And the example this :

    ​​​​$ kubectl describe pod nginx-pod
    

    And it will outputed like this :

    ​​​​Name:             nginx-pod
    ​​​​Namespace:        default
    ​​​​Priority:         0
    ​​​​Service Account:  default
    ​​​​Node:             minikube/192.168.49.2
    ​​​​Start Time:       Fri, 23 Aug 2024 22:34:10 +0700
    ​​​​Labels:           <none>
    ​​​​Annotations:      <none>
    ​​​​Status:           Running
    ​​​​IP:               10.244.0.3
    ​​​​IPs:
    ​​​​  IP:  10.244.0.3
    ​​​​Containers:
    ​​​​  nginx:
    ​​​​    Container ID:   docker://20bc159abb465f1bf9bd4548805aa485091934463c6e365c24ec2ca972b88580
    ​​​​    Image:          nginx
    ​​​​    Image ID:       docker-pullable://nginx@sha256:447a8665cc1dab95b1ca778e162215839ccbb9189104c79d7ec3a81e14577add
    ​​​​    Port:           80/TCP
    ​​​​    Host Port:      0/TCP
    ​​​​    State:          Running
    ​​​​      Started:      Fri, 23 Aug 2024 22:35:14 +0700
    ​​​​    Ready:          True
    ​​​​    Restart Count:  0
    ​​​​    Environment:    <none>
    ​​​​    Mounts:
    ​​​​  /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-jrw6d (ro)
    ​​​​Conditions:
    ​​​​  Type                        Status
    ​​​​  PodReadyToStartContainers   True
    ​​​​  Initialized                 True
    ​​​​  Ready                       True
    ​​​​  ContainersReady             True
    ​​​​  PodScheduled                True
    ​​​​Volumes:
    ​​​​  kube-api-access-jrw6d:
    ​​​​    Type:                    Projected (a volume that contains injected data from multiple sources)
    ​​​​    TokenExpirationSeconds:  3607
    ​​​​    ConfigMapName:           kube-root-ca.crt
    ​​​​    ConfigMapOptional:       <nil>
    ​​​​    DownwardAPI:             true
    ​​​​QoS Class:                   BestEffort
    ​​​​Node-Selectors:              <none>
    ​​​​Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
    ​​​​                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
    ​​​​Events:
    ​​​​  Type    Reason     Age   From               Message
    ​​​​  ----    ------     ----  ----               -------
    ​​​​  Normal  Scheduled  25m   default-scheduler  Successfully assigned default/nginx-pod to minikube
    ​​​​  Normal  Pulling    25m   kubelet            Pulling image "nginx"
    ​​​​  Normal  Pulled     24m   kubelet            Successfully pulled image "nginx" in 1m0.809s (1m0.809s including waiting). Image size: 187694648 bytes.
    ​​​​  Normal  Created    24m   kubelet            Created container nginx
    ​​​​  Normal  Started    24m   kubelet            Started container nginx
    

    Yeah, its full of description and info that need it.

4.2.3 Accessing Pod

In certain cases, it is necessary to check whether the pod is running properly or not. To check the Pod, use the access method with the command:

$ kubectl port-forward (podname) (portaccess:podport)

Replace podname, portaccess, and podport with the existing node names without brackets. portaccess is the port that will be accessed through your device, podport is the port running in the Container according to the configuration

For example, to access a previously created port :

$ kubectl port-forward nginx-pod 8888:80

It will outputed like this :

Forwarding from 127.0.0.1:8888 -> 80
Forwarding from [::1]:8888 -> 80

And if you check use cat command ($ curl 127.0.0.1:8888) it wil outputed nginx hello like this :

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

**

4.2.4 Deleting Pod

For certain cases, sometimes it is necessary to delete Pods, the way to delete Pods can use the following method:

$ kubectl delete pod (podname)

or

$ kubectl delete pod (podname-1) (podname-2) (podname-3)

if there are many pods to delete, or

$ kubectl delete pod -l (key=value)

If based on a specific label key, and finally, if you want to delete what is based on namespace, you can use :

$ kubectl delete pod -all --namespace (namespacename)

Just adjust it for what kind of use. Here's some example :

$ kubectl delete pod nginx-pod

and the nginx-pod will deleted :

hilmi@minkube:~/kubernetes/Chapter 4 - Kubernetes Component$ kubectl delete pod nginx-pod
pod "nginx-pod" deleted

4.3 Label

Labels in Kubernetes are useful for marking Pods, so that Pods will be organized, Pods will also be clearer because there is additional information in the Pod Label.

Labels are also not only for Pods, but all resources in Kubernetes, such as Replication Controllers, Replica Sets, Services, etc.

Here is an example of a Pod template with labels :

4.3.1-template-pod-label.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod-name
  labels:
    label-key1: label-value1
    label-key2: label-value2
    label-key3: label-value3
spec:
  containers:
    - name: container-name
      image: image-name
      ports:
        - containerPort: 80

Actually it's the same, but the only difference is that there are additional labels, and here we will use nginx as before :

4.3.2-nginx-pod-labeled.yaml

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
    team: finance
    version: 1.7.2
    environment: production
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
      - containerPort: 80

Here to write free labels as needed and as efficient as possible.

To insert Pods is the same as before:

$ kubectl create -f 4.3.2-nginx-pod-labeled.yaml 

Make sure the metadata name is different from the previously created Pod, or differentiate the Pod metadata name in the yaml so that it can be added.

If happen like this :
Error from server (AlreadyExists): error when creating "4.3.2-nginx-pod-labeled.yaml": pods "nginx-pod" already exists

You must delete the same Pod or use diffrent name in yaml configuration file

To see previously created labels, use the command:

$ kubectl get pod --show-labels

Sehingga akan beroutput :

NAME        READY   STATUS    RESTARTS   AGE   LABELS
nginx-pod   1/1     Running   0          13s   environment=production,team=finance,version=1.7.2

You can also use descibe :

$ kubectl describe pod nginx-pod

And the output, it will diffrent :

Name:             nginx-pod
Namespace:        default
Priority:         0
Service Account:  default
Node:             minikube/192.168.49.2
Start Time:       Sat, 24 Aug 2024 09:59:17 +0700
Labels:           environment=production
                  team=finance
                  version=1.7.2
Annotations:      <none>
Status:           Running
IP:               10.244.0.8
...

It is also possible to add or change labels in Pods directly, but this is not recommended. Here is the command to add:

$ kubectl label pod (podname) (key=value)

Meanwhile, to change, here is the command:

$ kubectl label pod (podname) (key=value) --overwrite

Here's a quick example, to add a flag:

$ kubectl label pod nginx-pod validate=false

And an example of a command to change it:

$ kubectl label pod nginx-pod validate=true --overwrite

And the output :

$ kubectl label pod nginx-pod validate=false
pod/nginx-pod labeled
$ kubectl get pod --show-labels
NAME        READY   STATUS    RESTARTS   AGE   LABELS
nginx-pod   1/1     Running   0          14m   environment=production,team=finance,validate=false,version=1.7.2
$ kubectl label pod nginx-pod validate=true --overwrite
pod/nginx-pod labeled
$ kubectl get pod --show-labels
NAME        READY   STATUS    RESTARTS   AGE   LABELS
nginx-pod   1/1     Running   0          14m   environment=production,team=finance,validate=true,version=1.7.2

As you can see, the label is change, as the command .

Maybe you are thinking right now whether the label is just like that? Of course not, the labels that we have written or added can be searched, this is for ease of searching among other pods, here's how:

$ kubect1 get pods -1 key
$ kubect1 get pods -1 key=value
$ kubect1 get pods -1 '!key'
$ kubectl get pods -1 key! = value
$ kubectl get pods -1 'key in (value1, value2)'
$ kubectl get pods -1 'key notin (value1, value2)

Example for searching labels:

$ kubectl get pods -l environment
$ kubect1 get pods -1 environment=production
$ kubect1 get pods -1 '!environment'
$ kubectl get pods -1 environment! = production
$ kubectl get pods -1 'environment in (production, development)'
$ kubectl get pods -1 'key notin (production, development)

4.4 Annotation

Annotation is similar to Label, only cannot be filtered or queried like label, usually used to add additional information in large sizes, only holds information up to 256kB.

Annotation because of its small memory is usually only for adding information, such as Documentation, Description, etc.

Here is an example of an Annotation template on Kubernetes:

4.4.1-template-pod-annotation.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod-name
  labels:
    label-key1: label-value1
  annotations:
    annotation-key1: "annotation-value"
    annotation-key2: "very-long-annotation-value"
spec:
  containers:
    - name: container-name
      image: image-name
      ports:
        - containerPort: 80

The only difference is that annotations are added, here is an example:

4.4.2-nginx-pod-annotation.yaml

apiVersion: v1
kind: Pod
metadata:
  name: nginx-with-annotation
  labels:
    team: product
    version: "1.0"
    environment: development
  annotations:
    description: "Ini adalah aplikasi yang dibuat oleh tim product"
    apapun: "Apapun itu..."
spec:
  containers:
    - name: nginx
      image: nginx
      ports:
        - containerPort: 80

To see it, run as before:

$ kubectl describe pod (podname)

Ganti podname dengan nama node yang ada tanpa ada tanda kurung.

Lets try :

$ kubectl create -f 4.4.2-nginx-pod-annotation.yaml
pod/nginx-with-annotation created
$ kubectl describe pod nginx-with-annotation

Then it will come out like this:

Name:             nginx-with-annotation
Namespace:        default
Priority:         0
Service Account:  default
Node:             minikube/192.168.49.2
Start Time:       Sat, 24 Aug 2024 17:26:33 +0700
Labels:           environment=development
                  team=product
                  version=1.0
Annotations:      apapun: Apapun itu...
                  description: Ini adalah aplikasi yang dibuat oleh tim product
Status:           Running
IP:               10.244.0.10
...

You can also add annotations directly, same like label, use with this command:

$ kubectl annontate pod (podname) (key=value)

and to change with this command:

$ kubectl annontate pod (podname) (key=value) --overwrite

4.5 Namespace

Namespaces in Kubernetes are a way to share cluster resources between multiple users, teams, or projects. So the case of having the same resources can be resolved.

When to Use Namespaces?

  • When resources in Kubernetes are too many.
  • When you need to separate resources for multi-tenant, team, or environment.
  • The name of the resources can be the same if they are in different namespaces.

To see the namespace use this command:

$ kubectl get namespaces

or

$ kubectl get namespace

or

$ kubectl get ns

Then it will come out with the output:

NAME              STATUS   AGE
default           Active   20h
kube-node-lease   Active   20h
kube-public       Active   20h
kube-system       Active   20h

As an example, we will try to see the Namespace on the Pod :

$ kubectl get pod --namespace (namespacename)

or

$ kubectl get pod -n (namespacename)

Replace namespacename with the name of the namespace you want to search for without the brackets.

Direct example of the code :

$ kubectl get pod -n default

default in namespace is the basic value if the value is not specified by the user

Then it will produce the output:

NAME                    READY   STATUS    RESTARTS   AGE
nginx-with-annotation   1/1     Running   0          8m

To create a namespace on Kubernetes, here is a template for a namespace:
4.5.1-template-namespace.yaml

apiVersion: v1
kind: Namespace
metadata:
  name: nama-namespace
  1. kind: Namespace ; identify that a namespace type will be created.
  2. metadata: name-namespace ; determines what the space will be named.

For Example :
4.5.2-finance-namespace.yaml

apiVersion: v1
kind: Namespace
metadata:
  name: finance

To enter namespace yaml into Kubernetes use the usual command :

$ kubectl create -f (file.yaml)

Replace (file.yaml) with the name of the namespace you want to search for without the brackets.

For Example :

$ kubectl create -f 4.5.2-finance-namespace.yaml
namespace/finance created
$ kubectl get namespaces
NAME              STATUS   AGE
default           Active   20h
finance           Active   37s
kube-node-lease   Active   20h
kube-public       Active   20h
kube-system       Active   20h

To create a Pod in a Namespace, you can do the following:

$ kubectl create -f (yamlpod.yaml) --namespace (namespacename)

Replace (yamlpod.yaml), (namespacename) with the name of the namespace you want to search for without the brackets.
For Example :

$ kubectl create -f 4.2.2.2-nginx-pod.yaml --namespace finance
pod/nginx-pod created

If you search without namespace name, it will outputed like this :

No resources found in default namespace.

Because nginx-pod in finance namespace :

$ kubectl get pod -n finance
NAME        READY   STATUS    RESTARTS   AGE
nginx-pod   1/1     Running   0          4m9s
$ kubectl describe pod -n finance
Name:             nginx-pod
Namespace:        finance
Priority:         0
Service Account:  default
Node:             minikube/192.168.49.2
Start Time:       Sat, 24 Aug 2024 17:53:13 +0700
Labels:           <none>
Annotations:      <none>
Status:           Running
IP:               10.244.0.11

And done, nginx-pod in finance namespace.

Things to note about namespaces:

  1. Pods with the same name can run as long as they are in different namespaces.
  2. Namespaces are not a way to isolate resources.
  3. Even though they are in different namespaces, pods can still communicate with other pods in different namespaces.

Unfortunately, if you already have a Pod and want to put it in a namespace, you can't do it directly, you have to delete the Pod or directly add a new one.

Deleting a Namespace

$ kubectl delete namespace (namespacename)

Replace namespacename with the name of the namespace you want to search for without the brackets.