Kubernetes for DevOps 7 minute read

Hai semuanya, di materi kali ini kita akan membahas Menggunakan image yang kita buat pada Kubernetes cluster dengan Minikube. Jadi selain menggunakan service yang di publish oleh official image docker/podman terkadang kita juga perlu menjalankan service docker/podman image yang kita buat sendiri. Ada beberapa cara yang bisa kita gunakan pada Minikube cluster

  1. Save/Load from archive .tar files
  2. Build container image in minikube cluster
  3. Publish to public registry

Ok langsung aja kita ke pembahasan yang pertama

Save/Load from archive .tar files

Untuk menggunakan Save/Load Container image pada minikube, kita perlu build dulu image yang akan kita gunakan, contohnya berikut adalah file Dockerfile

Dan berikut adalah file index.html yang digunakan pada Dockerfile diatas:

Sekarang kita coba build dengan menggunakan perintah docker seperti berikut:

Jika dirunning hasilnya seperti berikut:

 01-getting-started  docker build -t dimmaryanto93/kubernetes-cource:1.0 .
[+] Building 3.9s (7/7) FINISHED
 => [internal] load build definition from Dockerfile                                           0.0s
 => => transferring dockerfile: 31B                                                            0.0s
 => [internal] load .dockerignore                                                              0.0s
 => => transferring context: 2B                                                                0.0s
 => [internal] load metadata for docker.io/library/nginx:mainline                              3.8s
 => [internal] load build context                                                              0.0s
 => => transferring context: 32B                                                               0.0s
 => [1/2] FROM docker.io/library/nginx:mainline@sha256:2834dc507516af02784808c5f48b7cbe38b8ed  0.0s
 => CACHED [2/2] COPY index.html /usr/share/nginx/html/                                        0.0s
 => exporting to image                                                                         0.0s
 => => exporting layers                                                                        0.0s
 => => writing image sha256:7b1c3ff864355cd0c597c87ba6bf6bed73f8313bd30e9e2ce1ea9575bb749963   0.0s
 => => naming to docker.io/dimmaryanto93/kubernetes-cource:1.0

Sekarang setelah kita memiliki container image, kita akan load container image tersebut ke minikube cluster dengan menggunakan perintah minikube image

 01-getting-started  minikube image -h
Manage images

Available Commands:
  build       Build a container image in minikube
  load        Load a image into minikube
  ls          List images
  pull        Pull images
  push        Push images
  rm          Remove one or more images
  save        Save a image from minikube
  tag         Tag images

Use "minikube <command> --help" for more information about a given command.

Pertama kita akan menggunakan perintah image load command pada minikube, Untuk perintah load kita bisa menggunakan 2 cara yaitu directly from docker image atau dengan load from file .tar. Nah kalau saya sendiri lebih sering menggunakan directly from docker image dengan perintah seperti berikut:

Jika sudah selesai, kita bisa lihat dengan menggunakan perintah

Jika dijalankan maka hasilnya seperti berikut:

 01-getting-started  minikube image load dimmaryanto93/kubernetes-cource:1.0

 01-getting-started  minikube image ls
...
docker.io/dimmaryanto93/kubernetes-cource:1.0

Nah sekarang setelah imagenya tersedia di cluster, kita bisa jalankan dengan menggunakan perintah kubectl run --image-pull-policy='Never' seperti berikut:

Jika di jalankan maka hasilnya seperti berikut:

 01-getting-started  kubectl run nginx-app --image='dimmaryanto93/kubernetes-cource:1.0' --image-pull-policy='Never' --port=80
pod/nginx-app created

 01-getting-started  kubectl get pod
NAME        READY   STATUS    RESTARTS   AGE
nginx-app   1/1     Running   0          10s

Build container image in minikube cluster

Selain menggunakan Save/Load kita juga bisa menggunakan build directly ke minikube cluster menggunakan perintah minikube image build Untuk lebih detail kita bisa check dokumentasinya:

 01-getting-started  minikube image build -h
Build a container image, using the container runtime.

Examples:
minikube image build .

Options:
      --all=false: Build image on all nodes.
      --build-env=[]: Environment variables to pass to the build. (format: key=value)
      --build-opt=[]: Specify arbitrary flags to pass to the build. (format: key=value)
  -f, --file='': Path to the Dockerfile to use (optional)
  -n, --node='': The node to build on. Defaults to the primary control plane.
      --push=false: Push the new image (requires tag)
  -t, --tag='': Tag to apply to the new image (optional)

Usage:
  minikube image build PATH | URL | - [flags] [options]

Use "minikube options" for a list of global command-line options (applies to all commands).

Sekarang kita coba untuk build docker image yang sebelumnya, dengan perintah seperti berikut:

Jika dijalankan hasilnya seperti berikut:

 01-getting-started  minikube image build -t dimmaryanto93/kubernetes-cource:1.1 .
Sending build context to Docker daemon  9.216kB
Step 1/2 : FROM nginx:mainline
 ---> c316d5a335a5
Step 2/2 : COPY index.html /usr/share/nginx/html/
 ---> 9a6dfda72b33
Successfully built 9a6dfda72b33
Successfully tagged dimmaryanto93/kubernetes-cource:1.1

 01-getting-started  minikube image ls dimmaryanto93/kubernetes-cource
...
docker.io/dimmaryanto93/kubernetes-cource:1.1
docker.io/dimmaryanto93/kubernetes-cource:1.0

 01-getting-started   kubectl set image pod/nginx-app nginx-app='dimmaryanto93/kubernetes-cource:1.1'
pod/nginx-app image updated

 01-getting-started  kubectl get pod
NAME        READY   STATUS    RESTARTS      AGE
nginx-app   1/1     Running   1 (19s ago)   100s

 01-getting-started  kubectl describe pod nginx-app
Name:         nginx-app
Namespace:    default
Priority:     0
Node:         minikube/192.168.59.119
Start Time:   Tue, 01 Feb 2022 18:48:23 +0700
Labels:       run=nginx-app
Annotations:  <none>
Status:       Running
IP:           172.17.0.3
IPs:
  IP:  172.17.0.3
Containers:
  nginx-app:
    Container ID:   docker://c78bf452350b1371120d1439bf7fff48a5f3f2115c336f4b8108ad3ae5f06f19
    Image:          dimmaryanto93/kubernetes-cource:1.1
    Image ID:       docker://sha256:9a6dfda72b3330b8725de35c6e8934e9b35fe1eef8393e2e0b5708a72b23b6c0
    Port:           80/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Tue, 01 Feb 2022 18:49:44 +0700
    Last State:     Terminated
      Reason:       Completed
      Exit Code:    0
      Started:      Tue, 01 Feb 2022 18:48:25 +0700
      Finished:     Tue, 01 Feb 2022 18:49:44 +0700
    Ready:          True
    Restart Count:  1
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-s6dfp (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  kube-api-access-s6dfp:
    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  2m7s                default-scheduler  Successfully assigned default/nginx-app to minikube
  Normal  Pulled     2m6s                kubelet            Container image "dimmaryanto93/kubernetes-cource:1.0" already present on machine
  Normal  Created    46s (x2 over 2m6s)  kubelet            Created container nginx-app
  Normal  Started    46s (x2 over 2m5s)  kubelet            Started container nginx-app
  Normal  Killing    46s                 kubelet            Container nginx-app definition changed, will be restarted
  Normal  Pulled     46s                 kubelet            Container image "dimmaryanto93/kubernetes-cource:1.1" already present on machine

Publish to public registry

Dengan menggunakan minikube kita juga bisa menggunakan Public Registry seperti Docker HUB, Red Hat Quay dan lain-lain.

Sekarang yang kita perlu lakukan adalah coba push imagenya ke Public Registry, misalnnya kita menggunakan Docker HUB dengan perintahnya seperti berikut:

docker login

docker push dimmaryanto93/kubernetes-cource:1.0

Seperti berikut hasilnya:

docker-private-registry

Jika dijalankan maka hasilnya seperti berikut:

➜  ~ kubectl run nginx-private-app --image dimmaryanto93/kubernetes-cource:1.0
pod/nginx-private-app created

➜  ~ kubectl get pod
NAME                READY   STATUS    RESTARTS   AGE
nginx-private-app   1/1     Running   0          71s

➜  ~ kubectl describe pod/nginx-private-app
Name:         nginx-private-app
Namespace:    default
Priority:     0
Node:         minikube/192.168.59.116
Start Time:   Tue, 01 Feb 2022 22:00:28 +0700
Labels:       run=nginx-private-app
Annotations:  <none>
Status:       Running
IP:           172.17.0.3
IPs:
  IP:  172.17.0.3
Containers:
  nginx-private-app:
    Container ID:   docker://7d7c24228450ec909bdff802bf7c3cfba856f95985b882f70f6f7f1e28424d44
    Image:          dimmaryanto93/kubernetes-cource:1.0
    Image ID:       docker-pullable://dimmaryanto93/kubernetes-cource@sha256:bce870a1cfc768aa9cb6affe71e18ac7dc3c6997ad016d3ce44af0e8ecae50c9
    Port:           <none>
    Host Port:      <none>
    State:          Running
      Started:      Tue, 01 Feb 2022 22:01:09 +0700
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-7zv7k (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  kube-api-access-7zv7k:
    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  95s   default-scheduler  Successfully assigned default/nginx-private-app to minikube
  Normal  Pulling    94s   kubelet            Pulling image "dimmaryanto93/kubernetes-cource:1.0"
  Normal  Pulled     54s   kubelet            Successfully pulled image "dimmaryanto93/kubernetes-cource:1.0" in 39.727921156s
  Normal  Created    54s   kubelet            Created container nginx-private-app
  Normal  Started    54s   kubelet            Started container nginx-private-app