記事を書いた経緯
今回、フリーランスエンジニアの方々と勉強会を開くことになりまして、その時たまたまDocker構築周りの作業をしていたので、私の第一回目の発表はDockerにすることにしました。
折角なので、準備してからというわけで、記事を書いてます。
記事の目的
- Dockerが何かわかる
- Dockerの仕組みがなんとなくわかる
- Dockerのユースケースがわかる
- Dockerを身近に感じる
※Dockerが使えるようにはなるわけじゃなく、Dockerの足掛かりになるのが目的
Dockerとは?
Dockerとはコンテナを配布、実行するためのプラットフォームです。(え、簡潔すぎ。。
じゃあコンテナとは?
コンテナとはアプリケーションとその実行環境を一式でパッケージ化したものです。
このコンテナの技術を使うと、アプリケーションの配布と実行が簡単に出来る上に、1つのOS上で複数のコンテナを同時に動作させることができます。下記はWindows上で3つのLinux(コンテナ)を動かす構成図になります。
コンテナの配布と実行方法
配布側の手順
- docker build
- docker push
実行側の手順
- docker pull
- docker run
というわけで、ここでは何かすごく簡単に配布・実行できそうというところだけお伝えできたらなと思います。
仕組みについてはこの後に解説します。
Dockerはプラットフォーム?
以下にDockerの全体像であります。これがアプリではなくプラットフォームに分類される所以です。
矢印は、そのコマンドによって何がどう作成されていくかを表しています。
次に画像の登場人物について説明します。
Images
イメージとは、コンテナを作成する際に必要な、OSや設定などの情報一式をまとめたものになります。
このイメージを使うことでいつでも、まったく同じコンテナを再現して実行することができます。
docker buildによって自分でカスタマイズした設定でイメージを作成することもできますし、docker pullによって既にレジストリに登録されているイメージを持ってくることもできます。
Containers
先ほども記載しましたが、コンテナとはアプリケーションとその実行環境を一式でパッケージ化したものです。
コンテナはdocker runを実行した際に、イメージを元に作成されます。
イメージ1つから複数のコンテナを同時に動作させることができます。
Client
Clientはcliでrunやbuildなどのコマンドを使ってホストに対して指示を出します。
DOCKER_HOST
ホストはClientからの指示によって動きます。イメージを保持し、イメージからコンテナを実行します。Clientとホストはよく同一PC上に存在します。
Registry
レジストリはホストからイメージの配布ができ、逆にレジストリからイメージをホストにダウンロードすることもできます。
有名なのはDocker Hubというレジストリで、世界中の人が色々なイメージを配布しているため、自分でイメージを作成しなくてもDocker Hubからイメージを持ってきてコンテナを実行することができます。
レジストリは自分で作成することもできるため、組織で共有したいイメージなどは組織用のプライベートレジストリを作成して運用することもできます。
イメージをビルドするための設定をファイル(DockerFile)を紹介
たとえばGo言語の開発環境のイメージを自分で作成する際は、以下のようなDockerFileを作成することになります。
FROM golang:1.16-alpine AS build
RUN apk add --no-cache git
RUN go get github.com/golang/dep/cmd/dep
COPY Gopkg.lock Gopkg.toml /go/src/project/
WORKDIR /go/src/project/
RUN dep ensure -vendor-only
COPY . /go/src/project/
RUN go build -o /bin/project
FROM scratch
COPY --from=build /bin/project /bin/project
ENTRYPOINT ["/bin/project"]
CMD ["--help"]
このDockerFileをdocker buildすることでイメージができます。Go言語の開発環境のこのDockerFileをdocker buildすることでイメージが作成されます。
よく使われるFromやRunが何をしているかを解説して、少しだけ理解を深められたらと思います。
From句
From句ではベースとなるイメージを選択しています。
既にあるイメージをベースにすることで、OSや特定のミドルウェアをインストールするコマンドを書かなくて済むため、大幅にDockerFileがシンプルになります。
「FROM golang:1.16-alpine」はDockerHubに公開されている「golang:1.16-alpine」という名前のイメージをベースにするという指定になります。
RUN句
RUN句は、このイメージが実行され、コンテナが作成された際に、コンテナ内で初期化処理として走るコマンドを指定できます。
つまりこのイメージが実行されると「apk add –no-cache git」と「go get github.com/golang/dep/cmd/dep」の2つのコマンドが走ります。
このようにいくつかのコマンドをDockerFileに定義することで、定義に従ったイメージができあがります。
Dockerのよくあるユースケース
Linux上で稼働するソフトウェアの開発環境として
例えば、Linux上で稼働するソフトウェアを複数人で開発する際に、各自がLinuxの開発環境を構築していては、手間もかかりますし、何よりバージョンや設定など細かい環境の差分で不具合が起きがちです。
そこでOSを含めた開発環境ごと配布してしまえば、開発者全員が同じ環境で、すぐに作業を始めることができます。
自動テスト環境として
自動テスト自体はテストが実行できるサーバーがあれば、Dockerは必要ありませんが、1つのサーバー内で様々なイメージを切り替えることができれば、様々な動作環境に対応でき、複数のアプリケーションをテストすることができます。そういった点で、自動テストとDockerは相性がいいため、よくあるユースケースだと思います。
GithubやGitLabなど、一部のプロジェクト管理ツールでも自動テストを実行する際にDockerを使用することができます。
運用環境として
運用フェースでもDockerが活躍する場面は多く、最近だとマイクロサービスアーキテクチャで構成されるシステムではDockerで運用することが前提になっているケースがほとんどかと思います。
クラウド開発でもイメージをプライベートレジストリにアップしてそこからデプロイしたりします。
おわりに
事前に書いたとおり、使い方ではなく足掛かりになる情報は提供できたかなと思います。
もしDokcerが必要になった際に、ここでの情報が役立てば幸いです。