なぜコンテナを導入するのか?

本記事では、コンテナに触ったことがない人に対して、コンテナ利用時のメリットを説明するための資料を公開します。

コンテナ技術とコンテナイメージ

コンテナ技術とは、プロセスを隔離して実行するための技術です。
コンテナイメージ(イメージ)とは、「アプリケーションコードと依存関係を一つにまとめたファイル」です。
コンテナイメージを元に実行された、隔離されたプロセスになったものをコンテナと呼ばれます。

https://www.docker.com/resources/what-container

VMとの違い

VMは一つ一つにゲストOSが必要です。
コンテナは、プロセスを隔離してHostOS上で動作させることができます。
そのためオーバーヘッドや利用するリソースも少なく、高速に起動します。

https://www.docker.com/resources/what-container

コンテナを導入するメリット

プログラミング/エンジニア初心者

  • アプリケーションコードと依存関係を一つのイメージにまとめられる
    • 依存パッケージによるエラーがなくなる
  • 最初の環境構築がめっちゃ楽になる
    • 複雑なインストール手順を踏まなくていい
  • 公開されているコンテナイメージが多数存在する
    • 主要なプログラミング言語やミドルウェアは、公式のコンテナイメージを公開してる
    • 特別な設定は必要なく、動作が保証された環境で動かすことができる 

サービス開発者

  • 開発環境の構築がコードベースで行える
  • 開発開始までの時間が短い
  • VMに比べてコンピュータリソースを有効活用できる
  • 既存の環境に影響を与えず、新しい環境を利用できる
    • 実際にプログラムをインストールしなくてよい 

以下の例では、PHPをインストールせず、PHP5.6とPHP7.3の各バージョンでPHPのコードを動かしています。
https://github.com/tomoyamachi/docker-tutorial/blob/master/00-introduction-ja.md

# ver5.6環境で実行
$ docker run --rm -it -v $(pwd)/00-php-sample:/app \
    --rm php:5.6-cli-alpine \
    php /app/main.php
NULL

# ver7.3環境で実行
$ docker run --rm -it -v $(pwd)/00-php-sample:/app \
    --rm php:7.3-cli-alpine \
    php /app/main.php

Fatal error: Redefinition of parameter $void in /app/main.php on line 3

インフラ担当向け

  • The Twelve-Factor Apps の文脈に沿っている
    • コードベースでインフラを管理できる
    • OSへの依存度を減らし、移植しやすくする
    • 開発環境と本番環境の差異を最小限 → CI/CDの促進
    • スケールアップしやすい
  • コンテナベースのオーケストレーションサービスが複数存在する

セキュリティ担当向け

  • CI/CDを実行すると、自動でパッケージが最新のものになる
    • アプリケーションに関するパッケージのアップデート非常に楽
  • コンテナプロセスは非root権限で実行されるので、侵入されたときのリスクが下げられる
  • アプリケーションコードと依存関係を一つのイメージにまとめた「イメージ」ごとに責任を分割できる → どこで利用されているかわからないパッケージ/ライブラリを減らせる
  • ただし、Dockerやオーケストレーションツール(Kubernetesなど)に脆弱性が発見されることもある

FAQ

どういう原理で動くの?

Linuxカーネルの機能を組み合わせて動きます。
Mac / Windowsだと、Linuxカーネルの機能を小さくまとめたLinuxKitを動かしています。

これまで覚えた知識は無駄になるの?

無駄になりません。
たとえば、コンテナ間のネットワーク通信では、veth(バーチャルイーサネットデバイス)を用いて通信を実現しています。また、iptablesなどを駆使してコンテナ間の名前解決を行っています。
伝統的な手法を仮想的に行っていることが多いので、トラブルシュートの際は、これまでの知識が必要になってきます。

向いてないことはある?

たとえば以下の場合は向いてません。

複雑なモノリスアプリケーション
Dockerは1プロセスごとにコンテナを分けることが推奨されます。そのため、複雑すぎてプロセスの分離が難しいものは向いていません。その場合は、LXCなど1コンテナで複数プロセス起動が許されているコンテナ技術をつかえます。

特殊なデバイス/リソースを利用する
たとえば、現在NVIDIA以外のGPUを利用できません。特殊なリソースを利用したい場合、対応できないことがあります。
※ 2020/8/21追記 : AMDのGPUも利用可能になったようです。またその他のGPU driverも利用できるようになる予定です。

次のステップ

Docker Playgroundで実際にさわってみる

  1. DockerHubのアカウントを作成
  2. Docker Playground にDockerHubアカウントでログインする
  3. 「ADD NEW INSTANCE」でインスタンスをつくって、dockerコマンドを実行する
  4. https://events.docker.com/learndocker-workshop/ の手順に沿ってコマンドを打つ