コンテナオーケストレーションツール「Kubernetes」をUbuntu上にセットアップしました。その際に構築した環境、手順、トラブル対応などについて解説しております。
CRIにはDocker v20.10、オーバーレイネットワーク機能にはflannelを利用しています。
Hyper-V上にUbuntuを2台用意しまして、マスターノードとワーカーノードを1台ずつセットアップしてから、サンプルとしてnginxコンテナを動かすところまでの内容です。
Kubernetesの構築環境について
構築した環境は以下のとおりです。
サーバは仮想サーバ(Hyper-V)を利用しました。
OSは、私が普段利用していますUbuntuです。
インストールには、便利で確実なkubeadmコマンドを使用して行いました。
各コンポーネントのバージョンは以下のとおりです。
名称 | バージョン | 概説 |
---|---|---|
Ubuntu | 20.04.3 | OS |
Kubernetes | 1.22.2 | Kubernetesプロジェクト |
kube-apiserver | 1.22.2 | Kubernetesのフロントエンド |
kube-controller-manager | 1.22.2 | Kubernetesのコントローラ |
kube-scheduler | 1.22.2 | Kubernetesのスケジューラ |
kubectl | 1.22.2 | Kubernetesのコマンドラインツール |
kubeadm | 1.22.2 | Kubernetes構築ツール |
kubelet | 1.22.2 | ワーカー用エージェント |
kube-proxy | 1.22.2 | ワーカー用ネットワークプロキシ |
etcd | 3.5.0 | キーバリューストア |
Docker | 20.10.8 | Dockerパッケージ |
containerd | 1.4.9-1 | CRI |
flannel | 0.14.0 | オーバーレイネットワーク |
Kubernetesのセットアップ
セットアップの流れは、以下のようになります。
- 仮想マシン作成
- OS(Ubuntu)インストール
- UbuntuのKubernetes用設定
- Docker(CRIとして)のインストールおよび設定
- Kubernetesのインストール
- kubernetesのマスターノード(もしくはワーカーノード)のセットアップ
上の項目の内の1~5(黄色いアンダーライン)は、マスターノードとワーカーノードで同じ手順です。(注:IPアドレスやホスト名など設定内容に関しては異なる部分があります)
以下で各手順を詳しく説明します。
なお、本手順は特に断り書きが無い場合はroot権限で行って下さい。
Kubernetes(マスターノード)の構築
最初はマスターノードからです。
仮想マシン作成
※マスターとワーカー共通の手順
Hyper-Vは、Windows10Pro(バージョン21H1)上のものを使用しました。
最初の1台は新規に仮想マシンを作成してUbuntuのインストールを行いましたが、2台目は仮想マシンのインポート機能を利用して作成(インポートの種類はコピー)しました。もちろん2台ともインストールしても問題ありません。
1台目を作成した際に、作成ウィザードで設定した主な項目は以下のとおりです。
※全部の設定項目ではなく、ポイントになる部分のみ挙げています。
名称 | 設定値 |
---|---|
起動メモリ | 4096MB 「この仮想マシンに動的メモリを使用します」→ON |
仮想ハードディスク | 127GB(デフォルト) |
ネットワークの構成 | ブリッジ接続した仮想スイッチを選択 |
仮想スイッチを作成して、ブリッジ接続にてインターネット接続できるようにしてください。
仮想マシン作成後に、「設定」から「プロセッサ」内の仮想プロセッサの数を「2」に設定します。
OS(Ubuntu)インストール
※マスターとワーカー共通の手順
Ubuntuは、「Ubuntu Server 20.04.3 LTS」のISOイメージをダウンロードしました。
OSインストール時の設定内容は、特に気をつける点などはなく、ほぼデフォルトです。
いくつかポイントになりそうなところを挙げておきます。
- IPアドレスは固定IPを設定(デフォルトGWとDNSサーバの設定も)
- 初期ユーザ作成時にサーバのホスト名を設定
- 「OpenSSH server」のインストールにチェックを入れる
- 「Featured Server Snaps」(追加で入れるパッケージを選択する部分)はチェック無し
UbuntuのKubernetes用設定
※マスターとワーカー共通の手順
Kubernetesを動作させるために必要な設定として、Ubuntuに以下の設定を行います。
- Swapシステム停止
- /etc/hostsファイルへのサーバ追加
以下で説明します。
swapシステム停止
Kubernetesの要件として、Swapの停止があります。
以下のコマンドで停止させてください。
# swapoff -a
停止後は、topコマンドでswap容量がゼロになっていることを確認しましょう。
これだけですとサーバを再起動させるとswapが起動してしまいますので、/etc/fstabファイル内のswap設定に関する行をコメントアウトします。
# vi /etc/fstab
<略>
/dev/disk/by-uuid/9b2893-7d4b-43b1-9dad-xxxxxxxxxxx /boot ext4 defaults 0 0
# /swap.img none swap sw 0 0 (←この行をコメントアウトする)
<略>
※サーバの再起動は後ほど行います
/etc/hostsファイルへのサーバ追加
マスターノードとワーカーノードの名前解決が可能となるように設定します。
DNSなどの他システムですと、DNSにトラブルが発生しますとKubernetesにも影響が出る可能性があります。
ですので、原始的なhostsファイルを利用した方が良いでしょう。
# vi /etc/hosts
<略>
192.168.1.100 master01
192.168.1.101 worker01
※上の内容は一例です。
Ubuntuのインストール時に指定したIPアドレスとホスト名を使用して、すべてのマスターノードとワーカーノードに設定してください。
Docker(CRI機能)のインストールおよび設定
※マスターとワーカー共通の手順
公式手順に従ってDockerをインストールします。
インストール後にcgroupドライバーの設定変更を行います。
Docker(CRIとして)のインストール
DockerをKubernetesのCRIとして利用する場合でも、インストール手順は通常のDockerインストール手順と同様です。
まずはパッケージリストのアップデートを行います。(※古いパッケージの削除はUbuntuインストール直後なので省略)
# apt-get update
Dockerのインストールに必要なパッケージを入れます。
# apt-get install apt-transport-https ca-certificates curl gnupg lsb-release
Dockerの公式GPGキーを追加します。
# curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
Dockerリポジトリを追加します。
# echo \
"deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
再度パッケージリストのアップデートを行います。
# apt-get update
Dockerをインストールします。
# apt-get install docker-ce docker-ce-cli containerd.io
Dockerのインストールはここまでです。
念のため、以下のコマンドにてDockerサービスが起動していることを確認しましょう。
# systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: e
Drop-In: /etc/systemd/system/docker.service.d
mqdocker.conf
Active: active (running) since Wed 2021-08-11 17:33:26 JST; 1 months 16 days
Docs: https://docs.docker.com
Main PID: 1841 (dockerd)
Tasks: 190
CGroup: /system.slice/docker.service
tq1841 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/contain
・・・・・・・
<略>
上記の青線部分が「active (running)」になっていれば起動成功です。
Dockerのcgroupドライバーの設定変更
Dockerはcgroupドライバーとして、デフォルトでは「cgroupfs」を使用しています。
# docker info
<略>
・・・・・・・・・
Server:
Containers: 20
Running: 12
Paused: 0
Stopped: 8
Images: 36
Server Version: 20.10.8
Storage Driver: overlay2
Backing Filesystem: extfs
Supports d_type: true
Native Overlay Diff: true
userxattr: false
Logging Driver: json-file
Cgroup Driver: cgroupfs
Cgroup Version: 1
Plugins:
・・・・・・・・・
<略>
上記出力内容の青枠部分をご確認ください。
一方、Ubuntu20.04.3のinitシステムは「systemd」を採用おり、Kubernetesのcgroupドライバーも「systemd」を使用しています。
このため、CRIであるDockerのcgroupドライバーは「systemd」のほうがシステムが安定する旨の記載がKubernetes公式ドキュメントにありました。
※ドキュメント内の2番目の章「Cgroupドライバー」に記載あり
ですので、以下の手順でDockerのcgroupドライバを「cgroupfs」から「systemd」に変更します。
※Dockerはcgroupドライバとして「systemd」をサポートしています
所定の場所に「daemon.json」ファイルを作成します。
# vi /etc/docker/daemon.json
「daemon.json」ファイルには、以下を記載します。
{
"exec-opts": ["native.cgroupdriver=systemd"]
}
以下のコマンドでディレクトリを作成します。
# mkdir -p /etc/systemd/system/docker.service.d
dockerの再起動を行って、作成した定義を反映します。
# systemctl daemon-reload
# systemctl restart docker
念のため、dockerのcgroupドライバーの設定値を確認してください。
# docker info
<略>
・・・・・・・・・
Server:
Containers: 33
Running: 16
Paused: 0
Stopped: 17
Images: 8
Server Version: 20.10.8
Storage Driver: overlay2
Backing Filesystem: extfs
Supports d_type: true
Native Overlay Diff: true
userxattr: false
Logging Driver: json-file
Cgroup Driver: systemd
Cgroup Version: 1
Plugins:
・・・・・・・・・
<略>
「systemd」に変更されています。
なお、この設定を行わなかった場合は、kubenetesマスター構築時の手順内でエラーになります。
Kubernetesのインストール
※マスターとワーカー共通の手順
本手順のメインとなりますKubernetesのインストールです。
最初に、GoogleのGPGキーを取得します。
# curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add
Kubernetesのリポジトリを追加します。
# apt-add-repository "deb http://apt.kubernetes.io/ kubernetes-xenial main"
パッケージリストのアップデートを行います。
# apt-get update
Kubernetes関連パッケージをインストールします。
# apt install kubeadm kubelet kubectl kubernetes-cni
これでインストールは完了しました。
サーバを再起動して、Kubernetesに必要なサービスが自動的に起動するか確認します。
Kubernetesのマスターノードのセットアップ
※ワーカーノードのセットアップの場合は不要
マスターノードのセットアップは、以下の2つの作業になります。
- kubeadmコマンドによるマスターノードとしてのKubernetesの起動
- 管理者ユーザ環境のセットアップ
- オーバーレイネットワークを制御するflannelのインストール
kubectlコマンドによるマスターとしてのKubernetesの起動
以下のコマンドでKubernetesのマスターノードのセットアップを行います。
# kubeadm init --pod-network-cidr=10.244.0.0/16
オプションとして指定しています「--pod-network-cidr」は、podが使用するネットワークのアドレスです。
上に記載してます「10.244.0.0/16」の値は、後ほど出てきますflannelで作成するオーバレイネットワークのデフォルト値になります。
問題が無いようでしたら、そのままの値をお使いください。
コマンドを実行しますと、画面上に大量のメッセージが出力されます。
最後に以下のようなメッセージが出力されれば正常終了です。
<略>
・・・・・・・・
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.1.100:6443 --token 7ycxxx.xxx372opcxxx \
--discovery-token-ca-cert-hash sha256:xxx692e6ccxxx7667ecbxxxd725727xxx860b61xxx376418cxxx1ecb62xxx38f
途中でエラーメッセージが出力された場合は、内容を確認して原因を取り除いてください。
正常終了メッセージの最後に出力されているメッセージは重要ですので、テキストエディタなどにコピペして保存しておきましょう。
ワーカーノードで実行するコマンドになります。このコマンドを実行することでワーカーのセットアップが完了します。
管理者ユーザ環境のセットアップ
Kubernetesの管理(kubectlなどのコマンドを利用する)をrootユーザで行う場合は、お使いのシェルのプロファイル(bashの場合はホームディレクトリの.bashrc)の最後の行に以下の内容を記載してください。
export KUBECONFIG=/etc/kubernetes/admin.conf
記載したあと、プロファイルを読込むために以下のコマンドを実行します。(シェルがbashの場合)
# source ~/.bashrc
もちろん、ログインし直しでも大丈夫です。
もし上の設定を行わずにkubectlコマンドなどを実行した場合は、以下のようなエラーでコマンドが実行できないはずです。
The connection to the server localhost:8080 was refused - did you specify the right host or port?
もし一般ユーザを管理ユーザにする場合は、対象のユーザでログイン後、以下のコマンドを実行してください。(対象の一般ユーザでのオペレーションになります。)
$ mkdir -p $HOME/.kube
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
$ sudo chown $(id -u):$(id -g) $HOME/.kube/config
flannel(オーバーレイネットワーク機能)のインストール
flannelのインストールはkubectlコマンドにて行います。
コマンドのオプションとして、ネット上に公開されてますflannel公式の定義ファイルを指定します。
公開されているファイルの内容をそのまま使う場合は、以下のコマンドを実行してください。
# kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
定義ファイルを別途ダウンロードする場合や、定義内容を変更して利用する場合などは、curlコマンドなどでファイルをダウンロードして編集した後、kubectlコマンドで反映しても大丈夫です。
その場合は、例えば以下のようにしてください。
# curl https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml -o flannel.yml
入手したflannel.ymlファイルを編集する
# kubectl apply -f flannel.yml
以上でマスターノードのインストールは完了です。
次はワーカーノードのインストールになります。
Kubernetes(ワーカーノード)の構築
最初の方で書きましたKubernetesのセットアップの流れの手順1~5に関しましては、マスターノードと同じですので、ここでは省略させてください。
お手数ですが、上にお戻りになって、「Kubernetesのインストール」まで行った後で以下の手順にお進みください。
こちらから戻れます。
kubernetesのワーカーノードのセットアップ
kubernetesのワーカーノードのセットアップは、マスターノードのセットアップ時に出力されたコマンドを実行するだけです。
本記事の例では、以下の内容になります。
# kubeadm join 192.168.1.100:6443 --token 7ycxxx.xxx372opcxxx \
--discovery-token-ca-cert-hash sha256:xxx692e6ccxxx7667ecbxxxd725727xxx860b61xxx376418cxxx1ecb62xxx38f
ワーカーノードのセットアップに成功しますと、以下のメッセージが出力されます。
<略>
・・・・・・・・・
This node has joined the cluster:
* Certificate signing request was sent to apiserver and a response was received.
* The Kubelet was informed of the new secure connection details.
Run 'kubectl get nodes' on the control-plane to see this node join the cluster.
ワーカーノードのセットアップは以上で終了です。
セットアップ後の動作確認
簡単な動作確認として、以下を行いました。
- マスターノードにて各ノードのステータス確認
- nginxのpodを作成、起動、動作確認
マスターノードにて各ノードのステータス確認
マスターノードで以下のコマンドを実行します。
# kubectl get nodes
以下のような内容が出力されました。
NAME STATUS ROLES AGE VERSION
master01 Ready control-plane,master 13m v1.22.2
worker01 Ready <none> 2m v1.22.2
master01とworker01は、マスターノードとワーカノードに設定した名前です。
両ノードともSTATUSが「Ready」になっています。マスターノードはワーカーノードを正常に認識していることがわかります。
(参考)
ワーカーノードのサービスが起動処理中の場合には、以下のようにSTATUSが「NotReady」になる場合があります。
NAME STATUS ROLES AGE VERSION
master01 Ready control-plane,master 12m v1.22.2
worker01 NotReady <none> 22s v1.22.2
もう少し待ってからステータスを確認しますと、Readyになると思います。(経験上は遅くとも1分以内)
nginxのpodを作成、起動、動作確認
nginxのdockerイメージを使用してポッドを起動してみましょう。
以下の内容のマニフェストファイルnginx.yamlを作成してください。ファイル名は任意です。
apiVersion: v1
kind: Pod
metadata:
name: nginx-test
spec:
containers:
- image: nginx:1.21.3
name: nginx-c
以下のコマンドでKubernetesに登録してみます。
# kubectl apply -f nginx.yaml
pod/nginx-test created
「pod/nginx-test created」と出力されれば成功です。
以下のコマンドで、ポッドが作成されていることを確認します。
# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-test 1/1 Running 0 43s
(参考)
ポッドが起動処理中の場合は、以下のようにSTATUSが「ContainerCreating」になる場合があります。
NAME READY STATUS RESTARTS AGE
nginx-test 0/1 ContainerCreating 0 15s
もう少し待ってからステータスを確認しますと、Runningになると思います。(経験上は遅くとも1分以内)
以下のコマンドで「nginx-test」ポッドの詳細情報を確認してみましょう。
# kubectl describe pod nginx-test
Name: nginx-test
Namespace: default
Priority: 0
Node: kube002/192.168.1.101
Start Time: Mon, 27 Sep 2021 12:14:07 +0000
Labels: <none>
Annotations: <none>
Status: Running
IP: 10.244.1.2
IPs:
IP: 10.244.1.2
Containers:
nginx-c:
・・・・・・・・・・・・・
<略>
出力内容の「IP」のところに、「10.244.1.2」と出力されています。
このIPアドレスは、ポッドが存在するKubernetesの内部ネットワーク内での「nginx-test」ポッドのものです。
curlコマンドで接続してみましょう。
# curl http://10.244.1.2/
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
nginxのデフォルトページのhtmlソースの内容が表示されました。
本記事はここまでとします。
おわりに
これまでは、使い慣れたDockerを直接利用してKubernetesを動かすという安心感で、CRIとしてDockerを使用してきました。
でも、Kubernetesのdockershim手離れの件があってからは、やはりCRIはCRI専門のものを使うのが良いのではないかと考えるようになりました。そっちのほうがあるべき姿だと。
というわけで、現在はCRIとしてcontainerdを使ったKubernetes環境をメインに利用しています。
そちらのほうのインストール手順の記事は近日公開予定です。
最後までお読みいただきありがとうございました!
コメント