
Topics
- Key Concepts
- Docker
- Customize a docker image for your app
- local Kubernetes cluster with Minikube
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).
Troubleshooting
Sometimes when occure an error I useq this website to troubleshoot the kubernetes errors (https://managedkube.com/kubernetes/k8sbot/troubleshooting/imagepullbackoff/2019/02/23/imagepullbackoff.html).
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

- 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

# 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
- Learning kubernetes
- The Certified Kubernetes Application Developer (CKAD) examination from the Linux Foundation. Learn more about the certification and exam details at https://training.linuxfoundation.org/certification/certified-kubernetes-application-developer-ckad/”.
- Learning kubernetes (2)
You owe your dreams your courage.
Koleka Putuma
One thought on “Docker, container, Kubernetes”