Linuxコンテナ・Docker入門(後編)

#前編

[Linuxコンテナ・Docker入門(前編)](https://qiita.com/satken2/items/10b22bed7a331e425cfe)からの続きです。

# Docker

Docker社が提供しているOSSのコンテナエンジン。(有償版もある)

前述の通り、<u>LXCには最低限の機能しかないため利便性は高くない</u>
**⇒LXCをラッピングする形で拡張し、簡単に扱えるようにしたものがDocker**

※以前のDockerは内部でLXCを使用していたが今は違うらしい。でも、上記の考え方は変わらない。

## Dockerの概要

Dockerは、前述のLXCの技術をラッピングし、より使いやすくするためのツールである。
以下のような機能を付加する。

- 可搬性、共有機能
Dockerは、コンテナをtarファイルにアーカイブして他の物理マシンに送ったり、コンテナレジストリを介して共有できる機能を有する。これにより、作ったコンテナを他のマシンで流用することができる。

- アプリケーション主眼
LXCは元々「軽量なVM」という観点で作られているが、DockerはLXCを軽量化してより手軽にすることで、アプリケーション単位、プロセス単位でのコンテナ化を容易にしている。

- IaC
コンテナの中に作成するファイルやインストールするアプリケーションなどをDockerfileという形式で定義できるようになっている。これにより、IaC的にコンテナの中身を定義することができる。

- バージョン管理
Dockerで作成したコンテナはバージョン番号を付与でき、Dockerで管理することができる。これにより、バージョン間の差分管理やトラブル時のロールバックが実現できる。

- コンポーネントの再利用
Dockerでは、レイヤーという仕組みを利用して既存のコンテナイメージにファイルやアプリケーションを追加していく形式でコンテナのイメージを作成する。複数のコンテナで共通する部分は共有化することで、ディスク容量や管理コストを削減することができる。

- エコシステム
Dockerは最もメジャーなコンテナエンジンであり、取り巻くエコシステムも多い。例として、以下のような関連ソフトウェアやサービスがある。

  - Docker Hub … インターネット上でDockerコンテナを共有するサイト
  - Docker-Compose … 複数のコンテナを連携して立ち上げるソフト
  - Kubernetes … 多数のLinuxホストでクラスタを組み、コンテナをより柔軟に運用できるようにしたソフト(後述)

## Dockerの用語と構成要素

### イメージとインスタンス

VMで例えると、イメージはテンプレート、インスタンスは実際に起動しているVM。
内部的にはインスタンスはイメージを参照しているだけなので、起動時にコピーなどは発生しない。
Dockerのコマンドでイメージ名を指定して`run`することで、実際にLinuxコンテナが作成される。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215103/61a46d97-9a34-1eea-612f-b91080566025.png)




Dockerでは、既存のイメージにファイルを追加したりコマンドを実行する形で新しいイメージを作成していく。
メジャーなOSSでは、Docker Hubというインターネット上のサイトで公式のコンテナイメージが公開されている。
実際に利用する際はその公式イメージに設定値などを追加したカスタムイメージを作成して利用することが多い。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215103/35549130-7003-1dc0-4fa1-972747761daa.png)

### Dockerfile

イメージを作成する際の定義(どんなファイルを追加するか、どんなコマンドを実行するか)はDockerfileというテキストに記述する。
Dockerfileを使用してコンテナイメージを作成することを`ビルド`と呼ぶ。

- コンテナイメージ(ベースイメージ) + Dockerfile => (ビルド) => **コンテナイメージ(カスタムイメージ)**
- コンテナイメージ => (起動) => **コンテナインスタンス**

以下の例のように、基本的にDocker hubなどから取ってきた既存のコンテナイメージにファイルを追加したりコマンドを実行したりすることで作成する。
1からコンテナを作ることはできなくはないが、大変な割にメリットが少ないのでやめた方がいい。

app.pyというPythonプログラムを実行するためのコンテナは以下のように作る。
(入れてるパッケージ等は例として適当に書いただけで、特に意味はない)

```Dockerfile:Dockerfile
# Pythonの公式イメージから作成
FROM python:3.7.6-stretch

# pipでパッケージをインストール
RUN pip install pip --upgrade && \
    pip install numpy scipy

# aptでパッケージをインストール
RUN apt-get update -y && \
    DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
    sshpass

# ディレクトリを作成
WORKDIR /work

# プログラムを配置
COPY app.py /work

# コンテナインスタンス起動時に最初に実行するコマンドを指定
ENTRYPOINT python /work/app.py
```

これを書いて保存したら、`docker build`コマンドで読み込ませることでコンテナのビルドができる。

### コンテナレジストリ

作成したコンテナイメージを共有するための仕組み。
インターネット上のDocker Hubでは多数のOSSコンテナイメージや個人が作成したコンテナイメージが公開されている。
(!)個人が公開しているイメージは、中に何が入っているか分からないので注意

クローズドな環境で運用する場合はそのネットワーク内にコンテナレジストリを立てることが望ましい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/215103/f9b566a7-597a-af79-a968-be6ddc93b4a9.png)

レジストリからイメージをダウンロードすることを`pull`、アップロードすることを`push`と呼ぶ。

# まとめ

## Docker

- **コンテナイメージ** … コンテナのテンプレート。既存のイメージにファイルを追加(変更)して
                       カスタムイメージを作ることができる。

- **コンテナインスタンス** … コンテナイメージから作成する実際の実行環境。
                           内部的にはイメージを参照しているだけなので作成は一瞬。ストレージもあまり使わない。

- **コンテナレジストリ** … コンテナイメージを保管しておく場所。
                         インターネット上にもあるし、ローカルにも立てられる。