Kubernetes Cluster Using Terraform and Ansible
Kubernetes Cluster Using Terraform and Ansible
com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
• Jenkins server to run Jenkins jobs
• An AWS account. The EKS cluster may incur some charges so
make sure to monitor that
• Terraform installed
• Jenkins Knowledge
Apart from this I will explain all of the steps so it can be followed
easily. I will cover each of the steps in detail so if you have some
basic conceptual understanding of the above mentioned topics,
you should be able to follow along.
Functional Flow
Let me first explain whats the process I will be following to deploy
the cluster. I will go through two methods of deploying the cluster:
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
First method we will go through is deploying the cluster using EC2
instances. In this we will deploy both the controlplane and some
nodes on various EC2 instances. Below flow shows the overall
process.
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
• S3 buckets to stora various temporary files needed
during the deployment flow. Also to store the
infrastructure state during the deployment
• Deploy the Controlplane Instance: In this stage the EC2
instance is deployed on the above infrastructure. In this
process I am deploying one EC2 instance as the controlplane
of the cluster. Normally Production grade Kubernetes cluster
can have multiple controlplane nodes and add a scalability to
it. But for this example, I am deploying one EC2 instance as
the controlplane.
• Bootstrap the controlplane: The EC2 instance deployed
above is needed to be prepared so Kubernetes cluster can
start on it. In this stage multiple packages will be installed on
the EC2 instance and the Kubernetes cluster will be started
on the instance. At this point the cluster only comprises of
the controlplane node.
• Launch the EC2 instances for Nodes: To make the
Kubernetes cluster scalable, we will need more nodes added
to it. In this step I am deploying some more EC2 instances
which will become the child nodes in the Kubernetes cluster
with the controlplane EC2 instance as the controller.
• Prepare the Nodes and join cluster: For the nodes to be
part of the cluster, they need to be prepared. In this step the
needed packages are installed on the Nodes and the
Kubernetes cluster join command is executed on each of the
node EC2 instance, so they join the cluster.
That completes the high level flow of deploying the cluster on EC2
instances.
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
Using AWS EKS
In this method, the cluster will be deployed on the AWS managed
platform called EKS (Elastic Kubernetes Service). This platform
takes away many of the steps to prepare the cluster and takes a
more declarative approach. Below flow shows what I will be
following in this process:
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
• Deploy the Infrastructure: In this step, the supporting
infrastructure is deployed. Even though the cluster is AWS
managed, the supporting infrastructure has to be deployed
and can be controlled by us. As part of this step, these are the
items which are deployed:
• Networking components like VPC, subnets etc.
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
Tech Details
Let me explain how each of the cluster will be composed using
different AWS components. For both of the methods, I will be
using Jenkins to automate the whole deployment. Here I am
describing each of the cluster.
Cluster on EC2
This cluster comprises of EC2 instances which are deployed
separately. Below image will show the overall cluster which will
be built in this process:
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
controlplane, few packages are installed on the instance.
Ansible is used to bootstrap the instance and install all the
needed packages. At high level these are the steps which will
be followed on the controlplane instance after it is spun up:
• Install Docker
• Install Kubernetes
• Start Kubernetes using Kubeadm and start the service
on this node
• Generate the Kubeadm join command for other nodes to
join the cluster
• Auto Scaling Group for the nodes: Now we have the
controlplane for the cluster but we will need other nodes
joined to the cluster to have a scalable Kubernetes cluster. To
launch the nodes automatically based on load on the cluster,
an auto scaling group is being deployed here. The ASG scales
in and out with the number of nodes which become part of
the cluster. Based on the load on the cluster, the node count
varies and is controlled by the ASG. Once the nodes launch,
Ansible is used to bootstrap the nodes and make them join
the cluster. These are the steps which are performed using
Ansible on the nodes:
• Install Docker
• Install Kubernetes
• Run the Kubeadm join command with the join token, so
the node becomes part of the cluster
• Networking: All of the instances which are spun up by this
process are deployed inside a VPC which also gets created
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
part of the process. These are the components which gets
deployed as part of the networking for the whole cluster:
• VPC for the whole cluster
Cluster on EKS
In the next method, I am describing the cluster architecture which
is deployed using AWS EKS. In this there are no direct
involvement with launching EC2 instances and bootstrapping
them. Below image describes the cluster architecture:
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
added to the cluster. Will cover in detail later how the
workloads get deployed to the Fargate instances.
• Use of Terraform: All of the infrastructure described above
is deployed using Terraform. The declarative configuration
for the cluster is specified in the Terraform script which
deploys the whole cluster.
That explanation should give a good idea of both of the processes
and what we will be setting up in this post. Lets walk through
setting up each of the clusters.
Setup Walkthrough
In this setup I will walk you through the setting up of the whole
cluster via both of the processes. You can use any of these to spin
up your own cluster. At high level this is the general flow which I
will be setting up on Jenkins to launch each of the cluster.
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
Folder Structure
Before diving in the setup process, let me explain the folder
structure of the scripts on my repo. If you are using my repo for
spinning up your cluster, this should help understand the setup. I
have divided both of the approaches in two separate folders with
their own folder structure in each.
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
• Using EC2 Instances: Below is the folder structure for this
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
Jenkinsfile:Finally the Jenkinsfile for the pipeline to launch the
whole cluster step by step
That is the folder structure I have created in the repo I shared for
this post. But in the steps below, what I have done is separate out
those folders in separate branches in the same repo. Each of those
branches trigger different Jenkins stages. I will go through the
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
stages below. But just to understand the branch structure, this is
what I will be following in this post. You can take my repo as is or
convert to a branch structure as this to easily trigger separate
pipelines.
Jenkins Setup
Now that we have seen the structure of how the codebase looks,
now its the time to prepare Jenkins for running the deployment
steps. Let go through the steps one by one. But before starting to
setup Jenkins, since we will be deploying to AWS, we will need an
IAM user which the pipeline will use to connect to AWS. So first go
ahead and create an IAM user with permissions to work with EC2
and EKS. Not e down the AWS keys for the user as we will be
needing those next.
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
• Install Jenkins:
Of course the first step is to install Jenkins on a server or a
system as suitable. I wont go through the steps to install
Jenkins but you can follow the steps Here.
• Setup Credentials:
For Jenkins to connect to AWS, it needs the AWS credentials. In
this step we will setup the credentials in Jenkins. Login to
Jenkins and Navigate to the Manage credentials page:
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
Add two such credentials for each of the AWS key from the IAM
user we created earlier. There should be two credentials now.
If you added on a different name, update accordingly on the
Jenkinsfile too. This is what I have used for my Jenkins pipeline:
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
On the options page, select the GIT repo source which will be
the source for the scripts and the two branches. To be able to
connect the repo, the credentials will also have to be specified
on the same option. If its a public repo no credentials needed. I
would suggest clone my repo and use your own repo for the
pipeline.
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
Save the pipeline. Once you save, Jenkins will start scanning for
branches in the repo. At this point it will fail since you wont
have any content in the pipeline. If you have created the
branches already, you should have the multiple branches
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
showing up as separate runnable pipeline on Jenkins
That should complete the initial Jenkins setup and you are ready
to run the pipelines for deployment. Next lets move on to
understanding the two pipelines and run them.
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
the pipeline. Here are the environment variables which are
being set:
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
• Deploy networking modules: In this stage the networking
components are deployed. All of the network components
are defined in a Terraform script. The Terraform module gets
deployed in the pipeline stage. These are the items which get
deployed in this stage:
• VPC
• Subnets
• Security Groups
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
After the Kubernetes service starts, there is also a test step which
runs in this stage to ensure the Kubernetes starts properly on the
controlplane EC2. The kubectl test step is also performed using
Ansible. During the test step, same Inventory file is also
downloaded from the S3 bucket, and used by Ansible to connect to
the EC2.
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
along with the cluster, This profile makes sure if any
workloads with these specific labels are launched on the
cluster, they will be launched on these Fargate instances
which will launch automatically based on load.
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
Once the cluster deploys successfully, you can view the cluster on
console
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
Once the pods start running, the Fargate instances can be seen on
the AWS console for EKS:
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
To test the nodes, run this command from your local terminal.
Make sure to configure AWS CLI so it authenticates to correct AWS
instance
aws eks update-kubeconfig --name cluster_name
kubectl get nodes
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
• Notify on Slack: Once the cluster is completely deployed, the
pipeline sends out a message to a specific slack channel
notifying the successful deployment of the cluster. The
message also provides the cluster name.
That completes the deployment of the EKS cluster. Once all these
script changes are done, push the changes to the Git repo so the
pipeline can execute.
git add .
git commit -m "updated pipeline files"
git push -u origin main
Execute the pipeline or the pipeline automatically runs (whatever
is configured on Jenkins), once the execution finishes the EKS
cluster should be up and running.
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar
pipeline in my repo by setting the environment variable. It will
destroy all of the resources which were created by the pipeline.
Improvements
The steps explained in the post are very basic way to spin up the
cluster and actual Production steps are way more. Some of the
improvements I am working on the process are:
Follow on:
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
https://www.linkedin.com/in/lokeshkumar-%E2%98%81%EF%B8%8F-4a2860244
Lokeshkumar