【入門書のメモ】Docker入門

# はじめに
こんにちは。オガネソンです。今回は僕の大好きなDockerについて、[こちらの本](https://www.amazon.co.jp/%E9%96%8B%E7%99%BA%E7%B3%BB%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AEDocker%E7%B5%B5%E3%81%A8%E3%81%8D%E5%85%A5%E9%96%80-%E9%88%B4%E6%9C%A8%E4%BA%AE/dp/4798071501?tag=googhydr-22&source=dsa&hvcampaign=books&gad_source=1)を参考に勉強したのでそれをまとめようと思います！
![q](https://www.shuwasystem.co.jp//images/book/640397.jpg)

# 仮想マシン
まず前提となる仮想マシンの定義についておさえます。
## 仮想化とは
- 物理マシン：OS、CPUなどの物理的に用意できるコンピューター
- 仮想マシン：ハードウェアの一部をソフトウェアで実現したもの
### 物理マシンをわざわざ他に用意しないで良いように仮想マシンを用意すること
  
## 仮想化のメリット
- 物理マシンのリソースを節約できる
- CPU、メモリの変更もソフトウェアの設定で変更できる
- それぞれのソフトウェアの用途によって環境を分けることができる
- 開発者の物理マシンの差異を無くすことができる

## どのように仮想化しているのか
- 1 ホスト型仮想化　VirtualMachine　ホストOSでゲストOSを起動できる
- 2 ハイパーバイザー型仮想化　Hyper-V　物理マシンにインストールして起動
- 3 コンテナ型仮想化　Docker、Podman　ホストOSにインストールしてコンテナ単位で管理

ゲストOSは起動しないのでリソース消費が少なく、起動が速い。
ゲストOSが無いのでホストOS（またはLinux仮想マシン）のLinuxカーネルを使用して起動する
  
## コンテナ型仮想化のメリット
- 一つのコンテナで一つのアプリケーションを管理できる（個々の要素をアップデートしやすい）
- アプリケーションの実行環境ごと移動できる

## 問題点
- Linuxマシンが必要
- CPUアーキテクチャが違うとコンテナも違う
      intel用のamd64とApple Silicon用のArm64で借りるLinux仮想マシンが違うから
  
# Dockerの構成要素
## Docker engine：Docker daemon、CLIクライアント、daemonの提供するAPIの3つを管理するパッケージ。

## Docker daemon：Dockerを起動するために必要なサーバー。CLIクライアントから命令を受けると実行する。
## Docker compose：複数コンテナを一括で起動するためのツール
## Docker desktop：GUIでDockerを扱うアプリケーション。上記の他、内臓CPUに対応したLinuxカーネルも持つ。
## Docker hub：コンテナの元になるイメージを管理できるレジストリサービス。
  
# コンテナとイメージの仕様
## Open Container Initiative（OCI）
コンテナの仕様を定義している。OCI Runtime SpecificationとOCI Image Specificationに分かれる。

# コマンドとプロセス
- コマンド：Linuxコマンド
- プロセス：プログラムの中でも実行して動作中のもの。OSに管理され、終了したら消える
- プロセスID：OSがプロセスを管理するために割り当てる一意の番号。すべてのプロセスの親になるプロセスのIDは1

# コンテナとは
  **ホストマシンから隔離されたプロセスのメモリ領域のこと。**
  コンテナでの最初に実行されるプロセスのプロセスIDは１

## コンテナの特徴
  - １。コンテナはイメージから作る
  - ２。個々のコンテナは独立
  - ３．コンテナはコンテナランタイムがあればどこでも動く（クラウド上、PCどちらでも）

# イメージとは
  コンテナの実行に必要なパッケージ。複数のレイヤーごとにtarファイルで格納されている。
  レイヤーを上に重ね合わせることでイメージを作る。

# Dockerfileとは
  イメージにレイヤーを追加する設定ファイル。元になるイメージの上にレイヤーを重ねる。

# Dockerに対するコマンド
  - container：大まかに４つの状態に対して対応する命令がある
  - volume：コンテナに紐づけるディレクトリ、ファイルに対しての命令
  - network：コンテナ同士で通信できるネットワークに対しての命令
  - image：イメージに対しての命令（よく使うのはDockerfileからビルドする命令）
  
# コンテナの７つのステータス（状態）
  - created：コンテナが作成された。PID1は存在しない
  - running：コンテナ起動中。PID1が実行中
  - paused：一時停止。PID1が停止（ほぼ使わない）
  - （restarting：再起動）
  - exited：コンテナが終了。PID1が存在しない
  - （dead：終了に失敗）
  - （removing：削除された）

# コンテナへのコマンド（dockerコマンドのサブコマンドなので省略）
  - container run：起動する
  - container ls：コンテナ一覧を確認する
  - container stop [複数コンテナ]：コンテナを終了する
  - container rm：コンテナを削除する
  - rm -f：コンテナの終了＋削除
  - container logs [オプション] コンテナ名：コンテナの出力の確認ができる
        `--follow、-f`：出力されたログの最新情報を常に表示
  
- container exec [オプション] コンテナ名 [コマンド] [引数]：起動中コンテナにコマンドを追加
        `-it`：インライン実行できる
        execは既にPID1が存在するコンテナで新しくプロセスを追加している
  

# コンテナへのコマンド応用
  - container run [オプション] イメージ名 [実行コマンド]：オプションの機能を使ってコンテナをイメージから実行コマンドによって起動する
## container runのオプション一覧

--name：コンテナの名前を指定

--rm：終了したらコンテナを削除

--interactive --tty、-it：コンテナのインライン実行（シェルでコマンドを実行できる）

--publish、-p：コンテナのポートをホストマシンに公開（主にwebページにアクセス）、ホストマシンのポート:コンテナのポート　で表記する

--env、-e：コンテナの環境変数の設定

--detach、-d：コンテナをバックグラウンドで実行（入出力ストリームを分離）->コンテナが起動したかの判断が難しくなる

--mount type=volume | bind ,source=マウント元,destination=マウント先：コンテナにマウント（紐づけ）したいファイルを指定できる

（--volume マウント先:マウント元：ボリュームのマウント（簡易バージョン））

--network：デフォルトブリッジネットワークをコンテナ起動時に利用できる
  

### コラム（container attach）アタッチは、ホストマシンのシェル操作をコンテナに紐づけることを指す。
コンテナの起動にはcontainer create->exec->attachが隠れている
         **detachしてからattachするとdetachしていない状態に戻る！**
         
# イメージの基礎
  コンテナ内の変更は他の環境には一切影響しないため、今後のコンテナに設定を反映させたい場合はイメージを変更する必要がある。

## 完全なイメージ名とタグ
  **[ホスト[:ポート番号]/][名前空間]レポジトリ:タグ** ：ホストは、レジストリサービスのホスト名（だいたいDocker hubのdocker.io）
- 名前空間は大体Docker公式を意味するlibrary
- レポジトリは必須で、イメージの名前部分
- タグはイメージの派生を示す識別子（省略するとlatest）

## レイヤーとメタデータ
- レイヤー（イメージレイヤー）は読み取り専用だが、コンテナ作成時にコンテナレイヤーという書き込み可能なレイヤーが最上位に作られる
  - コンテナでいろいろな設定ができるのはコンテナレイヤーのおかげ
  - コンテナレイヤーはコンテナ終了時（Ctrl+C）に削除される
  - コンテナを建てるときのベースイメージがイメージレイヤー
  
- **メタデータ**：イメージがレイヤーとは別に、環境変数や起動時のデフォルトコマンドを保存してある。

## イメージへのコマンド
  - image ls [リポジトリ]：イメージの一覧を確認（同じリポジトリのイメージを指定して取得できる）
  - image pull：イメージをレジストリから取得
  - image history：イメージのビルドの履歴を表示
  - image inspect ：イメージの詳細を確認（JSON形式でタグや環境変数、コマンドが表示）
                          ConfigとContainerConfigが出るが、ContainerConfigはイメージを作成したときのコンテナ情報
  - image build [オプション] Dockerfileのパス|URL：イメージをビルドしてコンテナを作成

# コンテナをイメージにする
  - container commit [オプション] コンテナ名 イメージ名：コンテナにある環境をイメージにする
  - container export + image import [オプション] file|URL| イメージ名：コンテナをtarファイルに変換してからイメージにする（メタデータが保存されない）
  - image save [-o ファイル名] + image load [-i ファイル名]：saveで作成したtarファイルをloadで読み込む（メタデータは保存される）

**デメリット：tarファイルではどのような操作をしたイメージか把握できない（再現性がない）**
  
# Dockerfileの基礎
  - Docker hubにあるレイヤー情報がこれ　コンテナの構築履歴を作る　RUNがレイヤー、ENVがメタデータを作る
  - FROMで元となるベースイメージの命令をそのまま実行する。たどっていくとscratchというイメージにたどりつく
  - ベースイメージは作成したいイメージに近いものを採用する！

## Dockerfileの命令
  - `FROM` [--platform=プラットフォーム] イメージ名：ベースイメージを指定する
- `RUN` コマンド：コマンドを実行して、その結果を新たなレイヤーとして確定する。
  - Tips:コマンドを&&や;でつなげるとレイヤーが少なくなって便利
               ベースイメージでコツコツ実行したコマンドを貼り付ける方が確実
- `ENV` キー=値：イメージのメタデータに環境変数を追加（タイムゾーン、パスなど）
- `COPY` [--chown=user:group] [--chmod=perms] 移したいファイル コンテナ内のパス：イメージのレイヤーにファイルをコピー
- `CMD` ["実行コマンド","param1","param2",...]：コンテナ起動時に実行するコマンド（絶対パスが推奨）

# ボリュームとネットワークの基礎
  - コンテナで行ったファイルの変更をローカルでも保存したいとき、ボリュームを使う
  - データをコンテナの生死にかかわらず連動して保持し続けられる
  - ボリュームはDocker engineの管理するストレージをコンテナにマウント（Docker engineだけ影響）
### バインドマウントとは：ホストマシンのディレクトリをコンテナにマウント（ホストマシンに影響）
  
- ネットワークドライバ：仮想ネットワークを制御するソフトウェア。複数あるから切り替えられる（plaggable）
  - ブリッジネットワーク：デフォルトのドライバ。同一Docker engine上にあるコンテナで相互通信できる
**ユーザ定義ブリッジネットワークを使うことが推奨**

## ボリュームとネットワークに対するコマンド
  - volume create [--name] ボリューム名：ボリュームの作成
  - volume ls：ボリューム確認
  - network create ネットワーク名：ブリッジネットワークを作成
  - network ls：ネットワークの確認 bridgeとhostとnoneはDockerが自動で作成するデフォルトのネットワーク

# Docker Composeの基礎
  複数コンテナの定義および実行をするためのツール。yamlファイルに定義した内容に従って全てのコンテナを起動
  
  バージョンが１と２あり、１は2021年5月以降アップデートされていない。
  一つ一つのコンテナをサービスとして扱う
  
  起動時にブリッジネットワークを作成するのでサービス名を指定すれば通信できる

# 終わりに
画像が一つも無くてすみませんw
## 参考文献

https://www.amazon.co.jp/%E9%96%8B%E7%99%BA%E7%B3%BB%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AEDocker%E7%B5%B5%E3%81%A8%E3%81%8D%E5%85%A5%E9%96%80-%E9%88%B4%E6%9C%A8%E4%BA%AE/dp/4798071501?tag=googhydr-22&source=dsa&hvcampaign=books&gad_source=1