Dockerとは?
コンテナ技術を使ったアプリの実行環境を構築、運用するためのプラットフォームです。ポイントとしては単なる仮想環境ではなくアプリケーションのデプロイに特化した技術である点です。Docker自体はGo言語で記述されています。
コンテナ型の仮想環境を実現するための常駐アプリケーションとそれを操作するためのCLI(コマンドインターフェイス)からなります。アプリの実行に必要なものを一つにまとめて、Dockerイメージとして管理し、様々な環境でアプリの実行環境を構築・運用することができます。
Dockerのエディション
Docker Community Edition(Docker CE)
特徴
- 無償
- 基本的なDockerの機能は利用できる。
- リリース周期の違いでStable版とEdge版に分かれる。
Stable版(ステイブル)
4半期ごとのリリースになります。安定した機能を利用したい場合はこちらを選択します。
Edge版
1ヶ月ごとのリリースになります。最新機能を利用したい場合はこちらを利用します。
Docker Enterprize Edition(Docker EE)
特徴
- 有償
- Docker社が認定したコンテナやプラグインが利用可能
- プライベートリポジトリが利用できる。
- イメージのセキュリティスキャンが行われる。
- リリース周期は4半期ごとになっています。
Dockerのバージョン
1 |
YY.MM.N-[エディション名] |
例えば、2019年10月にリリースされたCEエディションであれば「19.10.0-CE」とかになります。
コンテナ技術とは?
ホストOSのリソースを論理的に分割し、複数のコンテナで共有して使います。Dockerエンジンさえ動いていれば容易に他にコンテナ丸ごと移し替えせることからコンテナと呼ばれます。
コンテナ内のプロセスは一つのグループとして管理されていてコンテナごとにファイルシステムやホスト名、IPアドレスが割り当てられています。なのでコンテナが異なると異なるグループと見做されて他コンテナのプロセスやファイルへのアクセスはできません。
従来の、VirtualBoxや、VMware Player等のホスト型の仮想化技術に比べるとハイパーバイザー等によるハードウェアを再現しない分コンテナは軽量(オーバーヘッドも従来の仮想化ソフトに比べて少ないです。)で高速に動作します。
コンテナを区画する技術(namespace)
Linuxカーネルのnamespaceという機能を使っています。
PID namespace
各プロセスに割り当てられたユニークなIDのことです。namespaceが異なるPIDにはアクセスできません。
Network namespace
ネットワークを区画します。この機能のおかげでホストOSで使用中のポートがあっても各コンテナで同じ番号のポートを使えます。
UID namespace
UIDやGIDを区画します。ホストOSと区別してユーザーやグループを持てます。
MOUNT namespace
ホストOSとは独立したファイルシステムツリーを作れます。
UTS namespace
ホスト名やドメイン名を独自に持てます。
IPC namespace
プロセス間通信(PIC)オブジェクトをnamespaceごとに独立して持てます。
コンテナ上で動くアプリの特徴
- Dockerエンジンさえあればコンテナを別の環境に移行させることが容易になります。
- データを格納するディレクトリを共有します。
- サーバーに設定された、ホストOSと同じIPアドレスを使います。
上記、特徴があることによるメリット
個々のアプリで一つのサーバー上のリソースを占有しているように見せることができます。
構成
- Dockerデーモン(サーバ)
- dockerコマンド(クライアント)
- イメージの保管場所(レジストリ)
Dockerデーモン
クライアントであるdockerコマンドから要求を受け取り、イメージ、コンテナ、ボリューム、ネットワークといったDockerオブジェクトを管理する。ネットワークを超えてリクエストを受け取ることも可能です。
Dockerクライアント
コンテナを操作するCLIです。Docker APIを利用してDockerデーモンに要求を送り機能を活用します。
Dockerのユースケース
開発時の各環境をイメージとして持っておき、流用する使い方。
「ステージング環境」や、「プロダクション環境」等の各環境をコンテナとして管理したりして、使うDockerのユースケースがあります。
開発時の環境の種類に関しては下記の記事で解説しています。
メリット1:手順書不要で簡単に環境を構築できる。
開発したアプリに必要な全てが含まれるDockerイメージを作成し、それをコンテナの雛形とします。従来は本番環境を手順書に沿ってセットアップして必要なミドルウェアをインストールするという方式が主だったのですがDockerを使えば数行の構成ファイルとコマンドを一つ叩くだけで簡単に構築することができます。
メリット2:環境ごとの差異をなくせる。
Dockerをインストールしている環境であればDocker Engineによる実行環境の標準化がなされていたり、コンテナ内にアプリとOSが常に同梱されており、基本どこでも動かすことができるので、「テスト環境では動くが、本番環境では動かない」というようなリスクを減らすことができます。ローカルDocker環境で動作しているコンテナをそのまま本番環境に持っていくことも可能ですしその逆も可能になりコンテナは非常にポータビリティが高い開発が可能です。
Dockerの注意点
「インフラは全てDockerでいいのでは?」と思われる方もいらっしゃるかもしれませんが下記の注意点がありますので導入の際は下記の点も考慮に入れて検討をする必要があります。
完全なLinux環境を再現しているわけではない点
Docker内部にはLinuxOSのような物で構成されていますが完全にLinuxを再現しているわけではないです。厳密にLinuxOSとして動作することを求めるシステムにおいては従来通りVMwareやVirtualBox等の仮想化技術を使って構築されることをお勧めします。また、FreeBSD等のUnix環境にも対応していないので注意です。あくまでアプリのデプロイに特化した環境になります。
データストアはDockerでの運用が難易度が高い
DB等のデータストアはデータが蓄積すると負荷が高くなり必ずしもDockerを利用するのが正解ではありません。最近はクラウド上で運用負荷が少なくかつスケールするようなマネージドデータストアが充実しているのでそちらを使うのが一般的でしょう。
特定のCPUアーキテクチャやOS前提の上に成り立っている。
DockerはホストOSのカーネルリソースを共有しているので異なるアーキテクチャ上では動かすことはできません。
環境ごとの分離レベルが低くセキュリティリスクは上がる。
従来のVMware等の仮想環境に比べるとコンテナ型仮想環境はホストOSのカーネルに依存しておりホストOSの1プロセスとして動くので環境の分離レベルが低い状態になります。なので一つの環境がセキュリティリスクに晒された場合は他の環境まで影響を及ぼす可能性がありセキュリティリスクは高まります。本番運用する場合は下記の意識が重要です。
- 不用意にパブリックネットワークに公開しない。
- 不必要なアプリはインストールしない。
- 脆弱性アップデートは定期的に実施する。
Dockerの機能
- Dockerイメージを作る機能(Build)
- Dockerイメージを共有する機能(Ship)
- Dockerコンテナを動かす機能(Run)
Dockerイメージを作る機能(Build)
「Dockerfile」という「Dockerイメージを作る機能」があります。
Dockerイメージを共有する機能(Ship)
「Dockerイメージ」は、「Dockerレジストリ」で共有できます。
Dockerのコマンドを使えば、Dockerレジストリ(Docker Hub)に、ログインして、レジストリ上のイメージの検索やアップロード、ダウンロードができます。
Dockerレジストリとは?
公式のDockerレジストリとしては、「Docker Hub」があり、そこで個人が作成したDockerイメージを自由に共有することができます。
Dockerコンテナを動かす機能(Run)
Dockerは、Linux上でコンテナ単位でサーバーを動かします。
1つのLinuxカーネルを複数コンテナで共有しています。コンテナ内で動作するプロセスを一つのグループとして管理して、ファイルシステム、ホスト名、ネットワーク等を割り当てています。
グループが異なった場合は、ファイルや、プロセスへのアクセスができなくなります。
カーネルの仕組み
DockerはホストOSのカーネルを共有しています。なのでDockerコンテナが実行できるホストは特定のOSやCPUアーキテクチャに依存することになります。(例えば、Linux系のDockerイメージであればLinuxやMacをホストOSにした環境でしかコンテナを動かせません。Windowsとかでは無理です。)
また、一つのLinuxカーネルを複数コンテナで共有することになります。
リソース管理の仕組み
ホストOS上のリソースを複数コンテナで分割して持ちます。その際はLinuxカーネル機能である「cgroups」の機能を使って実現しています。
ネットワーク
いくつかのネットワークがあります。
ブリッジドライバを使用したネットワーク
単一のDockerホスト内で構成されるネットワークで比較的小規模なネットワークを構築する場合に利用されます。
Dockerをインストールするとサーバの物理NICがdocker0という仮想ブリッジネットワークに接続されます。また、コンテナごとに仮想ブリッジから仮想NICにそれぞれ接続されてプライベートIPアドレスが割り当てられます。仮想NICはトンネリング通信を行います。外部からネットワークでアクセスする場合はNAPT(Linuxのiptables)でポートフォワーディングさせてアクセスさせています。
Docker for Macなどの設定項目
General
下記の設定があります。
- OS起動時に自動で起動するかの設定
- 「自動アップデートを通知するか」等の設定を行えます。
- Mac上の仮想VMのバックアップを行うか。
- MacのキーチェーンにDockerログイン情報を保存するか。
- Dockerが不正終了した際の情報をDocker開発元に送るか。
File Sharing
Dockerコンテナにマウントを許可するホスト側のディレクトリを設定します。デフォルトでは下記のディレクトリが指定されています。これらのディレクトリ配下にあるディレクトリはDockerコンテナにマウントが可能になります。
- /Users
- /Volumes
- /tmp
- /private
Disk
Dockerを実行している仮想ディスクのサイズを指定できます。サイズは16GB単位で指定できます。
Advanced
「ホストOSのメモリ、CPUをどれだけ割り当てるか」や「ネットワークのサブネット」を指定します。なお設定した分のリソースが常に消費されるわけではありません。デフォルトでは下記のようになっています。
- CPUs = 2
- Memory = 2.0GB
Proxies
DockerイメージをリモートのDockerリポジトリからpullしてくる際にhttpかhttpsのプロキシを使うかどうか指定できます。基本的には「System proxy」で事足りるかと思います。ただ、直接インターネットに出られないような環境の場合や、アクセス元を制限したプライベートレジストリからDockerイメージを取得する場合は「Manual proxy configuration」にて設定する必要があります。
Daemon
Basic
Insecure registers
HTTPでのセキュアでないDockerレジストリ通信の登録を行えます。基本的にDockerではHTTPSでのセキュアな通信を推奨しているのでセキュアでないHTTPを使用する場合はここで指定します。
Advanced
Dockerの設定ファイルをJSON形式で設定できます。DockerのGUIの設定項目にない項目はここでJSON形式で指定する必要があります。
Kubernetes
「Enable Kubernetes」を選べばKubernetes」が有効になります。
Reset
Dockerをインストール時の綺麗な状態に戻したり、Docker自体のアンイストールができます。アンインストールをした場合はDockerイメージやコンテナは全て削除されます。
「Automated Build」(自動ビルド)とは?
GitHubやBitbucket等のホスティングサービスでDockerfile等のビルドコンテキストを管理してリポジトリ上のビルドコンテキストが更新されたら自動的にビルドを行う仕組みのことです。Docker Hub上で行い事前にGitHub等へのアクセス許可設定を行います。Git Hubに変更が入ればDocker HubへPUSH通知してその通知を元に自動ビルドしてくれるというわけです。
自動ビルドの設定(Docker Hub側)
設定項目としては下記のような物があります。
- GitHub上のどのリポジトリのどのDockerfileを自動ビルド対象とするか。
- 自動ビルドした際につけるタグ名の指定
マウント
Dockerのマウントにはいくつのか種類があります。
- Volumes
- bind mounts
- tmpfs mounts
Volumes
- 一般的にはこれを最優先で使用するように言われています。
- Dockerで管理されるホストのファイルシステムの一部に保存されます。
- Dockerによって管理され、ホストマシンのコア機能から分離されます。
- 複数コンテナに同時にマウントが可能です。
コンテナとボリュームの違いは?
コンテナ内部にデータを保存してもコンテナを破棄するとデータは消えるが、ボリュームはコンテナを破棄してもデータを消えないのでそのような用途の場合に使う。
ボリュームの保存場所
保存場所は二つあります。
ホスト上のボリューム
普通にホストOS上に作成できます。lsやmkdir等のLinuxコマンドで作成します。
dockerのリソース上のボリューム
ボリュームを作成する。
1 |
docker volume create ボリューム名 |
作成されているボリューム一覧を確認する。
下記コマンドを実行すれば確認することが可能です。
1 |
docker volume ls |
bind mounts
- Volumesよりも機能が限られています。
- ホストシステム上であればどこでも保存できます。
- ホストマシンによって管理されます。
- コンテナにマウントされます。
- マウント対象のファイルやディレクトリはホストマシン上の絶対パスによって管理されます。
tmpfs mounts
- ホストシステムのメモリに保存されます。ホストのファイルシステムには書き込まれません。
- コンテナが作成されて削除されるまでに保持するので、非永続的なデータを保管するために使います。
- 例えば、パスワード等の機密情報を管理するために使います。
共通した特徴
マウントにはいくつか種類がありますが、コンテナ内からは全て同じようにデータが見えます。
この記事へのコメントはありません。