Rocky Linuxにシングルマスタークラスターの構築をしてみた

2022年7月2日

概要

こんにちは。

Rocky Linux release 8.5 (Green Obsidian) に対してkubernetesをインストールします。

x86_64環境となります。

シングルマスタークラスターの作成となり、ワーカーノードの追加等は実施しないので注意してください。

すべてのコマンドは管理者権限で操作しております。

Dockerインストール

リポジトリ追加

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

docker-ce-stableが追加されたことが確認出来ます。

dnf repolist

repo id                                                                 repo name
appstream                                                               Rocky Linux 8 - AppStream
baseos                                                                  Rocky Linux 8 - BaseOS
docker-ce-stable                                                        Docker CE Stable - x86_64
extras                                                                  Rocky Linux 8 - Extras

インストール

dnf -y install docker-ce

Docker CE Stable - x86_64                                                                                                 85 kB/s |  19 kB     00:00
Dependencies resolved.
・
・[中略]
・
Installed:
  container-selinux-2:2.167.0-1.module+el8.5.0+710+4c471e88.noarch               containerd.io-1.4.12-3.1.el8.x86_64
  docker-ce-3:20.10.12-3.el8.x86_64                                              docker-ce-cli-1:20.10.12-3.el8.x86_64
  docker-ce-rootless-extras-20.10.12-3.el8.x86_64                                docker-scan-plugin-0.12.0-3.el8.x86_64
  fuse-common-3.2.1-12.el8.x86_64                                                fuse-overlayfs-1.7.1-1.module+el8.5.0+710+4c471e88.x86_64
  fuse3-3.2.1-12.el8.x86_64                                                      fuse3-libs-3.2.1-12.el8.x86_64
  iptables-1.8.4-20.el8.x86_64                                                   libcgroup-0.41-19.el8.x86_64
  libnetfilter_conntrack-1.0.6-5.el8.x86_64                                      libnfnetlink-1.0.1-13.el8.x86_64
  libnftnl-1.1.5-4.el8.x86_64                                                    libslirp-4.4.0-1.module+el8.5.0+710+4c471e88.x86_64
  slirp4netns-1.1.8-1.module+el8.5.0+710+4c471e88.x86_64

Complete!

containerdはDocker社が開発している、コンテナーランタイムになりDockerのコンポーネントの一部として動作します。

それぞれ、インストールされたことを確認します。

rpm -qa | grep -E "docker-ce|docker-ce-cli|containerd.io"

docker-ce-cli-20.10.12-3.el8.x86_64
docker-ce-rootless-extras-20.10.12-3.el8.x86_64
containerd.io-1.4.12-3.1.el8.x86_64
docker-ce-20.10.12-3.el8.x86_64

一般ユーザでもdockerを使えるようにする

gpasswd -a dev_user docker

Adding user dev_user to group docker

→※dev_userは事前に追加したユーザになります。(読者環境で適宜置き換えてください。)

追加されたことが分かりますね。

grep docker /etc/group

docker:x:987:dev_user

自動起動有効化および起動

dockerサービスが起動状態でないかつ自動起動が無効になっているので起動および有効にします。

systemctl --now enable docker.service

Created symlink /etc/systemd/system/multi-user.target.wants/docker.service → /usr/lib/systemd/system/docker.service.

systemctl is-active docker.service

active

systemctl is-enabled docker.service

enabled

Kubernetes構築事前準備

SWAP無効化

KubernetesではSWAP領域を無効化することが条件になっていますので確認します。

以下コマンドでSWAPが有効になっているか確認できます、筆者環境では元々、SWAP領域がなかったようです。

この場合、なんの問題もないのでスルーしましょう。

/sbin/swapon -s

cat /proc/swaps

Filename                                Type            Size    Used    Priority

ファイアウォールの確認

Kubernetesはnftables等に互換性がないので、nftablesやiptablesがインストールされており有効になっている場合には無効化します。

筆者、環境ではiptablesのみなのでこの場合、対応不要です。

rpm -qa | grep -E "firewalld|iptables|nftables"

iptables-1.8.4-20.el8.x86_64
iptables-libs-1.8.4-20.el8.x86_64

Selinux無効化

getenforce コマンドで Disabled になっていない場合、Selinuを無効化します。

無効化後、サーバ再起動を実施し、再度、 getenforce コマンドで確認し、 Disabled になっていることを確認します。

sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/sysconfig/selinux
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config

reboot

→サーバ再起動

getenforce

Disabled

iptablesがブリッジを通過するトラフィックを処理できるようにする

cat << EOF | tee /etc/modules-load.d/containerd.conf
overlay
br_netfilter
EOF
cat << EOF | tee /etc/sysctl.d/99-kubernetes-cri.conf
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF

カーネルモジュールの読み込み

modprobe overlay
modprobe br_netfilter

設定を適用します。

sysctl --system

・
・[中略]
・
* Applying /etc/sysctl.d/99-kubernetes-cri.conf ..
・
・[中略]
・

必要なパッケージのインストール

dnf install iproute-tc chrony -y

・
・[中略]
・
Running transaction
  Preparing        :                                                                                                                                                    1/1
  Installing       : iproute-tc-5.12.0-4.el8.x86_64                                                                                                                     1/1
  Running scriptlet: iproute-tc-5.12.0-4.el8.x86_64                                                                                                                     1/1
  Verifying        : iproute-tc-5.12.0-4.el8.x86_64                                                                                                                     1/1

Installed:
  iproute-tc-5.12.0-4.el8.x86_64

Complete!

コンテナーランタイム設定書き換え

Dockerとcontainerdの両方が同時に検出された場合、Dockerが優先されます。

cp -p /etc/containerd/config.toml /etc/containerd/config.toml_$(date +%Y%m%d)

containerd config default | tee /etc/containerd/config.toml

[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] 箇所に SystemdCgroup = true を追加します。

vi /etc/containerd/config.toml

[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
  SystemdCgroup = true

systemctl restart containerd.service

systemctl restart docker.service

Kubernetessリポジトリ追加

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

Kubernetesレポジトリが追加されたことが確認出来ます。

dnf repolist

repo id                                                                           repo name
appstream                                                                         Rocky Linux 8 - AppStream
baseos                                                                            Rocky Linux 8 - BaseOS
docker-ce-stable                                                                  Docker CE Stable - x86_64
extras                                                                            Rocky Linux 8 - Extras
kubernetes                                                                        Kubernetes

Kubernetessインストール

以下、ツールのインストールをおこないます。

kubeadm :クラスターを起動するコマンドです。
kubelet :クラスターの各ノードでPodを管理するコンポーネントです。
kubectl :クラスターにアクセスするためのコマンドラインツールです。

dnf -y install kubelet kubeadm kubectl

・
・[中略]
・
Installed:
  conntrack-tools-1.4.4-10.el8.x86_64          cri-tools-1.19.0-0.x86_64               iptables-ebtables-1.8.4-20.el8.x86_64   kubeadm-1.23.1-0.x86_64
  kubectl-1.23.1-0.x86_64                      kubelet-1.23.1-0.x86_64                 kubernetes-cni-0.8.7-0.x86_64           libnetfilter_cthelper-1.0.0-15.el8.x86_64
  libnetfilter_cttimeout-1.0.0-11.el8.x86_64   libnetfilter_queue-1.0.4-3.el8.x86_64   socat-1.7.4.1-1.el8.x86_64

Complete!

起動前準備

kubeadm config print init-defaults | tee ClusterConfiguration.yaml

sed -i '/name/d' ClusterConfiguration.yaml

advertiseAddress: 192.168.254.20 箇所のIPは、ネットワークインターフェースのIPを指定します。

sed -i 's/ advertiseAddress: 1.2.3.4/ advertiseAddress: 192.168.254.20/' ClusterConfiguration.yaml

sed -i 's/ criSocket: \/var\/run\/dockershim\.sock/ criSocket: \/run\/containerd\/containerd\.sock/' ClusterConfiguration.yaml

cat << EOF | cat >> ClusterConfiguration.yaml
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: systemd
EOF

起動

初期化をおこないます。

kubeadm join が初期化後に出てくるのでメモをしておいてください。

ワーカーノードを追加する際に必要となってくる情報です。

今回は、ワーカーノードの追加はおこないません。

kubeadm init --config=ClusterConfiguration.yaml

[init] Using Kubernetes version: v1.23.0
・
・[中略]
・
Your Kubernetes control-plane has initialized successfully!
・
・[中略]
・

systemctl enable kubelet.service

→自動起動の有効化。

kubeletサービスが起動していることを確認します。

systemctl status kubelet.service

● kubelet.service - kubelet: The Kubernetes Node Agent
   Loaded: loaded (/usr/lib/systemd/system/kubelet.service; enabled; vendor preset: disabled)
  Drop-In: /usr/lib/systemd/system/kubelet.service.d
           mq10-kubeadm.conf
   Active: active (running) since Wed 2022-01-12 09:44:27 UTC; 13s ago
     Docs: https://kubernetes.io/docs/
 Main PID: 5306 (kubelet)
    Tasks: 15 (limit: 23463)
   Memory: 34.1M
   CGroup: /system.slice/kubelet.service

configファイルのコピー

kubectl get nodes を実行するため、configファイルをコピーします。

mkdir -p $HOME/.kube

cp -i /etc/kubernetes/admin.conf $HOME/.kube/config

chown $(id -u):$(id -g) $HOME/.kube/config

NotReady状態になっていることを確認します。

kubectl get nodes

NAME               STATUS     ROLES                  AGE   VERSION
**********   NotReady   control-plane,master   23m   v1.23.1

CNI(Container Network Interface)インストール

CNIは複数存在しますが、今回は、calicoを使用します。

kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml

configmap/calico-config created
customresourcedefinition.apiextensions.k8s.io/bgpconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/bgppeers.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/blockaffinities.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/caliconodestatuses.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/clusterinformations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/felixconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/globalnetworkpolicies.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/globalnetworksets.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/hostendpoints.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamblocks.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamconfigs.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipamhandles.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ippools.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/ipreservations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/kubecontrollersconfigurations.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/networkpolicies.crd.projectcalico.org created
customresourcedefinition.apiextensions.k8s.io/networksets.crd.projectcalico.org created
clusterrole.rbac.authorization.k8s.io/calico-kube-controllers created
clusterrolebinding.rbac.authorization.k8s.io/calico-kube-controllers created
clusterrole.rbac.authorization.k8s.io/calico-node created
clusterrolebinding.rbac.authorization.k8s.io/calico-node created
daemonset.apps/calico-node created
serviceaccount/calico-node created
deployment.apps/calico-kube-controllers created
serviceaccount/calico-kube-controllers created
Warning: policy/v1beta1 PodDisruptionBudget is deprecated in v1.21+, unavailable in v1.25+; use policy/v1 PodDisruptionBudget
poddisruptionbudget.policy/calico-kube-controllers created

POD状態の確認

下記のようにすべてRunning状態になっていれば問題ありません。

kubectl get pods --all-namespaces

NAMESPACE     NAME                                       READY   STATUS    RESTARTS   AGE
kube-system   calico-kube-controllers-647d84984b-44wx7   1/1     Running   0          20m
kube-system   calico-node-6q4j2                          1/1     Running   0          20m
kube-system   coredns-64897985d-4xfh6                    1/1     Running   0          46m
kube-system   coredns-64897985d-ljrpn                    1/1     Running   0          46m
kube-system   etcd-i-15100000247731                      1/1     Running   0          46m
kube-system   kube-apiserver-i-15100000247731            1/1     Running   0          46m
kube-system   kube-controller-manager-i-15100000247731   1/1     Running   0          46m
kube-system   kube-proxy-nsh9g                           1/1     Running   0          46m
kube-system   kube-scheduler-i-15100000247731            1/1     Running   0          46m

docker停止

containerdを使用するようにしているので、dockerは停止します。

systemctl stop docker.socket

systemctl disable docker.service

Removed /etc/systemd/system/multi-user.target.wants/docker.service.

systemctl enable containerd.service

Created symlink /etc/systemd/system/multi-user.target.wants/containerd.service → /usr/lib/systemd/system/containerd.service.

起動状態の確認、containerd.serviceのみ起動状態であることを確認します。

systemctl is-active docker.socket docker.service containerd.service

inactive
inactive
active

containerd.serviceのみ自動起動が有効状態であることを確認します。

systemctl is-enabled docker.socket docker.service containerd.service

disabled
disabled
enabled

バージョン固定化

バージョンを固定するパッケージのインストールをおこないます。

dnf install yum-plugin-versionlock -y

・
・[中略]
・
Running transaction
  Preparing        :                                                                                                                                                    1/1
  Installing       : python3-dnf-plugin-versionlock-4.0.21-3.el8.noarch                                                                                                 1/1
  Running scriptlet: python3-dnf-plugin-versionlock-4.0.21-3.el8.noarch                                                                                                 1/1
  Verifying        : python3-dnf-plugin-versionlock-4.0.21-3.el8.noarch                                                                                                 1/1

Installed:
  python3-dnf-plugin-versionlock-4.0.21-3.el8.noarch

Complete!

バージョンが固定がされたことが確認出来ます。

dnf versionlock kubelet kubeadm kubectl

Last metadata expiration check: 0:08:41 ago on Wed 12 Jan 2022 10:44:06 AM UTC.
Adding versionlock on: kubelet-0:1.23.1-0.*
Adding versionlock on: kubectl-0:1.23.1-0.*
Adding versionlock on: kubeadm-0:1.23.1-0.*

おまけ

CRI(コンテナランタイム)変更

コンテナランタイムでDockerを使用したい場合の変更方法を記載します。

dockerのcgroupドライバーがcgroupfsになっていますので、systemdに変更します。

docker info | grep -i cgroup

 Cgroup Driver: cgroupfs
 Cgroup Version: 1

dockerデーモン設定にsystemdを使用するように設定します。

cat <<EOF > /etc/docker/daemon.json
{
  "exec-opts": ["native.cgroupdriver=systemd"]
}
EOF

systemctl daemon-reload && systemctl restart docker

→設定を適用します。

適用後、systemdに変更されました。

docker info | grep -i cgroup

 Cgroup Driver: systemd
 Cgroup Version: 1

kubeadm reset

→kubernetes設定をリセットします。

kubeadm init --config=ClusterConfiguration.yaml

Your Kubernetes control-plane has initialized successfully! となることを確認します。

configをコピーしなおします。

cp -i /etc/kubernetes/admin.conf $HOME/.kube/config

chown $(id -u):$(id -g) $HOME/.kube/config

kubectl get nodes

→masterが見えることを確認します。

kubectl get pods --all-namespaces

→すべてRunning状態であることを確認します。

docker imagesdocker ps で動作していることが確認出来れば、切り替え完了です。

まとめ

うまく、kubernetesをインストールできるか不安でしたが無事にインストールできて良かったです。

参考文献

Create a CentOS 8 or Rocky Linux 8 kubernetes cluster with kubeadm

containerd のイメージ取得はどのように動作するか? – SIerだけど技術やりたいブログ

kubelet is not properly working on 1.22 version – k8s