今回のネタは、おそらく docker-machine を使っていればいつか遭遇するエラーについて。 結論から先に言うと docker-machine を使っていて、ある日 Docker 本体のバージョンを更新するとこうなる。 まず前提として Docker は Linux コンテナが動作する Docker ホストと、それを制御する Docker クライアントに分かれている。 通常は Docker ホスト = Docker クライアントなんだけど docker-machine を使っているとその状況が崩れる。 Docker クライアントがハイパーバイザを動かしているマシンで、Docker ホストがハイパーバイザ上で動く仮想マシンに分かれるから。 その状況で Docker クライアントのバージョンだけを更新してしまうと、このようなエラーになる。
実際に起こしてみる
使った環境は次の通り。
$ sw_vers ProductName: Mac OS X ProductVersion: 10.11.3 BuildVersion: 15D21
Mac OS X なので Homebrew Cask で Docker と Docker Toolbox をインストールできる。 このコマンドを入力している時点で、既に両者は古いバージョンがインストール済みで docker-machine の仮想マシンも作られているという想定。
$ brew cask install docker dockertoolbox
こうなると Docker クライアントだけが新しくなって API のバージョンがミスマッチを起こしてしまう。
$ docker version Client: Version: 1.10.0 API version: 1.22 Go version: go1.5.3 Git commit: 590d5108 Built: Thu Feb 4 18:18:11 2016 OS/Arch: darwin/amd64 Error response from daemon: client is newer than server (client API version: 1.22, server API version: 1.21)
対処方法
このエラーに対処するには落ち着いて docker-machine upgrade サブコマンドを実行する。 これで対象の仮想マシンが最新のバージョンに更新される。 ここで指定している「default」は docker-machine で使っている仮想マシンの名前。
$ docker-machine upgrade default Waiting for SSH to be available... Detecting the provisioner... Upgrading docker... Stopping machine to do the upgrade... Upgrading machine "default"... Copying /Users/amedama/.docker/machine/cache/boot2docker.iso to /Users/amedama/.docker/machine/machines/default/boot2docker.iso... Starting machine back up... (default) Check network to re-create if needed... (default) Waiting for an IP... Restarting docker...
これでエラーが解消できた。
$ docker version Client: Version: 1.10.0 API version: 1.22 Go version: go1.5.3 Git commit: 590d5108 Built: Thu Feb 4 18:18:11 2016 OS/Arch: darwin/amd64 Server: Version: 1.10.0 API version: 1.22 Go version: go1.5.3 Git commit: 590d5108 Built: Thu Feb 4 19:55:25 2016 OS/Arch: linux/amd64
めでたしめでたし。