<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Surendu Suresh</title>
    <description>The latest articles on Forem by Surendu Suresh (@surendusuresh).</description>
    <link>https://forem.com/surendusuresh</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F568938%2F49ed3e8b-18de-414f-a960-070cd859aba5.jpg</url>
      <title>Forem: Surendu Suresh</title>
      <link>https://forem.com/surendusuresh</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/surendusuresh"/>
    <language>en</language>
    <item>
      <title>Setting up kubernetes cluster in AWS - Free of cost</title>
      <dc:creator>Surendu Suresh</dc:creator>
      <pubDate>Tue, 30 May 2023 04:42:25 +0000</pubDate>
      <link>https://forem.com/surendusuresh/setting-up-kubernetes-cluster-in-aws-free-of-cost-1ed1</link>
      <guid>https://forem.com/surendusuresh/setting-up-kubernetes-cluster-in-aws-free-of-cost-1ed1</guid>
      <description>&lt;p&gt;In my previous &lt;a href="https://dev.to/surendusuresh/kubernetes-getting-started-4pf"&gt;article&lt;/a&gt;, I was talking about Kubernetes fundamentals and a small hands on exercise of kubernetes using Docker Desktop. So I thought of showing how to set up a basic kubernetes cluster in AWS EC2, using only free tier components. We will be using kubeadm to setup the cluster.&lt;/p&gt;

&lt;h4&gt;
  
  
  Prerequisites
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;AWS Free Tier Account Access. Use this &lt;a href="https://aws.amazon.com/free/" rel="noopener noreferrer"&gt;link&lt;/a&gt; to set it up.&lt;/li&gt;
&lt;li&gt;Basic knowledge of AWS&lt;/li&gt;
&lt;li&gt;Basic knowledge of Linux&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Standing up two EC2 instances
&lt;/h2&gt;

&lt;p&gt;We will be using two ubuntu t2.micro instances for this purpose. Create the instance as below.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;As a first step, create a security group with below inbound rules. I am enabling all ICMP and TCP traffic between the servers in the same security groups. Also, enable SSH from all sources, if you want to use SSH client to connect to the servers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnsreg8qe80qjvap2mo3r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnsreg8qe80qjvap2mo3r.png" alt="Setting up security group"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;After creating the security group, click on launch instance in instance screen. I am calling first instance as kubemaster and second instance as node01. &lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqp4kbm8we1v86q0l6nxp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqp4kbm8we1v86q0l6nxp.png" alt="AWS EC2 Instance Creation"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select t2.micro instance type and proceed without a key pair. Kubernetes recommends at least 2 CPUs and 2 GB RAM for the nodes. However, as this is just for setting up basic cluster, i am going with t2.micro instances. Also, you can choose to create key pairs if you want to connect instances using ssh clients. I will be using EC2 Instance Connect to establish connection with servers.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fubfb7c3d1gbnw7ay63tq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fubfb7c3d1gbnw7ay63tq.png" alt="Selecting the instance type"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click EDIT on the network settings and select the same subnet for both instances. I am selecting the first subnet from the list. This is done to ensure that the network will be open between these two instances. Select the security group we created in the first step.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fky2zx5numub5lpc22km2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fky2zx5numub5lpc22km2.png" alt="EC2 Network Configuration"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click Advanced Network Configuration and set two consecutive primary ip addresses for kubemaster and node01. Please make sure the IP address is from the subnet range. I am selecting 172.31.32.10 and 172.31.32.11 for kubemaster and node01 respectively.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxpwhk3j9tf7d72vi3ds3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxpwhk3j9tf7d72vi3ds3.png" alt="EC2 IP Address Setup"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Leave other fields as it is and launch the instance. Do the same steps for node01 instance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6h1im43he9njqr80romh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6h1im43he9njqr80romh.png" alt="Launch Instance"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Make sure both instance are in running state and then select one instance at a time and click on the connect button on top of the page to connect using EC2 instance connect. Or you can choose to connect using the ssh client of your choice using the ssh key.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fak844kbp4reqk2vnuyno.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fak844kbp4reqk2vnuyno.png" alt="EC2 Instance Status"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting up Kubernetes cluster
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Setting up instance hostname and hosts file
&lt;/h3&gt;

&lt;p&gt;As a first step, we will setup the hostname for these two ec2 instances and set up /etc/hosts file to resolve both these machines.&lt;/p&gt;

&lt;p&gt;On kubemaster instance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root@ip-172-31-32-10:~# hostnamectl set-hostname kubemaster
root@ip-172-31-32-10:~# vi /etc/hosts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enter below and save in hosts file. Use your specific IP addresses.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;127.0.0.1 localhost kubemaster
172.31.32.10 kubemaster
172.31.32.11 node01
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On node01 instance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root@ip-172-31-32-11:~# hostnamectl set-hostname node01
root@ip-172-31-32-11:~# vi /etc/hosts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enter below and save in hosts file. Use your specific IP addresses.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;127.0.0.1 localhost node01
172.31.32.11 node01
172.31.32.10 kubemaster
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Installing Container Runtime
&lt;/h4&gt;

&lt;p&gt;We will be using Docker Engine for our purpose. Run below commands in both &lt;strong&gt;kubemaster&lt;/strong&gt; and &lt;strong&gt;node01&lt;/strong&gt; instances.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Forwarding IPv4 and letting iptables see bridged traffic
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cat &amp;lt;&amp;lt;EOF | sudo tee /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF

sudo modprobe overlay
sudo modprobe br_netfilter

# sysctl params required by setup, params persist across reboots
cat &amp;lt;&amp;lt;EOF | sudo tee /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables  = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward                 = 1
EOF

# Apply sysctl params without reboot
sudo sysctl --system
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Installing Docker Engine
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt-get update
sudo apt-get install ca-certificates curl gnupg

sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

echo \
  "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  "$(. /etc/os-release &amp;amp;&amp;amp; echo "$VERSION_CODENAME")" stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list &amp;gt; /dev/null
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt-get update
sudo apt-get install docker-ce
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Installing cri-dockerd. This might take few minutes to complete.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/Mirantis/cri-dockerd.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Run these commands as root
###Install GO###
wget https://storage.googleapis.com/golang/getgo/installer_linux
chmod +x ./installer_linux
./installer_linux
source ~/.bash_profile

cd cri-dockerd
mkdir bin
go build -o bin/cri-dockerd
mkdir -p /usr/local/bin
install -o root -g root -m 0755 bin/cri-dockerd /usr/local/bin/cri-dockerd
cp -a packaging/systemd/* /etc/systemd/system
sed -i -e 's,/usr/bin/cri-dockerd,/usr/local/bin/cri-dockerd,' /etc/systemd/system/cri-docker.service
systemctl daemon-reload
systemctl enable cri-docker.service
systemctl enable --now cri-docker.socket
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Installing kubeadm, kubelet and kubectl
&lt;/h4&gt;

&lt;p&gt;These commands needs to be run on both kubemaster and node01.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl

curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-archive-keyring.gpg

echo "deb [signed-by=/etc/apt/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list

sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Initializing the controlplane using kubeadm
&lt;/h4&gt;

&lt;p&gt;These commands needs to be run only on &lt;strong&gt;kubemaster&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubeadm init --pod-network-cidr=192.16.0.0/16 --apiserver-advertise-address=172.31.32.10 --cri-socket=unix:///var/run/cri-dockerd.sock --ignore-preflight-errors=NumCPU,Mem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here I am suppressing the errors due to the low CPU and Memory of t2.micro instance as our aim is just to bring up the bare minimum cluster. Once the above command is run, controlplane will be initialized and you will get an output similar to the below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0lyx1lp5tg1o4mu75vkk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0lyx1lp5tg1o4mu75vkk.png" alt="kubeadm output"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From the output, please keep a note of the kubeadm join command somewhere for setting up node01 later.&lt;/p&gt;

&lt;p&gt;Run the below commands from the kubeadm init output to setup kubectl configuration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  mkdir -p $HOME/.kube
  sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
  sudo chown $(id -u):$(id -g) $HOME/.kube/config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can see that the controlplane and components are running.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root@ip-172-31-32-10:~# kubectl get nodes
NAME         STATUS     ROLES           AGE     VERSION
kubemaster   NotReady   control-plane   4m46s   v1.27.2
root@ip-172-31-32-10:~# kubectl get pods -A
NAMESPACE     NAME                                 READY   STATUS    RESTARTS   AGE
kube-system   coredns-5d78c9869d-67skv             0/1     Pending   0          4m34s
kube-system   coredns-5d78c9869d-xsck7             0/1     Pending   0          4m34s
kube-system   etcd-kubemaster                      1/1     Running   0          4m48s
kube-system   kube-apiserver-kubemaster            1/1     Running   0          4m51s
kube-system   kube-controller-manager-kubemaster   1/1     Running   0          4m51s
kube-system   kube-proxy-7qfxs                     1/1     Running   0          4m34s
kube-system   kube-scheduler-kubemaster            1/1     Running   0          4m46s
root@ip-172-31-32-10:~
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Installing pod network using weave-net
&lt;/h4&gt;

&lt;p&gt;Run the below command using kubectl&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -f https://github.com/weaveworks/weave/releases/download/v2.8.1/weave-daemonset-k8s.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We need to update the pod network cidr we provided during the kubeadm init to the Weave-net configuration. Run the below command and edit the environment variable as shown below. We need to include a environment variable named IPALLOC_RANGE and value 192.16.0.0/16. Please make sure you are editing the container named 'weave'.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl edit daemonset weave-net -n kube-system
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;spec:
      containers:
      - command:
        - /home/weave/launch.sh
        env:
        - name: IPALLOC_RANGE
          value: 192.16.0.0/16
        - name: INIT_CONTAINER
          value: "true"
        - name: HOSTNAME
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: spec.nodeName
        image: weaveworks/weave-kube:latest
        imagePullPolicy: Always
        name: weave

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Joining the node01 instance to the cluster.
&lt;/h4&gt;

&lt;p&gt;In node01 terminal, use the kubeadm join command we had copied before to join the node01 to the cluster. At the end of the command add the --cri-socket=unix:///var/run/cri-dockerd.sock, to select docker as the container runtime.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root@ip-172-31-32-11:~# kubeadm join 172.31.32.10:6443 --token pew42g.8wcpqxe3c2avc3ky         --discovery-token-ca-cert-hash sha256:4fb3037e7e98599763dae8f2aa62deac27139c1af96cb8b8e482590ebaaeb45c --cri-socket=unix:///var/run/cri-dockerd.sock
[preflight] Running pre-flight checks
[preflight] Reading configuration from the cluster...
[preflight] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'
[kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
[kubelet-start] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
[kubelet-start] Starting the kubelet
[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...
[kubelet-check] Initial timeout of 40s passed.

This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.

Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have successfully added two node cluster in AWS EC2.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;root@ip-172-31-32-10:~# kubectl get nodes
NAME         STATUS   ROLES           AGE     VERSION
kubemaster   Ready    control-plane   62m     v1.27.2
node01       Ready    &amp;lt;none&amp;gt;          2m56s   v1.27.2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Please note that since we used the lowest capacity EC2 instances for the cluster, we should expect low performance on this Kubernetes cluster. But this would give an experience on how to setup the cluster using kubeadm.&lt;/p&gt;

</description>
      <category>cloudnative</category>
      <category>kubernetes</category>
      <category>devops</category>
      <category>aws</category>
    </item>
    <item>
      <title>Kubernetes - Getting Started</title>
      <dc:creator>Surendu Suresh</dc:creator>
      <pubDate>Tue, 23 May 2023 09:40:05 +0000</pubDate>
      <link>https://forem.com/surendusuresh/kubernetes-getting-started-4pf</link>
      <guid>https://forem.com/surendusuresh/kubernetes-getting-started-4pf</guid>
      <description>&lt;p&gt;When you think about DevOps, Kubernetes is one of the most important tool you need to learn. It is easy to grasp and valuable tool to have under your belt. This article will give you some basic understanding of Kubernetes and a bit of hands-on experience.&lt;/p&gt;

&lt;h4&gt;
  
  
  Prerequisites
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Basic knowledge of Linux operating system.&lt;/li&gt;
&lt;li&gt;Basic knowledge of container technologies like Docker.&lt;/li&gt;
&lt;li&gt;Basic knowledge of docker registry like DockerHub.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is Kubernetes
&lt;/h2&gt;

&lt;p&gt;Kubernetes is an open-source container orchestration tool used for deploying, managing and monitoring the containerized applications. It was developed by Google and later donated to Cloud Native Computing Foundation (CNCF) which is a sub-foundation of Linux Foundation.&lt;/p&gt;

&lt;p&gt;Kubernetes supports different container runtimes, including containerd, Docker Engine, CRI-O, Mirantis Container Runtime etc.&lt;/p&gt;

&lt;h3&gt;
  
  
  What are Containers, Pods and Nodes
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Container&lt;/strong&gt; is a bundling of software that packages up code and all its dependencies. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pod&lt;/strong&gt; is a group of one or more containers, with shared storage, network resources and a specification for how to run the containers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Node&lt;/strong&gt; is a physical or virtual machine which runs the workload Kubernetes places in it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can think of Kubernetes as a ship carrying lot of containers on it. In reality, Kubernetes cluster, is a group of physical or virtual machines, which can run and manage multiple containers in the form of Pods.&lt;/p&gt;

&lt;p&gt;So, let's look at the architecture of Kubernetes and it's building blocks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--U0P84gyA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/flq2c217f3s4wfirq24w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--U0P84gyA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/flq2c217f3s4wfirq24w.png" alt="Kubernetes Architecture" width="731" height="611"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Control Plane Components
&lt;/h2&gt;

&lt;h4&gt;
  
  
  kube-apiserver
&lt;/h4&gt;

&lt;p&gt;The API Server acts as a front end for the Kubernetes. It manages all the interactions between all other components. You can run multiple instances of kube-apiserver by deploying more instances.&lt;/p&gt;

&lt;h4&gt;
  
  
  etcd
&lt;/h4&gt;

&lt;p&gt;etcd is a key value store used by Kubernetes to store all data related to the Kubernetes cluster. You can backup the cluster by taking backup of the etcd data.&lt;/p&gt;

&lt;h4&gt;
  
  
  kube-scheduler
&lt;/h4&gt;

&lt;p&gt;kube-scheduler is responsible for watching for unassigned pods and scheduling it in one of the available nodes. The node is selected based on the resource requirements of the pod and the resource availability in the nodes among other things.&lt;/p&gt;

&lt;h4&gt;
  
  
  kube-controller-manager
&lt;/h4&gt;

&lt;p&gt;This component runs all the controller processes. There are many controller processes, Node controller, Job controller, Replication Controller, etc.&lt;/p&gt;

&lt;h4&gt;
  
  
  cloud-controller-manager
&lt;/h4&gt;

&lt;p&gt;This is an optional component which helps in embedding cloud specific control logic. It lets you link the cluster to your cloud provider.&lt;/p&gt;

&lt;h4&gt;
  
  
  DNS
&lt;/h4&gt;

&lt;p&gt;Cluster DNS is a DNS server which stores a DNS record for Kubernetes services. Each new services and pods created in Kubernetes has an entry in the DNS.&lt;/p&gt;

&lt;h2&gt;
  
  
  Node Components
&lt;/h2&gt;

&lt;p&gt;Node components runs on every node and responsible for managing the pods.&lt;/p&gt;

&lt;h4&gt;
  
  
  kubelet
&lt;/h4&gt;

&lt;p&gt;kubelet is responsible for running the containers in the pod. It is responsible for restarting any crashed pods and making sure the desired amount of pods are running as per the specification.&lt;/p&gt;

&lt;h4&gt;
  
  
  kube-proxy
&lt;/h4&gt;

&lt;p&gt;kube-proxy maintains networks rules on nodes. It enables communication between pods and from outside your cluster. &lt;/p&gt;

&lt;h4&gt;
  
  
  Container runtime
&lt;/h4&gt;

&lt;p&gt;Container runtime is responsible for running the container inside the pod. Kubernetes supports various container runtimes which follows the Kubernetes Container Runtime Interface (CRI).&lt;/p&gt;

&lt;h2&gt;
  
  
  Playing with Kubernetes
&lt;/h2&gt;

&lt;p&gt;Enough with the theory! Let's get started running a Kubernetes cluster on your laptop. Easiest way to get your hands on Kubernetes is to install Docker Desktop application.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.docker.com/desktop/install/windows-install/"&gt;Docker Desktop Installation For Windows&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Above link will guide you through the steps to install Docker Desktop for Windows. Similar guides are available for Mac and Linux OS as well. For Windows, we need to enable WSL 2 (Windows Subsystem for Linux).&lt;/p&gt;

&lt;p&gt;Once Docker Desktop is installed, go to Settings -&amp;gt; Kubernetes -&amp;gt; Enable Kubernetes as below. Wait for the Kubernetes to be up.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s---Q04Zij_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/84xny75vqua3cxvsbm9x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---Q04Zij_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/84xny75vqua3cxvsbm9x.png" alt="Docker Desktop" width="800" height="425"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  kubectl
&lt;/h4&gt;

&lt;p&gt;kubectl is the &lt;strong&gt;Command Line Interface (cli)&lt;/strong&gt; tool used for managing all the operations of Kubernetes cluster. It can be used for monitoring the nodes, pods, services etc. It can create, modify and delete pods, deployments, services etc. &lt;/p&gt;

&lt;p&gt;Open Ubuntu for Windows or Terminal to run the below commands once Kubernetes is up.&lt;/p&gt;

&lt;p&gt;For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To list all the nodes in the cluster
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ubuntu: ~ &amp;gt; kubectl get nodes
NAME             STATUS   ROLES           AGE   VERSION
docker-desktop   Ready    control-plane   27d   v1.25.4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Above shows, there is only one node in the cluster named docker-desktop. It is in ready status and version is 1.25.4.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To list all the pods in all namespaces
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ubuntu: ~ &amp;gt; kubectl get pods --all-namespaces
NAMESPACE     NAME                                     READY   STATUS    RESTARTS         AGE
kube-system   coredns-565d847f94-f7k2x                 1/1     Running   4 (6d1h ago)     27d
kube-system   coredns-565d847f94-s78sp                 1/1     Running   4 (6d1h ago)     27d
kube-system   etcd-docker-desktop                      1/1     Running   4 (6d1h ago)     27d
kube-system   kube-apiserver-docker-desktop            1/1     Running   4 (6d1h ago)     27d
kube-system   kube-controller-manager-docker-desktop   1/1     Running   4 (6d1h ago)     27d
kube-system   kube-proxy-9ll9n                         1/1     Running   4 (6d1h ago)     27d
kube-system   kube-scheduler-docker-desktop            1/1     Running   4 (6d1h ago)     27d
kube-system   storage-provisioner                      1/1     Running   68 (6d1h ago)    27d
kube-system   vpnkit-controller                        1/1     Running   1040 (12m ago)   27d
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hope you are seeing few familiar names above. All the controlplane components are in kube-system namespace. Namespace is a logical separator for the objects we create in Kubernetes. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run an nginx server at port 80
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ubuntu: ~ &amp;gt; kubectl run nginx --image=nginx --port=80
pod/nginx created
ubuntu: ~ &amp;gt; kubectl get pods
NAME    READY   STATUS    RESTARTS   AGE
nginx   1/1     Running   0          10s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;kubectl run command creates a new pod with the docker image provided by --image argument. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To access the nginx container in the pod from outside.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ubuntu: ~ &amp;gt; kubectl port-forward nginx 30081:80
Forwarding from 127.0.0.1:30081 -&amp;gt; 80
Forwarding from [::1]:30081 -&amp;gt; 80
Handling connection for 30081
Handling connection for 30081
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is for local testing only. After the above command is run, if you access &lt;a href="http://localhost:30081"&gt;http://localhost:30081&lt;/a&gt;, you will get the nginx default page as below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GaSzkgh8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0wzm14zbbywwxre5bs4a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GaSzkgh8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0wzm14zbbywwxre5bs4a.png" alt="Nginx Output" width="617" height="257"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Delete the nginx pod
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ubuntu: ~ &amp;gt; kubectl delete pod nginx
pod "nginx" deleted
ubuntu: ~ &amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Creating a deployment using nginx image
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ubuntu: ~ &amp;gt; kubectl create deployment nginx --image=nginx --replicas=2
deployment.apps/nginx created
ubuntu: ~ &amp;gt; kubectl get all
NAME                        READY   STATUS    RESTARTS   AGE
pod/nginx-76d6c9b8c-vz677   1/1     Running   0          8s
pod/nginx-76d6c9b8c-zw999   1/1     Running   0          8s

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    &amp;lt;none&amp;gt;        443/TCP   27d

NAME                    READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/nginx   2/2     2            2           8s

NAME                              DESIRED   CURRENT   READY   AGE
replicaset.apps/nginx-76d6c9b8c   2         2         2       8s
ubuntu: ~ &amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here we are creating a new deployment with the nginx image. Number of replicas are mentioned using --replicas argument. You can see there are 2 pods created by this deployment. Replicaset is another object created by the deployment to control the replication process.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scaling up deployment
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ubuntu: ~ &amp;gt; kubectl scale deployment nginx --replicas=3
deployment.apps/nginx scaled
ubuntu: ~ &amp;gt; kubectl get pods
NAME                    READY   STATUS    RESTARTS   AGE
nginx-76d6c9b8c-56llc   1/1     Running   0          8s
nginx-76d6c9b8c-vz677   1/1     Running   0          3m11s
nginx-76d6c9b8c-zw999   1/1     Running   0          3m11s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command created an additional pod for nginx&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Scaling down deployment
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ubuntu: ~ &amp;gt; kubectl scale deployment nginx --replicas=1
deployment.apps/nginx scaled
ubuntu: ~ &amp;gt; k get pods
NAME                    READY   STATUS    RESTARTS   AGE
nginx-76d6c9b8c-zw999   1/1     Running   0          4m28s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command deleted two replicas of nginx and kept only one.&lt;/p&gt;

&lt;p&gt;This is just a brief introduction to the world of Kubernetes. You can explore further on your own using the Docker Desktop setup or you can use one of the cloud providers, which is paid service. &lt;/p&gt;

&lt;p&gt;Happy learning!!&lt;/p&gt;

</description>
      <category>devops</category>
      <category>cloudnative</category>
      <category>docker</category>
      <category>kubernetes</category>
    </item>
  </channel>
</rss>
