{"id":493656,"date":"2022-09-17T03:48:43","date_gmt":"2022-09-17T00:48:43","guid":{"rendered":"https:\/\/en.buradabiliyorum.com\/how-to-start-a-kubernetes-cluster-from-scratch-with-kubeadm-and-kubectl\/"},"modified":"2022-09-17T03:48:43","modified_gmt":"2022-09-17T00:48:43","slug":"how-to-start-a-kubernetes-cluster-from-scratch-with-kubeadm-and-kubectl","status":"publish","type":"post","link":"https:\/\/buradabiliyorum.com\/en\/how-to-start-a-kubernetes-cluster-from-scratch-with-kubeadm-and-kubectl\/","title":{"rendered":"#How to Start a Kubernetes Cluster From Scratch With Kubeadm and Kubectl"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_85 counter-hierarchy ez-toc-counter ez-toc-custom ez-toc-container-direction\">\n<p class=\"ez-toc-title\" style=\"cursor:inherit\">Table of Contents<\/p>\n<label for=\"ez-toc-cssicon-toggle-item-6a33e4b5ea2dd\" class=\"ez-toc-cssicon-toggle-label\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #dd3333;color:#dd3333\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #dd3333;color:#dd3333\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/label><input type=\"checkbox\"  id=\"ez-toc-cssicon-toggle-item-6a33e4b5ea2dd\" checked aria-label=\"Toggle\" \/><nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-start-a-kubernetes-cluster-from-scratch-with-kubeadm-and-kubectl\/#%E2%80%9CHow_to_Start_a_Kubernetes_Cluster_From_Scratch_With_Kubeadm_and_Kubectl%E2%80%9D\" >&#8220;How to Start a Kubernetes Cluster From Scratch With Kubeadm and Kubectl&#8221;<\/a><ul class='ez-toc-list-level-2' ><li class='ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-start-a-kubernetes-cluster-from-scratch-with-kubeadm-and-kubectl\/#Installing_a_Container_Runtime\" >Installing a Container Runtime<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-start-a-kubernetes-cluster-from-scratch-with-kubeadm-and-kubectl\/#Installing_Kubeadm_Kubectl_and_Kubelet\" >Installing Kubeadm, Kubectl, and Kubelet<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-start-a-kubernetes-cluster-from-scratch-with-kubeadm-and-kubectl\/#Disabling_Swap\" >Disabling Swap<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-start-a-kubernetes-cluster-from-scratch-with-kubeadm-and-kubectl\/#Loading_the_br_netfilter_Module\" >Loading the br_netfilter Module<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-6\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-start-a-kubernetes-cluster-from-scratch-with-kubeadm-and-kubectl\/#Creating_Your_Cluster\" >Creating Your Cluster<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-7\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-start-a-kubernetes-cluster-from-scratch-with-kubeadm-and-kubectl\/#Preparing_Your_Kubeconfig_File\" >Preparing Your Kubeconfig File<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-8\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-start-a-kubernetes-cluster-from-scratch-with-kubeadm-and-kubectl\/#Installing_a_Pod_Networking_Addon\" >Installing a Pod Networking Addon<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-9\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-start-a-kubernetes-cluster-from-scratch-with-kubeadm-and-kubectl\/#Interacting_With_Your_Cluster\" >Interacting With Your Cluster<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-10\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-start-a-kubernetes-cluster-from-scratch-with-kubeadm-and-kubectl\/#Adding_Another_Node\" >Adding Another Node<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-2'><a class=\"ez-toc-link ez-toc-heading-11\" href=\"https:\/\/buradabiliyorum.com\/en\/how-to-start-a-kubernetes-cluster-from-scratch-with-kubeadm-and-kubectl\/#Summary\" >Summary<\/a><\/li><\/ul><\/li><\/ul><\/nav><\/div>\n<h1><span class=\"ez-toc-section\" id=\"%E2%80%9CHow_to_Start_a_Kubernetes_Cluster_From_Scratch_With_Kubeadm_and_Kubectl%E2%80%9D\"><\/span>&#8220;How to Start a Kubernetes Cluster From Scratch With Kubeadm and Kubectl&#8221;<span class=\"ez-toc-section-end\"><\/span><\/h1>\n<div>\n<img loading=\"lazy\" decoding=\"async\" class=\"type:primaryImage alignnone size-full wp-image-806255\" data-pagespeed-no-defer=\"\" src=\"https:\/\/www.howtogeek.com\/wp-content\/uploads\/2022\/05\/Kubernetes-New.jpg?width=1198&amp;trim=1,1&amp;bg-color=000&amp;pad=1,1\" alt=\"Graphic with the Kubernetes logo\" width=\"1202\" height=\"677\"\/><\/p>\n<p>Kubernetes has a reputation for complexity but modern releases are relatively straightforward to set up. The official cluster administration tool <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/kubernetes.io\/docs\/setup\/production-environment\/tools\/kubeadm\/create-cluster-kubeadm\">Kubeadm<\/a> provides an automated experience for booting your control plane and registering worker nodes.<\/p>\n<p>This article will walk you through setting up a simple Kubernetes cluster using the default configuration. This is a \u201cfrom scratch\u201d guide which should work on a freshly provisioned host. A Debian-based system is assumed but you can adjust most of the commands to match your operating system\u2019s package manager. These steps have been tested using Ubuntu 22.04 and Kubernetes v1.25.<\/p>\n<h2 id=\"installing-a-container-runtime\"><span class=\"ez-toc-section\" id=\"Installing_a_Container_Runtime\"><\/span>Installing a Container Runtime<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Kubernetes needs a CRI-compatible container runtime to start and run your containers. The standard Kubernetes distribution doesn\u2019t come with a runtime so you should install one before you continue. containerd is the most popular choice. It\u2019s the runtime included with modern Docker releases.<\/p>\n<p>You can install containerd using Docker\u2019s Apt repository. First add some dependencies that\u2019ll be used during the installation procedure:<\/p>\n<pre>$ sudo apt update&#13;\n$ sudo apt install -y \\&#13;\n   ca-certificates \\&#13;\n   curl \\&#13;\n   gnupg \\&#13;\n   lsb-release<\/pre>\n<p>Next add the repository\u2019s GPG key to Apt\u2019s <code>keyrings<\/code> directory:<\/p>\n<pre>$ sudo mkdir -p \/etc\/apt\/keyrings&#13;\n$ curl -fsSL https:\/\/<a href=\"https:\/\/buradabiliyorum.com\/en\/category\/download-scripts-themes-apps\/\" data-internallinksmanager029f6b8e52c=\"9\" title=\"Download Scripts &amp; Themes &amp; Apps\" target=\"_blank\" rel=\"noopener\">download<\/a>.docker.com\/linux\/ubuntu\/gpg | sudo gpg --dearmor -o \/etc\/apt\/keyrings\/docker.gpg<\/pre>\n<p>Now you can add the correct repository for your system by running this command:<\/p>\n<pre>$ echo \\&#13;\n  \"deb [arch=$(dpkg --print-architecture) signed-by=\/etc\/apt\/keyrings\/docker.gpg] https:\/\/download.docker.com\/linux\/ubuntu \\&#13;\n  $(lsb_release -cs) stable\" | sudo tee \/etc\/apt\/sources.list.d\/docker.list &gt; \/dev\/null<\/pre>\n<p>Update your package list to include the contents of the Docker repository:<\/p>\n<pre>$ sudo apt update<\/pre>\n<p>Finally install containerd:<\/p>\n<pre>$ sudo apt install -y containerd.io<\/pre>\n<p>Check the containerd service has started up:<\/p>\n<pre>$ sudo service containerd status&#13;\n containerd.service - containerd container runtime&#13;\n     Loaded: loaded (\/lib\/systemd\/system\/containerd.service; enabled; vendor preset: enabled)&#13;\n     Active: active (running) since Tue 2022-09-13 16:50:12 BST; 6s ago<\/pre>\n<p>A few tweaks to the containerd config file are required to get it working properly with Kubernetes. First replace the file\u2019s content with containerd\u2019s default configuration:<\/p>\n<pre>$ sudo containerd config default &gt; \/etc\/containerd\/config.toml<\/pre>\n<p>This populates all the available config fields and sorts out some issues, such as CRI support <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/kubernetes.io\/docs\/setup\/production-environment\/container-runtimes\/#containerd-systemd\">being disabled<\/a> on fresh installs.<\/p>\n<p>Next open <code>\/etc\/containerd\/config.toml<\/code> and find the following line:<\/p>\n<pre class=\"toml\"><code>SystemdCgroup = false<\/code><\/pre>\n<p>Change the value to <code>true<\/code>:<\/p>\n<pre class=\"toml\"><code>SystemdCgroup = true<\/code><\/pre>\n<p>This modification is required to enable full support for <code>systemd<\/code> <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/man7.org\/linux\/man-pages\/man7\/cgroups.7.html\">cgroup<\/a> management. Without this option, Kubernetes system containers will <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/github.com\/kubernetes\/kubernetes\/issues\/110177#issuecomment-1161647736\">periodically restart themselves<\/a>.<\/p>\n<p>Restart containerd to apply your changes:<\/p>\n<pre>$ sudo service containerd restart<\/pre>\n<h2 id=\"installing-kubeadm-kubectl-and-kubelet\"><span class=\"ez-toc-section\" id=\"Installing_Kubeadm_Kubectl_and_Kubelet\"><\/span>Installing Kubeadm, Kubectl, and Kubelet<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>The second phase in the process is to install Kubernetes tools. These three utilities provide the following capabilities:<\/p>\n<ul>\n<li><strong>Kubeadm<\/strong> \u2013 An administration tool that operates at the cluster level. You\u2019ll use this to create your cluster and add additional nodes.<\/li>\n<li><strong>Kubectl<\/strong> \u2013 Kubectl is the CLI you use to interact with your Kubernetes cluster once it\u2019s running.<\/li>\n<li><strong>Kubelet<\/strong> \u2013 This is the Kubernetes process that runs on your cluster\u2019s worker nodes. It\u2019s responsible for maintaining contact with the control plane and starting new containers when requested.<\/li>\n<\/ul>\n<p>The three binaries are available in an Apt repository hosted by Google Cloud. First register the repository\u2019s GPG keyring:<\/p>\n<pre>$ sudo curl -fsSLo \/etc\/apt\/keyrings\/kubernetes.gpg https:\/\/packages.cloud.google.com\/apt\/doc\/apt-key.gpg<\/pre>\n<p>Next add the repository to your sources\u2026<\/p>\n<pre>$ echo \"deb [signed-by=\/etc\/apt\/keyrings\/kubernetes.gpg] https:\/\/apt.kubernetes.io\/ kubernetes-xenial main\" | sudo tee \/etc\/apt\/sources.list.d\/kubernetes.list<\/pre>\n<p>\u2026and update your package list:<\/p>\n<pre>$ sudo apt update<\/pre>\n<p>Now install the packages:<\/p>\n<pre>$ sudo apt install -y kubeadm kubectl kubelet<\/pre>\n<p>It\u2019s best practice to \u201chold\u201d these packages so Apt doesn\u2019t automatically update them when you run <code>apt upgrade<\/code>. Kubernetes cluster upgrades <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/kubernetes.io\/docs\/tasks\/administer-cluster\/kubeadm\/kubeadm-upgrade\">should be initiated manually<\/a> to prevent downtime and avoid unwanted breaking changes.<\/p>\n<pre>$ sudo apt-mark hold kubeadm kubectl kubelet<\/pre>\n<h2 id=\"disabling-swap\"><span class=\"ez-toc-section\" id=\"Disabling_Swap\"><\/span>Disabling Swap<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Kubernetes <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/github.com\/kubernetes\/kubernetes\/issues\/53533\">does not work<\/a> when swap is enabled. You must turn swap off before you create your cluster. Otherwise you\u2019ll find the provisioning process hangs while waiting for Kubelet to start.<\/p>\n<p>Run this command to disable swap:<\/p>\n<pre>$ sudo swapoff -a<\/pre>\n<p>Next edit your <code>\/etc\/fstab<\/code> file and disable any swap mounts:<\/p>\n<pre>UUID=ec6efe91-5d34-4c80-b59c-cafe89cc6cb2 \/               ext4    errors=remount-ro 0       1&#13;\n\/swapfile                                 none            swap    sw              0       0<\/pre>\n<p>This file shows a mount with the <code>swap<\/code> type as the last line. It should be removed or commented out so that swap remains disabled after system reboots.<\/p>\n<h2 id=\"loading-the-br_netfilter-module\"><span class=\"ez-toc-section\" id=\"Loading_the_br_netfilter_Module\"><\/span>Loading the br_netfilter Module<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>The <code>br_netfilter<\/code> kernel module is required to enable iptables to see bridged traffic. Kubeadm won\u2019t let you create your cluster when this module\u2019s missing.<\/p>\n<p>You can enable it with the following command:<\/p>\n<pre>$ sudo modprobe br_netfilter<\/pre>\n<p>Make it persist after a reboot by including it in your system\u2019s modules list:<\/p>\n<pre>$ echo br_netfilter | sudo tee \/etc\/modules-load.d\/kubernetes.conf<\/pre>\n<h2 id=\"creating-your-cluster\"><span class=\"ez-toc-section\" id=\"Creating_Your_Cluster\"><\/span>Creating Your Cluster<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>You\u2019re ready to create your Kubernetes cluster. Run <code>kubeadm init<\/code> on the machine you want to host your control plane:<\/p>\n<pre>$ sudo kubeadm init --pod-network-cidr=10.244.0.0\/16<\/pre>\n<p>The <code>--pod-network-cidr<\/code> flag is included so that <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/www.digitalocean.com\/community\/tutorials\/understanding-ip-addresses-subnets-and-cidr-notation-for-networking\">a correct CIDR allocation<\/a> is available to the Pod networking addon that will be installed later on. The default value of <code>10.244.0.0\/16<\/code> works in most cases but you might have to change the range if you\u2019re using a heavily customized networking environment.<\/p>\n<p>Cluster creation can take several minutes to complete. Progress information will be displayed in your terminal. You should see this message upon success:<\/p>\n<pre>Your Kubernetes control-plane has initialized successfully!<\/pre>\n<p>The output also includes information on how to start using your cluster.<\/p>\n<h2 id=\"preparing-your-kubeconfig-file\"><span class=\"ez-toc-section\" id=\"Preparing_Your_Kubeconfig_File\"><\/span>Preparing Your Kubeconfig File<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Begin by copying the auto-generated Kubeconfig file into your own <code>.kube\/config<\/code> directory. Adjust the file\u2019s ownership to yourself so that Kubectl can read its contents correctly.<\/p>\n<pre>$ mkdir -p $HOME\/.kube&#13;\n$ sudo cp -i \/etc\/kubernetes\/admin.conf $HOME\/.kube\/config&#13;\n$ sudo chown $(id -u):$(id -g) $HOME\/.kube\/config<\/pre>\n<h2 id=\"installing-a-pod-networking-addon\"><span class=\"ez-toc-section\" id=\"Installing_a_Pod_Networking_Addon\"><\/span>Installing a Pod Networking Addon<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Kubernetes requires a Pod networking addon to exist in your cluster before worker nodes begin operating normally. You must manually install a <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/kubernetes.io\/docs\/concepts\/cluster-administration\/addons\/#networking-and-network-policy\">compatible addon<\/a> to complete your installation.<\/p>\n<p><a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/projectcalico.docs.tigera.io\/about\/about-calico\">Calico<\/a> and <a rel=\"nofollow noopener\" target=\"_blank\" href=\"https:\/\/github.com\/flannel-io\/flannel#deploying-flannel-manually\">Flannel<\/a> are the two most popular choices. This guide uses Flannel because of it\u2019s simple installation experience.<\/p>\n<p>Use Kubectl to add Flannel to your cluster:<\/p>\n<pre>$ kubectl apply -f https:\/\/raw.githubusercontent.com\/flannel-io\/flannel\/master\/Documentation\/kube-flannel.yml<\/pre>\n<p>Wait a few moments and then run <code>kubectl get nodes<\/code> in your terminal. You should see your Node shows as <code>Ready<\/code> and you can begin interacting with your cluster.<\/p>\n<pre>$ kubectl get nodes&#13;\nNAME       STATUS   ROLES           AGE     VERSION&#13;\nubuntu22   Ready    control-plane   7m19s   v1.25.0<\/pre>\n<p>If you run <code>kubectl get pods --all-namespaces<\/code>, you should see that the control plane components, CoreDNS, and Flannel are all up and running:<\/p>\n<pre>$ kubectl get pods --all-namespaces&#13;\nNAMESPACE      NAME                               READY   STATUS    RESTARTS        AGE&#13;\nkube-flannel   kube-flannel-ds-xlrk6              1\/1     Running   5 (16s ago)     11m&#13;\nkube-system    coredns-565d847f94-bzzkf           1\/1     Running   5 (2m9s ago)    14m&#13;\nkube-system    coredns-565d847f94-njrdc           1\/1     Running   4 (30s ago)     14m&#13;\nkube-system    etcd-ubuntu22                      1\/1     Running   6 (113s ago)    13m&#13;\nkube-system    kube-apiserver-ubuntu22            1\/1     Running   5 (30s ago)     16m&#13;\nkube-system    kube-controller-manager-ubuntu22   1\/1     Running   7 (3m59s ago)   13m&#13;\nkube-system    kube-proxy-r9g9k                   1\/1     Running   8 (21s ago)     14m&#13;\nkube-system    kube-scheduler-ubuntu22            1\/1     Running   7 (30s ago)     15m<\/pre>\n<h2 id=\"interacting-with-your-cluster\"><span class=\"ez-toc-section\" id=\"Interacting_With_Your_Cluster\"><\/span>Interacting With Your Cluster<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Now you can start using Kubectl to interact with your cluster. Before you continue, remove the default taint on your control plane node to allow Pods to schedule onto it. Kubernetes prevents Pods from running on the control plane node to avoid resource contention but this restriction is unnecessary for local use.<\/p>\n<pre>$ kubectl taint node ubuntu22 node-role.kubernetes.io\/control-plane:NoSchedule-&#13;\nnode\/ubuntu22 untainted<\/pre>\n<p>Replace <code>ubuntu22<\/code> in the command above with the name assigned to your own node.<\/p>\n<p>Now try starting a simple NGINX Pod:<\/p>\n<pre>$ kubectl run nginx --image nginx:latest&#13;\npod\/nginx created<\/pre>\n<p>Expose it with a NodePort service:<\/p>\n<pre>$ kubectl expose pod\/nginx --port 80 --type NodePort&#13;\nservice\/nginx exposed<\/pre>\n<p>Find the host port that was allocated to the service:<\/p>\n<pre>$ kubectl get services&#13;\nNAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE&#13;\nkubernetes   ClusterIP   10.96.0.1       &lt;none&gt;        443\/TCP        18m&#13;\nnginx        NodePort    10.106.44.155   &lt;none&gt;        80:30647\/TCP   27s<\/pre>\n<p>The port is <code>30647<\/code>. HTTP requests to this endpoint should now issue the default NGINX landing page in response:<\/p>\n<pre>$ curl http:\/\/localhost:30647&#13;\n&lt;!DOCTYPE html&gt;&#13;\n&lt;html&gt;&#13;\n&lt;head&gt;&#13;\n&lt;title&gt;Welcome to nginx!&lt;\/title&gt;<\/pre>\n<p>Your Kubernetes cluster is working!<\/p>\n<h2 id=\"adding-another-node\"><span class=\"ez-toc-section\" id=\"Adding_Another_Node\"><\/span>Adding Another Node<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>To configure additional worker nodes, first repeat all the steps in the sections up to \u201cCreating Your Cluster\u201d on each machine you want to use. Every Node will need containerd, Kubeadm and Kubelet installed. You should also check your node has full network connectivity to the machine that\u2019s running your control plane.<\/p>\n<p>Next run the following command on your new worker node:<\/p>\n<pre>kubeadm join 192.168.122.229:6443 \\&#13;\n    --node-name node-b \\&#13;\n    --token &lt;token&gt; \\&#13;\n    --discovery-token-ca-cert-hash sha256:&lt;token-ca-cert-hash&gt;<\/pre>\n<p>Replace the IP address with that of your control plane node. The values of <code>&lt;token&gt;<\/code> and <code>&lt;token-ca-cert-hash&gt;<\/code> will have been displayed when you ran <code>kubeadm init<\/code> to create your control plane. You can retrieve them using the following steps.<\/p>\n<p><strong>Token<\/strong><\/p>\n<p>Run <code>kubeadm token list<\/code> on the control plane node. The token value will be shown in the <code>TOKEN<\/code> column.<\/p>\n<pre>$ kubeadm token list&#13;\nTOKEN                     TTL         EXPIRES                USAGES                   DESCRIPTION                                                EXTRA GROUPS&#13;\nlkoz6v.cw1e01ckz2yqvw4u   23h         2022-09-14T19:35:03Z   authentication,signing<\/pre>\n<p><strong>Token CA Cert Hash<\/strong><\/p>\n<p>Run this command and use its output as the value:<\/p>\n<pre>$ openssl x509 -pubkey -in \/etc\/kubernetes\/pki\/ca.crt | openssl rsa -pubin -outform der 2&gt;\/dev\/null | \\&#13;\n   openssl dgst -sha256 -hex | sed 's\/^.* \/\/'<\/pre>\n<p><strong>Joining the Cluster<\/strong><\/p>\n<p>The <code>kubeadm join<\/code> command should produce this output upon success:<\/p>\n<pre>$ kubeadm join 192.168.122.229:6443 \\&#13;\n    --node-name node-b \\&#13;\n    --token &lt;token&gt; \\&#13;\n    --discovery-token-ca-cert-hash sha256:&lt;token-ca-cert-hash&gt;&#13;\n[kubelet-start] Starting the kubelet[kubelet-start] Waiting for the kubelet to perform the TLS Bootstrap...&#13;\n&#13;\nThis node has joined the cluster:&#13;\n* Certificate signing request was sent to apiserver and a response was received.&#13;\n* The Kubelet was informed of the new secure connection details.&#13;\n&#13;\nRun 'kubectl get nodes' on the control-plane to see this node join the cluster.<\/pre>\n<p>Verify the node\u2019s joined the cluster and is ready to receive Pods by running the <code>kubectl get nodes<\/code> command:<\/p>\n<pre>$ kubectl get nodes&#13;\nNAME       STATUS   ROLES           AGE    VERSION&#13;\nnode-b     Ready    &lt;none&gt;          91s    v1.25.0&#13;\nubuntu22   Ready    control-plane   100m   v1.25.0<\/pre>\n<p>The node shows up in the list and has <code>Ready<\/code> as its status. This means it\u2019s operational and Kubernetes can schedule Pods to it.<\/p>\n<h2 id=\"summary\"><span class=\"ez-toc-section\" id=\"Summary\"><\/span>Summary<span class=\"ez-toc-section-end\"><\/span><\/h2>\n<p>Setting up Kubernetes can seem daunting but Kubeadm automates most of the hard bits for you. Although there\u2019s still several steps to work through, you shouldn\u2019t run into issues if you make sure the prerequisites are satisfied before you begin.<\/p>\n<p>Most problems occur because there\u2019s no container runtime available, the <code>br_netfilter<\/code> kernel module is missing, swap is enabled, or the need to provide a Pod networking addon has been overlooked. Troubleshooting should begin by checking these common mistakes.<\/p>\n<p>Kubeadm gives you the latest version of Kubernetes straight from the project itself. Alternative distributions are available that let you start a single-node cluster with a single command. Minikube, MicroK8s, and K3s are three popular options. Although these are usually easier to set up and upgrade, they all have slight differences compared to upstream Kubernetes. Using Kubeadm gets you closer to Kubernetes\u2019 internal workings and is applicable to many different environments.<\/p>\n<\/div>\n<p><script>\n setTimeout(function(){\n  !function(f,b,e,v,n,t,s)\n  {if(f.fbq)return;n=f.fbq=function(){n.callMethod?\n  n.callMethod.apply(n,arguments):n.queue.push(arguments)};\n  if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';\n  n.queue=[];t=b.createElement(e);t.async=!0;\n  t.src=v;s=b.getElementsByTagName(e)[0];\n  s.parentNode.insertBefore(t,s) } (window, document,'script',\n  'https:\/\/connect.facebook.net\/en_US\/fbevents.js');\n   fbq('init', '335401813750447');\n   fbq('track', 'PageView');\n  },3000);\n<\/script><\/p>\n<blockquote><p><strong><span style=\"color: #ff6600;\">If you liked the article, do not forget to share it with your friends. Follow us on\u00a0<span style=\"color: #ff0000;\"><a style=\"color: #ff0000;\" href=\"https:\/\/news.google.com\/publications\/CAAqBwgKMLG0nwswvr63Aw\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Google News<\/a><\/span>\u00a0too, click on the star and choose us from your favorites.<\/span><\/strong><\/p><\/blockquote>\n<blockquote>\n<p style=\"text-align: center;\">For forums sites go to <span style=\"color: #ff9900;\"><a style=\"color: #ff9900;\" href=\"https:\/\/forum.buradabiliyorum.com\/\" target=\"_blank\" rel=\"noopener\">Forum.BuradaBiliyorum.Com<\/a><\/span><\/strong><\/p>\n<\/blockquote>\n<blockquote>\n<p style=\"text-align: center;\"><strong>If you want to read more like this article, you can visit our <span style=\"color: #ff9900;\"><a style=\"color: #ff9900;\" href=\"https:\/\/en.buradabiliyorum.com\/technology\/\" target=\"_blank\" rel=\"noopener\">Technology category.<\/a><\/span><\/strong><\/p>\n<\/blockquote>\n<p><span style=\"color: black;\"><a style=\"color: #ff9900;\" href=\"https:\/\/www.howtogeek.com\/devops\/how-to-start-a-kubernetes-cluster-from-scratch-with-kubeadm-and-kubectl\/\" target=\"_blank\" rel=\"noopener\">Source<\/a><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>&#8220;How to Start a Kubernetes Cluster From Scratch With Kubeadm and Kubectl&#8221; Kubernetes has a reputation for complexity but modern releases are relatively straightforward to set up. The official cluster administration tool Kubeadm provides an automated experience for booting your control plane and registering worker nodes. This article will walk you through setting up a&#8230;<\/p>\n","protected":false},"author":1,"featured_media":493657,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"fifu_image_url":"https:\/\/www.howtogeek.com\/wp-content\/uploads\/2022\/05\/Kubernetes-New.jpg?height=200p&trim=2,2,2,2","fifu_image_alt":"","footnotes":""},"categories":[18],"tags":[],"class_list":["post-493656","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-technology"],"_links":{"self":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts\/493656","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/comments?post=493656"}],"version-history":[{"count":0,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/posts\/493656\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media\/493657"}],"wp:attachment":[{"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/media?parent=493656"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/categories?post=493656"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/buradabiliyorum.com\/en\/wp-json\/wp\/v2\/tags?post=493656"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}