はじめに
Minikubeだと物足りない感じがあったので、ESXiで立てたVMでkubernetesの環境を作ります。
ラズパイクラスタ作るとかも考えてたのですが、半導体価格高騰の影響でラズパイが高いので、それは諦めてVM立てて作ることにしました。
準備
AlmaLinuxのノードを構築します。
メモリは2GだとMAXまで使ってしまってそうだったので4Gで設定。
VM | CPU(Core) | MEM(GB) | DISK(GB) | 0S | IP Address | comment |
---|---|---|---|---|---|---|
k8s-master | 2 | 4 | 100 | AlmaLinux8.7 | 192.168.0.111 | コントローププレーン(マスターノード) |
k8s-worker01 | 2 | 4 | 100 | AlmaLinux8.7 | 192.168.0.112 | ワーカーノード1台目 |
k8s-worker02 | 2 | 4 | 100 | AlmaLinux8.7 | 192.168.0.113 | ワーカーノード2台目 |
CRI:containerd
CNI:Calico
上記設定で構築していく
共通設定
コントロールプレーンもワーカーノードも共通の設定をします。
root権限で実行していきます。
パッケージアップデート
# dnf -y update
swap領域の無効化
swap領域とは、ストレージ上の領域をメモリの延長領域として使う技術をいう。
swap領域が設定されていると、kubeletが起動しません。なので無効化させる。
# swapon --show
NAME TYPE SIZE USED PRIO
/dev/dm-1 partition 4G 0B -2
一時的にswapを無効化
# swapoff -a
# swapon --show
(何も表示されない)
これだとまだ不完全で、再起動するとswapが復活してしまうので、
永続的にswapを無効化する必要がある。
以下のとおり、swapの記載がある行をコメントアウトすることで永続無効化させることができる。
# cp -p /etc/fstab /etc/fstab.org
# vi /etc/fstab
コメントアウトさせる
- /dev/mapper/almalinux_k8s--master-swap none swap defaults 0 0
+ # /dev/mapper/almalinux_k8s--master-swap none swap defaults 0 0
SELinux無効化
# cp -p /etc/selinux/config /etc/selinux/config.org
# vi /etc/selinux/config
- SELINUX=enforcing
+ SELINUX=permissive
以下SELinuxの設定の参考
- enforcing: SELinux有効(アクセス制御有効、ログ出力あり)
- permissive: SELinux有効(アクセス制御無効、ログ出力あり)
- disabled: SELinux無効(アクセス制御無効、ログ出力なし)
名前解決の設定
各ノードで名前解決できるようにしておく。
DNSサーバーが立っていて設定済みであれば不要。
# vi /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.0.111 k8s-master
192.168.0.112 k8s-worker01
192.168.0.113 k8s-worker02
必要ポートの空き確認
ss -atn
コマンドを使ってポート空き状態を確認します。
必要なポートは以下のリンクで確認できます。
MACアドレスとproduct_uuidが一意であることを確認
他のノードとMACアドレス、プロダクトUUIDが重複していないことを確認します。
特にVMの場合は重複する可能性があるので。
# ip link
# cat /sys/class/dmi/id/product_uuid
Firewalld無効化
自動起動設定の無効化。再起動したときに自動起動しない(=停止する)。
# systemctl disable firewalld
IPv6無効化
# echo "net.ipv6.conf.all.disable_ipv6 = 1" >> /etc/sysctl.conf
# echo "net.ipv6.conf.default.disable_ipv6 = 1" >> /etc/sysctl.conf
設定反映
設定反映のために再起動させておく。
# shutdown -r now
コンテナランタイムをインストール
コンテナランタイムには、各ノードがPodを生成処理を出す高レベルランタイム。
高レベルランタイムから指示を受けて、コンテナを生成する低レベルランタイムの2種類がある。
コンテナランタイムの選択肢はいくつかあります。
今回はcontainerd
をインストールしてみる。
以下のページを参考にインストールすればいいのだが・・・。
https://kubernetes.io/ja/docs/setup/production-environment/container-runtimes/#containerd
上記ページでは、こちらのGitHubのドキュメントを参考にするよう書いてある。
https://github.com/containerd/containerd/blob/main/docs/getting-started.md
そして、上記ドキュメントを読むと、Docker公式を読めと書いてある。
https://docs.docker.com/engine/install/centos/
ということで、Docker公式の手順に従ってインストールする。
古いパッケージのアンインストール
インストールされていなくても、以下実行する分には問題なし。
# dnf remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
Dockerインストール
# dnf config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
# dnf -y install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
Docker起動時の設定
プライベートレジストリがある場合は、insecure-registries
を設定する。
# 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"
],
"insecure-registries": [
"192.168.0.105"
]
}
EOF
Docker起動&起動設定
systemctl daemon-reload
は設定を変更した場合に実行しないといけない。
# systemctl daemon-reload
# systemctl start docker
# systemctl enable docker
Kubernetesパッケージリポジトリ設定
# 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
exclude=kube*
EOF
Kubernetes関連パッケージのインストール
# dnf -y install kubelet kubeadm kubectl --disableexcludes=kubernetes
kubeletの設定
cgroupfsドライバーとして利用できるのは、cgroupfsとsystemdがあるようで、initプロセスでsystemdを使っている場合は、systemdを使うようにするらしい。
https://kubernetes.io/ja/docs/setup/production-environment/container-runtimes/
# mkdir /var/lib/kubelet
# cat <<EOF > /var/lib/kubelet/config.yaml
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
cgroupDriver: "systemd"
EOF
# mkdir /etc/systemd/system/kubelet.service.d
# cat <<EOF > /etc/systemd/system/kubelet.service.d/20-extra-args.conf
[Service]
Environment="KUBELET_EXTRA_ARGS=--fail-swap-on=false"
EOF
# systemctl enable --now kubelet
# systemctl daemon-reload
iproute-tcインストール
# dnf -y install iproute-tc
containerdインストール
CRIのひとつである、containerdをインストールします。
公式ドキュメントを参考にインストールしました。(というか公式そのまま)
# cat > /etc/modules-load.d/containerd.conf <<EOF
overlay
br_netfilter
EOF
# modprobe overlay
# modprobe br_netfilter
ブリッジでのトラフィック許可設定
以下の設定を入れて、sysctl --system
で設定を反映させる。(設定反映は再起動でも良い)
# cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
# sysctl --system
モジュールが読み込まれていることを確認
br_netfilter
とoverlay
モジュールが表示されること
# lsmod | grep br_netfilter
br_netfilter 24576 0
bridge 290816 1 br_netfilter
# lsmod | grep overlay
overlay 139264 0
カーネルパラメータ確認
各パラメータが1で設定されていることを確認する
# sysctl net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables net.ipv4.ip_forward
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
config変更
config.toml
のdisable_plugin
リストからcriを削除する。
# cp -p /etc/containerd/config.toml /etc/containerd/config.toml.org
# vi /etc/containerd/config.toml
- disabled_plugins = ["cri"]
+ disabled_plugins = [""]
# systemctl restart containerd
コントロールプレーンのセットアップ
本番運用する場合は、コントロールプレーンを複数台でロードバランシングするみたいですが、今回はお試しでの構築のため、コントロールプレーン1台構成(シングルコントロールプレーン)とします。
コントロールプレーンノードの初期化
kubeadm init <args>
で初期化する。
の部分で色々とオプションを設定する必要があるようです。
オプション | 内容 |
---|---|
--pod-network-cidr | CNI(Podネットワークアドオン)のCIDR(サイダー)を指定。この設定がpodに払い出されるIPアドレスセグメントになる。下記の設定ではCalicoのデフォルト値(192.168.0.0/16)を設定している。 |
--control-plane-endpoint | HA構成にする予定がある場合は、LBのIPアドレスを設定すれば良さそう。シングル構成にしない場合はオプションつけなくて良さそう。 ※シングル構成にしてから、あとでHA構成にはできないようなので作り直しになるっぽい。 |
--apiserver-advertise-address | ノードに複数のIPアドレスを割り当ててる場合に、どのIPアドレスを使うかを指定する。 |
--cri-socket | 異なるランタイムを複数インストールしている状態の場合、どれを使用するかを指定するのに使う。 |
以下のとおりで設定。
※成功時に表示される、kubeadm join...
の部分はワーカーノードを加えるときに必要になるため控えておくこと。
# kubeadm init --pod-network-cidr=192.168.0.0/16
Your Kubernetes control-plane has initialized successfully!
To start using your cluster, you need to run the following as a regular user:
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
Alternatively, if you are the root user, you can run:
export KUBECONFIG=/etc/kubernetes/admin.conf
You should now deploy a pod network to the cluster.
Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
https://kubernetes.io/docs/concepts/cluster-administration/addons/
Then you can join any number of worker nodes by running the following on each as root:
kubeadm join 192.168.0.111:6443 --token nekoto.o0nekotonustimih \
--discovery-token-ca-cert-hash sha256:6e55555da567890517b35d60df22222d7a2bc53f85f3fc0d7633b7ff13049453
環境変数のパスを指定
rootユーザーの場合は、以下を実行する。(kubeadm initに成功した場合のコメントにも書いてある)
# export KUBECONFIG=/etc/kubernetes/admin.conf
動作確認
ブラウザでアクセス可能かどうかを確認。
http://192.168.0.111:6443/api
にアクセスできること。
この時点ではコントロールプレーンはNotReady状態。
# kubectl get node
NAME STATUS ROLES AGE VERSION
k8s-master NotReady control-plane 2d23h v1.27.1
corednsがPendingの状態。
# kubectl get pod -A
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-5d78c9869d-24jbg 0/1 Pending 0 2d23h
kube-system coredns-5d78c9869d-tqfcs 0/1 Pending 0 2d23h
kube-system etcd-k8s-master 1/1 Running 1 (12h ago) 2d23h
kube-system kube-apiserver-k8s-master 1/1 Running 1 (12h ago) 2d23h
kube-system kube-controller-manager-k8s-master 1/1 Running 1 (12h ago) 2d23h
kube-system kube-proxy-4z55l 1/1 Running 1 (12h ago) 2d23h
kube-system kube-scheduler-k8s-master 1/1 Running 1 (12h ago) 2d23h
Calicoインストール
公式に書いてあるとおりにインストールする。
# kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.25.1/manifests/tigera-operator.yaml
# kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.25.1/manifests/custom-resources.yaml
コントロールプレーンがReady状態になっていることを確認。
# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master Ready control-plane 3d v1.27.1
corednsを含む、すべてのPodがRunning状態であることを確認。
# kubectl get pod -A
NAMESPACE NAME READY STATUS RESTARTS AGE
calico-apiserver calico-apiserver-6d788c89ff-lbwbn 1/1 Running 0 4m54s
calico-apiserver calico-apiserver-6d788c89ff-s2zsp 1/1 Running 0 4m54s
calico-system calico-kube-controllers-789dc4c76b-blwh2 1/1 Running 0 5m39s
calico-system calico-node-jj54g 1/1 Running 0 5m39s
calico-system calico-typha-6b5f86658b-khcl5 1/1 Running 0 5m39s
calico-system csi-node-driver-6mbmj 2/2 Running 0 5m39s
kube-system coredns-5d78c9869d-24jbg 1/1 Running 0 3d
kube-system coredns-5d78c9869d-tqfcs 1/1 Running 0 3d
kube-system etcd-k8s-master 1/1 Running 1 (13h ago) 3d
kube-system kube-apiserver-k8s-master 1/1 Running 1 (13h ago) 3d
kube-system kube-controller-manager-k8s-master 1/1 Running 1 (13h ago) 3d
kube-system kube-proxy-4z55l 1/1 Running 1 (13h ago) 3d
kube-system kube-scheduler-k8s-master 1/1 Running 1 (13h ago) 3d
tigera-operator tigera-operator-549d4f9bdb-p8qp4 1/1 Running 0 6m45s
ワーカーノードの構築
コントロールプレーンと同じく環境変数のパスを指定しておく。
# export KUBECONFIG=/etc/kubernetes/admin.conf
コントロールプレーンでkubeadm init
したときに表示されていたコマンドを実行する。
# kubeadm join 192.168.0.111:6443 --token nekoto.o0nekotonustimih \
--discovery-token-ca-cert-hash sha256:6e55555da567890517b35d60df22222d7a2bc53f85f3fc0d7633b7ff13049453
トークンは、発行されてから24時間しか有効期限がないようである。必要であれば再発行すること。
# kubeadm token create
e1oxsm.m7p2c9t9pv5oat84
トークンを忘れてしまった場合は、こちらのコマンドで確認が可能である。
# kubeadm token list
TOKEN TTL EXPIRES USAGES DESCRIPTION EXTRA GROUPS
e1oxsm.m7p2c9t9pv5oat84 23h 2023-05-06T14:10:28Z authentication,signing <none> system:bootstrappers:kubeadm:default-node-token
コントロールプレーンで確認すると、ワーカーノードが追加されていることが分かる。
joinしてすぐだとNotReadyになっているが、しばらく待つとReadyになる。
# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master Ready control-plane 3d1h v1.27.1
k8s-worker01 Ready <none> 4m15s v1.27.1
同じ要領でもう1つワーカーノードを追加して終わり。
# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k8s-master Ready control-plane 3d2h v1.27.1
k8s-worker01 Ready <none> 68m v1.27.1
k8s-worker02 Ready <none> 24s v1.27.1
参考書籍
構築はこちらの書籍が一番参考になりました。
参考にしたかった書籍
評価高かったので最初にこっち買ったけど、構築に関する部分が全然なくて積読してた。
レビューに分かりやすいと書いてあって次に購入。こちらも構築に関する情報が足りず構築できず。
参考サイト様
お世話になったサイト様。理解深まりました。