0
1

More than 1 year has passed since last update.

学習用Kubernetes環境を作る1 Ubuntu 20.04 LTS+kubeadm+containerd+CalicoなKubernetes環境をHyper-V上にTailscaleの固定IPで構築

Last updated at Posted at 2021-09-02

はじめに

注意:今回作る環境は,初心者が学習用に作成したものです.
決して本番環境等,外部に公開するような重要な環境ではそのままの手順通りで行わないで下さい.
また,insecureな設定やベストプラクティスから外れた運用をしている箇所があります.

学習用Kubernetes環境を作るの第1回です.

Part 1 学習用Kubernetes環境を作る1 Ubuntu 20.04 LTS+kubeadm+containerd+CalicoなKubernetes環境をHyper-V上にTailscaleの固定IPで構築

Part 2 学習用Kubernetes環境を作る2 動的PVが使えない環境でKubernetes管理WebUIのPortainer環境を作る/データ永続化/NodePortについて

Part 3 学習用Kubernetes環境を作る3 Kubernetes上にKubernetes用プライベートDockerレジストリHarbor環境を作る/httpなDockerレジストリをDocker・containerdで使う

今回は,Hyper-V上にインストールしたUbuntu 20.04 LTS(CUI環境)上に,Kubernetesのシングルノードを作成する.

Kubernetes環境の構築ツールとしてkubeadmを,CRI(Container Runtime Interface)としてDockerのコア部分であるcontainerdを,CNI(Container Network Interface)を採用したKubernetes環境を構築する.

また,KubernetesのパッケージマネージャーとしてHelmを利用する.

KubernetesノードのNICやIPはP2PなWireguardを利用したVPNであるTailscaleの固定IPを利用して構築する(Hyper-V外部からは,TailscaleのIPアドレスやmagicDNSを利用して接続してください).

構成

物理PC

  • Intel Core i5-8400
  • RAM 8GB (少ないので本当は最低でも16GBは欲しい)
  • Windows 10 Pro(21H1)

仮想マシン

  • CPU 6コア割り当て
  • RAM 5GB(起動メモリ,最大8GB)
  • ネットワークDefault Switch(Tailscaleの固定IPやmagicDNSで構築)
  • Ubuntu 20.04 LTS(GUIは無効)
lscpu
アーキテクチャ:                      x86_64
CPU 操作モード:                      32-bit, 64-bit
バイト順序:                          Little Endian
Address sizes:                       39 bits physical, 48 bits virtual
CPU:                                 6
オンラインになっている CPU のリスト: 0-5
コアあたりのスレッド数:              1
ソケットあたりのコア数:              6
ソケット数:                          1
NUMA ノード数:                       1
ベンダー ID:                         GenuineIntel
CPU ファミリー:                      6
モデル:                              158
モデル名:                            Intel(R) Core(TM) i5-8400 CPU @ 2.80GHz
ステッピング:                        10
CPU MHz:                             2808.009
BogoMIPS:                            5616.01
ハイパーバイザのベンダー:            Microsoft
仮想化タイプ:                        完全仮想化
L1d キャッシュ:                      192 KiB
L1i キャッシュ:                      192 KiB
L2 キャッシュ:                       1.5 MiB
L3 キャッシュ:                       9 MiB
NUMA ノード 0 CPU:                   0-5
Vulnerability Itlb multihit:         KVM: Mitigation: VMX unsupported
Vulnerability L1tf:                  Mitigation; PTE Inversion
Vulnerability Mds:                   Mitigation; Clear CPU buffers; SMT Host state unknown
Vulnerability Meltdown:              Mitigation; PTI
Vulnerability Spec store bypass:     Mitigation; Speculative Store Bypass disabled via prctl and seccomp
Vulnerability Spectre v1:            Mitigation; usercopy/swapgs barriers and __user pointer sanitization
Vulnerability Spectre v2:            Mitigation; Full generic retpoline, IBPB conditional, IBRS_FW, STIBP disabled, RSB
                                     filling
Vulnerability Srbds:                 Unknown: Dependent on hypervisor status
Vulnerability Tsx async abort:       Not affected
フラグ:                              fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx
                                      fxsr sse sse2 ss ht syscall nx pdpe1gb rdtscp lm constant_tsc rep_good nopl xtopol
                                     ogy cpuid pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 movbe popcnt aes xsave av
                                     x f16c rdrand hypervisor lahf_lm abm 3dnowprefetch invpcid_single pti ssbd ibrs ibp
                                     b stibp fsgsbase bmi1 avx2 smep bmi2 erms invpcid rdseed adx smap clflushopt xsaveo
                                     pt xsavec xgetbv1 xsaves md_clear flush_l1d arch_capabilities
cat /etc/os-release
NAME="Ubuntu"
VERSION="20.04.3 LTS (Focal Fossa)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 20.04.3 LTS"
VERSION_ID="20.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=focal
UBUNTU_CODENAME=focal
uname -r
5.8.0-1040-azure

OSのアップグレード/curlのインストールを行う

まず,以下のコマンドのように,環境のアップグレード及び,(一応)再起動を行う.

sudo apt update

sudo apt -y upgrade

sudo apt -y autoremove

sudo apt -y autoclean

sudo reboot

必要なファイルをダウンロードするため,curlをインストールする.

sudo apt install -y curl

Tailscaleのセットアップ

Tailscaleのセットアップを行う.

Tailscaleをインストールし,magicDNSを有効化し,認証キーを使い認証し,PodのIPとCLUSTER-IPのサブネットを公開します.

Tailscaleをインストール

Tailscaleのインストールを行う.

以下のURLを参考にする.

以下のようなコマンドでTailscaleをaptのリポジトリに追加し,インストールします.

curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/focal.gpg | sudo apt-key add -

curl -fsSL https://pkgs.tailscale.com/stable/ubuntu/focal.list | sudo tee /etc/apt/sources.list.d/tailscale.list

sudo apt update

sudo apt install -y tailscale

Tailscaleアカウントを作成

以下のURLから,Get Startedを押し,アカウントを作成します.

アカウントは,Google,Microsoft,Githubのアカウントのいずれかから作成出来ます.

magicDNSを有効化

以下のURLからmagicDNSを有効化します.

DNSサーバーには,8.8.8.8(Google Public DNS)等,好きなDNSサーバーを指定して有効化して下さい.

認証キーを生成

以下のURLから,One-off keyを選択し,Generate One-off keyを押し,認証キーを生成します.

生成したら,生成された認証キーの横のCopyをクリックし,クリップボードに保存します(認証するまでなくさないで下さい).

クリップボードにコピー出来たことを確認したら,Doneをクリックします.

One-off keyなので認証すれば,Tailscaleの認証キーの管理画面から消えますが,キーを生成し直す場合等,対象のキーのRevokeを押して削除する事もできます.

Tailscaleを起動

以下のURLを参考に,サブネットをTailscaleに転送出来るようにします.

以下のようなコマンドを実行します.

echo 'net.ipv4.ip_forward = 1' | sudo tee -a /etc/sysctl.conf

echo 'net.ipv6.conf.all.forwarding = 1' | sudo tee -a /etc/sysctl.conf

sudo sysctl -p /etc/sysctl.conf

以下のコマンドで,生成された認証キーを利用し,Tailscaleを起動・認証し,公開するサブネットを設定します.

sudo tailscale up --authkey 認証キー --advertise-routes=10.96.0.0/12,192.168.0.0/16

192.168.0.0/16は,今回採用したCNIのCalicoデフォルトのPodのIPのサブネットで,10.96.0.0/12は,デフォルトのCLUSTER-IPのサブネットです.

Tailscaleの管理画面でサーバーのサブネットを公開するように設定

以下のURLから,Tailscaleを起動したサーバーをクリックします.

SubnetsにあるReviewボタンを押し,公開したサブネットをEnableにして有効化します.

これで,サーバーに繋ぐクライアントにもTailscaleをインストール・ログインすれば,Tailscaleを起動している間は,サーバーのホスト名(とTailscaleの固定IP)でサーバーに接続したり,PodのIPや,CLUSTER-IPで直接接続出来るようになります.

Kubernetesの環境構築

Tailscaleのセットアップが終われば,Kubernetesの環境を構築します.

containerd(CRI)をインストール

今回は,コンテナランタイムとして,Docker Engineのコア部分であるContainerdを利用する.

多くのkubeadmを利用したKubernetesの環境構築記事では,Dockerをインストールし,kubeadmのデフォルトCRIがDockerだからか,CRIとしてDockerを利用しているが,現在ではKubernetesのCRIとしてDockerを利用することは非推奨となっているので,これを使う.

今回は,Canonicalが管理しているUbuntuのデフォルトのリポジトリにあるcontainerdを利用する.

以下のコマンドのようにしてインストールする.

同じ環境でDockerを既に利用している/利用する場合は,既にインストールされているはずなので,この手順は不要です.

また,最新版のcontainerdやDockerを利用したい場合,または,x64とArm64のマルチアーキテクチャイメージを,この環境のDockerを利用してビルドしたいと考えてる場合,マルチアーキテクチャイメージをビルドするためのbuildxがバンドルされているDocker公式のインストール手順に従い,docker-ceをインストールすることをおすすめする(Canonical版はbuilxのバイナリーを手動で直接配置する必要があります).

尚,どちらにせよcontainerdはインストールされるので,以降の手順は同一です.

sudo apt install -y containerd

次に,containerdをKubernetesで利用できるように設定する.

cat <<EOF | sudo tee /etc/modules-load.d/containerd.conf
overlay
br_netfilter
EOF

sudo modprobe overlay

sudo modprobe br_netfilter

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

sudo sysctl --system

sudo mkdir -p /etc/containerd

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

設定が完了すれば,Systemdを利用して,Containerdを自動起動出来るようにし,containerdを起動する.

sudo systemctl enable containerd

sudo systemctl start containerd

Swapを無効

kubeletの正常な稼働のためには,swapを無効化する必要があります.

以下の様なコマンドを利用し,swapを一時的に無効にする.

sudo swapoff -a

これでは,再起動後,swapが有効になってしまうのでfstabを編集する.

nanoで編集するためのコマンドは以下の通りです.

sudo nano /etc/fstab

/etc/fstabを開き,swapという文字が含まれる行の行頭に#を入れ,以下のようにコメントアウトすれば良い.

#/swapfile                                 none            swap    sw              0       0

行頭は/swapfileではなく,UUIDで始まる場合もありますが,swapと書かれている行をコメントアウトすれば良い.

kubeadmやkubectl等,Kubernetesのコマンド,Helmをインストール

まずは,リポジトリを追加する.

# add repo kubernetes commands
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -

sudo apt-add-repository "deb http://apt.kubernetes.io/ kubernetes-xenial main"

# add repo helm
curl https://helm.baltorepo.com/organization/signing.asc | sudo apt-key add -

sudo apt install -y apt-transport-https

echo "deb https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.list

リポジトリを更新し,各コマンドをインストールする.

sudo apt update

sudo apt install -y kubeadm kubelet kubectl helm

Kubernetesをセットアップ

今回は,固定IPはTailscaleのものを利用する.
以下の様なコマンドでTailscaleに割り当てられた固定IPアドレスを確認する.

ip a show dev tailscale0

このIPアドレスを利用して以下の様にしてKubernetes環境を作成する.

sudo kubeadm init --control-plane-endpoint=Tailscaleの固定IP:6443  --apiserver-advertise-address=Tailscaleの固定IP --pod-network-cidr=192.168.0.0/16 --cri-socket=/run/containerd/containerd.sock

今回はCNIとしてCalicoを利用するため,--pod-network-cidr=192.168.0.0/16としている.

また,今回はシングルノードであるため触れませんが,init時に出てくるjoinコマンドを利用すれば,(Tailscaleでつながるマシンからであれば)クラスタを構築出来る.

init時に,表示されたようにkubectlコマンドを利用出来るようにするために以下のコマンドで設定ファイルを移動させる.

mkdir -p $HOME/.kube

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

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

リモートで,このKubernetes環境を管理したい場合,kubectlコマンドを,そのマシンにインストールした後,上記と同じように,ホームディレクトリ(Windowsなら%USERPROFILE%)以下に.kubeというフォルダを作り,上記のconfigファイルをコピーすれば,対象マシンにTailscaleで接続可能であれば,管理出来るようになる.

その場合,Kubernetesのエンドポイントポート(6443)を以下の様なコマンドで許可しておく必要があります.

sudo ufw allow 6443

また,ローカルに戻り,rootでも実行出来るようにするためには,rootの.bashrcに以下の様なコマンドで追記する(再構築した場合手動で,削除していない場合,このコマンドの再実行は不要).

echo "export KUBECONFIG=/etc/kubernetes/admin.conf" | sudo tee -a /root/.bashrc

TailscaleのIPを利用するようにkubeletの設定を変更する.

nanoで編集するためのコマンドは以下の通りです.

sudo nano /etc/systemd/system/kubelet.service.d/10-kubeadm.conf

nanoで開いた後,以下のように変更する.

Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml --node-ip=Tailescaleの固定IP"

以下の様なコマンドでサービスファイルの変更を適用し,サービスを再起動させる.

sudo systemctl daemon-reload

sudo systemctl restart kubelet

Calico(CNI)をインストール

今回は,コンテナネットワークとして,Calicoを利用する.

以下の様なコマンドでCalicoをインストールすることが可能です.

helm repo add projectcalico https://docs.projectcalico.org/charts #add Helm repo Calico

helm install calico projectcalico/tigera-operator #Helm install Calico

Podをデプロイ出来るようにスケジューリングの設定を変更

デフォルト状態では,taintにより,Podのデプロイが無効になっているので,デプロイ出来るようにする.

以下の様なコマンドを複数回実行して,

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

以下の様なエラーが出るようになれば良い.

error: taint "node-role.kubernetes.io/master" not found

schedulerのステータスがUnhealthyなのを解消

このままの状態だと,schedulerのステータスがUnhealthyなことが以下のコマンドでわかる.

kubectl get cs scheduler

そのため,設定を変更する.

nanoで編集する場合は,以下のコマンドです.

sudo nano /etc/kubernetes/manifests/kube-scheduler.yaml

- --port=0となっている行を,コメントアウトまたは,削除する.

そして,以下のようなコマンドでkubeletを再起動する.

sudo systemctl restart kubelet

metrics-serverをインストールして,リソースを監視

まずは,Helmにリポジトリを追加する.

helm repo add bitnami https://charts.bitnami.com/bitnami

以下のコマンドでインストールする.

helm install -n kube-system metrics-server bitnami/metrics-server --set apiService.create=true \
  --set hostNetwork=true --set extraArgs.metric-resolution=15s \
  --set extraArgs.kubelet-insecure-tls=true --set extraArgs.kubelet-preferred-address-types=InternalIP

以下のようなコマンドで,

kubectl -n kube-system get deployment metrics-server

以下のように,動作していることを確認し,

NAME             READY   UP-TO-DATE   AVAILABLE   AGE
metrics-server   1/1     1            1           2d4h

以下のようなコマンドで,

kubectl top node

以下のように,ノードのリソース消費が表示されれば問題ない.

NAME             CPU(cores)   CPU%   MEMORY(bytes)   MEMORY%
ノード名(手順どおりならホスト名小文字)   707m         11%    2827Mi          58%

kubectl editで起動するエディターを設定

環境変数KUBE_EDITORに,指定したいエディター名を入れれば良い.

毎回同じエディターで起動したいのなら,以下のようなコマンドを実行すれば良い.

echo "export KUBE_EDITOR=nano" >> ~/.bashrc

echo "export KUBE_EDITOR=nano" | sudo tee -a /root/.bashrc

source ~/.bashrc

これは,エディターとしてnanoを選んだ場合の例です.

rootで実行する可能性がない場合,2つ目のコマンドは不要です.

VSCodeで起動する場合(Remote-SSH含む),=nanoを,='code --wait'に変更して下さい.

1つ目のコマンドの場合,以下のようにします.

echo "export KUBE_EDITOR='code --wait'" >> ~/.bashrc

起動オプションとして,--waitを指定しなかった場合,開かずに終了してしまいます.

VSCodeは,基本的にrootで起動出来ないようになっているし,rootで起動すべきではないので,nano等のエディターを使って下さい.

Kubernetesがしっかり設定されているかを確認

以下の様なコマンドを実行し,

kubectl get node -o wide

以下の様な出力結果になっていれば良い.

NAME             STATUS   ROLES                  AGE    VERSION   INTERNAL-IP      EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION     CONTAINER-RUNTIME
ノード名(手順どおりならホスト名小文字)   Ready    control-plane,master   2d3h   v1.22.1   Tailscaleの固定IP   <none>        Ubuntu 20.04.3 LTS   5.8.0-1040-azure   containerd://1.5.2

特に,設定したTailscaleの固定IPアドレスになっていること,コンテナランタイムがcontainerdになっていることは重要です(dockerdになっていないか).

ここまで確認すれば,(Windowsホストごと)一度再起動する.

しっかり,設定できていれば,仮想マシンを再起動してもswapは無効化されているのでkubeletは問題なく動作するはずだし,Windowsを再起動してDefault Switchで割り当てられたIPアドレスが変化しても問題なく,利用出来るようになっているはずです.

上記のコマンドをもう一度実行して特に問題がなければ良い.

もし,エラーが出た場合は,まずswapを確認して

sudo swapoff -a

で,もう一度無効にして,しばらくして再度上記コマンドを実行して,特に問題なければ,swapの無効化ができていないのでswapを無効をもう一度確認する.

それでも,解決しない場合は,TailscaleのIPアドレスの問題であるため,この手順で環境をリセットし,再度,Kubernetesをセットアップからやり直してください.

利用していないイメージを削除

コンテナがアップグレードされると,旧バージョンのイメージが残ってしまう.

以下のコマンドで利用していないイメージを全て削除することが出来る.

sudo crictl rmi --prune

Kubernetes環境をアップグレード

まずは,KubernetesのコマンドやCRIをアップグレードするために,以下のコマンドを実行.

sudo apt update

sudo apt -y upgrade

sudo apt -y autoremove

sudo apt -y autoclean

次にPodを退避する.

kubectl drain ノード名(手順どおりならホスト名小文字)

エラーが出た場合は,その対象のPodを一旦削除し,再度実行する.

アップグレード出来るバージョンを確認する.

sudo kubeadm upgrade plan

アップグレード出来るバージョンを確認したら,そのバージョンを指定してアップグレードする.

指定するバージョンが,v1.22.1の場合,以下のようなコマンドとなる.

sudo kubeadm upgrade apply v1.22.1

退避させたPodを元に戻す.

kubectl uncordon ノード名(手順どおりならホスト名小文字)

もし,退避時にエラーが出ていて一旦Podを削除した場合は,再度デプロイし直す.

Kubernetes環境をリセット

構築に失敗した場合,途中で誤った場合はリセットする必要がある場合があります.

その場合,以下の様なコマンドを実行し,

sudo kubeadm reset

以下の様に再起動すれば良い.

sudo reboot

再起動後,以下の様なコマンドで,cniのネットワークが削除されているかを確認する.

ip a

上記のコマンドで,caliから始まるネットワークとtunl0@NONEのネットワークが削除されていれば,正常にリセットされている.

上記を実行後Kubernetesをセットアップからやり直すと良い.

感想

途中(helmの手順を追加した時)まで,出来るだけプレーンな環境で,理想的な環境を作りたいと考えていたので,kubeadmとcontainerdを採用したが,おかげで手順が多くなってしまった(第2回以降も).

単純にKubernetes環境が欲しいだけなら,素直にminikubeやmicrok8s,Docker Desktop等を使ったほうが多分楽です(metrics-serverとかはそのままで動かなかったものとかも多い).

後,Kubernetesのバックエンドをcontainerdにしたら,Dockerで使っていた時より,なぜか重い気がするのと,Ubuntuのシャットダウンや再起動の時間がかなり長くなってしまった.

Next

0
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1