Skip to content

Containerize Window Application & deploy into AWS Elastic Kubernetes Service (EKS)

|

Hi everyone! for this general walkthrough I will be explaining my experiences containerizing an Window Application into Window Container which will be deployed onto Amazon Elastic Kubernetes Service (AWS EKS – managed Kubernetes). The window application which i will be containerizing is my frontend IIS Window Application.

In deployment of containers in AWS EKS , you can opt to use AWS Fargate for serverless compute or deploy Amazon EC2 as worker node as compute services register to Kubernetes control plane.

Fargate is a great way to run your workloads on AWS EKS without having to worry about managing servers & run them. This means that concerns around security, upgrades/patches, cost optimizations etc. are all taken care of for you. However, not all workloads are compatible with Fargate. But for this walkthrough i will be using the latter method by deploying EC2 as Worker Nodes

No alt text provided for this image

My journey wasn’t straightforward and cost approximately >150 USD (time = $$) spinning AWS EKS clusters up and shutting it down on my non-production node which did save some cost when i am not using worker nodes. Nevertheless, i hope this guide will help kickstart your Window Application containerization journey at the very least

No alt text provided for this image
Good News! As of 8th Oct 2019, Amazon Web Services has release support for Windows Container service in AWS EKS which is generally available across all regions with Kubernetes version 1.14 and above

( A ) Building your Application Container image with Docker Desktop

1. In your Window host, install Docker Desktop (Docker Desktop is an application for MacOS and Windows machines for the building and sharing of containerized applications and microservices)

2. Feel free to sign up an Dockerhub account as well and visit the forum for support issues and updates

No alt text provided for this image

Launch Docker Desktop > Switch to Window Container

3. Docker Desktop Engine running on a Window Host machine:

No alt text provided for this image

4. Next will be the challenging process of building your own container image from a Window Based OS image:

No alt text provided for this image

Why need base OS Image? The containers on a Host shares the (host’s) kernel but each container must provide the subset of the OS that it needs.

5. In Dockerhub site, search for a suitable Window Base OS image container, the image will be the Base OS to support your window application + software packages:

No alt text provided for this image

6. Run Windows Powershell (run as administrator) , execute the following command to download the latest Window base OS image:

docker pull mcr.microsoft.com/windows/servercore:ltsc2019


#Run this command after you have execute the above successfully , this is to check the images you have downloaded

docker images

7. Proceed to install Visual Studio Code which it will be use to create the Dockerfile

“A Dockerfile is a text document that contains all the commands a user could call on the command line to assemble an image”

No alt text provided for this image
Right click > New File > Input the filename as Dockerfile

8. For my Windows frontend application (my web-app required IIS) , i will input the following code in the Dockerfile:

#Grab the image from Microsoft official repository
FROM mcr.microsoft.com/windows/servercore:ltsc2019


#Enable the IIS webserver feature in the servercore OS
RUN dism /online /enable-feature /all /featurename:iis-webserver /NoRestart


#Create this location inside container while its building
WORKDIR /inetpub/wwwroot


#Copy the files from your PS directory you have invoke into container's /inetpub/wwwroot folder
COPY content/ .


#expose port 80 inside the container
EXPOSE 80

content‘ is a folder which consist of the window application files

9. In Powershell terminal again, build the Docker image by invoking the following :(remember the dot . at the end of char) :

cd < location of the where the Dockerfile is >

docker build -t my-app .
No alt text provided for this image

10. Once the docker build process completed, execute docker run which will create a container from a given set of processes in the Dockerfile. ( port 8000 is the local machine port )

docker run -d -p 8000:80 myapp
No alt text provided for this image
No alt text provided for this image

Once the container in Docker Desktop is running, you can click “Open Browser” to view your customized window container running in your local machine

PS: If you need to change your default website to your application page during startup within the container runtime, you can add the following in your Dockerfile with your default page eg. myapp.html

RUN powershell.exe -NoProfile -Command  ; \
     Import-module WebAdministration ; \
     Add-WebConfigurationProperty -Filter "//defaultDocument/files" 
     - PSPath 'IIS:\sites\Default Web Site' -AtIndex 0 -Name collection -Value @{value='myapp.html'} ; \

( B ) Push your Docker Image into Cloud Container Repository

You can use your preferred cloud container repository like (Microsoft) Azure Container Registry, Google Container Registry or (Amazon Web Services) AWS Elastic Container Registry.

For this walkthrough i will use AWS ECR as my existing application is hosted in Amazon Web Services. Feel free to use your preferred container repository as it will work perfectly too!

What is AWS ECR?

No alt text provided for this image
Amazon Elastic Container Registry (ECR) is a fully-managed Docker container registry that makes it easy for developers to store, manage, and deploy Docker container images. Amazon ECR is integrated with Amazon Elastic Container Service (ECS), simplifying your development to production workflow.

1. AWS Console > Search AWS ECR > create your new repository in AWS ECR

No alt text provided for this image

2. After creating the repository, installed AWS Tools for Powershell in your window host. Then push your docker image into container registry using the following Powershell command:

First you will need to retrieve an authentication token :

(Get-ECRLoginCommand).Password | docker login --username AWS --password-stdin <your aws account ID> .dkr.ecr.<aws region>.amazonaws.com

Next, perform tagging of docker image created earlier in Docker Desktop (A) – 9 :

docker tag myapp:latest  <your aws account ID>.dkr.ecr.<aws region>.amazonaws.com/myapp:latest

Lastly, run the following command to push the image into the newly created repository :

docker push <your aws account ID>.dkr.ecr.<aws region>..amazonaws.com/myapp:latest

Check in AWS ECR if the image has been pushed

No alt text provided for this image

( C ) Setup your AWS Elastic Kubernetes Service (EKS) – Window Cluster

No alt text provided for this image

There are a few ways to setup AWS EKS Cluster (Managed Linux Node / Self Manage Windows nodes). In this walkthrough I will be using the aws console for easier picture reference.

Note: To have Windows Nodes in your EKS Cluster, the minimum requirement (as to date) is to have at least 1 x managed Linux node setup prior to deploying your Self managed Windows Nodes.

Prerequisite >> Do ensure that the appropriate IAM roles, VPC and Subnets are ready to contain the AWS EKS cluster, if you are unsure what to create, click here

1. Launch AWS EKS > Create > Input the name of your choice for your EKS cluster > Select all the subnets you wish the Kubernetes control plane to associate with

No alt text provided for this image

2. Once AWS EKS cluster has been provisioned, you can begin to add a Linux Node Group

No alt text provided for this image

3. After your Linux Node Group has been provisioned, you can create your self-managed Windows Node and add into the same EKS Cluster

https://amazon-eks.s3.us-west-2.amazonaws.com/cloudformation/2020-08-12/amazon-eks-windows-nodegroup.yaml

4. After the above Cloudformation template has been provisioned, you will need to enable the Window Nodes to join into your AWS EKS Cluster:

To enable nodes to join your EKS cluster:

i. Download, edit, and apply the AWS IAM Authenticator configuration map.

ii. Use the following command to download the configuration map:

curl -o aws-auth-cm-windows.yaml https://amazon-eks.s3.us-west-2.amazonaws.com/cloudformation/2020-08-12/aws-auth-cm-windows.yaml

iii. Open the file with your favourite text editor.

Replace the <ARN of instance role (not instance profile) of **Linux** node> and <ARN of instance role (not instance profile) of **Windows** node> snippets with the NodeInstanceRole values that you recorded for your Linux and Windows nodes, and save the file

apiVersion: v1
kind: ConfigMap
metadata:
  name: aws-auth
  namespace: kube-system
data:
  mapRoles: |
    - rolearn: <ARN of instance role (not instance profile) of **Linux** node>
      username: system:node:{{EC2PrivateDNSName}}
      groups:
        - system:bootstrappers
        - system:nodes
    - rolearn: <ARN of instance role (not instance profile) of **Windows** node>
      username: system:node:{{EC2PrivateDNSName}}
      groups:
        - system:bootstrappers
        - system:nodes
        - eks:kube-proxy-windows

After editing the roleARN, apply the configuration into the EKS Cluster. This command may take a few minutes to finish.

kubectl apply -f aws-auth-cm-windows.yaml

( D ) Pull Docker Image from AWS ECR repository and deploy into AWS EKS

1. In you deployment file, use this deploy.yaml template to deploy a 1 x pod into the windows EKS Cluster Node, edit the URI (Uniform Resource Identifier ) to the AWS ECR image you have push in previously eg. 123456789123.dkr.ecr.ap-southeast-1.amazonaws.com/myapp:latest

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  selector:
    matchLabels:
      app: my-app
      tier: frontend
  replicas: 1
  template:
    metadata:
      labels:
        app: my-app
        tier: frontend
    spec:
      containers:
      - name: my-app
        image: < Input your ECR repository URI >
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          containerPort: 80
      nodeSelector:
        kubernetes.io/os: windows
---
apiVersion: v1
kind: Service
metadata:
  name: my-app
  labels:
    app: my-app
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: my-app
  sessionAffinity: None
  type: LoadBalancer
No alt text provided for this image

Deploy the configuration into EKS Cluster :

kubectl apply -f deploy.yaml

check kubectl get svc
No alt text provided for this image

The deployment (deploy.yaml) above will deploy 1 x Container Pod and 1 x AWS Load Balancer (it will take some time for the deployment to complete), run the command below to check on the status of your Container Pod

kubectl get pods

2. Now proceed to your AWS Console > EC2 service > Load Balancer , you will see a new Load Balancer created. Copy the DNS name of the Load Balancer and launch into a Internet browser

No alt text provided for this image
No alt text provided for this image
You are done ! Your Window application has successfully deployed into AWS EKS Cluster

More work to do?

Yes! although the deployment has completed, the security aspect of the AWS EKS cluster will still need to be looked into, eg. SSL encryption for web application, introduce Gateway Endpoints to access to various services privately within Amazon Web Services, areas on how to administrate Kubernetes clusters in large scale with auto-scaling of containers in the event of availability zone failures


(Optional)

You may launch AWS Cloud9 IDE to create Kubernetes Dashboard for easier management of your nodes, pods & containers. Refer to this amazing video guide for more information:

No alt text provided for this image

Great references and information on Kubernetes / EKS, do check out this sites: techbeatly / Video Link / Amazon EKS Workshop

If you want to learn more about the specific components that make up Kubernetes and EKS, you can check out the official docs on EKS

Lastly, everyone please stay safe and take care of your health during this pandemic!

Tags:

Schnauzer Lover | Amazon Web Services | Microsoft Azure | An individual passionate in commercial cloud - design, operations & ever changing automation on infrastructure. Evergreen learning is what i believe , it is a journey not a destination

Schnauzer Lover | Amazon Web Services | Microsoft Azure | An individual passionate in commercial cloud - design, operations & ever changing automation on infrastructure. Evergreen learning is what i believe , it is a journey not a destination

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.