{"id":3131,"date":"2021-03-19T13:51:12","date_gmt":"2021-03-19T18:51:12","guid":{"rendered":"https:\/\/microsoftgeek.com\/?p=3131"},"modified":"2021-06-17T14:08:35","modified_gmt":"2021-06-17T19:08:35","slug":"how-to-install-a-kubernetes-cluster-on-centos-8","status":"publish","type":"post","link":"https:\/\/microsoftgeek.com\/?p=3131","title":{"rendered":"How to Install a Kubernetes Cluster on CentOS 8"},"content":{"rendered":"\n<h4 class=\"wp-block-heading\">Logical Architecture<\/h4>\n\n\n\n<p>Our installation is designed to have the&nbsp;<strong>Master-Node<\/strong>&nbsp;controlling the&nbsp;<strong>Worker Nodes<\/strong>. At the end of this installation, our logical architecture will look something like this.<\/p>\n\n\n\n<p><strong>Master Node<\/strong>&nbsp;\u2013 This machine generally acts as the control plane and runs the cluster database and the API server (which the kubectl CLI communicates with).<\/p>\n\n\n\n<p>Our 3-node&nbsp;<strong>Kubernetes Cluster<\/strong>&nbsp;will look something like this:<\/p>\n\n\n\n<figure class=\"wp-block-image\" id=\"attachment_35752\"><img decoding=\"async\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2020\/01\/Kubernetes-Cluster-Setup-Diagram.jpg\" alt=\"Kubernetes Cluster Diagram\" class=\"wp-image-35752\"\/><figcaption>Kubernetes Cluster Diagram<\/figcaption><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Installation of Kubernetes Cluster on Master-Node<\/h3>\n\n\n\n<p>For&nbsp;<strong>Kubernetes<\/strong>&nbsp;to work, you will need a containerization engine. As mentioned, we will be using&nbsp;<strong>Docker-CE<\/strong>.<\/p>\n\n\n\n<p>The following institutions will be performed on&nbsp;<strong>CentOS 8 Master-Node<\/strong>.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Step 1: Prepare Hostname, Firewall, and SELinux<\/h4>\n\n\n\n<p>On your&nbsp;<strong>CentOS 8 Master-Node<\/strong>, set the system hostname and update DNS in your&nbsp;<strong>\/etc\/hosts<\/strong>&nbsp;file.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># hostnamectl set-hostname master-node\n# cat &lt;&lt;EOF&gt;&gt; \/etc\/hosts\n192.168.0.47 master-node\n192.168.0.48 node-1 worker-node-1\n192.168.0.49 node-2 worker-node-2\nEOF\n<\/pre>\n\n\n\n<p>Next, ping your&nbsp;<strong>worker-node-1<\/strong>&nbsp;and&nbsp;<strong>worker-node-2<\/strong>&nbsp;to check if your updated host file is working correctly using the&nbsp;ping command.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># ping 192.168.0.48\n# ping 192.168.0.49\n<\/pre>\n\n\n\n<p>Next, disable&nbsp;<strong>Selinux<\/strong>, as this is required to allow containers to access the host filesystem, which is needed by pod networks and other services.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># setenforce 0\n<\/pre>\n\n\n\n<p>Setting&nbsp;<strong>setenforce<\/strong>&nbsp;to&nbsp;<code>0<\/code>&nbsp;effectively sets SELinux to permissive, which effectively disables SELinux until the next reboot. To completely disable it, use the below command and reboot.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># sed -i --follow-symlinks 's\/SELINUX=enforcing\/SELINUX=disabled\/g' \/etc\/sysconfig\/selinux\n# reboot\n<\/pre>\n\n\n\n<p>Kubernetes makes use of various ports for communication and access and these ports need to be accessible to Kubernetes and not limited by the firewall.<\/p>\n\n\n\n<figure class=\"wp-block-image\" id=\"attachment_35788\"><img decoding=\"async\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2020\/01\/Kubernetes-Ports.png\" alt=\"Kubernetes Ports\" class=\"wp-image-35788\"\/><figcaption>Kubernetes Ports<\/figcaption><\/figure>\n\n\n\n<p>Configure the firewall rules on the ports.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># firewall-cmd --permanent --add-port=6443\/tcp\n# firewall-cmd --permanent --add-port=2379-2380\/tcp\n# firewall-cmd --permanent --add-port=10250\/tcp\n# firewall-cmd --permanent --add-port=10251\/tcp\n# firewall-cmd --permanent --add-port=10252\/tcp\n# firewall-cmd --permanent --add-port=10255\/tcp\n# firewall-cmd --reload\n# modprobe br_netfilter\n# echo '1' &gt; \/proc\/sys\/net\/bridge\/bridge-nf-call-iptables\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Step 2: Install Docker-CE on CentOS 8<\/h4>\n\n\n\n<p>You will need to add the&nbsp;<strong>Docker<\/strong>&nbsp;repository first as it is no longer in the default package list using the following&nbsp;<strong>dnf config-manager<\/strong>&nbsp;command.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># dnf config-manager --add-repo=https:\/\/download.docker.com\/linux\/centos\/docker-ce.repo\n<\/pre>\n\n\n\n<p>Also install&nbsp;<strong>containerd.io<\/strong>&nbsp;package which is available as a daemon that manages the complete container lifecycle of its host system, from image transfer and storage to container execution and supervision to low-level storage to network attachments and beyond.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># dnf install https:\/\/download.docker.com\/linux\/centos\/7\/x86_64\/stable\/Packages\/containerd.io-1.2.6-3.3.el7.x86_64.rpm\n<\/pre>\n\n\n\n<p>Now install the latest version of a&nbsp;<strong>docker-ce<\/strong>&nbsp;package.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># dnf install docker-ce\n<\/pre>\n\n\n\n<p>You can now enable and start the docker service.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># systemctl enable docker\n# systemctl start docker\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Step 3: Install Kubernetes (Kubeadm) on CentOS 8<\/h4>\n\n\n\n<p>Next, you will need to add&nbsp;<strong>Kubernetes<\/strong>&nbsp;repositories manually as they do not come installed by default on&nbsp;<strong>CentOS 8<\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># cat &lt;&lt;EOF &gt; \/etc\/yum.repos.d\/kubernetes.repo\n<\/pre>\n\n\n\n<p>name=Kubernetes baseurl=https:\/\/packages.cloud.google.com\/yum\/repos\/kubernetes-el7-x86_64 enabled=1 gpgcheck=1 repo_gpgcheck=1 gpgkey=https:\/\/packages.cloud.google.com\/yum\/doc\/yum-key.gpg https:\/\/packages.cloud.google.com\/yum\/doc\/rpm-package-key.gpg EOF<\/p>\n\n\n\n<p><strong>Kubeadm<\/strong>&nbsp;helps you bootstrap a minimum viable Kubernetes cluster that conforms to best practices. With&nbsp;<strong>kubeadm<\/strong>, your cluster should pass the Kubernetes Conformance tests.<\/p>\n\n\n\n<p><strong>Kubeadm<\/strong>&nbsp;also supports other cluster lifecycle functions, such as upgrades, downgrade, and managing bootstrap tokens. Kubeadm is also integration-friendly with other orchestration tools like&nbsp;<strong>Ansible<\/strong>&nbsp;and&nbsp;<strong>Terraform<\/strong>.<\/p>\n\n\n\n<p>With the package repo now ready, you can go ahead and install&nbsp;<strong>kubeadm<\/strong>&nbsp;package.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># dnf install kubeadm -y \n<\/pre>\n\n\n\n<p>When the installation completes successfully, enable and start the service.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># systemctl enable kubelet\n# systemctl start kubelet\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Step 4: Create a control-plane Master with kubeadm<\/h4>\n\n\n\n<p>The Kubernetes master which acts as the&nbsp;<strong>control plane<\/strong>&nbsp;for the cluster runs a few critical services necessary for the cluster. As such, the initialization process will do a series of prechecks to ensure that the machine is ready to run Kubernetes. These prechecks expose warnings and exit on errors.&nbsp;<strong>kubeadm init<\/strong>&nbsp;then downloads and installs the cluster control plane components.<\/p>\n\n\n\n<p>Now it\u2019s time to initialize Kubernetes master, but before that, you must disable swap in order to run \u201c<strong>kubeadm init<\/strong>\u201c command.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># swapoff -a\n<\/pre>\n\n\n\n<p>Initializing&nbsp;<strong>Kubernetes<\/strong>&nbsp;master is a completely automated process that is controlled by the \u201c<strong>kubeadm init<\/strong>\u201c command as shown.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># kubeadm init\n<\/pre>\n\n\n\n<figure class=\"wp-block-image\" id=\"attachment_35754\"><img decoding=\"async\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2020\/01\/Initialize-Kubernetes-Cluster-on-Master.png\" alt=\"Initialize Kubernetes Master\" class=\"wp-image-35754\"\/><figcaption>Initialize Kubernetes Master<\/figcaption><\/figure>\n\n\n\n<p>Next, copy the following command and store it somewhere, as we required to run this command on the worker nodes later.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">kubeadm join 192.168.0.47:6443 --token nu06lu.xrsux0ss0ixtnms5  \\ --discovery-token-ca-cert-hash ha256:f996ea35r4353d342fdea2997a1cf8caeddafd6d4360d606dbc82314683478hjmf7<\/pre>\n\n\n\n<p><strong>Tip<\/strong>: Sometimes the above command might throw errors about the arguments passed, so to avoid errors, you need to remove the&nbsp;<code>\u2018\\\u2019<\/code>&nbsp;character and your final command will look like this.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># kubeadm join 192.168.0.47:6443 --token nu06lu.xrsux0ss0ixtnms5 \u2013discovery token-ca-cert-hash sha256:f996ea35r4353d342fdea2997a1cf8caeddafd6d4360d606dbc82314683478hjmf7\n<\/pre>\n\n\n\n<p>Once&nbsp;<strong>Kubernetes<\/strong>&nbsp;initialized successfully, you must enable your user to start using the cluster. In our scenario, we will be using the root user. You can also start the cluster using sudo user as shown.<\/p>\n\n\n\n<p>To use&nbsp;<strong>root<\/strong>, run:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># mkdir -p $HOME\/.kube\n# cp -i \/etc\/kubernetes\/admin.conf $HOME\/.kube\/config\n# chown $(id -u):$(id -g) $HOME\/.kube\/config\n<\/pre>\n\n\n\n<p>To use a&nbsp;<strong>sudo enabled user<\/strong>, run:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">$ mkdir -p $HOME\/.kube\n$ sudo cp -i \/etc\/kubernetes\/admin.conf $HOME\/.kube\/config\n$ sudo chown $(id -u):$(id -g) $HOME\/.kube\/config\n<\/pre>\n\n\n\n<p>Now confirm that the&nbsp;<strong>kubectl command<\/strong>&nbsp;is activated.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># kubectl get nodes\n<\/pre>\n\n\n\n<figure class=\"wp-block-image\" id=\"attachment_35644\"><img decoding=\"async\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2020\/01\/Check-Status-of-Nodes.png\" alt=\"Check Status of Nodes\" class=\"wp-image-35644\"\/><figcaption>Check Status of Nodes<\/figcaption><\/figure>\n\n\n\n<p>At this moment, you will see the status of the master-node is \u2018<strong>NotReady<\/strong>\u2019. This is because we are yet to deploy the pod network to the cluster.<\/p>\n\n\n\n<p>The pod Network is the overlay network for the cluster, that is deployed on top of the present node network. It is designed to allow connectivity across the pod.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Step 5: Setup Your Pod Network<\/h4>\n\n\n\n<p>Deploying the network cluster is a highly flexible process depending on your needs and there are many options available. Since we want to keep our installation as simple as possible, we will use&nbsp;<strong>Weavenet<\/strong>&nbsp;plugin which does not require any configuration or extra code and it provides one IP address per pod which is great for us.<\/p>\n\n\n\n<p>These commands will be important to get the pod network setup.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># export kubever=$(kubectl version | base64 | tr -d '\\n')\n# kubectl apply -f \"https:\/\/cloud.weave.works\/k8s\/net?k8s-version=$kubever\"\n<\/pre>\n\n\n\n<figure class=\"wp-block-image\" id=\"attachment_35645\"><img decoding=\"async\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2020\/01\/Setup-pod-network.png\" alt=\"Setup Pod Network\" class=\"wp-image-35645\"\/><figcaption>Setup Pod Network<\/figcaption><\/figure>\n\n\n\n<p>Now if you check the status of your master-node, it should be \u2018<strong>Ready<\/strong>\u2019.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># kubectl get nodes\n<\/pre>\n\n\n\n<figure class=\"wp-block-image\" id=\"attachment_35646\"><img decoding=\"async\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2020\/01\/Check-Status-of-Master-Nodes.png\" alt=\"Check Status of Master Nodes\" class=\"wp-image-35646\"\/><figcaption>Check Status of Master Nodes<\/figcaption><\/figure>\n\n\n\n<p>Next, we add the&nbsp;<strong>worker nodes<\/strong>&nbsp;to the cluster.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Adding Worker Nodes to Kubernetes Cluster<\/h3>\n\n\n\n<p>The following instructions will be performed on each&nbsp;<strong>worker node<\/strong>&nbsp;when joining the Kubernetes cluster.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Step 1: Prepare Hostname, Firewall, and SELinux<\/h4>\n\n\n\n<p>First set the hostname on your&nbsp;<strong>worker-node-1<\/strong>&nbsp;and&nbsp;<strong>worker-node-2<\/strong>, and then add the host entries to the&nbsp;<strong>\/etc\/hosts<\/strong>&nbsp;file.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># hostnamectl set-hostname 'node-1'\n# cat &lt;&lt;EOF&gt;&gt; \/etc\/hosts\n192.168.0.47 master-node\n192.168.0.48 node-1 worker-node-1\n192.168.0.49 node-2 worker-node-2\nEOF\n<\/pre>\n\n\n\n<p>Next, ping your&nbsp;<strong>master node<\/strong>&nbsp;from your&nbsp;<strong>worker nodes<\/strong>&nbsp;to confirm that your updated host file is working fine using the&nbsp;ping command.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># 192.168.0.47\n<\/pre>\n\n\n\n<p>Next, disable&nbsp;<strong>SElinux<\/strong>&nbsp;and update your firewall rules.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># setenforce 0\n# sed -i --follow-symlinks 's\/SELINUX=enforcing\/SELINUX=disabled\/g' \/etc\/sysconfig\/selinux\n# firewall-cmd --permanent --add-port=6783\/tcp\n# firewall-cmd --permanent --add-port=10250\/tcp\n# firewall-cmd --permanent --add-port=10255\/tcp\n# firewall-cmd --permanent --add-port=30000-32767\/tcp\n# firewall-cmd --reload\n# echo '1' &gt; \/proc\/sys\/net\/bridge\/bridge-nf-call-iptables\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Step 2: Setup Docker-CE and Kubernetes Repo<\/h4>\n\n\n\n<p>Add the Docker repository first using DNF config-manager.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># dnf config-manager --add-repo=https:\/\/download.docker.com\/linux\/centos\/docker-ce.repo\n<\/pre>\n\n\n\n<p>Next, add the&nbsp;<strong>containerd.io<\/strong>&nbsp;package.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># dnf install https:\/\/download.docker.com\/linux\/centos\/7\/x86_64\/stable\/Packages\/containerd.io-1.2.6-3.3.el7.x86_64.rpm\n<\/pre>\n\n\n\n<p>With these two packages installed, install the latest version of&nbsp;<strong>docker-ce<\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># dnf install docker-ce\n<\/pre>\n\n\n\n<p>Enable and start the docker service.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># systemctl enable docker\n# systemctl start docker\n<\/pre>\n\n\n\n<p>You will need to add&nbsp;<strong>Kubernetes<\/strong>&nbsp;repositories manually as they do not come pre-installed on&nbsp;<strong>CentOS 8<\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># cat &lt;&lt;EOF &gt; \/etc\/yum.repos.d\/kubernetes.repo\n<\/pre>\n\n\n\n<p>name=Kubernetes baseurl=https:\/\/packages.cloud.google.com\/yum\/repos\/kubernetes-el7-x86_64 enabled=1 gpgcheck=1 repo_gpgcheck=1 gpgkey=https:\/\/packages.cloud.google.com\/yum\/doc\/yum-key.gpg https:\/\/packages.cloud.google.com\/yum\/doc\/rpm-package-key.gpg EOF<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Step 3: Install Kubeadm on CentOS 8<\/h4>\n\n\n\n<p>With the package repo now ready, you can go ahead and install&nbsp;<strong>kubeadm<\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># dnf install kubeadm -y \n<\/pre>\n\n\n\n<p>Start and enable the service.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># systemctl enable kubelet\n# systemctl start kubelet\n<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Step 4: Join the Worker Node to the Kubernetes Cluster<\/h4>\n\n\n\n<p>We now require the token that&nbsp;<strong>kubeadm init<\/strong>&nbsp;generated, to join the cluster. You can copy and paste it to your&nbsp;<strong>node-1<\/strong>&nbsp;and&nbsp;<strong>node-2<\/strong>&nbsp;if you had copied it somewhere.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># kubeadm join 192.168.0.47:6443 --token nu06lu.xrsux0ss0ixtnms5  --discovery-token-ca-cert-hash sha256:f996ea35r4353d342fdea2997a1cf8caeddafd6d4360d606dbc82314683478hjmf78\n<\/pre>\n\n\n\n<p>As suggested on the last line, go back to your&nbsp;<strong>master-node<\/strong>&nbsp;and verify if worker&nbsp;<strong>node-1<\/strong>&nbsp;and&nbsp;<strong>worker node-2<\/strong>&nbsp;have joined the cluster using the following command.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\"># kubectl get nodes\n<\/pre>\n\n\n\n<figure class=\"wp-block-image\" id=\"attachment_35648\"><img decoding=\"async\" src=\"https:\/\/www.tecmint.com\/wp-content\/uploads\/2020\/01\/Check-All-Nodes-Status-in-Kubernetes-Cluster.png\" alt=\"Check All Nodes Status in Kubernetes Cluster\" class=\"wp-image-35648\"\/><figcaption>Check All Nodes Status in Kubernetes Cluster<\/figcaption><\/figure>\n\n\n\n<p>If all the steps run successfully, then, you should see&nbsp;<strong>node-1<\/strong>&nbsp;and&nbsp;<strong>node-2<\/strong>&nbsp;in ready status on the&nbsp;<strong>master-node<\/strong>. At this point, you have now successfully deployed a Kubernetes cluster on&nbsp;<strong>CentOS 8<\/strong>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Logical Architecture Our installation is designed to have the&nbsp;Master-Node&nbsp;controlling the&nbsp;Worker Nodes. At the end of this installation, our logical architecture will look something like this. Master Node&nbsp;\u2013 This machine generally acts as the control plane and runs the cluster database and the API server (which the kubectl CLI communicates with). Our 3-node&nbsp;Kubernetes Cluster&nbsp;will look something [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[78,77,82,79,13],"tags":[],"class_list":["post-3131","post","type-post","status-publish","format-standard","hentry","category-containers","category-devops","category-docker","category-kubernetes","category-linux"],"_links":{"self":[{"href":"https:\/\/microsoftgeek.com\/index.php?rest_route=\/wp\/v2\/posts\/3131","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/microsoftgeek.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/microsoftgeek.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/microsoftgeek.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/microsoftgeek.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=3131"}],"version-history":[{"count":4,"href":"https:\/\/microsoftgeek.com\/index.php?rest_route=\/wp\/v2\/posts\/3131\/revisions"}],"predecessor-version":[{"id":3160,"href":"https:\/\/microsoftgeek.com\/index.php?rest_route=\/wp\/v2\/posts\/3131\/revisions\/3160"}],"wp:attachment":[{"href":"https:\/\/microsoftgeek.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3131"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/microsoftgeek.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3131"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/microsoftgeek.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3131"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}