Win10 の WSL2 に Ubuntu をインストールして Docker 上の minikube で Flask アプリを Hello World
Kubernetes を勉強しようと思って手元の Windows に minikube の環境を構築したら、その過程でいろいろなエラーに遭遇したので解決方法を添えて手順をまとめた。
構築した環境は手元のノート PC (Windows 10 Home 64bit) に WSL2 をインストールし、それで Ubuntu を動かして、その上の Docker で minikube を動かすというもの。試しに簡単な Flask アプリをデプロイしてみた。
WSL2 の有効化と Ubuntu のインストール
Windows 上で Ubuntu を動かすために、WSL2 を有効にする。
手順は Microsoft 公式のドキュメント に従えばできた。
ただし最後、Windows Store から Ubuntu 20.04 をインストールしていざ起動してみたところ、ターミナルが立ち上がってエラーコード 0xc03a001a
のエラーが発生した。これは
WSL2 にしたいのにエラーが出る問題 - Qiita に従い、フォルダーのプロパティから圧縮設定を解除したら回避できた (後で気づいたが、上に挙げた Microsoft のドキュメントにもエラーコードこそなかったが対処方法は書いてあった)。
これで Windows10 の WSL2 で Ubuntu が起動できるようになった。
Ubuntu に Docker をインストール
続いて Ubuntu に Docker をインストールする。
これも Docker 公式のドキュメント に従ってインストールした。
ただし動作確認のために適当な Dockerfile をビルドしようとしたところ、cannot find cgroup mount destination: unknown
というエラーが出た。このエラーは
WSL2 時の Dockerコンテナの起動について – すらりん日記 に従って次のコマンドを打って回避した。
sudo mkdir /sys/fs/cgroup/systemd sudo mount -t cgroup -o none,name=systemd cgroup /sys/fs/cgroup/systemd
これで WSL2 上の Ubuntu で Docker が動くようになった。
Ubuntu に minikube をインストール
これも基本は Kubernetes の公式ドキュメント に従ってインストールする。
今回は Docker で minikube を動かすので CPU の仮想化支援機構は必須ではない。ので grep -E --color 'vmx|svm' /proc/cpuinfo
の結果が空でも OK. 手順にある「ハイパーバイザーのインストール」も必要なし。
今回は 直接ダウンロードによるMinikubeのインストール の手順を実行した。
そして minikube の起動。Docker コンテナとして minikube を動かすので
minikube start --driver=docker
で起動する。
動作確認として minikube status
を打ってみる。
$ minikube status minikube type: Control Plane host: Running kubelet: Running apiserver: Running kubeconfig: Configured
ここまでで WSL2 上の Ubuntu で Docker コンテナとして minikube を動かせた。
Flask アプリを用意
minikube で簡単な Flask アプリを動かしてみる。Flask の公式ドキュメント にある次のサンプルコードを使う。ファイル名は app.py とする。
from flask import Flask, escape, request app = Flask(__name__) @app.route('/') def hello(): name = request.args.get("name", "World") return f'Hello, {escape(name)}!'
またこのアプリを動かすコンテナをビルドするための Dockerfile を用意する。
FROM python:3 RUN pip install flask COPY ./app.py /app.py ENV FLASK_ENV=/app.py CMD ["flask", "run", "--host", "0.0.0.0"]
これらのファイルを
~/flast-test/ +- app.py +- Dockerfile
というように配置する。
Flask アプリをビルド
このコンテナイメージをビルドしたいが、単に docker build
しても後の手順がうまくいかない。いくつかポイントがあるので一つずつ説明していく。
Docker ホストの向き先の切り替え
まず、minikube は組み込みの Docker エンジンを持っていて、Kubernetes の各種デーモンやデプロイされるコンテナはこの minikube 組み込みの Docker エンジンが利用される。この組み込みの Docker エンジンは先に Ubuntu 自体にインストールした Docker とは別のものである。
この後の手順ではコンテナレジストリを使わずに、ローカルに保存されているコンテナイメージを使いたいので、minikube 組み込みの Docker エンジンの方にデプロイしたいコンテナイメージを登録する。
そのために docker
コマンドで参照する Docker ホストを minikube のものに変更したい。それは次のコマンドで行う。
eval $(minikube -p minikube docker-env)
このコマンドを実行すると環境変数 DOCKER_HOST
や他の必要な変数がセットされ、docker
コマンドの向き先が minikube のものになる。
minikube の DNS サーバーの変更
そして docker build
を行おうとすると、以下のようなエラーが出る。IP アドレスは変わり得る。
Get https://registry-1.docker.io/v2/: dial tcp: lookup registry-1.docker.io on 192.168.49.1:53: read udp 192.168.49.2:37dd860911922e: Download complete
これは minikube 内の DNS サーバーの設定がまずいので、minikube コンテナに入って /etc/resolv.conf
を書き換える。それには kubernetes - Error response from daemon: Get https://registry-1.docker.io/v2/: dial tcp: lookup registry-1.docker.io...i/o timeout - Stack Overflow を参考に次の手順で行う。
minikube ssh # 以下は minikube コンテナ内での作業 sed -E 's/nameserver .*/nameserver 8.8.8.8/' /etc/resolv.conf > resolv.conf sudo cp resolv.conf /etc/resolv.conf exit
これでコンテナのビルドができるようになる。
ビルド
Flask アプリを動かすコンテナをビルドしてイメージを minikube 内の Docker エンジンに登録する。
docker build ~/flask-test -t flask-test
Flask アプリを minikube にデプロイ
ようやくビルドしたコンテナを Kubernetes にデプロイできる。
まずは次のような Deployment を定義する yaml ファイルを用意する。これを ~/flask-test/deployment.yaml
として保存する。
apiVersion: apps/v1 kind: Deployment metadata: name: flask-test labels: app: flask spec: replicas: 3 selector: matchLabels: app: flask template: metadata: labels: app: flask spec: containers: - name: app image: flask-test:latest imagePullPolicy: Never ports: - containerPort: 5000
コンテナイメージは先ほどビルドしたものを使いたいので imagePullPolicy: Never
としている。こうするとリモートのレジストリから Pull せずに常にローカルのイメージを使うようになる。
またレプリカ数は 3 にしている。
これを次のようにして Kubernetes に適用する。
kubectl apply -f ~/flask-test/deployment.yaml
うまくデプロイできていれば次のような結果が得られる。
$ kubectl get deployments flask-test NAME READY UP-TO-DATE AVAILABLE AGE flask-test 3/3 3 3 10s $ kubectl get pods -l app=flask NAME READY STATUS RESTARTS AGE flask-test-7d5c9c88b-2thh4 1/1 Running 0 10s flask-test-7d5c9c88b-52j79 1/1 Running 0 10s flask-test-7d5c9c88b-j6rpl 1/1 Running 0 10s
さらにこれらのコンテナに HTTP でアクセスできるように Service を定義する。
kubectl expose deployment flask-test --type NodePort
サービスが登録されていることを確認する。
$ k get services flask-test NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE flask-test NodePort 10.103.56.173 <none> 5000:31859/TCP 10s
Flask アプリへアクセス
ここまで来ればデプロイした Flask アプリにアクセスできる。まずは URL を調べるために次のコマンドを実行する。
minikube service list |-------------|------------|--------------|---------------------------| | NAMESPACE | NAME | TARGET PORT | URL | |-------------|------------|--------------|---------------------------| | default | flask-test | 5000 | http://192.168.49.2:31859 | | default | kubernetes | No node port | | kube-system | kube-dns | No node port | |-------------|------------|--------------|---------------------------|
http://192.168.49.2:31859
でサービスが公開されていることが分かるので次のようにして Flask アプリにアクセスできる。
curl http://192.168.49.2:31859 Hello, World!
めでたしめでたし。
Ubuntu とか Docker いらなかったかもしれない
と、手順をまとめてみて思ったが、Ubuntu とか Docker とかいらなかったかもしれない。
手元の Windows 環境を汚したくなかったので独立した Linux 環境上で Kubernetes を試したかったのだが、Docker コンテナとして minikube が動くなら Docker Desktop for Windows でもよかったかも。それか Ubuntu で直接 minikube を動かすか。
これは次回ということで。
まとめ
- WSL2 と Docker を駆使して minikube で Flask アプリを動かした
- いろいろエラー出たがエラーメッセージでググったら全部解決した
- もうちょっとシンプルな構成ができたかもしれない
参考
- Windows Subsystem for Linux (WSL) を Windows 10 にインストールする | Microsoft Docs
- WSL2 にしたいのにエラーが出る問題 - Qiita
- Ubuntu — Docker-docs-ja 1.13.RC ドキュメント
- WSL2 時の Dockerコンテナの起動について – すらりん日記
- Minikubeのインストール | Kubernetes
- Flask | The Pallets Projects
- kubernetes - Error response from daemon: Get https://registry-1.docker.io/v2/: dial tcp: lookup registry-1.docker.io...i/o timeout - Stack Overflow