I have another post regarding Docker and Kubernetes, but it’s related to CentOS 7. In this post, I’ll explain how to install Docker and Kubernetes on CentOS 8. There is not that much difference in the installation process, but some things changed so it’s easier to write a new post than modify the original one.
I’ll explain how to install Docker and Kubernetes on one master and one node. You can have as many nodes you want. All commands will be executed as root but we’ll create a user called devops that will ultimately manage both Docker and Kubernetes.
Table of Contents
Docker
Log as root and execute this command on both master and the node server. The highlighted line is what you type. The rest is the output.
dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo Adding repo from: https://download.docker.com/linux/centos/docker-ce.repo
Then install docker. This will also install Docker CLI and containerd.io. Do this on both servers too.
dnf -y install docker-ce
Let’s make sure that it starts now and on boot.
systemctl enable --now docker
If you check the status, you’ll see that Docker is running.
systemctl status docker | grep active Active: active (running) since Sat 2020-09-26 09:28:50 EDT; 50s ago
Let’s make sure it’s running and it’s functioning. Do this on one server.
docker run hello-world
You’ll see a bunch of output, some greetings and Hello from Docker! message. You don’t need this container and image so you can delete it.
docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES bb436fac0476 hello-world "/hello" About a minute ago Exited (0) About a minute ago quirky_chatelet
Look at the end. In my case, the container name is quirky_chatelet. In your case it’s something different. Remove the container.
docker rm quirky_chatelet quirky_chatelet
Remove the image.
docker rmi hello-world Untagged: hello-world:latest Untagged: hello-world@sha256:4cf9c47f86df71d48364001ede3a4fcd85ae80ce02ebad74156906caff5378bc Deleted: sha256:bf756fb1ae65adf866bd8c456593cd24beb6a0a061dedf42b26a993176745f6b Deleted: sha256:9c27e219663c25e0f28493790cc0b88bc973ba3b1686355f221c38a36978ac63
We also have to make some changes how Docker uses the storage and cgroups. By default, it’s not using systemd.
docker info | grep Storage Storage Driver: overlay2 docker info | grep Cgroup Cgroup Driver: cgroupfs
Overlay2 is fine but cgroupfs is not. Make these changes on both servers. Just copy and paste the whole snippet and it will create a file for you.
cat <<EOF > /etc/docker/daemon.json { "exec-opts": ["native.cgroupdriver=systemd"], "log-driver": "json-file", "log-opts": { "max-size": "100m" }, "storage-driver": "overlay2", "storage-opts": [ "overlay2.override_kernel_check=true" ] } EOF
Restart Docker daemon on both servers and check the changes.
systemctl restart docker docker info | grep -i cgroup Cgroup Driver: systemd
Finally, we need a user that will manage Docker. We don’t want to use root for that. If you don’t have a user created, do it with adduser command. In addition, we need to add this user to be a member of the group docker that was created when we installed docker. In my case the user is devops. Do this on both servers.
usermod -aG docker devops
If you log as the devops user and execute docker ps -a, you’ll see that Docker accepted your command. Otherwise, you’ll see some access denied error.
Kubernetes
In order to run Kubernetes (k8s) we need to make some changes to the OS. There are several prerequisites.
First, we’ll have to enable bridge networking. Do this on both servers and make sure you are logged as root.
modprobe br_netfilter echo '1' > /proc/sys/net/bridge/bridge-nf-call-iptables echo '1' > /proc/sys/net/bridge/bridge-nf-call-ip6tables
Then we have to disable SELinux security.
setenforce 0 sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
We also need to disable swap disk.
swapoff -a sed -i '/ swap / s/^\(.*\)$/#/g' /etc/fstab
Now it’s time to install Kubernetes. Copy & paste this snippet that will add the Kubernetes repo to CentOS. Do this on both servers logged as root.
cat <<EOF > /etc/yum.repos.d/kubernetes.repo [kubernetes] 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
Install Kubernetes on both.
dnf install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
(Optional) Install this handy tool that can help with Kubernetes commands auto-complete. For example, you type kubectl then g hit tab and it will give you a choice of commands that start with g.
dnf install -y bash-completion
Before we finish the installation, we’ll have to make some changes to the firewall. If you don’t have the firewall enabled, you can skip this section.
Firewall
On the master node only, open these ports.
firewall-cmd --add-port=6443/tcp --permanent firewall-cmd --add-port=2379-2380/tcp --permanent firewall-cmd --add-port=10250-10252/tcp --permanent firewall-cmd --reload
On the worker nodes only, open these ports.
firewall-cmd --add-port=10250/tcp --permanent firewall-cmd --add-port=30000-32767/tcp --permanent firewall-cmd --reload
Network
Now, it’s time to install the networking component. Kubernetes has several of them, such as flannel, callico, WeaveNet etc… We’ll go with flannel.
Do this on the master node only. There is no need to install the network component on the worker nodes. Kubernetes will take care of that.
Initialize flannel with this subnet on the master node only. This subnet will be where pods will be running. It takes a couple of minutes.
kubeadm init --pod-network-cidr=10.244.0.0/16
At the end you’ll see an output that tells how to join the worker nodes to the master node. In my case it was something like this. Copy this code and the token somewhere safe. You’ll need it anytime you need to join a worker node. Don’t execute this yet.
kubeadm join 192.168.1.115:6443 --token dgwe20.8pw4vd8ks2savzbf \ --discovery-token-ca-cert-hash sha256:6948547d7ff058a56aba374f44a583459f87e63aacaa53179e7adfeb5cf935a6
Let’s start Kubernetes and make sure it starts on boot. Do this on the master and the worker node logged as root.
systemctl enable --now kubelet
On the master node, log as your standard user that you made to run Docker, in my case it was devops.
Run these commands, one by one.
mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config echo 'source <(kubectl completion bash)' >>~/.bashrc
Now, we have to install flannel. Do this on the master node only logged as the regular user.
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
Check the nodes.
kubectl get nodes NAME STATUS ROLES AGE VERSION jupiter.andreev.local Ready master 12m v1.19.2
As you can see, we have only the master node. Go to the worker node and as root run this command. The command that you saved somewhere.
kubeadm join 192.168.1.115:6443 --token dgwe20.8pw4vd8ks2savzbf \ --discovery-token-ca-cert-hash sha256:6948547d7ff058a56aba374f44a583459f87e63aacaa53179e7adfeb5cf935a6
After a minute or two, if you run the same command (get nodes) again, you’ll see the worker node too.
kubectl get nodes NAME STATUS ROLES AGE VERSION ganymede.andreev.local Ready <none> 47s v1.19.2 jupiter.andreev.local Ready master 3m47s v1.19.2