servermemoのブログ

サーバー構築の手順をまとめる予定です。

UbuntuでkubeadmでKubernetesクラスターを構築

要件

このガイドは次のバージョンのUbuntu(の最新版)で動作確認をしています。

  • Ubuntu 18.04.6 LTS
  • Ubuntu 20.04.4 LTS
  • Ubuntu 22.04LTS (cgroup V1設定に変更が必要。詳細は後述)

現在の私の推奨はUbuntu 20.04.4 LTSです。

本ガイドでは Kubernetes 1.24.1をインストールする例を示しています。

SWAPのオフ

Swapパーティションコメントアウト、およびswapoffを実行します。

sudo vi /etc/fstab 
sudo swapoff -a

初期設定とランタイムのインストール

本例ではcontainerdをインストールします。UbuntuではUbuntu Archives版のcontaienrdパッケージとDockerリポジトリーに含まれるcontaienrd.ioパッケージのいずれかを使って、Ubuntuにcontainerdをインストールできます。Dockerリポジトリーに含まれる方が、新しいバージョンが使えるのでおすすめです。

まず、こちらに書かれている事前設定をそれぞれ行います。

sudo -i

cat > /etc/modules-load.d/containerd.conf <<EOF
overlay
br_netfilter
EOF

modprobe overlay
modprobe br_netfilter

cat > /etc/sysctl.d/99-kubernetes-cri.conf <<EOF
net.bridge.bridge-nf-call-iptables  = 1
net.ipv4.ip_forward                 = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF

sysctl --system
exit

Ubuntu 22.04ではCgroup v2を無効化してください。設定変更後、再起動が必要です(Ubuntu 22.04以前のバージョンでは不要です)。

tech.virtualtech.jp

次に従って、リポジトリーの有効化を行います。

docs.docker.com

インストールは次のように行います。

sudo apt-get update 
sudo apt-get install -y containerd.io

その後、containerdの設定の作成と必要に応じて設定の変更、containerdサービスの再起動を行います。

sudo mkdir -p /etc/containerd
sudo containerd config default | sudo tee /etc/containerd/config.toml
sudo systemctl restart containerd

kubeadmツールなどのインストール

公式のInstalling kubeadmに従って、リポジトリーの有効化を行います。

手元の環境ではインストール済みでしたが、インストールされていない場合は導入します。

sudo apt-get update
sudo apt-get install -y apt-transport-https ca-certificates curl

Google Cloudの公開署名キーをダウンロードします。

sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg

Kubernetes aptリポジトリーの追加を行います。

echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list

kubeadm,kubelet,kubectlのインストールとバージョンの固定を行います。

sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

Tips バージョンを指定する場合

アプリケーションの都合で特定のバージョンが必要な場合は次のように指定してインストールします。ただし、Kubernetesは最新版を使うのを最も推奨します。

sudo apt-get update
sudo apt-get install -y kubelet=1.24.1-00 kubeadm=1.24.1-00 kubectl=1.24.1-00
sudo apt-mark hold kubelet kubeadm kubectl

kubeadmツールでクラスターの作成

次のようなオプションを追加して、クラスターを作成します。

sudo kubeadm init --kubernetes-version 1.24.1 --pod-network-cidr=10.244.0.0/16 --control-plane-endpoint=<Public IP Address>

--kubernetes-version は、バージョンを指定します。指定できるバージョンにはある程度上限、下限があります。適切なkubeadmツールの導入が必要です。 --pod-network-cidr は、Podに割り当てるネットワークの範囲を定義するものです。ネットワークプラグイン(CNIとも呼ぶ)を追加する際に必要な範囲です。CNIをインストールするときにCNI側の設定を変更するか、クラスター作成時に後々インストールするCNIに合わせて設定をしておく必要があります。現在利用中のCIDRを指定しないように気をつけます。 --control-plane-endpoint は、Kubernetes APIなどが使うエンドポイントIPアドレスです。ホストのeth0とかのアドレスを設定すれば良いでしょう。決してグローバルIPアドレスを指定しないよう気をつけます。

上記を実行すると処理が始まります。最終的にクラスターが作成されるとYour Kubernetes control-plane has initialized successfully!と表示され、この後することが出力されます。

まず、kubectlコマンドを使えるようにするために、kubeconfigの設定を行います。

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

ノードを追加してマルチクラスター構成にする場合は、別のサーバーで出力されたkubectl join行のコマンドを実行します。 ちなみにここで示されたトークンキーには期限があり、数日経ってからノードを追加しようとしてもうまくいきません。

新しいトークンは kubeadm token create --print-join-commandで作成できます。これをkubectl joinの実行時に指定します。

1台目のマシンでPodをスケジューリングできるようにするには次のコマンドを実行します。

kubectl taint nodes --all node-role.kubernetes.io/control-plane- node-role.kubernetes.io/master-

クラスターネットワークの適用

Kubernetesクラスターにネットワークアドオンを追加します。 利用できるネットワークアドオンの代表的なものはアドオンのインストールにまとめられています。

Flannelの場合はGitHub flannelにあるように、次のように実行します。CIDRは10.244.0.0/16が要件です。どちらかを適切なものに合わせます。

kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml

クラスターでPodを作ってみる

構築したクラスターでPodが作成できるか試してみます。

#Deploymentを作成
kubectl create deployment hello-node --image=k8s.gcr.io/echoserver:1.4

#Deploymentを確認
kubectl get deployment

#作成したDeploymentを削除
kubectl delete deployment hello-node

以上でUbuntuでkubeadmを使ったKubernetesクラスタの構築は完了です。

Oracle Linux 8でkubeadmを使ってKubernetesを動かす(containerd)

動作確認したバージョン

忙しい人向け

Kubernetesコミュニティ提供のkubeadm公式ドキュメントCentOS 8向けのセットアップ方法と同じように設定すれば環境の準備はできる。

以下、Kubernetes 1.20.0時点のセットアップ方法を記述している。

Oracle Linuxのダウンロード

次からダウンロードする。

public-yum.oracle.com

リポジトリーの有効化

containerdパッケージはDocker Engineのリポジトリーのパッケージを利用する(EL8には標準リポジトリーにDockerがないため。これはRHEL8やCentOS8と一緒)。 本来Oracle LinuxはDocker EngineのサポートOSではないが、CentOS向けパッケージを利用することにする。Kubernetesにおけるdockershimを用いたDockerのサポートは間も無く終了なので、containerdを推奨。

$ sudo yum install -y yum-utils
$ sudo yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo

containerdのインストール

$ sudo yum intall containerd

ランタイム由来の設定の適用

ランタイムを入れるときの事前設定方法は公式の設定に従う。

https://kubernetes.io/docs/setup/production-environment/container-runtimes/

$ sudo mkdir -p /etc/containerd
$ containerd config default | sudo tee /etc/containerd/config.toml

「Using the systemd cgroup driver」で述べられている設定を忘れずに。インデント注意。

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

設定変更後にサービスを起動。

$ sudo systemctl enable --now containerd

kubeadmツールなどの導入

kubeadmツールなどのインストールは、公式に従うと最新のバージョンをセットアップできる。

https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/

ファイアウォールの設定

共通

2行目は実際のネットワークセグメントを許可する。

$ sudo firewall-cmd --permanent --add-port=10250/tcp     #kubelet API
$ sudo firewall-cmd --zone trusted --add-source 192.168.0.0/24 --permanent   #物理ネットワークセグメント許可
$ sudo firewall-cmd --zone=public --add-masquerade
$ sudo firewall-cmd --permanent --zone=public --add-masquerade
$ sudo firewall-cmd --reload

master

2行目はCNIで実際指定するネットワークセグメントを許可する。

$ sudo firewall-cmd --permanent --add-port=6443/tcp     #Kubernetes API server
$ sudo firewall-cmd --zone trusted --add-source 10.244.0.0/16 --permanent
$ sudo firewall-cmd --reload

worker

2行目はCNIで実際指定するネットワークセグメントを許可する。

$ sudo firewall-cmd --permanent --add-port=30000-32767/tcp      #NodePort Services
$ sudo firewall-cmd --zone trusted --add-source 10.244.0.0/16 --permanent
$ sudo firewall-cmd --reload

Calicoを使う場合は以下のポートなども許可。シングルノードでは特に設定しないでも良い。

https://docs.projectcalico.org/getting-started/kubernetes/requirements

kubeadmツールを使ったクラスター作成

クラスターを作成するにはkubeadm initコマンドを使う。は外からアクセスできるIPアドレスを指定。エンドポイントを外部にさらさない(内部で使うだけ)ならローカルネットワークアドレスで良い。

$ sudo kubeadm init --kubernetes-version 1.21.0 --pod-network-cidr=10.244.0.0/16 --control-plane-endpoint=<Public IP Address>

シングルクラスターにする(もしくはmasterでもPodスケジュールしたい)場合は以下を実施

$ kubectl taint nodes --all node-role.kubernetes.io/master-

Workerを別に用意する場合は以下を実施して出力されるコマンドをノードで実行

$ kubeadm token create --print-join-command
kubeadm join 10.211.55.44:6443 --token ....

CNIを導入。様々なネットワークアドオンが存在する。Calicoの場合は

https://docs.projectcalico.org/getting-started/kubernetes/self-managed-onprem/onpremises

構築後のクラスターの状態(シングルクラスターの場合)

$ kubectl get nodes
NAME                    STATUS   ROLES                  AGE   VERSION
localhost.localdomain   Ready    control-plane,master   58m   v1.21.0

$ kubectl get pods -A
NAMESPACE     NAME                                            READY   STATUS    RESTARTS   AGE
kube-system   calico-kube-controllers-6d8ccdbf46-pxr84        1/1     Running   0          57m
kube-system   calico-node-vj9cs                               1/1     Running   0          57m
kube-system   coredns-558bd4d5db-2t6sw                        1/1     Running   0          58m
kube-system   coredns-558bd4d5db-p84zs                        1/1     Running   0          58m
kube-system   etcd-localhost.localdomain                      1/1     Running   0          58m
kube-system   kube-apiserver-localhost.localdomain            1/1     Running   0          58m
kube-system   kube-controller-manager-localhost.localdomain   1/1     Running   0          58m
kube-system   kube-proxy-xsdt9                                1/1     Running   0          58m
kube-system   kube-scheduler-localhost.localdomain            1/1     Running   0          58m

$ kubectl get svc -A
NAMESPACE     NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE
default       kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP                  58m
kube-system   kube-dns     ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP,9153/TCP   58m

Oracle Linux 7でkubeadmを使ってKubernetesを動かす(containerd)

動作確認したバージョン

Oracle Linuxのダウンロード

次からダウンロードする。

public-yum.oracle.com

リポジトリーの有効化

add-onsリポジトリーを有効にすると、Dockerおよびcontainerdをインストールできる。このパッケージを使って構築できる。Kubernetesにおけるdockershimを用いたDockerのサポートは間も無く終了なので、containerdを推奨。

public-yum.oracle.com

$ sudo yum-config-manager --enable ol7_addons

containerdのインストール

$ sudo yum intall containerd

ランタイム由来の設定の適用

ランタイムを入れるときの事前設定方法は公式の設定に従う。

kubernetes.io

$ sudo mkdir -p /etc/containerd
$ containerd config default | sudo tee /etc/containerd/config.toml

「Using the systemd cgroup driver」で述べられている設定の追記を忘れずに。インデント注意。

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

設定変更後にサービスを起動。

$ sudo systemctl enable --now containerd

kubeadmツールなどの導入

kubeadmツールなどのインストールは、公式に従うと最新のバージョンをセットアップできる。

kubernetes.io

ファイアウォールの設定

共通

2行目は実際のネットワークセグメントを許可する。

$ sudo firewall-cmd --permanent --add-port=10250/tcp     #kubelet API
$ sudo firewall-cmd --zone trusted --add-source 192.168.0.0/24 --permanent   #物理ネットワークセグメント許可
$ sudo firewall-cmd --zone=public --add-masquerade
$ sudo firewall-cmd --permanent --zone=public --add-masquerade
$ sudo firewall-cmd --reload

master

2行目はCNIで実際指定するネットワークセグメントを許可する。

$ sudo firewall-cmd --permanent --add-port=6443/tcp     #Kubernetes API server
$ sudo firewall-cmd --zone trusted --add-source 10.244.0.0/16 --permanent
$ sudo firewall-cmd --reload

worker

2行目はCNIで実際指定するネットワークセグメントを許可する。

$ sudo firewall-cmd --permanent --add-port=30000-32767/tcp      #NodePort Services
$ sudo firewall-cmd --zone trusted --add-source 10.244.0.0/16 --permanent
$ sudo firewall-cmd --reload

Calicoを使う場合は以下のポートなども許可。シングルノードでは特に設定しないでも良い。

docs.projectcalico.org

kubeadmツールを使ったクラスター作成

クラスターを作成するにはkubeadm initコマンドを使う。は外からアクセスできるIPアドレスを指定。エンドポイントを外部にさらさない(内部で使うだけ)ならローカルネットワークアドレスで良い。

$ sudo kubeadm init --kubernetes-version 1.21.0 --pod-network-cidr=10.244.0.0/16 --control-plane-endpoint=<Public IP Address>

シングルクラスターにする(もしくはmasterでもPodスケジュールしたい)場合は以下を実施

$ kubectl taint nodes --all node-role.kubernetes.io/master-

Workerを別に用意する場合は以下を実施して出力されるコマンドをノードで実行

$ kubeadm token create --print-join-command
kubeadm join 10.211.55.44:6443 --token ....

CNIを導入。様々なネットワークアドオンが存在する。Calicoの場合は

docs.projectcalico.org

構築後のクラスターの状態(シングルクラスターの場合)

$ kubectl get nodes
NAME                    STATUS   ROLES                  AGE   VERSION
localhost.localdomain   Ready    control-plane,master   58m   v1.21.0

$ kubectl get pods -A
NAMESPACE     NAME                                            READY   STATUS    RESTARTS   AGE
kube-system   calico-kube-controllers-6d8ccdbf46-pxr84        1/1     Running   0          57m
kube-system   calico-node-vj9cs                               1/1     Running   0          57m
kube-system   coredns-558bd4d5db-2t6sw                        1/1     Running   0          58m
kube-system   coredns-558bd4d5db-p84zs                        1/1     Running   0          58m
kube-system   etcd-localhost.localdomain                      1/1     Running   0          58m
kube-system   kube-apiserver-localhost.localdomain            1/1     Running   0          58m
kube-system   kube-controller-manager-localhost.localdomain   1/1     Running   0          58m
kube-system   kube-proxy-xsdt9                                1/1     Running   0          58m
kube-system   kube-scheduler-localhost.localdomain            1/1     Running   0          58m

$ kubectl get svc -A
NAMESPACE     NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE
default       kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP                  58m
kube-system   kube-dns     ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP,9153/TCP   58m

CentOS 7でkubeadmを使ってKubernetesを動かす(CRI-O)

忙しい人向け

インストールについて

CentOS 7のインストール

  • インストール方法は省略。

ファイアウォール

firewall-cmdを使って以下のように設定しました。

CRI-Oのインストール前の事前準備

# cat > /etc/modules-load.d/containerd.conf <<EOF
overlay
br_netfilter
EOF

# modprobe overlay
# modprobe br_netfilter

ネットワーク関連の設定

# cat > /etc/sysctl.d/99-kubernetes-cri.conf <<EOF
net.bridge.bridge-nf-call-iptables  = 1
net.ipv4.ip_forward                 = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF

# sysctl --system

CRI-Oのインストール

CRI-Oの設定を確認

conmonとcgroup_managerの設定を確認。

# vi /etc/crio/crio.conf
...
conmon = "/usr/libexec/crio/conmon"
...
cgroup_manager = "systemd"

Kubeletの設定を変更

以下のように設定しました。

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

1.18.3を導入した

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

# Set SELinux in permissive mode (effectively disabling it)

setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

yum install -y kubelet-1.18.3-0.x86_64 kubeadm-1.18.3-0.x86_64 kubectl-1.18.3-0.x86_64 --disableexcludes=kubernetes

systemctl enable --now kubelet

K8sクラスタのデプロイ

「pod-network-cidr」は導入するCNIに適したものを設定する。 --control-plane-endpoint はノードに設定されているIPアドレスのうち、外部からアクセスできるものを指定する。

# kubeadm init --kubernetes-version 1.18.3 --pod-network-cidr=10.244.0.0/16 --control-plane-endpoint=192.168.1.70

Kubeconfigの用意

kubeadmでクラスター作成がうまくいくと、コマンドを実行しろと言われるので実行。

# mkdir -p $HOME/.kube
# cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
# chown $(id -u):$(id -g) $HOME/.kube/config

MasterノードをWorkerとして使う

master 1nodeにする場合は次を実行。Workerを追加する場合は、出力されているkubeadm joinコマンドをWorkerノードで実行。

# kubectl taint nodes --all node-role.kubernetes.io/master-

Podネットワークアドオンのインストール

任意のPodネットワークアドオンをインストールする。筆者が動作確認したバージョンは以下のとおり。

Calico and v1.18.3(実行にはメモリ8GB以上必要)

CentOS 7とK8s v1.18.3でCNI Calicoは以下のバージョンで正常に動いた。

# curl -LO https://docs.projectcalico.org/v3.14/manifests/calico.yaml
(YAMLのCALICO_IPV4POOL_CIDRをpod-network-cidrと同じものに変更)
# kubectl apply -f calico.yaml

構築手順は以上

構築した環境を使って、公式サイトの「アプリケーションの実行」を試してみましょう。

Oracle Linux 7でkubeadmを使ってKubernetesを動かす(CRI-O)

忙しい人向け

動作確認したバージョン

インストール手順

Oracle Linux のダウンロード

次からダウンロードする。

public-yum.oracle.com

Oracle Linux 7.8のインストール

  • 手順は省略

Oracle Linux 7.8のファイアウォール設定

CRI-Oのインストール前の事前準備

# cat > /etc/modules-load.d/containerd.conf <<EOF
overlay
br_netfilter
EOF

# modprobe overlay
# modprobe br_netfilter

ネットワーク関連の設定

# cat > /etc/sysctl.d/99-kubernetes-cri.conf <<EOF
net.bridge.bridge-nf-call-iptables  = 1
net.ipv4.ip_forward                 = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF

# sysctl --system

Oracle Linux Cloud Native Environmentリポジトリーを有効化

# yum install oracle-olcne-release-el7.x86_64

Oracle Linux Cloud Native Environment」の依存リポジトリーを有効化

# yum-config-manager --enable ol7_addons ol7_kvm_utils

デフォルトはol7_olcne(Oracle Linux Cloud Native Environment 1.0)が有効になっている。 より新しいパッケージはol7_olcne11(Oracle Linux Cloud Native Environment 1.1)にある。

ol7_olcne11(Oracle Linux Cloud Native Environment 1.1)を使いたい場合

# yum-config-manager --disable ol7_olcne    #disableにするのはオプション
# yum-config-manager --enable ol7_olcne11

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

# yum install cri-o kubelet kubeadm kubectl
# systemctl enable --now kubelet

CRI-Oの設定変更

# vi /etc/crio/crio.conf

conmon = "/usr/libexec/crio/conmon"

#cgroup_manager = "cgroupfs"
cgroup_manager = "systemd"

# systemctl enable --now cri-o

Kubeletの設定を変更

KubeletでCRI-O由来の設定をパラメータ指定する。設定は以下のように行いました。

K8sクラスタのデプロイ

オプションが変わったので注意。「pod-network-cidr」は導入するCNIに適したものを設定する。

(v1.14.9)
# kubeadm init --kubernetes-version 1.14.9 --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=192.168.1.70

(v1.17.4)
# kubeadm init --kubernetes-version 1.17.4 --pod-network-cidr=10.244.0.0/16 --control-plane-endpoint=192.168.1.70

Kubeconfigの用意

kubeadmでクラスター作成がうまくいくと、コマンドを実行しろと言われるので実行。

# mkdir -p $HOME/.kube
# cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
# chown $(id -u):$(id -g) $HOME/.kube/config

MasterノードをWorkerとして使う

master 1nodeにする場合は次を実行。Workerを追加する場合は、出力されているkubeadm joinコマンドをWorkerノードで実行。詳細は公式ドキュメントの「ノードの追加」を参照。

# kubectl taint nodes --all node-role.kubernetes.io/master-

Podネットワークアドオンのインストール

任意のPodネットワークアドオンをインストールする。筆者が動作確認したバージョンは以下のとおり。

Flannel and v1.14.9

Oracle Linux 7とK8s v1.14.9でCNI Flannelは以下のバージョンで正常に動いた。

# kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/62e44c867a2846fefb68bd5f178daf4da3095ccb/Documentation/kube-flannel.yml

Flannel and v1.17.4(See: https://github.com/coreos/flannel

Oracle Linux 7とK8s v1.17.4でCNI Flannelは以下のバージョンで正常に動いた。

# kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml

Calico and v1.14.9(実行にはメモリ8GB以上必要)

Oracle Linux 7とK8s v1.14.9でCNI Calicoは以下のバージョンで正常に動いた。

# curl -LO https://docs.projectcalico.org/v3.7/manifests/calico.yaml
(pod-network-cidrを変更)
# kubectl apply -f calico.yaml

Calico and v1.17.4(実行にはメモリ8GB以上必要)

Oracle Linux 7とK8s v1.17.4でCNI Calicoは以下のバージョンで正常に動いた。

# curl -LO https://docs.projectcalico.org/v3.8/manifests/calico.yaml
(pod-network-cidrを変更)
# kubectl apply -f calico.yaml

構築手順は以上

構築した環境を使って、公式サイトの「アプリケーションの実行」を試してみましょう。