Skip to content

vladcuevas/Minikubes-Labs

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Minikube Labs

Minikube is a local Kubernetes solution designed to make it easy to learn and develop for Kubernetes. All you need is Docker (or a similar container technology) or a Virtual Machine environment, and you can start a Kubernetes cluster with a single command: minikube start.

In this lab, we will use Docker for our container environment. You can find a few useful Docker commands here.

Minikube is designed to create single-node clusters, which can be helpful for those pursuing Kubernetes certifications. You can find more information about Kubernetes certifications from the Cloud Native Computing Foundation (CNCF) here, including the Certified Kubernetes Administrator (CKA) certification.

Once you have created a Docker image, you will want to run it in a cluster. There are several options for doing so, but we will start with the smallest unit, the pod. For example, you can create one pod for the API and another for the frontend.

To create a pod from your Docker images, follow the steps provided in this link.

To create a deployment with a custom Docker image, you can use the following kubectl command:

codekubectl run --image my-spring-boot-demo-docker:latest app

After executing this command, you should see a message confirming that the pod has been created:

codepod/app created

To view the status of your pods, you can run the following command:

codekubectl get pods

If you use the -w option with this command, it will watch for changes in the pod's status and display updates in real-time, similar to the -f option in the Linux tail command.

To delete a pod, you can use the following command:

codekubectl delete pod 

Replace `` with the actual name of the pod you want to delete.

Deployments

Lets start using Deployments and replicas with our Spring Boot application, that you can find in this link

> kubectl create deployment --image my-spring-boot-demo-docker:latest app

We can check the deployments with:

kubectl get deployments

We can also specify the option -l to filter by label.

You might also want to get the pods, and if you do so, there will be a pod with a random name. This is important in case that we want to scale, and for that we can create replicas like this:

> kubectl scale --replicas=3 deployment/app
deployment.apps/app scaled

We can delete our deployments with:

> kubectl delete deployment app
deployment.apps "app" deleted

Now, we'll start tagging with different names our container:

> docker image tag my-spring-boot-demo-docker:latest vlad0x/my-spring-boot-demo-docker:v1
> docker image tag my-spring-boot-demo-docker:latest vlad0x/my-spring-boot-demo-docker:v2
> docker image push vlad0x/my-spring-boot-demo-docker:v1
The push refers to repository [docker.io/vlad0x/my-spring-boot-demo-docker]
8053c93da4dd: Layer already exists
d03e5d303c2e: Layer already exists
dc9fa3d8b576: Layer already exists
27ee19dc88f2: Layer already exists
c8dd97366670: Layer already exists
v1: digest: sha256:2f76b217a9090a6b692681ee33c9259ca84d25068cd1723baf55d9dbb73ee1d0 size: 1374
> docker image push vlad0x/my-spring-boot-demo-docker:v2
The push refers to repository [docker.io/vlad0x/my-spring-boot-demo-docker]
8053c93da4dd: Layer already exists
d03e5d303c2e: Layer already exists
dc9fa3d8b576: Layer already exists
27ee19dc88f2: Layer already exists
c8dd97366670: Layer already exists
v2: digest: sha256:2f76b217a9090a6b692681ee33c9259ca84d25068cd1723baf55d9dbb73ee1d0 size: 1374

In order for the Kubernetes to work, the Docker images must be in a public location, if we are working with copyrighted images, we must provide a secret.

We can create a deployment using any of our images, then we can describe our deployment and see the image that is using, which is the same image that is used for replicas.

> kubectl create deployment app --image=vlad0x/my-spring-boot-demo-docker:v1
deployment.apps/app created
> kubectl get deployments
NAME       READY   UP-TO-DATE   AVAILABLE   AGE
app        1/1     1            1           9s
> kubectl describe deployment app
Name:                   app
Namespace:              default
CreationTimestamp:      Fri, 09 Sep 2022 19:37:38 -0500
Labels:                 app=app
Annotations:            deployment.kubernetes.io/revision: 1
Selector:               app=app
Replicas:               1 desired | 1 updated | 1 total | 1 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  app=app
  Containers:
   my-spring-boot-demo-docker:
    Image:        vlad0x/my-spring-boot-demo-docker:v1
    Port:         <none>
    Host Port:    <none>
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  <none>
NewReplicaSet:   app-65d8f569c4 (1/1 replicas created)
Events:
  Type    Reason             Age   From                   Message
  ----    ------             ----  ----                   -------
  Normal  ScalingReplicaSet  21s   deployment-controller  Scaled up replica set app-65d8f569c4 to 1

If you run the get pods command you'll see that the pod was replicated with same name followed by other random characters:

> kubectl get pods
NAME                        READY   STATUS    RESTARTS   AGE
app-65d8f569c4-4m6fj        1/1     Running   0          59s
app-65d8f569c4-hxn9j        1/1     Running   0          6m43s
app-65d8f569c4-kzrwg        1/1     Running   0          59s

The replicas will allow us to maintain high availability of the application, this is the secret of Kubernetes

We can test this by deleting the pods and then getting the pods, inmediately the replicaset will generate new pods for you.

> kubectl delete pods --all
pod "app-65d8f569c4-4m6fj" deleted
pod "app-65d8f569c4-hxn9j" deleted
pod "app-65d8f569c4-kzrwg" deleted

> kubectl get pods
NAME                        READY   STATUS    RESTARTS   AGE
app-65d8f569c4-k4j67        1/1     Running   0          19s
app-65d8f569c4-ns5br        1/1     Running   0          19s
app-65d8f569c4-q9nfp        1/1     Running   0          19s

We cannot update replicas, we can update deployments:

# kubectl set image <Name of the container>:<Name of the updated image>
> kubectl set image deployment/app my-spring-boot-demo-docker=vlad0x/my-spring-boot-demo-docker:v2
deployment.apps/app image updated

> kubectl get pods
NAME                        READY   STATUS              RESTARTS   AGE
app-545489db9f-k7qdq        1/1     Running             0          25s
app-545489db9f-pcfdk        1/1     Running             0          23s
app-545489db9f-zls2z        0/1     ContainerCreating   0          28s
app-65d8f569c4-q9nfp        1/1     Terminating         0          28s
balanced-76755b4cd4-n98sz   1/1     Running             0          12m

When we change the image, we can see how some pods are terminating, and other are being created, and this allows our application to stay running while we update, certainly a lot of stability for our application. To avoid downtime always have more than two replicas.

If we run again our describe command we can see how the image was changed and the replicas at the end of the result:

> kubectl describe deployment/app
Name:                   app
Namespace:              default
CreationTimestamp:      Fri, 09 Sep 2022 19:37:38 -0500
Labels:                 app=app
Annotations:            deployment.kubernetes.io/revision: 2
Selector:               app=app
Replicas:               3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  app=app
  Containers:
   my-spring-boot-demo-docker:
    Image:        vlad0x/my-spring-boot-demo-docker:v2
    Port:         <none>
    Host Port:    <none>
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  <none>
NewReplicaSet:   app-545489db9f (3/3 replicas created)
Events:
  Type    Reason             Age    From                   Message
  ----    ------             ----   ----                   -------
  Normal  ScalingReplicaSet  26m    deployment-controller  Scaled up replica set app-65d8f569c4 to 1
  Normal  ScalingReplicaSet  20m    deployment-controller  Scaled up replica set app-65d8f569c4 to 3
  Normal  ScalingReplicaSet  4m     deployment-controller  Scaled up replica set app-545489db9f to 1
  Normal  ScalingReplicaSet  3m57s  deployment-controller  Scaled down replica set app-65d8f569c4 to 2
  Normal  ScalingReplicaSet  3m57s  deployment-controller  Scaled up replica set app-545489db9f to 2
  Normal  ScalingReplicaSet  3m55s  deployment-controller  Scaled down replica set app-65d8f569c4 to 1
  Normal  ScalingReplicaSet  3m55s  deployment-controller  Scaled up replica set app-545489db9f to 3
  Normal  ScalingReplicaSet  3m52s  deployment-controller  Scaled down replica set app-65d8f569c4 to 0

As you can see in the above result, there is also a list of events that can help us to understand how our application is behaving

Now we are going to create a service to expose the ports:

kubectl expose deployment app --port=8080 --type=LoadBalancer

Then we can check the services with the below command:

> kubectl expose deployment app --port=8080 --type=LoadBalancer
service/app exposed

> kubectl get services
NAME             TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
app              LoadBalancer   10.102.45.139   <pending>     8080:30368/TCP   18s

You'll notice that the EXTERNAL-IP as pending, the Load Balance service gives you an external IP, anybody can connect to this external IP to the application, this is not recommended as it is bypassing completely your network. Only use load balancers when you know about security, this will be more noticeable when using a Cloud service, where the EXTERNAL-IP will be configured, in the Minikube it won't happen.

Now we can run our application with the below command, that will in our case open a browser to check the spring boot home page, this application contains more REST APIs that can be called with CURL or POST MAN:

minikube service app

Each of the pods will work with a round robin to select which of the pods to use.

So far we have created all our deployments in the default namespace. We can create a new namespace with the below command:

> kubectl create namespace dev
namespace/dev created
PS C:\Users\Vlad> kubectl get namespace
NAME                   STATUS   AGE
default                Active   18d
dev                    Active   7s
kube-node-lease        Active   18d
kube-public            Active   18d
kube-system            Active   18d

Note: only admins must ave access to the kube-system.

We can create another app in the new namespace like this:

kubectl create deployment --image vlad0x/my-spring-boot-demo-docker:v2 --namespace dev app

We can see all the services, deployments, apps with the below command:

kubectl get all -A

Don't forget that you can see all of this in the dashboard as well:

How to get all of this in the CI/CD process?

Just like with Docker, we can use a YAML, there is a very simple trick to create a YAML without writting a YAML, we can do so with the option --dry-run and -o specifying yaml like this:

> kubectl create deployment --image vlad0x/my-spring-boot-demo-docker:v2 --namespace dev app --dry-run=client -o yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  creationTimestamp: null
  labels:
    app: app
  name: app
  namespace: dev
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app
  strategy: {}
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: app
    spec:
      containers:
      - image: vlad0x/my-spring-boot-demo-docker:v2
        name: my-spring-boot-demo-docker
        resources: {}
status: {}

Our output is our YML. We can do exactly the same for pods:

>kubectl run --image vlad0x/my-spring-boot-demo-docker:v2 app --dry-run=client -o yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: app
  name: app
spec:
  containers:
  - image: vlad0x/my-spring-boot-demo-docker:v2
    name: app
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}
kubectl expose deployment app --namespace default --port=8080 --type=LoadBalancer --dry-run=client -o yaml
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  labels:
    app: app
  name: app
  namespace: default
spec:
  ports:
  - port: 8080
    protocol: TCP
    targetPort: 8080
  selector:
    app: app
  type: LoadBalancer
status:
  loadBalancer: {}

We can mix different YML separated by ---, where we must be careful with the labels, which is the way how the Service and the Deployments are going to be linked.

We can copy or pass this output to a file and we can save with any name we want, i.e deployment.yml and run it with the below command:

kubectl create -f deployment.yml

If by any reason we want to know more about the variables to set we can start for example setting the api with a command like this:

> kubectl api-resources

What exactly is Kubernetes?

At the very core it is just an API, you can use your browser, you can write a program like java, python, node, etc. Any utility that you want to use but the very popular client that people like is the kubectl "Cube Cutle".

Internally a cluster has the Constrol Plane, the nodes and the Cloud provider API. In the Control plane there are important componets like the brain of it called etcd, the scheduler, the api, the c-c-m and the c-m.

Each node consists of two components one is the kubelet the other one is the k-proxy (this one is very important because every part gets its own IP address). Much more documentation can be found in this link

When you install your kubernets, you can have hundreds of clusters, but generally you'll have one client, thats where kubectl comes into play.

Requirements

Container or virtual machine manager, such as: Docker, Hyperkit, Hyper-V, KVM, Parallels, Podman, VirtualBox, or VMware Fusion/Workstation

Installation

Installers can be found in this link from the official minikube page,

In case that you are using chocolatey, you can execute the below command:

choco install minikube

Start the cluster

From the terminal with administrator privileges, execute the below command, which will download Kubernetes with the current images, it will also create the docker container with 2 CPUs and 8GB of RAM:

minikube start

You should see a message like this at the end:

🏄  Done! kubectl is now configured to use "minikube" 
    cluster and "default" namespace by default

If anything goes wrong, the container was not properly initialized, you might see an output telling that the PROVIDER is not running

😄  minikube v1.26.1 on Microsoft Windows 11 Pro 10.0.22000 Build 22000
✨  Using the docker driver based on existing profile
💣  Exiting due to PROVIDER_DOCKER_NOT_RUNNING: "docker version --format -" 
    exit status 1: error during connect: This error may indicate that the 
    docker daemon is not running.: 
    Get "http://%2F%2F.%2Fpipe%2Fdocker_engine/v1.24/version": 
    open //./pipe/docker_engine: The system cannot find the file specified.
💡  Suggestion: Start the Docker service
📘  Documentation: https://minikube.sigs.k8s.io/docs/drivers/docker/

There is more help in this link

Interacting with the cluster

In previous step the kubectl was installed and configured, from this point we can make use of the cluster:

kubectl get po -A

We can see our contexts with the below command, a context is a mix of your user and the server where you are running, and will tell where the kubectl is executing commands, the context essentially dictates where to run the command:

kubectl config view

At any time we can list all the deployments with the below command:

kubectl get deploy

Dashboard

Minikube comes with a beautiful dashboard where we can see Workloads, Services, Config, Storage, Clusters, Definitions and Settings where we can configure a bunch of things

minikube dashboard

The Hello World Example

We can create a hello world sample with the below commands:

kubectl create deployment hello-minikube --image=k8s.gcr.io/echoserver:1.4
kubectl expose deployment hello-minikube --type=NodePort --port=8080

We can check if the service started with the below command:

kubectl get services hello-minikube

The easiest way to access this service is to let minikube launch a web browser for you:

minikube service hello-minikube

Alternatively, use kubectl to forward the port:

kubectl port-forward service/hello-minikube 7080:8080

We can delete a deployment with the delete deploy

kubectl delete deploy hello-minikube

LoadBalancer deployments

To access a LoadBalancer deployment, use the “minikube tunnel” command. Here is an example deployment:

kubectl create deployment balanced --image=k8s.gcr.io/echoserver:1.4
kubectl expose deployment balanced --type=LoadBalancer --port=8080

In another window, start the tunnel to create a routable IP for the ‘balanced’ deployment:

minikube tunnel

To find the routable IP, run this command and examine the EXTERNAL-IP column:

kubectl get services balanced

Your deployment is now available at :8080

Manage the cluster

Pause Kubernetes without impacting deployed applications:

minikube pause

Unpause a paused instance:

minikube unpause

Halt the cluster:

minikube stop

Increase the default memory limit (requires a restart):

minikube config set memory 16384

Browse the catalog of easily installed Kubernetes services, the below command allows us to see the installed addons:

minikube addons list

Create a second cluster running an older Kubernetes release:

minikube start -p aged --kubernetes-version=v1.16.1

Delete all of the minikube clusters:

minikube delete --all

Create a deployment for nginx

To create an nginx deployment using kubectl, run the following command:

kubectl create deployment --image nginx nginx

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors