こんにちは、Mashです。
本記事は、近年大注目されているコンテナオーケストレーション技術である Kubernetes について、図解と実機確認例を交えて解説するシリーズとなります。
今回は第2回。環境構築回になります。
もし「Kubernetesってなに?」というかたがいましたら、第1回の記事をざっとお読みいただけると嬉しいです。
- K8s環境のMasterとNodeの関係性を理解する
- K8s検証環境を構築できるようになる
※本シリーズはLinuxコマンドやネットワーク、Dockerの基礎知識がある方を前提としています。
それではいきましょう!
環境構築
さっそくK8s環境を構築していきましょう。
今回はRancher(ランチャー)という補助ツールを使います。
実はK8sの環境構築ってめっちゃたいへんなんですが、Rancherを使えば環境構築が簡単にでき、構築後もK8sをGUIで操作できるようになって便利なのです。
前提環境
今回ご紹介する構築手順は、以下が前提となります。
- 用意するマシンはUbuntu Server 20.04 LTS
- サーバ1台の最小構成(MasterとNodeを兼任)
- CPU2コア、メモリ4GB、ディスク20GB
- ノードがインターネットに接続していること
構築後のイメージ図
そして、今回構築する環境イメージを先にご紹介しておきます。

この絵で伝えたいポイントは3点です。
- Ubuntu1台にK8sのMasterとNodeの役割を兼任させます
- MasterがNodeに命令してコンテナなどを展開します
- 私たち人間からMasterへの指示は「kubectl(キューブシーティーエル)」というコマンドラインツールと、「Rancher」というGUIツールを使用します
今後Nodeを追加して複数台構成にも取り組む想定ですが、しばらくは最小構成で進めます。
下準備
それでは環境構築を進めましょう。
まずはUbuntuへSSH接続し、稼働要件設定などのもろもろを調整します。
# ファイアウォール無効化
$ sudo systemctl stop ufw
$ sudo systemctl disable ufw
# swapの無効化
# /etc/fstab を編集↓の行をコメントアウト
/swap.img none swap sw 0 0
# ブリッジ通信に関するカーネルパラメータ変更
$ modprobe br_netfilter
$ sudo sed -ie '$a net.bridge.bridge-nf-call-ip6tables = 1' /etc/sysctl.conf
$ sudo sed -ie '$a net.bridge.bridge-nf-call-iptables = 1' /etc/sysctl.conf
$ sudo sysctl -p
# OS再起動
$ sudo shutdown -r now
Dockerのインストール
つづいてUbuntuにDockerエンジンをインストールします。
以前の記事が参考になるかと思いますので、こちらをご参照ください。
Rancherサーバの起動
DockerがインストールできたらRancherを導入します。Rancher自体もコンテナで提供されています。
$ sudo docker run --privileged -d --restart=unless-stopped -p 4433:443 rancher/rancher
Dockerイメージのpullが始まります。
インターネット回線状況によってはコンテナ起動まで少し時間がかかります。
K8sクラスタの構成
docker run コマンド終了後しばらく待って、MasterノードにWebブラウザでアクセスします。docker run コマンドの-pオプションで4433番ポートを外部公開したので、ここでは
https://<Rancherノードのアドレス>:4433/
がURLになります。
ブラウザアクセスすると↓このようなWelcomeページが表示されます。こちらがRancherのGUI画面です。
Rancherの管理者ユーザ(admin)のパスワードを定義して I agree to… にチェックを入れ [Continue]ボタン をクリックします。

つづいてRancher Server URLを定義します。
ブラウザでアクセスしたアドレスがすでに入力されているはずですので、気にせず [Save URL]ボタンをクリックします。
注意書きにもある通り、このアドレスはKubernetesクラスタ内のすべてのノードから通信可能としておく必要があります。複数NICを持つノードの場合はご注意ください。

ここまでがRancherの初期設定ですね。
クラスタの作成
いよいよK8sクラスタの作成です。
Rancherコンソールのダッシュボード画面が表示されますので、画面右上の [Add Cluster]ボタンをクリックします。

Cluster Typeを選択します。
今回はクラウドサービスと連携などせず、オンプレミスで展開する想定なので [Existing nodes]を選択します。

作成するK8sクラスタの設定を定義します。
まずはCluster名ですね。お好きなものでかまいません。

画面を下にスクロールして、Network Providerを選択します。
今回はCalicoを選択してください。

CNIを選択したらさらに画面をしたにスクロールして、[Next]ボタンをクリックします。

あともう少しです。
前回記事で K8sクラスタ内にはMasterノードとWorkerノードが存在する というお話をしました。
ここ↓の選択肢でいうControl PlaneがMasterノードの役割、WorkerがそのままWorkerノードの役割になります。
etcdはK8sクラスタの情報をためておくデータストアで、管理系コンポーネントの一部になります。
今回はノード1台にすべての役割を兼任させたいのですべてにチェックをいれて、画面下部に表示されるコマンドをコピーします。(チェックをオンオフするたびにコマンド末尾のオプションがかわることをご確認いただけるかと思います)
コマンドをコピーしたら [Done]ボタンをクリックします。

前述コマンドをノード上で実行します。ここからしばらく時間がかかりますので気長にお待ち下さい。
Rancherコンソール上ではmash-clusterが ProvisioningになったりUpdatingになったりErrorになったりしますが、気にせず待ちます。

このように Active になればクラスタ作成が完了です!

kubectlのインストール
K8sクラスタの作成が完了したら、クラスタを操作するためのコマンドラインインターフェースツールである kubectl を導入しましょう。
もちろんノード外からもコマンド操作は可能ですが、今回は用意したノードにインストールしてしまいます。
# バイナリをダウンロードして移動
$ curl -LO "https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl"
$ chmod +x ./kubectl
$ sudo mv ./kubectl /usr/local/bin/kubectl
# 動作確認
# クライアントバージョンが表示されればOK
$ kubectl version --client
Client Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.4", GitCommit:"d360454c9bcd1634cf4cc52d1867af5491dc9c5f", GitTreeState:"clean", BuildDate:"2020-11-11T13:17:17Z", GoVersion:"go1.15.2", Compiler:"gc", Platform:"linux/amd64"}
無事kubectlコマンドが実行できましたが、まだこれだけでは足りません。どのK8sクラスタが操作対象かを登録してあげる必要があるのです。
まずは下記コマンドでconfigファイルを作成します。
# .kubeディレクトリを作成しconfigファイルを作成
# .kubeは隠しディレクトリのため要注意
$ mkdir ./.kube/
$ touch ./.kube/config
Webブラウザに操作を戻し、作成したK8sクラスタ名をクリックすると↓このような画面が表示されます。
画面右上の [Kubeconfig File]ボタンをクリックします。

表示された内容すべてをさきほど作成したconfigファイルに貼り付けます。
ページ下部に [Copy to Clipboard]ボタンがあるので使ってください。

configファイルに内容を貼り付けたら、もう一度動作確認コマンドを実行します。
「Server Version」がエラーなく取得できていればOKです。
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.4", GitCommit:"d360454c9bcd1634cf4cc52d1867af5491dc9c5f", GitTreeState:"clean", BuildDate:"2020-11-11T13:17:17Z", GoVersion:"go1.15.2", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"19", GitVersion:"v1.19.4", GitCommit:"d360454c9bcd1634cf4cc52d1867af5491dc9c5f", GitTreeState:"clean", BuildDate:"2020-11-11T13:09:17Z", GoVersion:"go1.15.2", Compiler:"gc", Platform:"linux/amd64"}
動作確認
さて!
それでは環境構築がおわりましたので動作確認してみましょう!
ちょっとまだ何が何やらでしょうが、いったん進めてください。
# Podの起動
$ kubectl run --namespace=default --image=nginx:latest --restart=Never nginx01
pod/nginx01 created
# Pod起動状況を確認
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx01 1/1 Running 0 6m37s 10.42.32.152 k8s-master01 <none> <none>
# Serviceを作成し、Podを外部公開
$ kubectl expose pods nginx01 --type=NodePort --port=80 --name=nginx-nodeport01
service/nginx-nodeport01 exposed
# 外部公開されたポート番号を確認
# 今回は 31968 番ポートがバインドされている
$ kubectl get services | grep nginx-nodeport01
nginx-nodeport01 NodePort 10.43.241.142 <none> 80:31968/TCP 26s
Webブラウザの操作に戻って、
http://<ノードのIPアドレス>:<上記で確認したポート番号>
へアクセスします。

Nginxコンテナへアクセスすることができました!
ちなみにRancherコンソールを覗いてみると、このようにコンテナが展開されている状況をGUIで確認することができます。
$ kubectl run で起動した「nginx01」がRunningになっていることが確認できますね。

最後に、次回以降のために環境をお掃除しておきます。
# podの削除
$ kubectl delete pods nginx01
pod "nginx01" deleted
# Serviceの削除
$ kubectl delete services nginx-nodeport01
service "nginx-nodeport01" deleted
まとめ
ちょっとたいへんだったかもしれませんが、これでK8s検証環境の準備が整いました。
「Pod」や「Service」という新しい言葉がでてきたり、kubectlコマンドがdockerコマンドと似ているようで違っていたりと、細かな点で???な状態かと思いますが次回以降でじっくり解説していきますね。
もし

環境構築がうまくいかない!

いまいちイメージがわかなくて理解できない
などありましたら、Twitterからご連絡いただければと思います。
最大限対応します。(解決を保証することはできません笑)
今回は以上です。
それじゃあまたね。