Home Docker CentOS: Install Docker and Kubernetes

CentOS: Install Docker and Kubernetes

by Kliment Andreev

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


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

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": [

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.


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
gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg

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.


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


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=

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 --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 --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

Related Articles

Leave a Comment

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More