WindowsのブラウザーからWSL Ubuntuに作成したKubernetes（minikube）クラスター内のPod（Webサーバー）にアクセスする（その１）

2025/01/28：WSL 2.3.26.0、および Ubuntu 24.04.1 LTS で本稿手順が動作する事を確認

## Windows で体験する Kubernetes（コンテナ）の最初の一歩！

本稿はタイトル通りの事を実施する内容ですが、コマンドなど詳しく手順を記述しているため、Kubernetes やコンテナを試してみたいけど検索したら様々なソリューションがヒットしすぎて訳が分からないという方にもお薦めの内容となっており、ローカルの Windows環境でササッっと手軽に試していただけます。

比較的新しい Windows 10（Windows 10 バージョン2004 OSビルド19041 コードネーム20H1 以降）または Windows 11 が使えればすぐに実施できます。
（ Windowsのバージョン確認はコマンドプロンプトで winver ）

だたし、**Kubernetes やコンテナ（Docker）についての知識がない場合は、事前にそれらの概要を把握してから**実施してください。

本稿で扱う主なコンポーネントは Windows WSL Ubuntu と Docker、およびコンテナオーケストレーションは minikube（ https://minikube.sigs.k8s.io/docs/ ）を使用した構成になります。minikube は名前の通り Kubernetes の小さくて軽量なコンテナオーケストレーション環境であり、開発時の単体テストなどに適したツールです。通常 Kubernetes 環境は複数のノード（OS区画）から構成され、全体を制御するマスターノードや、アプリケーションを動かすワーカーノードが必要となりますが、本稿では Docker を使って Kubernetes 環境（minikube）を構成します。

以下 Docker と Kubernetes などを説明しているリンクです。世の中にはもっと分かり易く解説されているコンテンツがいっぱいあると思うので色々検索してみてください。。
**Docker とは**：https://www.redhat.com/ja/topics/containers/what-is-docker
**Kubernetes とは**：https://www.redhat.com/ja/topics/containers/what-is-kubernetes

WSL の概要も以下リンクなどで
**Windows Subsystem for Linux (WSL) とは何ですか。**：https://learn.microsoft.com/ja-jp/windows/wsl/faq

## 前提環境
本稿検証の前提環境は Windows 10 バージョン 2004 以降 (ビルド 19041 以降) または Windows 11 です。

また WSL 導入後の minikube の前提は以下の通りとなっています。
2 CPUs or more
2GB of free memory
20GB of free disk space
Internet connection

比較的最近の Windowsをギリギリのリソースで動作させていなければ大抵大丈夫だと思います。


## Windows の事前準備
「コントロールパネル - プログラムと機能 - Windows の機能の有効化または無効化」で（コントロール パネルの表示はファイルエクスプローラーに、コントロール パネル と入力）、**「仮想マシン プラットフォーム」および「Linux 用 Windows サブシステム」にチェック**を入れ OS の指示に従い必要に応じて再起動を行います。
![クリップボード01_2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475210/a144cf88-d7d7-88f8-027a-3ca0c34aeb88.jpeg)
**※ Hyper-V は特に必要ありません。** 私は VMware Workstation Player も使用しているため、Hyper-V は使用しないのと同時に以下の点に注意しています。
・WSL を起動する前に VMware Workstation Player のゲストOS の電源を切る
・上記の逆で、VMware を起動する前には WSL をシャットダウンする
・VMware Workstation Player の設定で「Intel VT-x/EPTまたはAMD-V/RVIを仮想化」のチェックを外す
・**もしVMware Workstation Player 上の VM で Windows を動かし、その WIndows の 中の WSL で本稿の手順を実施したい場合は、上記の逆で「Intel VT-x/EPTまたはAMD-V/RVIを仮想化」のチェックが必要になります。**

## 以降の手順について
記述している手順には分かり易いようにプロンプトの文字（＄ など）が含まれていますが、**コマンドのみを１行づつ**コピー＆ペーストして実施してください。

## WSL の設定とUbuntu のインストール
コマンドプロンプトか PowerShell を管理者で開いて WSL のアップデートを行います。
```
PS C:\> wsl --update
```
WSL のアップデートが終われば WSL のバージョンが 2 以上になります。
```
PS C:\> wsl --version
```
現在利用可能なディストリビューションが確認できます。
```
PS C:\> wsl --list --online
インストールできる有効なディストリビューションの一覧を次に示します。
'wsl.exe --install <Distro>' を使用してインストールします。

NAME                                   FRIENDLY NAME
Ubuntu                                 Ubuntu
Debian                                 Debian GNU/Linux
kali-linux                             Kali Linux Rolling
Ubuntu-18.04                           Ubuntu 18.04 LTS
Ubuntu-20.04                           Ubuntu 20.04 LTS
Ubuntu-22.04                           Ubuntu 22.04 LTS
OracleLinux_7_9                        Oracle Linux 7.9
OracleLinux_8_7                        Oracle Linux 8.7
OracleLinux_9_1                        Oracle Linux 9.1
openSUSE-Leap-15.5                     openSUSE Leap 15.5
SUSE-Linux-Enterprise-Server-15-SP4    SUSE Linux Enterprise Server 15 SP4
SUSE-Linux-Enterprise-15-SP5           SUSE Linux Enterprise 15 SP5
openSUSE-Tumbleweed                    openSUSE Tumbleweed
```
このままコマンドラインからディストリビューションを指定してインストールする事も出来ますが、筆者や周辺メンバーの経験から Windows設定のアプリメニューでの表示に矛盾が出る事もあったため、Microsoft Store から 入手する方法をお薦めします。

スタートメニュー **Microsoft Store で Ubuntu を検索**して入手します。Ubuntu のバージョンは最新の 22.04.xx を選択します。

![クリップボード02.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475210/eed539e6-9312-e2dc-112c-5a6422d88f7b.jpeg)

Ubuntu が導入されたら WSL で Ubuntu を起動する準備が整いました。Windows のメニューに Ubuntu が追加されているので起動して root 以外のユーザー、パスワードを設定します。

先ほど操作したコマンドプロンプトで WSL の状態を確認します。
```
PS C:\> wsl -l -v
  NAME            STATE           VERSION
* Ubuntu-22.04    Running         2
```
ちなみに Ubuntu の内部で設定を変えたのにうまく反映されない場合や、確実に Ubuntu WSLをシャットダウンしたい場合は以下のコマンドを使用します。
```
PS C:\> wsl --shutdown
```

## 余談：WindowsファイルエクスプローラーからUbuntuのファイルを編集
Windows WSLのメリットのひとつとして、ファイルエクスプラーラーから Linuxのファイルシステムに直接アクセスできる事があげられます。
<font color="Orange">（ペンギンアイコンのクリックがエラーになる場合はファイルエクスプローラーに &yen;&yen;wsl$ と直接入力すればアクセスできます。**この記事のコピーではなく、円円wslドル と直接手入力してください**。ショートカットを作っておくと便利です）</font>
![クリップボード03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475210/1b78b14c-1c0e-6281-3317-9254cc8f95ce.jpeg)

ファイルエクスプローラーから直接アクセス出来て大変便利なのですが、手作業でテキストファイルを作成する場合は、Linux側で echo aaa > test.txt というように中身を伴って作成した方が良いでしょう。
Windowsファイルエクスプラーラーから新規作成（または Linux側の touchコマンドで空のファイル作成）してそのまま Windowsのメモ帳などで編集保存した場合は、改行コードが Windows標準の CRLF となってしまい、yamlファイルなどの内容を何度確認しても何故か実行エラーになるといった問題が発生します。yaml などの設定ファイル類の保存時には改行コードを Linux標準の LF に（文字コードは BOM なし UTF-8 に）するよう心掛ける事で予期せぬ問題の回避に繋がります。

## Docker のインストール
**もし Dockerの知識がないという方は、必ず Dockerの概要を理解してから進めてください。**
起動した Ubuntu に Docker 公式ドキュメント（ https://docs.docker.com/engine/install/ubuntu/ ）の手順で Docker をインストールします。
```
まずは更新
$ sudo apt update
```
```
インストールに必要なパッケージ
$ sudo apt-get install ca-certificates curl gnupg
```
```
Docker の公式 GPG キー
$ sudo install -m 0755 -d /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
$ sudo chmod a+r /etc/apt/keyrings/docker.gpg
```
```
Docker のパッケージリポジトリを追加 echoからすべてコピーしてペースト
$ echo \
  "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
```
```
最新版 Docker のインストール（ Docker Buildx、Docker Compose は省略 ）
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io
```

上記手順でセットアップしたWSL2 Ubuntu環境は systemd が標準になっているはずなので **systemctl コマンドが使用できます**。
Docker サービスを起動します。
```
$ sudo systemctl start docker
```
確認のために HelloWorld コンテナを run してみます。
```
$ sudo docker run --rm hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
・・・<省略>・・・
Hello from Docker!
This message shows that your installation appears to be working correctly.
・・・<省略>・・・
```
以降 sudo なしで docker コマンドを使用するために Ubuntu 実行ユーザーを docker グループに追加します。
```
$ sudo usermod -aG docker $USER

設定を有効にするため一旦 Ubuntu を exit
$ exit

Ubuntu 再起動後は Docker の起動も忘れずに
```
Ubuntu 起動時に Dockerのサービスも自動起動したい場合は登録しておきます。
```
$ sudo systemctl enable docker
```
自動起動の設定を反映させるためには WSL のシャットダウンが必要
```
PS C:\> wsl --shutdown
```

ここまでの手順で Docker を利用する環境が整いました。続いて minikube のインストールを行います。

## minikube のインストール
**もし Kubernetes（minikube）の知識がないという方は、必ず Kubernetes（minikube）の概要、特にコンテナ（Docker）との関係を理解してから進めてください。**
minikube に関するコマンドは基本的にこのドキュメント（ https://minikube.sigs.k8s.io/docs/ ）を参照しています。

minikube の前にクラスターの制御を行うために必要となる kubectl を入れておきます。
```
$ curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
$ sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
```
minikube のインストール
```
$ curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
$ sudo install minikube-linux-amd64 /usr/local/bin/minikube && rm minikube-linux-amd64
```
## minikube の起動
クラスターの作成、起動はこのコマンドだけで行えます。最初の実行時には必要となるコンテナイメージの取得や、クラスタの作成に時間を要します。クラスター名と namespace はそれぞれ "minikube" と "default" になります
```
$ minikube start
```

## クラスターにアプリ（Pod）をデプロイ
minikubeのクラスターが起動したら何か動かしてみましょう。
kubectl コマンドで 軽量Webサーバーの nginx を Pod として動かして（デプロイして）みます。**本稿の手順は全ての設定がデフォルト値で YAML 定義も使用しない最小限の手順です**。
公開されている nginx のコンテナイメージがクラスターに pull された後、mynginx という名前でデプロイされます。標準ポートの 80 で動作します。
```
$ kubectl create deployment --image nginx mynginx
```
デプロイメントのコマンドの後に Pod の状態を確認します。
```
$ kubectl get pods
NAME                       READY   STATUS              RESTARTS   AGE
mynginx-6cdf457c5f-4xtr6   0/1     ContainerCreating   0          10s

$ kubectl get pods
NAME                       READY   STATUS    RESTARTS   AGE
mynginx-6cdf457c5f-4xtr6   1/1     Running   0          23s
```
上記２回目のように STATUS が Running になっていれば正常に動作しています。

この nginx の Pod にアクセスするため、サービスを定義します。
```
$ kubectl expose deployment mynginx --port 80 --type=NodePort
$ kubectl get service
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)        AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP          20m
mynginx      NodePort    10.111.35.125   <none>        80:30563/TCP   10s
```
ここで表示される 10. のネットワークは、自動的に割り振られたminikubeクラスター内のネットワークです。

デプロイされた nginxは、minikubeのクラスター内のワーカーノード（マスターノードと兼用）上で動作しています。
以下コマンドでそのノードの情報が表示されます。
```
$ kubectl get nodes -o wide
NAME       STATUS   ROLES           AGE    VERSION   INTERNAL-IP    EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION                       CONTAINER-RUNTIME
minikube   Ready    control-plane    30m   v1.28.3   192.168.49.2   <none>        Ubuntu 22.04.3 LTS   5.15.146.1-microsoft-standard-WSL2   docker://24.0.7
```
表示されたノードで本当に nginxが動いているかを確かめます。先ほど定義したサービスポートと組み合わせて curl コマンドでアクセスします。（**実際のコマンドラインの表示結果に置き換えて実行してください**）
```
$ curl 192.168.49.2:30563

<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title> 以下省略
```

nginx からのレスポンスで正常に動作している事がわかりました。先ほどクラスターに定義したサービスに割り振られたポート番号30563が、クラスタ内のノードで動作する pod のポート番号80（ pod 内で動作する nginxコンテナのポート番号80 ）に繋がるため、minikubeクラスタの外の WSL Ubuntuからアクセスできました。

## Windows 上のブラウザーからのアクセス

次にWSL Ubuntu の更に外の Windowsからはアクセスできるでしょうか？
実はWindows 10 バージョン 2004以降からは、Windowsから WSL に localhost（127.0.0.1）でアクセス可能となっています。
ただし minikubeクラスターにアクセスするためにはもう一段ポート連携が必要になります。
```
$ minikube service mynginx --url
http://127.0.0.1:45103
❗  Because you are using a Docker driver on linux, the terminal needs to be open to run it.
```
この状態で表示されたURLにWindows上のブラウザーからアクセスしてみます。確認後は Ctr+c で終了。

![nginx.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/475210/c9ac4aae-22bb-4262-dac1-84a4fba7a3a2.jpeg)

通常WSL2 Ubuntuを導入した状態では localhost（127.0.0.1）でのアクセスが true になっていますが、何か別の機能の導入設定などで知らない間にアクセスできない定義（ localhostForwarding=false ）になってしまう事があるようです。Windowsから localhost（127.0.0.1）でアクセスできない場合は、「C:\Users\ユーザー名\.wslconfig」の設定を確認してください。localhostForwarding を true に設定する必要があります。
.wslconfig
[wsl2]
localhostForwarding=true

WSL での詳細設定の構成：https://learn.microsoft.com/ja-jp/windows/wsl/wsl-config

## minikube の停止、削除
```
$ minikube stop
stop のみであれば次回 start 時は前回の状態が保持されます。
```
再度 minikube start をすれば Pod や取得したコンテナイメージなど直前のクラスター状態が維持されます。
```
$ minikube delete
```
minikube delete 後の minikube start ではクラスターが初期状態になります。


## その１ はここまで
Windows上のブラウザーから minikube内の Podにアクセスできたところまでで、Kubernetes（コンテナ）体験の最初の一歩的な内容は修了となります。記述の手順通り問題なく実施できた方は簡単に感じたかもしれませんが、実際の商用クラウドの本番環境においても、各コンポーネントの理解は大変重要になります。基本的な仕組みや流れを学習したい時に、いきなりクラウド環境で試してしまうと、さらにクラウドの知識も要求されてしまい、自分で入力しているコマンドがどのレイヤーのどのコンポーネントに作用しているのか理解が追い付かずに混乱しているようなメンバーを度々見かけてきました。本稿ではコンポーネントの理解に重点を置いて出来るだけ簡単なコマンドを心掛けていますが、実際のシステムでは各コンポーネント毎に多様なコマンドを使いこなす必要があったり、デプロイメントで複雑な YAML 定義を作成する局面が多くあります。
コンテナ、Kubernetes に触れるタイミングがなかった方々の第一歩として、コンポーネントの関係や大まかな流れを理解するために本稿がその一助となれば幸いです。

次回「[その２](https://qiita.com/SHIRANO/items/881ad2f2d09e9ca02475)」は Python の Webアプリ（Hello World 的な）を自作のコンテナに組み込んで、今回構築した minikubeクラスター内での動作、およびクラスター外からのアクセスを確認しますので引き続きお試しいただければと思います。