Create Kubernetes Cluster with CRI-O on Rocky Linux 9.1
Overview
As a container orchestration, Kubernetes help anyone who needs to deploy a container service in a declarative way. Kubernetes will manage and maintain every resource to meet the state needed by the developer. Developer simply defined the desired state by JSON or YAML file and sends it to Kubernetes API. In this article, I will guide you to deploy a Kubernetes cluster with CRI-O as container runtime on RHEL-based OS, Rocky Linux 9.1.
Installation
Pre-requisites
We need 1 node for the control-plane node and at least 1 node or more nodes for the worker node with the specifications:
Control-plane node:
2 core or more processor
2 GB or more memory
Rocky Linux 9
Worker node:
4 core or more processor
8 GB or more memory
Rocky Linux 9
Steps
Master Node
Configure firewall on every node
You need to set firewall rules on the node(s) to open several inbound ports or connections between the Kubernetes cluster node based on Kubernetes Documentation.
firewall-cmd --permanent --new-zone=kubernetes-master firewall-cmd --permanent --zone=kubernetes-master --add-service=ssh firewall-cmd --permanent --zone=kubernetes-master --add-port={6443,2379,2380,10250,10259,10257}/tcp firewall-cmd --reload firewall-cmd --permanent --zone=kubernetes-master --change-interface=enp1s0 firewall-cmd --set-default-zone=kubernetes-master
Setup CRI-O
CRI-O repository will be added to YUM depending Kubernetes version want to be installed by specifying the
VERSION
environment variable.export VERSION=1.26 export OS=CentOS_8_Stream curl -L -o /etc/yum.repos.d/devel:kubic:libcontainers:stable:cri-o:$VERSION.repo https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/$VERSION/$OS/devel:kubic:libcontainers:stable:cri-o:$VERSION.repo yum install cri-o -y systemctl enable --now crio
Setup kubeadm, kubelet, and kubectl
Kubernetes’ repository will be added to YUM and install kubelet, kubectl and kubeadm following the version of Kubernetes want to installed. See Kubernetes Releases.
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-\$basearch enabled=1 gpgcheck=1 gpgkey=https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg exclude=kubelet kubeadm kubectl EOF # Set SELinux in permissive mode (effectively disabling it) sudo setenforce 0 sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config yum install kubelet-1.26.5 kubectl-1.26.5 kubeadm-1.26.5 --disableexcludes=kubernetes
Configure prerequisites
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf overlay br_netfilter EOF modprobe overlay modprobe br_netfilter # sysctl params required by setup, params persist across reboots cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.ipv4.ip_forward = 1 EOF # Apply sysctl params without reboot sysctl --system
Create kubeadm’s and InitConfiguration and ClusterConfiguration file for master node
vim kubeadm-worker-conf.yaml
apiVersion: kubeadm.k8s.io/v1beta3 kind: InitConfiguration nodeRegistration: name: "master-node0" criSocket: "/var/run/crio/crio.sock" --- apiVersion: kubeadm.k8s.io/v1beta3 kind: ClusterConfiguration networking: serviceSubnet: "10.10.0.0/16" podSubnet: "10.10.10.0/24" dnsDomain: "jesaya.lab" kubernetesVersion: "v1.26.5" controlPlaneEndpoint: "[control-plane-ip]:6443" clusterName: "[cluster-name]"
Initialize Kubeadm
systemctl enable kubelet.service kubeadm init --config kubeadm-cluster-conf.yaml
Check the Kubernetes has been initilized
mkdir -p $HOME/.kube cp -i /etc/kubernetes/admin.conf $HOME/.kube/config chown $(id -u):$(id -g) $HOME/.kube/config kubectl get node
Worker node(s)
Configure firewall on every node
You need to set firewall rules on the node(s) to open several inbound ports or connections between the Kubernetes cluster node based on Kubernetes Documentation.
firewall-cmd --permanent --new-zone=kubernetes-worker firewall-cmd --permanent --zone=kubernetes-worker --add-service=ssh firewall-cmd --permanent --zone=kubernetes-worker --add-port={10250,30000-32767}/tcp firewall-cmd --reload firewall-cmd --permanent --zone=kubernetes-worker --change-interface=enp1s0 firewall-cmd --set-default-zone=kubernetes-worker
Setup CRI-O
CRI-O repository will be added to YUM depending Kubernetes version want to be installed by specifying the
VERSION
environment variable.export VERSION=1.26 export OS=CentOS_8_Stream curl -L -o /etc/yum.repos.d/devel:kubic:libcontainers:stable:cri-o:$VERSION.repo https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable:/cri-o:/$VERSION/$OS/devel:kubic:libcontainers:stable:cri-o:$VERSION.repo yum install cri-o -y systemctl enable --now crio
Setup kubeadm, kubelet, and kubectl
Kubernetes’ repository will be added to YUM and install kubelet, kubectl and kubeadm following the version of Kubernetes want to installed. See Kubernetes Releases.
cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo [kubernetes] name=Kubernetes baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-\$basearch enabled=1 gpgcheck=1 gpgkey=https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg exclude=kubelet kubeadm kubectl EOF # Set SELinux in permissive mode (effectively disabling it) sudo setenforce 0 sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config yum install kubelet-1.26.5 kubeadm-1.26.5 --disableexcludes=kubernetes
Configure prerequisites needed on node
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf overlay br_netfilter EOF modprobe overlay modprobe br_netfilter # sysctl params required by setup, params persist across reboots cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.ipv4.ip_forward = 1 EOF # Apply sysctl params without reboot sysctl --system
Create kubeadm’s JoinConfiguration file for worker node
vim kubeadm-worker-conf.yaml
apiVersion: kubeadm.k8s.io/v1beta3 kind: JoinConfiguration nodeRegistration: name: "worker-node0" criSocket: "/var/run/crio/crio.sock" discovery: bootstrapToken: token: "[bootstrap-token]" apiServerEndpoint: "[control-plane-ip]:6443" caCertHashes: - "[CA-cert-Hash]"
Joining worker node
systemctl enable kubelet.service kubeadm join --config kubeadm-worker-conf.yaml