LoginSignup
1
0

More than 3 years have passed since last update.

Docker Engine - CE のソースビルド

Last updated at Posted at 2020-06-11

はじめに

Docker Engine - Community Edition をソースコードからビルドします。最新のソースビルドはいろいろ状況が変化しています。他所においてもソースビルドの情報は提供されていますが、日本語情報で最新のビルド手順を示しているものを、まだ見かけたことがありません。少々古い情報であると、ビルド手順が異なります1。そこで本文では 2020年6月執筆時点、最新の Docker-ce-19.03.11 ソースビルドを示します。

なお本文に示す手順に従って作業を進めようとするなら、十分に注意しておいてください。多くの方が利用している Linux ディストリビューションにおいてはパッケージマネージャーが存在し、Docker モジュールをパッケージ導入しているかと思います。本文の作業はパッケージ導入された Docker を無効にして、自ビルドした Docker で置き換えようとしています。また筆者は Linux From Scratch を利用しているため、パッケージマネージャーのことは考慮しておらず、インストール先も躊躇せずに /usr/bin としています。パッケージマネージャーが管理する状態を十分に理解し、環境を壊すリスクを十分に理解した上で、本文の作業を行ってください。たとえばインストール先を /usr/local/bin にするといった策を講じてください。

前提

筆者は当Qiitaの投稿 「Linux From Scratch に Docker Engine を導入」に示しているように、Linux From Scratch に基づいて構築した Linux OS を利用しており、その OS 上でのソースビルドを行います。ただこのソースビルド方法は、Linux OS 全般に通用すると思います。というのも Docker ソースからのビルドでは、ソースビルドを行うシステム(=ホストシステム)上にすでにインストールされている Docker(正確には Docker デーモン)を利用して Docker コンテナーを作り出し、そのコンテナー内にてソースビルドを行うからです。Docker 風に言えば、コンテナー内にカプセル化された環境において、必要なビルドツールを動的に、つまりその時点で導入してビルドを行うため、Linux ホストシステムは何でもよく、ホストシステムにビルドツールが整っていなくてもビルドできてしまうというものです。

全般的に以下を前提とします。

  • ビルドを行うためには Docker 自体がすでにインストールされていることが必要です。当然これに合わせて Docker の動作環境が構築済であり、実際に Docker が動作していなければなりません。
  • 本文では Linux OS 上において動作させる Linux 用の Docker 実行モジュール類をビルドすることとしています。
  • ビルドを行う Linux OS はたぶん何でもよいと思います。
  • それよりもマシン自体に十分なスペックがあるとよいでしょう。ビルドを行ってみるとわかりますが、ビルド時には複数のコンテナーがビルドされ並列的に処理されます。/var/lib/docker(Docker 関連の種々ファイルが収容されるディレクトリ)が、ビルドだけで 10 GB 以上膨れあがりましたので、それなりに空き容量は確保しておく必要があります。

手順

以下、本手順においては root ユーザーでの操作としています。ご注意ください。

1. ソースのダウンロード

ソース入手は2通りあります。一つは、tarball にまとめられているソースコードを利用する方法です。そしてもう一つは、随所でよく説明されているように git リポジトリから最新ソースを入手する方法です。どちらを選ぶかは目的や好みによって決めたらよいと思いますが、筆者としては tarball による方法をおすすめします。

  • tarball のソースコードはバージョンごとに公式サイトから提供されています。当然のことながら、これは git リポジトリにおいて管理されている Docker ソースコードの、特定時点のものをバージョンづけして tarball にまとめているものです。通常はこれを用いることをおすすめします。
  • git による方法は、本当に最新のソース(時々刻々と更新される git HEAD の最新)を入手したい場合、あるいはソースコードの修正履歴を確認したり追ったりする必要がある場合に利用します。ただし問題は「本当に」、たとえば本日のつい5分ほど前に更新されたばかりの出来立てのソースを、是が非でも必要かどうかです。たぶん開発者でもない限り、そういう最新ソースは不要であると思います。むしろ git HEAD のソースが、常に完全にエラーなくビルドできる保証はないので要注意です。長い時間をかけてソースビルドしても、最後にビルドエラーになったり実行時エラーで動作しなかったりといったことがないとも限りません。ですから明確な目的がない限り git によるソース入手はおすすめできません。
1.1. tarball 入手

tarball ソースは Docker 公式 Github サイトのリリースページ から提供されています。長い長いリリース説明文章の途中に tarball のダウンロードリンクがあって分かりにくいのですが、よく探してみると Source code
(tar.gz)
というものがあります。本文では執筆時点最新の v19.03.11.tar.gz を用います。

そこで wget を使ってダウンロードします。ダウンロードディレクトリは、これからソースビルドを行うディレクトリとして /mnt/lfs/sources というものを例にします。

ここで個人的な趣向の話になりますが、tarball 名が v19.03.11.tar.gz というものなので、見ただけでは何のソース tarball かわかりません。後々管理していくことを考慮して、以下のように wget のオプション --output-document を使って、ファイル名を変更してダウンロードすることにします。

# cd /mnt/lfs/sources
# wget -N https://github.com/docker/docker-ce/archive/v19.03.11.tar.gz \
    --output-document docker-ce-19.03.11.tar.gz

tarball の中身を念のため確認しておくと、docker-ce-19.03.11 というディレクトリ配下に各種ソースコードがまとめられていることがわかります。

# tar tf docker-ce-19.03.11.tar.gz | less
docker-ce-19.03.11/
docker-ce-19.03.11/.github/
docker-ce-19.03.11/.github/PULL_REQUEST_TEMPLATE
docker-ce-19.03.11/.gitignore
docker-ce-19.03.11/CHANGELOG.md
docker-ce-19.03.11/CONTRIBUTING.md
docker-ce-19.03.11/Makefile
docker-ce-19.03.11/README.md
docker-ce-19.03.11/VERSION
docker-ce-19.03.11/components.conf
docker-ce-19.03.11/components/
docker-ce-19.03.11/components/cli/
docker-ce-19.03.11/components/cli/.dockerignore
(以下略)

tarball を伸張(解凍)し、ソースのトップディレクトリ docker-ce-19.03.11 に移動します。

# tar xf docker-ce-19.03.11.tar.gz
# cd docker-ce-19.03.11

この tarball 入手の方法を選んだ場合は、次に示す git の説明を読み飛ばして「2. ソースビルド」の項に進んでください。

1.2. git によるソース入手

Docker 公式の git リポジトリをクローンして、最新のソースコードを入手します。新たに docker-ce ディレクトリが生成されるので、そこに移動します。

# cd /mnt/lfs/sources
# git clone https://github.com/docker/docker-ce.git
# cd docker-ce

2. ソースビルド

2.1. ソースビルドの方針決定

ソースビルドを進める前に、まずビルド方針を定めます。

2.1.1. ビルドターゲットの決定

ソースディレクトリに入って make と入力すると、これだけではビルド処理は開始されず、make のビルドターゲット一覧が表示されます。make では、所定のビルドターゲットを引数に与えて実行するようになっています。つまりどの make ビルドターゲットを選ぶかということが必要になります。いくつかのターゲットがあるのですが、Docker の実行モジュールを新規にビルドするには、以下の3つがあります。

  • make の3つのターゲット: staticdebrpm

明確なビルド目的を持っていない限り、結論から言うと static を選べばよいと思います。本文ではこれを選ぶことにします。

debrpm は、その名からわかるように、それぞれ deb パッケージ、rpm パッケージをビルドするものと思われます。筆者は実際には試していないため、本分では説明しません。

2.1.2. 最小ビルドのための方策

make のビルドターゲット static を選ぶと、ビルドされる実行モジュールが多すぎる難点があります。具体的には、Linux、Windows、Mac、ARM という対応アーキテクチャー向け実行モジュールをクロスコンパイルによって全部作り出してしまいます。これらすべてを作り出そうとする開発者の方なら別ですが、そうでない方にとって全部は必要のないものです。ただでさえ Docker ソースビルドに処理時間がかかるのに、全てをビルドするとなると相当な覚悟が必要となります。

筆者の意識は Linux OS 上で動作する Docker デーモンおよびクライントモジュールを、ソースビルドによって再構成することであり、Windows や Mac の実行モジュールは必要としていません。そこで Linux 実行モジュールのみをビルドするようにします。

2.2. ビルド前の確認

Docker ソースビルドを行うためには、Docker デーモンが起動していることが必要です。起動していない場合は以下のようにして起動します。

# systemctl start docker
2.3. ビルドの実行

tarball を伸張(解凍)して出来上がったディレクトリ docker-ce-19.03.11 がソーストップディレクトリです。(あるいは git リポジトリから入手した場合は、docker-ce がソーストップディレクトリです。)

  • git リポジトリから入手した場合のソースディレクトリは docker-ce ですが、いちいちお断りしながら説明するのは大変なので、ソーストップディレクトリは docker-ce-19.03.11 であるとして説明していくことにします。

まずはソーストップディレクトリに移動します。

# cd /mnt/lfs/sources/docker-ce-19.03.11

次に make static を実行します。ただしそのまま実行すると、前述したように対応アーキテクチャー向け実行モジュールをすべて作り出してしまいます。Linux 向け実行モジュールだけをビルドするには、以下のように入力します。

# make static DOCKER_BUILD_PKGS=static-linux

簡単に上のコマンドの意味を説明しておきます。

  • 上で指定した DOCKER_BUILD_PKGS は `<ソーストップディレクトリ>/components/packaging 内の Makefile に記述されています。このファイルに以下のような記述が存在します。
.PHONY: static
static: DOCKER_BUILD_PKGS:=static-linux cross-mac cross-win cross-arm
  • ただ単に make static を実行すると、DOCKER_BUILD_PKGS:=static-linux cross-mac cross-win cross-arm という変数定義のまま処理が進みます。それがデフォルトの処理になります。これを DOCKER_BUILD_PKGS=static-linux と上書き定義して make static を実行しているのが、本文のやり方です。

  • この変数定義内に見られる文字は容易に想像がつきます。cross-mac はクロスコンパイルによる Mac 用実行バイナリ、cross-win は Windows 用実行バイナリ、cross-arm は ARM 用実行バイナリを意味します。デフォルトではすべてをビルドすることが、ここに定義されているわけです。本文ではこの変数を DOCKER_BUILD_PKGS=static-linux とすることで、Linux 用実行バイナリのみをビルドすることにしましたが、この変数値を変更することで、ビルド対象を細かく設定することも可能ということです。

2.4. ビルド処理時間の検証

ちなみに make static のみの実行による全モジュールビルドと、DOCKER_BUILD_PKGS=static-linux をつけた Linux モジュールビルドのそれぞれについて、time コマンドを使ってビルド時間を測ってみました。ビルド環境は VMware 上仮想イメージ、Linux From Scratch、メモリ2GB、スワップ1GB の同じ環境です。圧倒的な差異をご覧ください。

処理方法 処理コマンド 処理時間
全モジュールビルド make static 4時間06分49秒
Linuxモジュールのみビルド make static DOCKER_BUILD_PKGS=static-linux 59分04秒

全モジュールビルドでは static-linuxcross-maccross-wincross-arm という4種類のアーキテクチャー向けモジュールをビルドしており、だいたい1つのアーキテクチャービルドに1時間要している、という結果になりました。

3. インストール(実行モジュールの保存)

3.1. 実行モジュールの確認

make static によりビルドされる実行モジュールは、<ソーストップディレクトリ>/components/packaging/static/build/linux に保存されます。保存されているのは、1つには実行モジュールを集めた tarball であり、もう1つはさらにサブディレクトリ docker(および docker-rootless-extras) 内に個々の実行モジュールが置かれています。その様子が以下です。tarball 2つとサブディレクトリ dockerdocker-rootless-extras が見えます。

# cd /mnt/lfs/sources/docker-ce-19.03.11
# cd components/packaging/static/build/linux
# ls
docker               docker-rootless-extras
docker-19.03.11.tgz  docker-rootless-extras-19.03.11.tgz

上に続けてサブディレクトリ dockerdocker-rootless-extras を見ると、実行モジュールがそのまま置かれています。

# ls docker
containerd       ctr     docker-init   dockerd
containerd-shim  docker  docker-proxy  runc

# ls docker-rootless-extras
dockerd-rootless.sh  rootlesskit  rootlesskit-docker-proxy  vpnkit

この次に行うインストール作業方法として、tarball をどこかにコピー保存し、場合によっては他マシンにコピーしてインストールするという方法が考えられます。単純には、サブディレクトリ docker(および docker-rootless-extras)内にある実行モジュールを直接ホストシステムにコピーしてしまう方法もあります。必要に応じて適当な方法を選びます。本文では後者の方法で進めます。

3.2. Docker サービスの停止

Docker サービスを再インストールするので、まずは Docker サービスを停止します。

# systemctl stop docker

これを行っておかないと、いざ Docker デーモンの実行モジュール dockerd をコピーしてインストールしようとしても、systemd がそれまでの古い dockerd を掴んでしまっているため、新たな実行モジュールを上書きコピーできません。

3.3. それまでの実行モジュールのバックアップ(または削除)

必要に応じて、それまで用いていた Docker モジュールのバックアップをとっておきます。どこかのディレクトリに移動させて保存するか、.orig などのサフィックスをつけて保存しておくなどです。バックアップ手順は本文では特に示しません。お好みの方法により実施してください。

あるいは十分に状況把握ができていて、かつ可能であるなら、それまでの Docker 実行モジュールをすべて削除する方法もあります。利用している Linux ディストリビューションが提供しているパッケージマネージャーを使って Docker 関連パッケージを導入しているのであれば、それを削除する操作を行うのでもよいでしょう。ただし、何度でも書きますが十分に状況を理解できている場合に限ります。

3.4. 実行モジュールのインストール

上で示したようにソースディレクトリ配下に、ビルドされた新たな実行モジュールが置かれているので、それを直接 /usr/bin にコピーする方法です。単にソースディレクトリ内から /usr/bin へのコピーを行うだけです。

実行モジュールの単体は <ソーストップディレクトリ>/components/packaging/static/build/linux/docker に置かれていると説明しました。
そこで前と同じくソーストップディレクトリが /mnt/lfs/sources/docker-ce-19.03.11 であるとして、以下を実行します。

# cd /mnt/lfs/sources/docker-ce-19.03.11
# cd components/packaging/static/build/linux/docker
# cp * /usr/bin

rootless の実行モジュールもインストールするのであれば、同様のことを docker-rootless-extras ディレクトリに対しても行います。

# cd /mnt/lfs/sources/docker-ce-19.03.11
# cd components/packaging/static/build/linux/docker-rootless-extras
# cp * /usr/bin

/usr/bin にインストールした dockerdockerd などの実行モジュールに対して、--version オプションをつけて実行してみます。間違いなく新しいバージョンがインストールされていることを確認してください。

# which -a docker
/usr/bin/docker

# docker --version
Docker version 19.03.11, build
# which -a dockerd
/usr/bin/dockerd

# dockerd --version
Docker version 19.03.11, build unsupported
3.5. Docker サービスの再起動

停止していた Docker サービスを起動します。

  • もしパッケージマネージャーを通じて、完全に Docker 関連パッケージを削除してしまっているなら、Docker デーモンを起動するための Docker サービス用ファイル、docker.servicedocker.socket も消してしまっているかもしれません。
  • その場合は、拙稿「Linux From Scratch に Docker Engine を導入」において、docker.servicedocker.socket の入手および設定方法を示していますから参照してください。

docker.servicedocker.socket が正しく用意できていれば、ここからは新たな Docker デーモン実行モジュール dockerd が動き出すことになります。実際に動かしてみます。

# systemctl start docker.service
3.6. 動作確認もろもろ

この後は docker run hello-world や、Docker 公式ドキュメントの チュートリアル などを試してみて、Docker デーモンや Docker クライアントが動作することを確認します。

本文は以上です。


  1. そもそも Docker のプロジェクト体制が変わり、Docker Engine は Moby プロジェクト が担うようになっています。したがって git ソースを [https://github.com/docker/docker] から入手している情報は古いものです。しかも Docker デーモンと Docker クライアントのビルドが、ある時点で分離されたため、デーモン、クライアントを一括してビルドするためには、本文の手順が必要となります。 

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0