{"id":2176,"date":"2020-04-14T20:08:59","date_gmt":"2020-04-14T17:08:59","guid":{"rendered":"https:\/\/upcloud.com\/global\/us\/resources\/tutorials\/install-kubernetes-cluster-centos-8\/"},"modified":"2020-04-14T20:08:59","modified_gmt":"2020-04-14T17:08:59","slug":"install-kubernetes-cluster-centos-8","status":"publish","type":"tutorial","link":"https:\/\/upcloud.com\/global\/resources\/tutorials\/install-kubernetes-cluster-centos-8\/","title":{"rendered":"How to install Kubernetes cluster on CentOS 8"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">There are many guides out there describing how to install Kubernetes on CentOS 8. Nevertheless, some steps might be unnecessary, and some might be missing. This guide is based on our notes from real-world deployments and has worked great.<\/p>\n\n\n\n\n\n<h2 class=\"wp-block-heading\">Prerequisites for both Master and Worker nodes<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In this guide, we will be using minimal resources with just two cloud servers for simplicity. After the initial setup, you can add more workers when necessary.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let\u2019s get started!<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">1. <a href=\"https:\/\/hub.upcloud.com\/deploy\" target=\"_blank\" rel=\"noopener\">Deploy two CentOS 8 cloud servers<\/a>. One for the master and the other for the worker node. Check this tutorial to learn more about <a href=\"https:\/\/upcloud.com\/global\/docs\/guides\/deploy-server\/\" target=\"_blank\" rel=\"noreferrer noopener\">deploying cloud servers<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/kubernetes.io\/docs\/setup\/production-environment\/tools\/kubeadm\/install-kubeadm\/#before-you-begin\" target=\"_blank\" rel=\"noopener\">Kubernetes has minimum requirements<\/a> for the server and both master and worker nodes need to have at least 2 GB RAM and 2 CPUs, the $20\/mo plan covers these requirements and with double the memory. Note that the minimum requirements are not just guidelines as Kubernetes will refuse to install on a server with less than the minimum resources.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">2. Log into both Master and Worker nodes over SSH using the root account and password you received by email after deployment.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Make note of the public IP and private IP addresses of your servers at the UpCloud control panel.&nbsp;You can also use the <tt>ip addr<\/tt> command to find these out later.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">3. Make sure the servers are up to date before installing anything new.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">dnf -y upgrade<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">4. Disable SELinux enforcement.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">setenforce 0\nsed -i --follow-symlinks 's\/SELINUX=enforcing\/SELINUX=disabled\/g' \/etc\/sysconfig\/selinux<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">5. Enable transparent masquerading and facilitate Virtual Extensible LAN (VxLAN) traffic for communication between Kubernetes pods across the cluster.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">modprobe br_netfilter<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You will also need to enable IP masquerade at the firewall.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">firewall-cmd --add-masquerade --permanent\nfirewall-cmd --reload<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">6. Set bridged packets to traverse iptables rules.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">cat &lt; \/etc\/sysctl.d\/k8s.conf\nnet.bridge.bridge-nf-call-ip6tables = 1\nnet.bridge.bridge-nf-call-iptables = 1\nEOF<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Then load the new rules.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">sysctl --system<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">7. Disable all memory swaps to increase performance.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">swapoff -a<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">With these steps done on both Master and worker nodes, you can proceed to install Docker.<\/p>\n\n\n\n<div class=\"wp-block-buttons is-layout-flex wp-block-buttons-is-layout-flex\">\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link wp-element-button\" href=\"https:\/\/signup.upcloud.com\/\">Try UpCloud for free!<\/a><\/div>\n<\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Installing Docker on Master and Worker nodes<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Next, we\u2019ll need to install Docker.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">1. Add the repository for the docker installation package.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">dnf config-manager --add-repo=https:\/\/download.docker.com\/linux\/centos\/docker-ce.repo<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">2. Install container.io which is not yet provided by the package manager before installing docker.<\/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<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">3. Then install Docker from the repositories.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">dnf install docker-ce --nobest -y<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">4. Start the docker service.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">systemctl start docker<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">5. Make it also start automatically on server restart.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">systemctl enable docker<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">6. Change docker to use systemd cgroup driver.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">echo '{\n  \"exec-opts\": [\"native.cgroupdriver=systemd\"]\n}' &gt; \/etc\/docker\/daemon.json<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">And restart docker to apply the change.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">systemctl restart docker<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Once installed, you should check that everything is working correctly.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">7. See the docker version.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">docker version<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">8. List what is inside the docker images. Likely still empty for now.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">docker images<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">REPOSITORY   TAG   IMAGE ID   CREATED   SIZE<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Now that Docker is ready to go, continue below to install Kubernetes itself.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Installing Kubernetes on Master and Worker nodes<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">With all the necessary parts installed, we can get Kubernetes installed as well.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">1. Add the Kubernetes repository to your package manager by creating the following file.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">cat &lt; \/etc\/yum.repos.d\/kubernetes.repo\n<\/pre>\n\n\n<p>[kubernetes]<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\nname=Kubernetes\nbaseurl=https:\/\/packages.cloud.google.com\/yum\/repos\/kubernetes-el7-$basearch\nenabled=1\ngpgcheck=1\nrepo_gpgcheck=1\ngpgkey=https:\/\/packages.cloud.google.com\/yum\/doc\/yum-key.gpg https:\/\/packages.cloud.google.com\/yum\/doc\/rpm-package-key.gpg\nexclude=kubelet kubeadm kubectl\nEOF\n<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">2. Then update the repo info.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">dnf upgrade -y<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">3. Install all the necessary components for Kubernetes.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">dnf install -y kubelet kubeadm kubectl --disableexcludes=kubernetes<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Start the Kubernetes services and enable them to run at startup.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">systemctl enable kubelet\nsystemctl start kubelet<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Once running on both nodes, begin configuring Kubernetes on the Master by following the instructions in the next section.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Configuring Kubernetes on the Master node only<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Once Kubernetes has been installed, it needs to be configured to form a cluster.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">1. Configure kubeadm.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">kubeadm config images pull<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">2. Open the necessary <a href=\"https:\/\/kubernetes.io\/docs\/setup\/production-environment\/tools\/kubeadm\/install-kubeadm\/#check-required-ports\" target=\"_blank\" rel=\"noopener\">ports used by Kubernetes.<\/a><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">firewall-cmd --zone=public --permanent --add-port={6443,2379,2380,10250,10251,10252}\/tcp<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">3. Allow docker access from another node, replace the <span style=\"color: #ff0000;\">worker-IP-address<\/span> with yours.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">firewall-cmd --zone=public --permanent --add-rich-rule 'rule family=ipv4 source address=<span style=\"color: #ff0000;\">worker-IP-address<\/span>\/32 accept'<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">4. Allow access to the host\u2019s localhost from the docker container.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">firewall-cmd --zone=public --permanent --add-rich-rule 'rule family=ipv4 source address=172.17.0.0\/16 accept'<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">5. Make the changes permanent.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">firewall-cmd --reload<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">6. Install CNI (container network interface) plugin for Kubernetes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For this setup, we\u2019ll be using Calico: <a href=\"https:\/\/docs.projectcalico.org\/getting-started\/kubernetes\/quickstart#overview\" target=\"_blank\" rel=\"noopener\">https:\/\/docs.projectcalico.org\/getting-started\/kubernetes\/quickstart#overview<\/a><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Issue the following command:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">kubeadm init --pod-network-cidr 192.168.0.0\/16<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">You should see something like the example below. Make note of the discovery token, it\u2019s needed to join worker nodes to the cluster.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Note that the join token below is just an example.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">kubeadm join 94.237.41.193:6443 --token 4xrp9o.v345aic7zc1bj8ba \n--discovery-token-ca-cert-hash sha256:b2e459930f030787654489ba7ccbc701c29b3b60e0aa4998706fe0052de8794c<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Make the following directory and configuration files.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">mkdir -p $HOME\/.kube\ncp -i \/etc\/kubernetes\/admin.conf $HOME\/.kube\/config\nchown $(id -u):$(id -g) $HOME\/.kube\/config\nkubectl apply -f https:\/\/docs.projectcalico.org\/manifests\/calico.yaml<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">7. Enable pod to run on Master. This is only for demonstration purposes and is not recommended for production use.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">kubectl taint nodes --all node-role.kubernetes.io\/master-<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">8. Check that Master node has been enabled and is running.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">kubectl get nodes<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">NAME&nbsp; STATUS&nbsp; &nbsp; &nbsp;ROLES&nbsp; AGE&nbsp; VERSION\nmaster&nbsp; NotReady&nbsp; master&nbsp; &nbsp;91s&nbsp; &nbsp; &nbsp;v1.18.0<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">On successful execution, you should see a node with ready status. If not, wait a moment and repeat the command.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">When the Master node is up and running, continue with the next section to join the Worker node to the cluster.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Configuring Kubernetes on the Worker node only<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Each Kubernetes installation needs to have one or more worker nodes that run the containerized applications. We\u2019ll only configure one worker in this example but repeat these steps to join more nodes to your cluster.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">1. Open ports used by Kubernetes.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">firewall-cmd --zone=public --permanent --add-port={10250,30000-32767}\/tcp<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">2. Make the changes permanent.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">firewall-cmd --reload<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">3. Join the cluster with the previously noted token.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Note that the join token below is just an example.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">kubeadm join 94.237.41.193:6443 --token 4xrp9o.v345aic7zc1bj8ba \n--discovery-token-ca-cert-hash sha256:b2e459930f030787654489ba7ccbc701c29b3b60e0aa4998706fe0052de8794c<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">4. See if the Worker node successfully joined.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Go back to the Master node and issue the following command.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">kubectl get nodes<\/pre>\n\n\n\n<pre class=\"wp-block-preformatted\">NAME&nbsp;   STATUS&nbsp;  ROLES&nbsp; &nbsp; AGE&nbsp;  VERSION\nmaster&nbsp; Ready&nbsp; &nbsp; master&nbsp; &nbsp;10m&nbsp;  v1.18.0\nworker&nbsp; Ready&nbsp; &nbsp; &nbsp;  28s&nbsp; &nbsp;v1.18.0<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">On success, you should see two nodes with ready status. If not, wait a moment and repeat the command.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Finished!<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Congratulations, you should now have a working Kubernetes installation running on two nodes.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In case anything goes wrong, you can always repeat the process.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Run this on Master and Workers: <tt>kubeadm reset &amp;&amp; rm -rf \/etc\/cni\/net.d<\/tt><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Have fun clustering.<\/p>\n\n\n","protected":false},"author":34,"featured_media":14247,"comment_status":"open","ping_status":"closed","template":"","community-category":[223,229],"class_list":["post-2176","tutorial","type-tutorial","status-publish","has-post-thumbnail","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/tutorial\/2176","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/tutorial"}],"about":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/types\/tutorial"}],"author":[{"embeddable":true,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/users\/34"}],"replies":[{"embeddable":true,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/comments?post=2176"}],"version-history":[{"count":0,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/tutorial\/2176\/revisions"}],"wp:attachment":[{"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/media?parent=2176"}],"wp:term":[{"taxonomy":"community-category","embeddable":true,"href":"https:\/\/upcloud.com\/global\/wp-json\/wp\/v2\/community-category?post=2176"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}