0xf

日記だよ

WSL2 + Docker 環境で minikube が起動しなくなった話(Docker volume のゴミが原因だった模様)

起きていた問題

WSL2 上の Ubuntu 24.04 で Docker driver を使って minikube を起動しようとすると、 kubeadm の初期化フェーズで毎回失敗するようになりました。

代表的なエラーは次のようなものです。

[certs] Using existing ca certificate authority  
error execution phase certs/apiserver-kubelet-client:  
x509: certificate signed by unknown authority (minikubeCA)

加えて、

  • /var/lib/minikube/etcd is not empty と警告される
  • kube-apiserver が起動しない
  • kubectl で API Server に接続できない

といった症状が同時に発生していました。

minikube delete や ~/.minikube の削除をしたり、cgroup2 の有効無効切り替えたり試行錯誤をしながら割と苦労したのでメモしておきます。

最初はネットワークを疑ったが違った

最初は、localhostIPv6(::1)解決されて Windows 側に流れていておかしなことになってるのでは、という疑いをもっていました。

見た目がこんな感じだったので...

$ minikube start
😄  minikube v1.37.0 on Ubuntu 24.04 (amd64)
✨  Automatically selected the docker driver
📌  Using Docker driver with root privileges
👍  Starting "minikube" primary control-plane node in "minikube" cluster
🚜  Pulling base image v0.0.48 ...
💾  Downloading Kubernetes v1.34.0 preload ...
    > preloaded-images-k8s-v18-v1...:  337.07 MiB / 337.07 MiB  100.00% 21.47 M
    > gcr.io/k8s-minikube/kicbase...:  488.52 MiB / 488.52 MiB  100.00% 9.05 Mi
🔥  Creating docker container (CPUs=2, Memory=6000MB) ...
🐳  Preparing Kubernetes v1.34.0 on Docker 28.4.0 ...
🔎  Verifying Kubernetes components...
    ▪ Using image gcr.io/k8s-minikube/storage-provisioner:v5
E0105 06:05:28.002428    1341 start.go:937] failed to get current CoreDNS ConfigMap: /bin/bash -c "sudo /var/lib/minikube/binaries/v1.34.0/kubectl --kubeconfig=/var/lib/minikube/kubeconfig -n kube-system get configmap coredns -o yaml": Process exited with status 1
stdout:

stderr:
E0104 21:05:27.995911    1973 memcache.go:265] "Unhandled Error" err="couldn't get current server API group list: Get \"https://localhost:8443/api?timeout=32s\": dial tcp [::1]:8443: connect: connection refused"
E0104 21:05:27.996434    1973 memcache.go:265] "Unhandled Error" err="couldn't get current server API group list: Get \"https://localhost:8443/api?timeout=32s\": dial tcp [::1]:8443: connect: connection refused"
E0104 21:05:27.998102    1973 memcache.go:265] "Unhandled Error" err="couldn't get current server API group list: Get \"https://localhost:8443/api?timeout=32s\": dial tcp [::1]:8443: connect: connection refused"
E0104 21:05:27.998463    1973 memcache.go:265] "Unhandled Error" err="couldn't get current server API group list: Get \"https://localhost:8443/api?timeout=32s\": dial tcp [::1]:8443: connect: connection refused"
E0104 21:05:27.999972    1973 memcache.go:265] "Unhandled Error" err="couldn't get current server API group list: Get \"https://localhost:8443/api?timeout=32s\": dial tcp [::1]:8443: connect: connection refused"
The connection to the server localhost:8443 was refused - did you specify the right host or port?
Failed to inject host.minikube.internal into CoreDNS, this will limit the pods access to the host IPE0105 06:05:38.017215    1341 start.go:160] Unable to scale down deployment "coredns" in namespace "kube-system" to 1 replica: non-retryable failure while getting "coredns" deployment scale: Get "https://127.0.0.1:32771/apis/apps/v1/namespaces/kube-system/deployments/coredns/scale": EOF - error from a previous attempt: read tcp 127.0.0.1:39386->127.0.0.1:32771: read: connection reset by peer

まさに簡単なWebアプリを書いたときに 127.0.0.1で接続するときとlocalhostで接続するときで数秒以上の解決時間の違いが出ていたので「またか」と思った感じです。

ただ、--alsologtostderr して大量のログをよく見ると、

  • kube-apiserver コンテナ自体が立ち上がっていない
  • その前段階の証明書生成フェーズで失敗している

ことが分かり、ネットワーク以前の問題ぽいですねと。

cgroupが v1 だから?

以下のようなログが気になったので cgroup2 を有効にしました。

  • cgroups v1 support is in maintenance mode
  • swap is supported for cgroup v2 only

vim /mnt/c/Users/<user_name>/.wslconfig でファイル編集して、

[wsl2]
swap=0
kernelCommandLine = systemd.unified_cgroup_hierarchy=1

と書き入れます。

また、WSL側の /etc/wsl.conf に以下を記述します。

[boot]
systemd=true

もしかすると /etc/docker/daemon.json の編集が必要かも。

$ cat /etc/docker/daemon.json
{
  "exec-opts": ["native.cgroupdriver=systemd"]
}

powershell側で wsl.exe --shutdown して落とし上げしました。

stat -fc %T /sys/fs/cgroup
docker info | grep -i cgroup

cgroup2 が使われてそう、という確認をします。ただ、minikube が起動しないのは変化なし。

Docker volume

違和感は、minikube をdeleteしてコンテナは消えているのに、起動ログに毎回次のメッセージが出続けていたことです。

[certs] Using existing ca certificate authority  
[WARNING DirAvailable--var-lib-minikube-etcd]: /var/lib/minikube/etcd is not empty

通常、minikube を完全に削除していれば、kubeadm は新しい CA 証明書を生成します。

それにもかかわらず「既存の CA を使う」と言われるのは謎。

  • minikube delete は成功している
  • ~/.minikube も消えている
  • それでも etcd が「空ではない」と言われる
  • minikube が管理していないどこかに状態が残っているのでは?

docker volume ls を確認すると、minikube という volume が削除後も残り続けていることに気づきました。

さらに、その volume を削除しようとすると、

volume is in use

と怒られるのに、対応するコンテナはすでに存在しない、という不整合な状態に陥っていました。

対応するコンテナは docker 上からは消したはずですが、

sudo ls -la /var/lib/docker/containers

すると、なんか残っているのでメタデータが壊れているのかしら...。

  • 古い Docker volume が残っている
  • その中に壊れた CA / etcd のデータがある
  • minikube がそれを再利用して失敗している
  • 消せない
  • 許せん

minikubeの別プロファイル起動

試しに、既存の minikube プロファイルとは別に、新しいプロファイル名で起動するとうまく動作しました。なるほど。

minikube start -p mk2 

すると、何事もなかったかのように正常起動しました。違いは docker のイメージなどに使われる名前が異なることかしら。

解決策

面倒になったので、関連ファイルを消して作り直す暴挙に出ました。

sudo systemctl stop docker.service docker.socket
sudo systemctl stop containerd.service
sudo mv /var/lib/docker /var/lib/docker.bak.$(date +%Y%m%d%H%M%S)
sudo mv /var/lib/containerd /var/lib/containerd.bak.$(date +%Y%m%d%H%M%S)
sudo mkdir -p /var/lib/docker /var/lib/containerd

これで平和になりました。まあイメージキャッシュとかいろいろ消えたけどいいでしょう。

環境

ma2saka:~$ docker --version
Docker version 29.1.3, build f52814d
ma2saka:~$ minikube version
minikube version: v1.37.0
commit: 65318f4cfff9c12cc87ec9eb8f4cdd57b25047f3