{"id":60746,"date":"2024-03-14T13:58:10","date_gmt":"2024-03-14T08:28:10","guid":{"rendered":"https:\/\/www.tothenew.com\/blog\/?p=60746"},"modified":"2024-03-19T14:08:25","modified_gmt":"2024-03-19T08:38:25","slug":"k8s-cluster-setup-using-kubeadm-with-bare-minimum-configurations","status":"publish","type":"post","link":"https:\/\/www.tothenew.com\/blog\/k8s-cluster-setup-using-kubeadm-with-bare-minimum-configurations\/","title":{"rendered":"K8s Cluster Setup using Kubeadm with Bare-minimum Configurations"},"content":{"rendered":"<h2><b>Introduction<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">Kubernetes is a powerful tool for managing containerized applications. It helps us to automate <\/span><span style=\"font-weight: 400;\">the deployment, scaling, and management of our applications in containers, which are like <\/span><span style=\"font-weight: 400;\">lightweight, standalone packages for software.<\/span><\/p>\n<p><span style=\"font-weight: 400;\">In the market, multiple tools are available to set up Kubernetes clusters locally (on our host <\/span><span style=\"font-weight: 400;\">machines), like <\/span><b>Minikube, Microk8s, Kind (Kubernetes in Docker), KubeSpray, <\/b><span style=\"font-weight: 400;\">etc. <\/span><span style=\"font-weight: 400;\">One of them is <\/span><b>Kubeadm, <\/b><span style=\"font-weight: 400;\">and we will be going to learn how to set up a <\/span><b>Kubeadm<\/b><span style=\"font-weight: 400;\"> cluster on an AWS <\/span><span style=\"font-weight: 400;\">EC2 machine.<\/span><\/p>\n<h2><b>Kubernetes Architecture<\/b><\/h2>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-60005 size-large\" src=\"\/blog\/wp-ttn-blog\/uploads\/2024\/01\/Kubernetes-Architecture-1024x796.png\" alt=\"\" width=\"625\" height=\"486\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2024\/01\/Kubernetes-Architecture-1024x796.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2024\/01\/Kubernetes-Architecture-300x233.png 300w, \/blog\/wp-ttn-blog\/uploads\/2024\/01\/Kubernetes-Architecture-768x597.png 768w, \/blog\/wp-ttn-blog\/uploads\/2024\/01\/Kubernetes-Architecture-624x485.png 624w, \/blog\/wp-ttn-blog\/uploads\/2024\/01\/Kubernetes-Architecture.png 1426w\" sizes=\"(max-width: 625px) 100vw, 625px\" \/><\/p>\n<h3><span style=\"font-weight: 400;\">Control Plane Components:<\/span><\/h3>\n<ul>\n<li><b>Etcd: <\/b><span style=\"font-weight: 400;\">Cluster Data Store\u200a\u2014\u200aKubernetes uses \u201cetcd.\u201d This is a strong, consistent, and highly-available key value store that Kubernetes uses for persistent storage of all API objects.\u00a0<\/span><\/li>\n<li><b>API Server<\/b><span style=\"font-weight: 400;\">: The API server exposes a restful Kubernetes API and consumes JSON manifest files.<\/span><\/li>\n<li><b>Controller Manager<\/b><span style=\"font-weight: 400;\">: Known as the \u201ckube-controller manager,\u201d this runs all the controllers that handle routine tasks in the cluster.\u00a0<\/span><\/li>\n<li><b>Scheduler<\/b><span style=\"font-weight: 400;\">: The scheduler watches for newly-created pods (groups of one or more containers) and assigns them to nodes.<\/span><\/li>\n<li><b>Cloud Controller Manager: <\/b><span style=\"font-weight: 400;\">If we are using Kubernetes as a cloud provider service like EKS (AWS\u2019s Kubernetes service), then the whole master node is managed by the AWS in the backend using this component<\/span><\/li>\n<\/ul>\n<h3><span style=\"font-weight: 400;\">Slave Node Components:<\/span><\/h3>\n<ul>\n<li><b>Kubelet: <\/b><span style=\"font-weight: 400;\">An agent that runs on each node and makes sure that containers are running in a pod<\/span><\/li>\n<li><b>Kube Proxy<\/b><span style=\"font-weight: 400;\">: <\/span><span style=\"font-weight: 400;\">An agent that runs on each node and makes sure that containers are running in a pod<\/span><\/li>\n<\/ul>\n<h2><b>About Kubeadm<\/b><\/h2>\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">A tool to create a Kubernetes cluster<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Different from <\/span><b>Microk8s, Minikube, Kind, <\/b>etc.,<b> Kubeadm sets<\/b><span style=\"font-weight: 400;\">\u00a0up the whole cluster from scratch. I.e., master node and slave nodes, respectively, with each component like <\/span><span style=\"font-weight: 400;\">etcd<\/span><span style=\"font-weight: 400;\">, <\/span><span style=\"font-weight: 400;\">scheduler<\/span><span style=\"font-weight: 400;\">, <\/span><span style=\"font-weight: 400;\">controller manager<\/span><span style=\"font-weight: 400;\">, <\/span><span style=\"font-weight: 400;\">api-server<\/span><span style=\"font-weight: 400;\">, etc. However, Microk8s, Minikube, etc.,<\/span><span style=\"font-weight: 400;\">\u00a0are mainly used to test our deployments and pods.<\/span><\/li>\n<li style=\"font-weight: 400;\"><b>Kubeadm<\/b><span style=\"font-weight: 400;\"> is versatile, i.e., it allows us to create clusters on our own hardware or cloud servers.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">We have more control over the cluster&#8217;s configuration, which is useful for custom setups.<\/span><\/li>\n<\/ul>\n<h2><b>Benefits of Kubeadm<\/b><\/h2>\n<ul>\n<li style=\"font-weight: 400;\"><b>Kubeadm<\/b><span style=\"font-weight: 400;\"> is more versatile and flexible, suitable for various scenarios, including production.<\/span><\/li>\n<li style=\"font-weight: 400;\"><b>MicroK8s<\/b><span style=\"font-weight: 400;\"> and <\/span><b>Minikube<\/b><span style=\"font-weight: 400;\"> are designed for simplicity and are excellent for beginners or local development.<\/span><\/li>\n<li style=\"font-weight: 400;\"><b>Kind<\/b><span style=\"font-weight: 400;\"> is great for lightweight, multi-node cluster simulation during development and testing.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">The choice depends on our needs i.e., if we want production-level control, then kubeadm is best suited. If we want a quick and easy setup, <\/span><b>MicroK8s<\/b><span style=\"font-weight: 400;\"> or <\/span><b>Minikube<\/b><span style=\"font-weight: 400;\"> might be better.<\/span><\/li>\n<li style=\"font-weight: 400;\"><b>Kubeadm<\/b><span style=\"font-weight: 400;\"> offers more customization and is best for advanced use cases, while <\/span><b>MicroK8s<\/b><span style=\"font-weight: 400;\">, <\/span><b>Minikube<\/b><span style=\"font-weight: 400;\">, and <\/span><b>Kind<\/b><span style=\"font-weight: 400;\"> are simpler tools tailored for specific purposes, like quick local setups or lightweight development and testing environments.<\/span><\/li>\n<\/ul>\n<h2><b>Prerequisites<\/b><\/h2>\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Two EC2 instances (1 for master node setup and 1 for slave node setup)<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Security group rules for master (control-plane) node and slave node:<\/span><\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\"><br \/>\n<img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-60006 size-large\" src=\"\/blog\/wp-ttn-blog\/uploads\/2024\/01\/SG-Rules-1024x724.png\" alt=\"\" width=\"625\" height=\"442\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2024\/01\/SG-Rules-1024x724.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2024\/01\/SG-Rules-300x212.png 300w, \/blog\/wp-ttn-blog\/uploads\/2024\/01\/SG-Rules-768x543.png 768w, \/blog\/wp-ttn-blog\/uploads\/2024\/01\/SG-Rules-1536x1086.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2024\/01\/SG-Rules-2048x1448.png 2048w, \/blog\/wp-ttn-blog\/uploads\/2024\/01\/SG-Rules-624x441.png 624w\" sizes=\"(max-width: 625px) 100vw, 625px\" \/><br \/>\n<\/span><\/p>\n<h2><b>Setup<\/b><\/h2>\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Setting up the master node by running the following script:<\/span><\/li>\n<\/ul>\n<pre>#! \/bin\/bash\r\n\r\nset -eo pipefail\r\n\r\n# disable swap\u00a0\r\n\r\nsudo swapoff -a\r\n\r\n# keeps the swaf off during reboot\r\n\r\nsudo sed -i '\/ swap \/ s\/^\\(.*\\)$\/#\\1\/g' \/etc\/fstab\r\n\r\n# Updating the system\r\n\r\nsudo apt-get update -y\r\n\r\nsudo apt-get install -y \\\r\n\r\n\u00a0\u00a0\u00a0\u00a0apt-transport-https \\\r\n\r\n\u00a0\u00a0\u00a0\u00a0ca-certificates \\\r\n\r\n\u00a0\u00a0\u00a0\u00a0curl \\\r\n\r\n\u00a0\u00a0\u00a0\u00a0gnupg \\\r\n\r\n\u00a0\u00a0\u00a0\u00a0lsb-release\r\n\r\n# Process to install Docker\r\n\r\ncurl -fsSL https:\/\/download.docker.com\/linux\/ubuntu\/gpg | sudo gpg --dearmor -o \/usr\/share\/keyrings\/docker-archive-keyring.gpg\r\n\r\necho \\\r\n\r\n\u00a0\u00a0\"deb [arch=amd64 signed-by=\/usr\/share\/keyrings\/docker-archive-keyring.gpg] https:\/\/download.docker.com\/linux\/ubuntu \\\r\n\r\n\u00a0\u00a0$(lsb_release -cs) stable\" | sudo tee \/etc\/apt\/sources.list.d\/docker.list &gt; \/dev\/null\r\n\r\nsudo apt-get update -y\r\n\r\nsudo apt-get install docker-ce docker-ce-cli containerd.io -y\r\n\r\n# Setting CGroup to systemd for Docker\r\n\r\ncat &lt;&lt;EOF | sudo tee \/etc\/docker\/daemon.json\r\n\r\n{\r\n\r\n\u00a0\u00a0\"exec-opts\": [\"native.cgroupdriver=systemd\"],\r\n\r\n\u00a0\u00a0\"log-driver\": \"json-file\",\r\n\r\n\u00a0\u00a0\"log-opts\": {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\"max-size\": \"100m\"\r\n\r\n\u00a0\u00a0},\r\n\r\n\u00a0\u00a0\"storage-driver\": \"overlay2\"\r\n\r\n}\r\n\r\nEOF\r\n\r\nsudo systemctl enable docker\r\n\r\nsudo systemctl daemon-reload\r\n\r\nsudo systemctl restart docker\r\n\r\necho \"Docker Runtime Configured Successfully\"\r\n\r\n# Installing net-tools, curl, kubernetes certs to install kubectl, kubeadm, and kubelet\r\n\r\nsudo apt-get update\r\n\r\nsudo apt-get install -y apt-transport-https ca-certificates curl\r\n\r\nsudo curl -fsSLo \/usr\/share\/keyrings\/kubernetes-archive-keyring.gpg https:\/\/packages.cloud.google.com\/apt\/doc\/apt-key.gpg\r\n\r\necho \"deb [signed-by=\/usr\/share\/keyrings\/kubernetes-archive-keyring.gpg] https:\/\/apt.kubernetes.io\/ kubernetes-xenial main\" | sudo tee \/etc\/apt\/sources.list.d\/kubernetes.list\r\n\r\nsudo apt-get update -y\r\n\r\nsudo apt-get install -y kubelet kubeadm kubectl\r\n\r\n# Pausing the updates for kubelet, kubeadm, and kubectl\r\n\r\nsudo apt-mark hold kubelet kubeadm kubectl\r\n\r\n# Initialize the cluster\r\n\r\nsudo kubeadm init\r\n\r\nmkdir -p $HOME\/.kube\r\n\r\nsudo cp -i \/etc\/kubernetes\/admin.conf $HOME\/.kube\/config\r\n\r\nsudo chown $(id -u):$(id -g) $HOME\/.kube\/config\r\n\r\n# Creating pod network (without setting this network, the deployments and pods will not come up....they will always be in not-ready state)\r\n\r\ncurl https:\/\/docs.projectcalico.org\/manifests\/calico.yaml -O\r\n\r\nkubectl apply -f calico.yaml<\/pre>\n<p><span style=\"font-weight: 400;\">The above script does the following:<\/span><\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li style=\"font-weight: 400;\"><b>sudo swapoff -a<\/b><span style=\"font-weight: 400;\">: Disables the system&#8217;s swap space. Kubernetes typically requires a swap to be disabled.<\/span><\/li>\n<li style=\"font-weight: 400;\"><b>sudo sed -i &#8216;\/ swap \/ s\/^\\(.*\\)$\/#\\1\/g&#8217; \/etc\/fstab<\/b><span style=\"font-weight: 400;\">: This line comments out the swap entry in the \/etc\/fstab file, ensuring that swap remains disabled even after a system reboot.<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Updating the system and then installing Docker<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Configuring the Docker to use <\/span><b>systemd <\/b><span style=\"font-weight: 400;\">as the <\/span><b>cgroup<\/b><span style=\"font-weight: 400;\"> driver and setting up some logging and storage options<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Installing additional packages required for Kubernetes installation, including curl and certificates, and then importing GPG keys<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Now, the most important part of installing the Kubernetes components: <\/span><b>kubelet <\/b><span style=\"font-weight: 400;\">(responsible for managing containers that are part of the pod)<\/span><b>, kubeadm, <\/b><span style=\"font-weight: 400;\">and <\/span><b>kubectl <\/b><span style=\"font-weight: 400;\">(cli to interact with Kube&#8217;s api-server)<\/span><\/li>\n<li style=\"font-weight: 400;\"><b>sudo apt-mark hold kubelet kubeadm kubectl: <\/b><span style=\"font-weight: 400;\">Pausing the updates for these components<\/span><\/li>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Initializing the Kubernetes cluster by running <\/span><b>sudo kubeadm init<\/b><span style=\"font-weight: 400;\">. This command sets up the control plane on the current node.<\/span>\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">The components of the control plane are the <\/span><b>scheduler, api-server, etcd, and the control manager.<\/b><\/li>\n<\/ul>\n<\/li>\n<li><span style=\"font-weight: 400;\">Setting up the Kubernetes configuration for the user by creating a ~\/.kube\/config file.<\/span>\n<ul>\n<li><span style=\"font-weight: 400;\">This file is responsible for accessing the Kubernetes cluster<\/span><\/li>\n<\/ul>\n<\/li>\n<li><span style=\"font-weight: 400;\">Now, we are setting up a <\/span><b>calico<\/b> <b>pod network.<\/b>\n<ul>\n<li><span style=\"font-weight: 400;\">Calico is a commonly used network plugin for Kubernetes that allows pods to communicate with each other<\/span><\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><span style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">We are all set now. To check whether our cluster is running or not, just ssh inside the master node and run the following Kubernetes commands:<br \/>\n<\/span><\/span><\/p>\n<p><em>kubectl get all; kubectl get all -n kube-system; kubectl get nodes\u2026\u2026etc<\/em><\/p>\n<p><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-60744 size-large\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2024\/03\/kubeadm-1024x704.png\" alt=\"\" width=\"625\" height=\"430\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2024\/03\/kubeadm-1024x704.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2024\/03\/kubeadm-300x206.png 300w, \/blog\/wp-ttn-blog\/uploads\/2024\/03\/kubeadm-768x528.png 768w, \/blog\/wp-ttn-blog\/uploads\/2024\/03\/kubeadm-1536x1056.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2024\/03\/kubeadm-624x429.png 624w, \/blog\/wp-ttn-blog\/uploads\/2024\/03\/kubeadm.png 1954w\" sizes=\"(max-width: 625px) 100vw, 625px\" \/><\/p>\n<p><b>NOTE: <\/b><span style=\"font-weight: 400;\">By default, the cluster is accessible via the <\/span><b>master node <\/b><span style=\"font-weight: 400;\">only because in <\/span><span style=\"font-weight: 400;\">$HOME\/.kube\/config<\/span> <span style=\"font-weight: 400;\">this file, there will be a private IP listed for the cluster, and to access this cluster from our local machine, we need to add public IP here (not secure). <\/span><span style=\"font-weight: 400;\">The more secure option to access the cluster is using a VPN.<\/span><\/p>\n<p>Now, it&#8217;s time to join the <b>slave nodes <\/b>in our cluster. To join slave nodes, run the below script in the slave nodes:<\/p>\n<pre>#! \/bin\/bash\r\n\r\nset -eo pipefail\r\n\r\n# disable swap\r\n\r\nsudo swapoff -a\r\n\r\n# keeps the swaf off during reboot\r\n\r\nsudo sed -i '\/ swap \/ s\/^\\(.*\\)$\/#\\1\/g' \/etc\/fstab\r\n\r\nsudo apt-get update -y\r\n\r\nsudo apt-get install -y \\\r\n\r\n\u00a0\u00a0\u00a0\u00a0apt-transport-https \\\r\n\r\n\u00a0\u00a0\u00a0\u00a0ca-certificates \\\r\n\r\n\u00a0\u00a0\u00a0\u00a0curl \\\r\n\r\n\u00a0\u00a0\u00a0\u00a0gnupg \\\r\n\r\n\u00a0\u00a0\u00a0\u00a0lsb-release\r\n\r\ncurl -fsSL https:\/\/download.docker.com\/linux\/ubuntu\/gpg | sudo gpg --dearmor -o \/usr\/share\/keyrings\/docker-archive-keyring.gpg\r\n\r\necho \\\r\n\r\n\u00a0\u00a0\"deb [arch=amd64 signed-by=\/usr\/share\/keyrings\/docker-archive-keyring.gpg] https:\/\/download.docker.com\/linux\/ubuntu \\\r\n\r\n\u00a0\u00a0$(lsb_release -cs) stable\" | sudo tee \/etc\/apt\/sources.list.d\/docker.list &gt; \/dev\/null\r\n\r\nsudo apt-get update -y\r\n\r\nsudo apt-get install docker-ce docker-ce-cli containerd.io -y\r\n\r\n# Setting up CGroup to systemd in docker runtime\r\n\r\ncat &lt;&lt;EOF | sudo tee \/etc\/docker\/daemon.json\r\n\r\n{\r\n\r\n\u00a0\u00a0\"exec-opts\": [\"native.cgroupdriver=systemd\"],\r\n\r\n\u00a0\u00a0\"log-driver\": \"json-file\",\r\n\r\n\u00a0\u00a0\"log-opts\": {\r\n\r\n\u00a0\u00a0\u00a0\u00a0\"max-size\": \"100m\"\r\n\r\n\u00a0\u00a0},\r\n\r\n\u00a0\u00a0\"storage-driver\": \"overlay2\"\r\n\r\n}\r\n\r\nEOF\r\n\r\nsudo systemctl enable docker\r\n\r\nsudo systemctl daemon-reload\r\n\r\nsudo systemctl restart docker\r\n\r\nsudo apt-get update\r\n\r\nsudo apt-get install -y apt-transport-https ca-certificates curl\r\n\r\nsudo curl -fsSLo \/usr\/share\/keyrings\/kubernetes-archive-keyring.gpg https:\/\/packages.cloud.google.com\/apt\/doc\/apt-key.gpg\r\n\r\necho \"deb [signed-by=\/usr\/share\/keyrings\/kubernetes-archive-keyring.gpg] https:\/\/apt.kubernetes.io\/ kubernetes-xenial main\" | sudo tee \/etc\/apt\/sources.list.d\/kubernetes.list\r\n\r\nsudo apt-get update -y\r\n\r\nsudo apt-get install -y kubelet kubeadm kubectl\r\n\r\nsudo apt-mark hold kubelet kubeadm kubectl<\/pre>\n<p><span style=\"font-weight: 400;\">The above script installs and configures the same things that are in the master node except for <\/span><b>initializing the cluster.<\/b><\/p>\n<ul>\n<li><b><\/b>Once we have installed all the required components via the above script, we need to ssh into the master node to generate the <b>Token <\/b>and <b>Hash, <\/b>which the slave nodes will use to join the cluster. The below command will generate the token and hash:<\/li>\n<\/ul>\n<pre>sudo kubeadm token create --print-join-command<\/pre>\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Once we get the command to join the slave nodes to the cluster, we ssh into the slave nodes and run that command:<\/span><\/li>\n<\/ul>\n<pre>sudo kubeadm join &lt;master node IP&gt;:6443 --token &lt;token value&gt; --discovery-token-ca-cert-hash sha256:&lt;hash value&gt;<\/pre>\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Once this is successful, you can ssh in the master node and check the status of the attached node using the below command:<\/span><\/span><\/li>\n<\/ul>\n<p>Kubectl get nodes<\/p>\n<p><span style=\"font-weight: 400;\"><span style=\"font-weight: 400;\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone wp-image-60745 size-large\" src=\"https:\/\/www.tothenew.com\/blog\/wp-ttn-blog\/uploads\/2024\/03\/kubeadm1-1024x206.png\" alt=\"\" width=\"625\" height=\"126\" srcset=\"\/blog\/wp-ttn-blog\/uploads\/2024\/03\/kubeadm1-1024x206.png 1024w, \/blog\/wp-ttn-blog\/uploads\/2024\/03\/kubeadm1-300x60.png 300w, \/blog\/wp-ttn-blog\/uploads\/2024\/03\/kubeadm1-768x154.png 768w, \/blog\/wp-ttn-blog\/uploads\/2024\/03\/kubeadm1-1536x308.png 1536w, \/blog\/wp-ttn-blog\/uploads\/2024\/03\/kubeadm1-624x125.png 624w, \/blog\/wp-ttn-blog\/uploads\/2024\/03\/kubeadm1.png 1932w\" sizes=\"(max-width: 625px) 100vw, 625px\" \/><\/span><\/span><\/p>\n<ul>\n<li style=\"font-weight: 400;\"><span style=\"font-weight: 400;\">Now, we have a running Kubernetes cluster with master and slave nodes.<\/span><\/li>\n<\/ul>\n<h2><b>Conclusion<\/b><\/h2>\n<p><span style=\"font-weight: 400;\">So, in this blog, we have learned about the basics of Kubernetes, which includes its architecture and comp<\/span><span style=\"font-weight: 400;\">onents, as well as the use of each element. We have also checked multiple <\/span><span style=\"font-weight: 400;\">approaches for creating Kubernetes clusters using different tools and how to use <\/span><b>Kubeadm <\/b><span style=\"font-weight: 400;\">to <\/span><span style=\"font-weight: 400;\">set up a Kubernetes cluster from scratch, including master and slave nodes.<\/span><\/p>\n<div class=\"ap-custom-wrapper\"><\/div><!--ap-custom-wrapper-->","protected":false},"excerpt":{"rendered":"<p>Introduction Kubernetes is a powerful tool for managing containerized applications. It helps us to automate the deployment, scaling, and management of our applications in containers, which are like lightweight, standalone packages for software. In the market, multiple tools are available to set up Kubernetes clusters locally (on our host machines), like Minikube, Microk8s, Kind (Kubernetes [&hellip;]<\/p>\n","protected":false},"author":1644,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"iawp_total_views":28},"categories":[2348],"tags":[1883,5700,3965],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/60746"}],"collection":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/users\/1644"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/comments?post=60746"}],"version-history":[{"count":2,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/60746\/revisions"}],"predecessor-version":[{"id":60867,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/posts\/60746\/revisions\/60867"}],"wp:attachment":[{"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/media?parent=60746"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/categories?post=60746"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tothenew.com\/blog\/wp-json\/wp\/v2\/tags?post=60746"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}