Docker入門① -Dockerコンテナ ハンズオン-

Docker入門① -Dockerコンテナ ハンズオン-

はじめに

 AIや機械学習のインフラとしてコンテナが注目されている。本記事ではコンテナ技術で主流であるDockerについて取り扱う。
Dockerを詳しく紹介する前に、コンテナを利用する理由を考えてみる。オンプレやクラウドを利用することも多くあるが、なぜコンテナなのだろうか。その理由は2つあると考えられる。
 一つ目は、アプリケーションの観点でテスト環境から本番環境に移行するときだ。テスト環境から本番環境に移行するときに、サーバのバージョンやハイパーバイザーのバージョンなどの違いでアプリケーションに影響がでることがある。その差異を極小化するツールの一つとして用いられる。実際に、Immutable Infrastructureという考え方があり、上記の課題を改善する方法として、同じ環境で高速にデプロイできるコンテナ環境では、デプロイしたら構成変更は禁止したり、コンテナのもとイメージから展開したりする。
 二つ目はマイクロサービスアーキテクチャだ。従来のアプリケーションは、いわゆるモノリシック・アーキテクチャと呼ばれ、複数のプロセス(役割)を一つのコンポーネントにパッケージすることでそれぞれが密に連携した作られ方だった。そのため、パッケージの中の何かのコンポーネントをアップグレードするために全体を止める必要性が出てきたり、パッケージごと改変する必要があるため影響の範囲が大きくなったりなどの課題がある。それを解決できるマイクロサービスアーキテクチャでは、アプリケーションがパッケージではなく個別に作成され、それらが疎結合しアプリケーションとして成り立っている。つまり、必要なコンポーネントのみをアップグレードしたり、同じコンポーネントを素早くデプロイしたり、することでアプリケーション全体での整合性を保つことができる。
このような理由からコンテナが注目されつつあり、AIや機械学習のインフラとしてコンテナが利用されている。そのコンテナ技術の中でもよく利用されるDocker とは開発者やシステム管理者が、アプリケーションの開発、移動、実行するためのプラットフォームとして提供されている。
今回は、Dockerの特徴とコンテナの起動方法を紹介する。

Dockerコンテナの特徴

  • ホストOS のkernel 機能を使い、複数のルート・ファイルシステムを実行しており各ルート・ファイルシステムをコンテナ(container)と呼ぶ
  • コンテナは各々のリソースを持つ
  • プロセス、メモリ、デバイス、ネットワークコンテナとはLinux カーネルの技術を使う
  • Namespaces (名前空間によるプロセス間の隔離・分離;isolation)
  • Cgroups(CPU・メモリ・Disk I/Oのリソース制限)

Docker01_01
“Dockerイメージの理解とコンテナのライフサイクル”のスライド8より参照

Dockerコンテナの実行する欠かせないコンポーネントの一つにDocker Engineがある。
Docker Engine:3つのコンポーネントを持つクライアント・サーバ型アプリケーション
 1.サーバはデーモン・プロセスと呼ばれる長期間実行するプログラムの種類
 2.インターフェースを規定する REST API は、プログラムがデーモンと通信に使うものであり、何をするか指示
 3.コマンドライン・インターフェース(CLI)クライアント
Docker01_02

クライアントサーバアーキテクチャなので、ユーザはdocker CLIもしくはAPIを介し命令を送り、Docker daemonを制御または対話する、という一連の流れでコンテナ操作を行う。
イメージにすると以下の感じとなる。
Docker01_03

Dockerコンテナのデプロイ

次は、Dockerの実際にコンテナをデプロイしてみよう!!
https://docs.docker.com/install/linux/docker-ce/ubuntu/
※インストール方法は公式サイトをご参照ください。Ubuntu環境でインストールしましたが、うまくいきました。

$ docker run docker/whalesay cowsay Hello
<引数の紹介>
・docker/whalesay 呼び出したいコンテナ名
・cowsay Hello コンテナ内で呼び出すコマンド

Docker01_04
<出力結果>
Docker01_05

クジラの絵が出てきて出力結果がHelloにあっていれば成功!

同じコマンドでもコンテナが存在する場所により出力結果の流れが変わるので紹介する。
パターン1. ローカルにImagesがあるとき:例えば、2回目以降コンテナを起動するときなど
Docker01_06

ユーザがDocker RunでDocker DaemonにアクセスしローカルにImagesがあればそのImagesからContainerを起動する。

パターン2. ローカルにImagesがないとき:初めてコンテナを起動するときなど
Docker01_07

ユーザがDocker RunでDocker DaemonにアクセスしローカルにImagesがなければ、外部のRepsitory(Docker社のDocker Hubが標準)から該当のImagesを取得する。
その後ローカルにあるImagesからContainerを起動する。
Docker01_08

補足:先に示したクジラの絵の出力結果は、Unable to find image ‘docker/whalesay:latest’ locallyとあり外部のRepositoryから docker imagesを持ってきている。しかし、既に同じdocker imagesを構成するlayerが既に存在しているので、Already existsと表記されている。本来のパターン1であれば以下のように入力から出力の結果は連続する。
Docker01_09

次に、今回使用した他のコマンドについて3つ紹介する。
~ローカルにあるImagesの確認コマンド~
$ docker images
<出力結果>
Docker01_10
nginx、hello-world、docker/whalesayの3つがimagesとしてある。

~起動しているContainerの確認コマンド~
$ docker ps
<出力結果>
Docker01_11
nginxがcontainerとして起動している

~起動しているContainerの中に入るコマンド~
$ docker exec -i -t some-nginx bash
<出力結果>
Docker01_12
root@aa44398a30d0:/がコンテナの中に入って、lsコマンドを打っている

まとめ

今回はコンテナ技術が利用される背景に触れ、Dockerコンテナの特徴や、実際にコンテナをデプロイする方法について紹介した。次回は、Docker images(Docker イメージ)について紹介する。

<参考資料>
Dockerイメージの理解とコンテナのライフサイクル https://www.slideshare.net/zembutsu/docker-images-containers-and-lifecycle
Docker公式サイト https://docs.docker.com/engine/docker-overview/