Prerequisites
Before proceeding with this tutorial, ensure you have:
- Experience creating Docker images
- Knowledge of running Docker containers locally
- Docker installed on your system.
What is a Docker?
Docker is a platform for developers and sysadmins to build, share, and run applications with containers. The use of containers to deploy applications is called containerization. Containers are not new, but their use for easily deploying applications is.
Containerization is increasingly popular because containers are:
Flexible: Even the most complex applications can be containerized. Lightweight: Containers leverage and share the host kernel, making them much more efficient in terms of system resources than virtual machines. Portable: You can build locally, deploy to the cloud, and run anywhere. Loosely coupled: Containers are highly self-sufficient and encapsulated, allowing you to replace or upgrade one without disrupting others. Scalable: You can increase and automatically distribute container replicas across a data center. Secure: Containers apply aggressive constraints and isolations to processes without any configuration required on the part of the user.
Benefits of using Containers over Virtual Machines
Now let’s discuss what is the benefit of Docker over VMs.
Unlike VMs( Virtual Machines ) that run on a Guest OS, using a hypervisor, Docker containers run directly on a host server (for Linux), using a Docker engine, making it faster and lightweight.
Docker containers can be easily integrated compared to VMs. With a fully virtualized system, you get more isolation. However, it requires more resources. With Docker, you get less isolation. However, as it requires fewer resources, you can run thousands of containers on a host. A VM can take a minimum of one minute to start, while a Docker container usually starts in a fraction of a second.
What is a container?
A container is an isolated environment for your code. This means that a container has no knowledge of your operating system, or your files. It runs on the environment provided to you by Docker Desktop. Containers have everything that your code needs in order to run, down to a base operating system. You can use Docker Desktop to manage and explore your containers.
Technology Used in Docker
The programming language used in Docker is GO. Docker takes advantage of various features of Linux kernel like namespaces and cgroups.
namespaces: Docker uses namespaces to provide isolated workspace called containers. When a container is run, docker creates a set of namespaces for it, providing a layer of isolation. Each aspect of a container runs in a separate namespace and its access is limited to that namespace.
cgroups( control groups ): croups are used to limit and isolate the resource usage( CPU, memory, Disk I/O, network etc ) of a collection of processes. cgroups allow Docker engine to share the available hardware resources to containers and optionally enforce limit and constraints.
UnionFS( Union file systems ): are file systems that operate by creating layers, making them very lightweight and fast.It is used by Docker engine to provide the building blocks for containers.
Docker Engine combines the namespaces, cgroups, and UnionFS into a wrapper called a container format. The default container format is libcontainer.
Dockerfile
FROM eclipse-temurin:17-jdk-alpine
VOLUME /tmp
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
Build docker image:
docker build --build-arg JAR_FILE=target/*.jar -t spring-docker .
List all docker images :
docker images
Run docker image:
docker run -p 8080:8080 spring-docker
push docker image to docker hub
login to docker hub:
docker login
Create docker tag :
docker tag spring-docker yourUser/spring-docker:v1
Once we have logged in, we can now push our container to Docker Hub.
docker push username/spring-docker:v1
Kubernetes — the container orchestrator
Kubernetes is a portable, extensible, open source platform for managing containerized workloads and services, that facilitates both declarative configuration and automation. It has a large, rapidly growing ecosystem.
Creating a Kubernetes cluster on your local machine with a tool called Minikube . Minikube creates a single-node Kubernetes cluster running on a virtual machine. A Minikube cluster is only intended for testing purposes, not for production.
Before you install Minikube, you have to install kubectl. Kubernetes provides a command line tool for communicating with a Kubernetes cluster's control plane, using the Kubernetes API.
Once kubectl is installed, go on and install Minikube
Minikube is a local Kubernetes setup primarily used for development and testing purposes. It is a lightweight setup that works with tools like Docker, Virtualbox, etc.
With Minikube installed, you can create a cluster as follows:
minikube start
Automatically select the docker driver in Windows if installed, there are other drivers as well.
The command creates a virtual machine and installs Kubernetes.
Check minikube status:
minikube status
When the command completes, you can verify that the cluster is created with:
kubectl cluster-info
The output will be something like this
Kubernetes control plane is running at https://127.0.0.1:59296
CoreDNS is running at https://127.0.0.1:59296/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
Retrieves Minikube node
List nodes available in the Kubernetes cluster:
kubectl get nodes
Note: Minikube creates a single node.
Retrieves the IP address of the specified node
Retrieves the IP address of the specified node.
minikube ip
SSH
minikube ssh -v 7
minikube ssh docker@{IP Address}
Access Minikube Kubernetes Dashboard
The following command will open the Kubernetes dashboard directly in the browser.
minikube dashboard
If you just want the dashboard URL, execute the following command. It will start the proxy and displays the Kubernetes dashboard URL in the output.
minikube dashboard --url
You have a fully functioning Kubernetes cluster on your machine now.
Create a file named deployment.yaml in your application directory
The first Kubernetes resource is a Deployment. A Deployment creates and runs containers and keeps them alive.
Sample deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-docker
spec:
replicas: 1
selector:
matchLabels:
app: spring-docker
template:
metadata:
labels:
app: spring-docker
spec:
containers:
- name: app
image: yourUser/spring-docker:v1
ports:
- containerPort: 8080
env:
imagePullPolicy: Always
The kubectl explain command can print the specification of every Kubernetes resource directly in your terminal:
kubectl explain deployment
You don't usually talk about containers in Kubernetes.
Instead, you talk about Pods.
What is a Pod?
A Pod is a wrapper around one or more containers.
Most often, a Pod contains only a single container — however, for advanced use cases, a Pod may contain multiple containers.
If a Pod contains multiple containers, they are treated by Kubernetes as a unit — for example, they are started and stopped together and executed on the same node.
A Pod is the smallest unit of deployment in Kubernetes — you never work with containers directly, but with Pods that wrap containers.
Technically, a Pod is a Kubernetes resource, like a Deployment or Service.
Defining a Service
A Service resource makes Pods accessible to other Pods or users outside the cluster.
Without a Service, a Pod cannot be accessed at all.
A Service forwards requests to a set of Pods
Deploying the application
So far, you created a few YAML files with resource definitions. You are going to submit your resource definitions to Kubernetes. And Kubernetes will bring your application to life. First of all, make sure that you have a deployment.yaml created. Also, make sure that your Minikube cluster is running:
minikube status
Submit resource definitions to Kubernetes with the following command:
kubectl apply -f deployment.yaml
OR
Create deployment resources as follows:
kubectl create deployment {name} --image={docker-image}
Describe deployment as follows:
kubectl describe deployment {name}
As soon as Kubernetes receives your resources, it creates the Pods.
Check your Pods coming alive with:
kubectl get pods --watch
Running get pods should now show only the new Pods:
kubectl get pods
kubectl get pods -o wide
Note: internal IP can't be accessed by the outside world directly. internal ip assigned.
Create service resources as follows:
get deployments:
kubectl get deploy
Let's create a service for a given deployment: we want to expose an internal container port to any other port outside a deployment
kubectl expose deployment {deployment-name} --port=8081 --target-port=8080
get Service :
kubectl get services
The CLUSTER-IP is a virtual IP address created by Kubernetes. can access from any Node within the cluster and will be available only within the cluster not outside.
kubectl describe service {service-name}
Note: load will be balanced across all ports mentioned in endpoints.
Creating Nodeport service:
delete existing CLUSTER-IP service associated with deployment as follows:
kubectl delete service {service-name}
Create a new node port service
kubectl expose deployment spring-docker --type=NodePort --port=8080
minikube service spring-docker
try to access the URL given by Minikube. it should be available outside the cluster. Ex-
Interact with running docker container:
The exec command is used to interact with already running containers on the Docker host. Use docker ps to get the name of the existing container Use the command docker exec -it /bin/bash to get a bash shell in the container
docker exec -it {id} sh
Next time you want to update these Pods, you only need to update the Deployment's Pod template again.
Get the details of a pod:
kubectl describe pod {pod-name}
Note: Without a Service, a Pod cannot be accessed at all.
Get details of your Deployment:
kubectl describe deployments
Get all namespaces available:
kubectl get namespaces
In Kubernetes, namespaces provide a mechanism for isolating groups of resources within a single cluster. Names of resources need to be unique within a namespace, but not across namespaces
kubectl get pods --namespace=kube-system
Deleting a pod:
kubectl delete pod {name}
Stopping a Cluster
This command shuts down the minikube virtual machine, but preserves all cluster state and data. Starting the cluster again will restore it to it’s previous state
minikube stop
Deleting a Cluster
This command shuts down and deletes the minikube virtual machine. No data or state is preserved
minikube delete
Top comments (0)