Docker, container, Kubernetes

Topics

Related topics

Key Concepts

  • Docker : Docker is a technology that enables you to deploy applications and services quickly and easily.
  • Docker app : A Docker app runs using a Docker image
  • Docker image : A Docker image is a prepackaged environment containing the application code and the environment in which the code executes [more].
  • Container
  • Docker registries/Docker Hub: is a repository of docker images https://hub.docker.com/
  • Containerized web application : A web app so that it can be deployed as a Docker image and run from an Azure Container Instance
  • Container[Source]
  • Kubernetest : Container orchestrator
  • Docker Swarm
  • Rancher
  • Mesos
  • Load Balancer
  • Ingress

Docker

The list of necessary commands for working with docker, docker image and container.

# pull a docker image from docker hub
docker pull mcr.microsoft.com/dotnet/core/samples:aspnetapp

# list local docker images
docker image list

# Run a Docker container. if the docker image isn't available locally, docker downloads it first
docker run mcr.microsoft.com/dotnet/core/samples:aspnetapp
# output
info: Microsoft.Hosting.Lifetime[0]
      Now listening on: http://[::]:80 # the cintainer now listening for requests to arrive on HTTP port 80 (http://localhost:80)
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Production
info: Microsoft.Hosting.Lifetime[0]
      Content root path: C:\app
# Info : if we use http://localhost:80 in browser we see nothing, read below.


# By default, Docker doesn't allow inbound network requests to reach your container.
# You need to tell Docker to assign a specific port number from your computer to a specific port number in the container
# by adding the -p option to docker run.
# This instruction enables network requests to the container on the specified port.
docker run -p 8080:80 -d mcr.microsoft.com/dotnet/core/samples:aspnetapp

# 8080 -> my computer port
# 80 -> my cotainer port

# Manage Docker containers
docker container ls [-a]
docker ps [-a] # this is the shortcut

#  stop an active container
docker stop elegant_ramanujan
docker container stop f9d0ce65d1f5

# restart a stopped container
docker start elegant_ramanujan

# once a container is stopped, it should also be removed
docker container rm f9d0ce65d1f5
docker container rm -f elegant_ramanujan # for force to stop and remove
docker rm elegant_ramanujan

# Remove Docker images
# Containers running the image must be terminated before the image can be removed
docker image rm mcr.microsoft.com/dotnet/core/samples:aspnetapp
Customize a docker image for your app
  • Docker Hub is an excellent source of images to get you started building your own containerized apps.
  • You can download an image that provides the basic functionality you require
    • and layer your own application on top of it to create a new custom image.
  • You can automate the steps for doing this process by writing a Dockerfile.
  • Dockerfile : is for automating docker image creation
  • the changes are
    • copying files into the container from the local filesystem,
    • and running various tools and utilities to compile code.
    • When finished, you would use the docker commit command to save the changes to a new image.
# sample dockerfile
#----------------------------------------

# FROM statement downloads the specified image and creates a new container based on this image.
FROM mcr.microsoft.com/dotnet/core/sdk:2.2

# The WORKDIR command sets the current working directory in the container, 
# used by the following commands.
WORKDIR /app

# The COPY command copies files from the host computer to the container. 
# The first argument (myapp_code) is a file or folder on the host computer.
# The second argument (.) specifies the name of the file or folder to act as 
# the destination in the container.
# In this case, the destination is the current working directory (/app).
COPY myapp_code .

# The RUN command executes a command in the container.
# Arguments to the RUN command are command-line commands.
RUN dotnet build -c Release -o /rel

# The EXPOSE command creates configuration in the new image that specifies which ports are intended to be opened when the container is run.
# If the container is running a web app, it's common to EXPOSE port 80.
EXPOSE 80

WORKDIR /rel

# The ENTRYPOINT command specifies the operation the container should run when it starts.
# In this example, it runs the newly built app.
# You specify the command to be run and each of its arguments as a string array.
ENTRYPOINT ["dotnet", "myapp.dll"]

By convention, applications meant to be packaged as Docker images typically have a Dockerfile located in the root of their source code, and it’s almost always named Dockerfile.

docker build -t myapp:v1 .

# The docker build command creates a new image by running a Dockerfile. 
# The -f flag indicates the name of the Dockerfile to use.
# The -t flag specifies the name of the image to be created, in this example, myapp:v1.
# The final parameter, ., provides the build context for the source files for the COPY command: the set of files on the host computer needed during the build process.

these commands help to create a customized doker image via command prompt

#------------------------------------------------------
# Customize a Docker image to run your own web app
#------------------------------------------------------

# clone source code
git clone https://github.com/MicrosoftDocs/mslearn-hotel-reservation-system.git

# change the directors
cd mslearn-hotel-reservation-system/src

# create a dockerfile
copy NUL Dockerfile
notepad Dockerfile


# Build and deploy the image using the Dockerfile
docker build -t reservationsystem .

# verify that the image has been created and stored in the local registry
docker image list

# Test the web app
docker run -p 8080:80 -d --name reservations reservationsystem

the content of the dockerfile is as follows

FROM mcr.microsoft.com/dotnet/core/sdk:2.2
WORKDIR /src
COPY ["HotelReservationSystem/HotelReservationSystem.csproj", "HotelReservationSystem/"]
COPY ["HotelReservationSystemTypes/HotelReservationSystemTypes.csproj", "HotelReservationSystemTypes/"]
RUN dotnet restore "HotelReservationSystem/HotelReservationSystem.csproj"

COPY . .
WORKDIR "/src/HotelReservationSystem"
RUN dotnet build "HotelReservationSystem.csproj" -c Release -o /app

RUN dotnet publish "HotelReservationSystem.csproj" -c Release -o /app

EXPOSE 80
WORKDIR /app
ENTRYPOINT ["dotnet", "HotelReservationSystem.dll"]

Source: https://docs.microsoft.com/en-us/learn/modules/intro-to-containers/4-create-custom-docker-image

Kubernetes (K8s)

kubernetset features [Source]

  • Provision hosts
  • Instantiate containers on a host
  • Restart failing containers
  • Expose containers as servíce outside the cluster
  • Scale the cluster up or down
  • Multi-Host container scheduling: handeled by kube-scheeduler, which assign containers, also known as pods in kubernetes to nodes at runtime.
  • Scalabilty and availability: kubernetes master can be deployed in a highly available configuration (multi-regin deployments are also available)
  • Scalability in v1.17
    • support 5,000 nodes clusters
    • max 150,000 pods
    • max 100 pods per node
    • Pods can be horizontally scaled via API.
  • Flexibility and modularization with add-ons e.g. network drivers, service discovery, container runtime, visualization, and command

Cloud-specific technologies

  • Amazon EC2 Container Service
  • Google Anthos

Mesos

  • Witten in c++
  • With APIs in Java, C++, and Python
  • Oldest, most stable tool
  • Distributed Kernel, where many machines act as one logical entity.
  • Marathon framework in Mesos is used to schedule and execute tasks.
  • It has more complex architecture than Docker Swarm.
  • Typical users
    • large enterprises, that require lot of compute or task-oriented workloads.
    • Companies with big data jobs.
    • driven by developers rather than operations but ops team manage the tool.

Rancher

  • Full stack container management platform
  • it allows to install and manage kubernetes clusters on-prem and cloud
  • early player in container ecosystem
  • Great user interface and API to interact with clusters
  • provide enterprise support
  • Typical users
    • small team to enterprises
    • support teams out of box
    • Nice user interface and APIs
    • easy to manage infrastructure effectively

Kubernetes gives you a platform to ___schedule and run___ containers on clusters of your machines.

What is the CNCF? Cloud Native Computing Foundation

What is Chef? Chef is a traditional tool to automate your entire infrastructure.

Two features that allow Kubernetes Clusters to scale are ___registration___ and ___discovery___.

How would you best describe Kubernetes? an open-source platform designed to automate deploying, scaling, and operating application containers

Why do organizations use containers? to build applications to incorporate a microservices-based architecture

Source : https://www.linkedin.com/learning/learning-kubernetes/other-implementations-2

local Kubernetes cluster with Minikube

  • for running kubernetes cluster the minikube and kubectl must be installed
    • if you have already installed docker desktop, you don’t need to install the kubectl because docker desktop contains it. Only add the path of the kubectl.exe under your docker folder to the “Path” in your local variables e.g. in my case the path is “C:\Program Files\Docker\Docker\resources\bin”
    • for installing minikube use
choco install minikube
  • I do all these steps in Visual Studio Code but you can use any other command prompt environments.
  • It’s imporant to run the command prompt window as administrator (it’s necessary for running and stopping the cluster).
Start/Stop a Minikube

I installed and started the minikube in CMD Prompt run as admin.

If you have any problem with minikube use delete and start it again.

minikube delete

# Start a Minikube 
minikube start   --kubernetes-version=v1.18.3 --addons="dashboard" --addons="metrics-server" --addons="ingress" --addons="ingress-dns" --feature-gates=EphemeralContainers=true

# Get version of the kubectl
Kubectl version

# Get the nodes
kubectl get nodes
# Output is as follows
# NAME       STATUS   ROLES    AGE   VERSION
# minikube   Ready    master   11h   v1.18.3 
# Node with role(master) control the cluster.
# Worker nodes are our containers that we deploy.

# Stop Minikube cluster
Minikube stop

# Start the minikube again
Minikube Start

Running Pod/Container
# You have to start minikube before using kubectl

# Create a Pod
kubectl run web --image=nginx
# What we run is a wrapper called Pod

# Get Pods
kubectl get pods

# Get pod information
kubectl describe pod web

# Create Pod in the correct way
kubectl apply -f .\web-declarative.yaml

The web-declarative.yaml file is as follows

apiVersion: v1
kind: Pod
metadata:
  name: web-declarative
  labels:
    site: blog
spec:
  containers:
    - name: web
      image: nginx:1.18.0

Access Pods via Services inside the cluster (loose coupling)
  • Services make the pod accessible inside the cluster
Sourec : Pod-a can talk to green vian blue-green
  • Pod-a can talk to green vian blue-green
  • blue-green
    • is not a Pod
    • It’s a Service
    • It cannot crash
    • It cannot move
    • It will always get traffic to green
  • Pod-a doesn’t have to know the IP of green
  • blue should only know the blue-green service (blue-green is like a DNS).
  • Service can be created in two ways
    • with exposing a port of the Pod (kubectl expose pod green –port 8080 .\blue-green.yaml)
    • wiht applying a service (kubectl apply -f .\blue-green.yaml)
      • for deploying a service we have to have a yaml file.

The following code to start the pod/green and then deploy service/blue-green

# Deploy a Pod
kubectl apply -f .\green.yaml

# A service is created to make the pod more accessible incide the cluster network
kubectl expose pod green --port 8080 blue-green

# If later want to remove service manually
kubectl delete service blue-green

# This command do the same like kubectl expose
kubectl apply -f .\blue-green.yaml

This is the configuration for service (blue-green.yaml)

apiVersion: v1
kind: Service
metadata:
  name: blue-green
spec:
  type: ClusterIP
  ports:
    - port: 80
      targetPort: 8080
  selector:
    app: blue-green

green.yaml (Pod deployment)

apiVersion: v1
kind: Pod
metadata:
  name: green
  labels:
    app: blue-green
spec:
  containers:
    - name: green
      image: docker.io/mtinside/blue-green:green

blue-green.yaml (Service Deployment)

apiVersion: v1
kind: Service
metadata:
  name: blue-green
spec:
  type: ClusterIP
  ports:
    - port: 80
      targetPort: 8080
  selector:
    app: blue-greendsdsd

Workflow: in service yaml file, we have configured the selector: (refer to a Pod with). It has been refered to a Pod with app: blue-greendsdsd, it means refer to a Pod, which has a app: blue-greendsdsd label.

The blue-green service can talk with all pods that have app: blue-greendsdsd label. This is called loose coupling.

Expose Pod to the outside world
  • Usually we cannot talk to the Pods (because they are in a cluster, which is a separate machine) and we have provide a way
  • To talk to a pod via browser we have to create a type of service
  • This service must open a port and listen to it.
  • Expose workers to other services within the culster

We create two Pods and one Service

# Deploy all yaml files in the current directory
kubectl apply -f .
# Output is as follows
# service/blue-green created
# pod/blue created
# pod/green unchanged

blue Pod

apiVersion: v1
kind: Pod
metadata:
  name: blue
  labels:
    app: blue-green
spec:
  containers:
    - name: blue
      image: docker.io/mtinside/blue-green:blue

green Pod

apiVersion: v1
kind: Pod
metadata:
  name: green
  labels:
    app: blue-green
spec:
  containers:
    - name: green
      image: docker.io/mtinside/blue-green:green

blue-green Service

apiVersion: v1
kind: Service
metadata:
  name: blue-green
spec:
  type: ClusterIP
  ports:
    - port: 80
      targetPort: 8080
  selector:
    app: blue-green

The default type of the service is ClusterIP (type: ClusterIP). To expose a port of service to be accessible from browser the type have to be changed to type: NodePort. The change have to be applied to service with following code.

# Apply changes to a running service
kubectl apply -f .\blue-green.yaml
# output is service/blue-green configured

# get IP of the Mnikube
Minikube ip # -> 192.168.165.187

# get the port number of the service
Kubectl get services
# NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
# blue-green   NodePort    10.105.57.15   <none>        80:30179/TCP   58m

# check this in your browser
http://192.168.165.187:30179

Sometimes the page is blue and sometimes is green.

Handling ingress to kubernetes
  • The workers can be exposed to services within the cluster and to the outside world
  • But exposing via service with type: NodePort isn’t a sophisticated (service of type load balancer).
  • In the modern architecture we don’t expose a service to outside.
  • The Ingress controller is exposed
  • Ingress controller is for Host- and path-based routing of HTTP traffic
First class architecture [Source]
# Initial the environment
kubectl apply -f .

Blue.yaml for creating a pod and its service (ClusterIP)

apiVersion: v1
kind: Pod
metadata:
  name: blue
  labels:
    app: blue-green
    colour: blue
spec:
  containers:
    - name: blue
      image: docker.io/mtinside/blue-green:blue
---
apiVersion: v1
kind: Service
metadata:
  name: blue
spec:
  ports:
    - port: 80
      targetPort: 8080
  selector:
    app: blue-green
    colour: blue

green.yaml for creating a pod and its service (ClusterIP)

apiVersion: v1
kind: Pod
metadata:
  name: green
  labels:
    app: blue-green
    colour: green
spec:
  containers:
    - name: green
      image: docker.io/mtinside/blue-green:green
---
apiVersion: v1
kind: Service
metadata:
  name: green
spec:
  ports:
    - port: 80
      targetPort: 8080
  selector:
    app: blue-green
    colour: green

ingress.yaml for ingree controller

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: example.com
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
    - host: blue-green.example.com
      http:
        paths:
          - path: /blue
            backend:
              serviceName: blue
              servicePort: 80
          - path: /green
            backend:
              serviceName: green
              servicePort: 80
    - host: nginx.example.com
      http:
        paths:
          - path: /
            backend:
              serviceName: nginx
              servicePort: 80

Host- and path-based routing of HTTP traffic as it enters the cluster is handled by which component? Ingress Controller

Which of these is not needed to deploy a container to Kubernetes? an IP address but a name for the wrapper pod object, and a container image to run are necessary.

Where does minikube deploy a Kubernetes cluster? our laptop

Which of these types of service does not allow connections to Pods from outside the cluster? ClusterIP

Exposing a cluster

Coming soon…


Resources & Related links


You owe your dreams your courage.

Koleka Putuma


Published by parisamoosavinezhad

- Software Engineer - Software Architect - Software and database specialist - Cloud solution architect

One thought on “Docker, container, Kubernetes

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: