inductor's blog

nothing but self note :)

WSL2 + Docker Desktop for Windows な環境で minikube を動かす

はじめに

お久しぶりです。転職してmacを使わない生活を続いているのですが、WSL2上でminikubeを動かそうと思ったら若干手間取ったのでメモがてら手記として残します。

WSL2とは

WSL2は、Windows 10上にて既にWSL(Windows Subsystems for Linux)として知られている機能の後継版です。

追記(2020/6/29): WSL2 + Minikubeに関するIssueがCloseされ、v1.12.0-beta.0以降では何も意識しなくてもこれが使えるようになったみたいです。

WSLのおさらい

従来のWSLではLXCoreを用いてLinuxのカーネル命令をWindowsのカーネル命令に変換することによって、Windows上で動くプロセスなのにLinuxのように動く環境を作り出していました。

このときLXCoreはLinuxカーネルのエミュレーションを行っているのですが、システムコールの種類に制限があったり、そもそも(特にファイルシステムI/O)パフォーマンスが非常に悪いなどの理由から、いまいち開発環境として浸透しきらなかった経緯があります。その一方で、Windowsで直接Linuxコマンドを実行でき、ファイルの閲覧もできるという点において非常に優れた仕組みでもあり、GitHubのIssueには多数の機能リクエストが提案されていました。

github.com

WSL2の仕組み

WSL2では、従来のようにWindows環境で全部頑張るのではなく、軽量なVMを立ち上げてその中でLinuxを動かすように方針を変えたようです。

カーネルも従来のように再実装するのではなく、Linuxカーネルをフォークする形でGitHub上にも公開されています。

github.com

VMなのにネットワークやボリュームがホスト側と同じものが使えるという変態仕様になっているのですが、目に見えてパフォーマンスが向上していて非常に素晴らしいなと思っています。

Docker Desktop for Windows with WSL2

Docker Desktop for WindowsのWSL2対応は既に実装が終わっていて、Edgeチャンネルのクライアントを導入すれば誰でも使うことができます。WSL2自体もまだ正式リリースはされていませんが、Insider Previewをサブスクライブすれば誰でもかんたんに利用することができます。

WSL2とDockerで何が変わるのか

  1. Hyper-Vが要らなくなります

つまり、ProじゃなくてHomeでもDockerが動かせるようになります!神対応

  1. DockerをTLSでExposeしなくても普通にLinuxと同じような形で使うことができます

  2. Docker Composeが使えるようになります

今までは深遠な理由によりまともに動かなかったDocker Composeが、ようやくDocker for Windows + WSL2によって動くようになります。うれしい

minikube on Docker for Windows with WSL2

minikubeはローカル環境でKubernetesクラスターを作成するためのツールです。

事前準備

ストアからWSLのUbuntuを入れ、WSL2化を済ませておきます。

kubectlや必要になりそうなツールは適宜入れておきましょう。

minikubeで環境の作成

minikubeで環境を作るためにはドライバーを選択する必要があるのですが、ここではDockerを使います。

$ minikube start --driver=docker --memory=4g
😄  Ubuntu 20.04 上の minikube v1.9.2
✨  Using the docker driver based on user configuration
👍  Starting control plane node m01 in cluster minikube
🚜  Pulling base image ...
🔥  Creating Kubernetes in docker container with (CPUs=2) (8 available), Memory=4096MB (25509MB available) ...
🐳  Docker 19.03.2 で Kubernetes v1.18.0 を準備しています...
    ▪ kubeadm.pod-network-cidr=10.244.0.0/16
🌟  アドオンを有効化しています: default-storageclass, storage-provisioner
❗  'default-storageclass' を有効にする際にエラーが発生しました。running callbacks: [Error making standard the default storage class: Error listing StorageClasses: Get https://172.17.0.2:8443/apis/storage.k8s.io/v1/storageclasses: dial tcp 172.17.0.2:8443: i/o timeout]

storageclassを有効化するフェーズでエラーになりました。どうやらkube-apiserverに接続できていないようです。コンポーネントが同展開されているか調べてみましょう。

$ docker ps
CONTAINER ID        IMAGE                                COMMAND                  CREATED             STATUS              PORTS                                                                           NAMES
ad2d168e8a14        gcr.io/k8s-minikube/kicbase:v0.0.8   "/usr/local/bin/entr…"   3 minutes ago       Up 3 minutes        127.0.0.1:32773->22/tcp, 127.0.0.1:32772->2376/tcp, 127.0.0.1:32771->8443/tcp   minikube

どうやらkube-apiserverのポートは32771のようですね。

.kube/configを変えてみましょう。

apiVersion: v1
clusters:
- cluster:
    certificate-authority: /home/kela/.minikube/ca.crt
    # server: https://172.17.0.2:8443 # コメントアウト
  server: https://localhost:32771
  name: minikube

KubernetesのAPIを叩いてみます。

$ kubectl get node
NAME       STATUS   ROLES    AGE     VERSION
minikube   Ready    master   7m20s   v1.18.0

とりあえずノードが見えるところまでは確認できました!

Podも作ってみます。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
$  kubectl apply -f nginx.yaml
deployment.apps/nginx created
$ kubectl expose deploy/nginx --port=80
service/nginx exposed
$ kubectl port-forward svc/nginx 8080:80 &
Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80
Handling connection for 8080
$ curl localhost:8080
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    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>

ちゃんと動いてそうですね。

最後はお掃除したらおわり。

$ kubectl delete deployment nginx
$ kubectl delete svc nginx

注意点

この対応はまだ完璧ではなく、今後も使い勝手が変わっていくものと予想されます。下記Issueをウォッチしておくと良さそうです。

github.com

というわけで今日はここまで。ありがとうございました。