仮想化、コンテナ、Docker、Kubernetesに関する自習メモ

# 概要
[図解即戦力 仮想化&コンテナがこれ1冊でしっかりわかる教科書](https://www.amazon.co.jp/%E5%9B%B3%E8%A7%A3%E5%8D%B3%E6%88%A6%E5%8A%9B-%E4%BB%AE%E6%83%B3%E5%8C%96-%E3%82%B3%E3%83%B3%E3%83%86%E3%83%8A%E3%81%8C%E3%81%93%E3%82%8C1%E5%86%8A%E3%81%A7%E3%81%97%E3%81%A3%E3%81%8B%E3%82%8A%E3%82%8F%E3%81%8B%E3%82%8B%E6%95%99%E7%A7%91%E6%9B%B8-%E4%BA%94%E5%8D%81%E5%B5%90-%E8%B2%B4%E4%B9%8B/dp/4297116901)の1章から5章までを、色々調べながら通読した過程で残したメモ。章立ては概ね本書の構成を踏襲。適宜アップデートしていく予定。

# 仮想化とは
* 実体のないものをあたかも実在しているかのごとく表現する技術
* サーバ仮想化、ネットワーク仮想化、ストレージ仮想化などがある
* クラウドとは仮想化技術によって構築されたインフラやその上に構築されたサービスのこと

|メリット|デメリット|
|----|----|
|環境のバックアップが容易で、耐障害性が高い|仮想化の導入や維持にコストが発生<br>→費用対効果を考え採用可否を検討する|
|柔軟にCPUやメモリなどスペック変更可能<br>(柔軟にスケールアップ/ダウン、スケールアウト/イン可能)|仮想化の処理をはさむことで、物理環境よりも性能が劣ることがある|

# サーバ仮想化
* ホストOS型、ハイパーバイザ型、コンテナ型の3種がある
* 仮想マシン (VM) とは、ゲストOS とアプリケーションを搭載した環境を提供するプログラム。ホストOSやその他のVMからは隔離されている。ホストOS型とハイパーバイザ型で使用。
Ref）[仮想マシンとは？よく聞く"仮想化" "仮想マシン"の基礎知識と特徴を解説](https://ferret-plus.com/8461)
[コンテナ技術と仮想マシンの違いとは？](https://psc-smartwork.com/topics/2021/08/162.html)

|サーバ仮想化の種類|説明|アーキテクチャ|
|----|----|----|
|ホストOS型仮想化|物理サーバにOSがインストールされ、その上で仮想サーバ(仮想マシン、ゲストOS、アプリのセット)が動作させる技術|物理サーバ→ホストOS→仮想化ソフト(Virtual Box, VMware etc)→仮想マシン→ゲストOS→アプリ|
|ハイパーバイザ型仮想化|物理サーバにOSインストール不要、ハイパーバイザ型仮想化ソフト上で仮想サーバを動作させる技術。ゲストOSで直接制御するため実機のリソースを活用しやすい|物理サーバ→ハイパーバイザ型仮想化ソフト(VMware etc)→仮想マシン→ゲストOS→アプリ|
|コンテナ型仮想化|OS単位ではなく**アプリ単位で仮想化する技術**|物理サーバ→ホストOS→コンテナ型仮想化ソフト(代表例がDocker)→アプリ|



# コンテナとは
* OSで実行されているプロセスであり、アプリケーションと実行環境をまとめて隔離する仕組み
Ref)
[Dockerライフサイクルの基礎　地雷を踏み抜けろ！のp.10,11
](https://www.slideshare.net/zembutsu/docker-underlying-and-containers-lifecycle)
* 仮想マシンやゲストOSが不要のため、手軽にアプリの導入可能。この手軽さが最大のメリット。
* 特に重要なのは、ファイルシステムの隔離。通常のプロセスは、OSのファイルシステムを他のプロセスと共有するのに対して、コンテナはそのコンテナ専用の独立したファイルシステムを使用しているため、ホストOS内にインストールされた他のアプリやファイルの影響は受けない。


* コンテナ技術は、開発と運用のスムーズな連携に活用できる。
* 一部のコンテナがボトルネックとなってシステム全体の処理能力が低下している場合に、ボトルネックとなるコンテナを複数起動することによって負荷を分散し、処理能力の低下を改善することができる

# Dockerとは
* コンテナ型仮想化ソフトウェアのデファクトスタンダード
* コンテナやコンテナイメージを操作する際にはDockerコマンドを利用。コンテナイメージの作成は実際には手作業で行わず、コンテナイメージの作成に必要なコマンドを記載したDockerfileの実行により行う。

### コンテナイメージ
* コンテナを実行するためのテンプレート
* コンテナイメージとコンテナの関係は、オブジェクト指向におけるクラスとオブジェクトの関係と似ている。
* コンテナイメージの大部分はコンテナの実行に必要なファイルシステムであり、ファイルシステムはレイヤー構造となっている。コンテナイメージは、ベースとなるコンテナイメージのファイルシステムに新しいレイヤーを重ねることによって作成
* コンテナイメージは、コンテナレジストリを介して配布
* Linuxマシンで動作するLinuxコンテナ、Windowsマシンで動作するWindowsコンテナがある。これらOSのコンテナイメージ(ベースイメージなどと呼ばれる)は、OSそのものを起動しているわけではなく、あくまでもアプリケーションの動作に必要な環境を「それっぽく」再現しているに過ぎない。
Ref) 
[コンテナってなんだろう― 「コンテナ」の概要を知る
](https://thinkit.co.jp/article/17301)[なぜDockerではホストOSと違うOSベースのコンテナイメージが動くのか
](https://qiita.com/kirikunix/items/33414240b4cacee362da)

### データの永続化
* コンテナは削除するとコンテナ上のデータが消えてしまうので、データを残しておきたい場合、Dockerのボリュームという機能を利用。また、似た機能としてバインドマウントという機能もある。

|マウントの種類|説明|
|----|----|
|ボリューム|Dockerが管理するディレクトリでホストマシンからは分離。コンテナ間でデータを共有する際にも利用可能。Dockerでデータを保持するための最良の方法。|
|バインドマウント|ホストOSのファイルシステムをコンテナにマウントする。主にホストとコンテナの間でファイルシステムを共有するための方法。|

Ref)
[Dockerのマウント3種類についてわかったことをまとめる
](https://qiita.com/y518gaku/items/456f34c317a65a9dae86)[コンテナでデータを管理する](https://docs.docker.jp/engine/userguide/dockervolumes.html)
[Kubernetes道場 5日目 - Volumeについて](https://cstoku.dev/posts/2018/k8sdojo-05/)

### リソースの隔離・管理
* Dockerでは名前空間のしくみを使って、コンテナを他のコンテナから隔離する。名前空間によって隔離されるリソースには、プロセスID、ネットワークインタフェース、ファイルシステムなどがある。
* ハードウェアリソース(CPUのコア数やメモリ容量、ディスクI/Oなど)の使用量に上限を設けるためにはcontrol groups(cgroups)と呼ばれる仕組みを利用。

# Kubernetesとは
* コンテナオーケストレーションツール(コンテナの管理・運用を自動化)のデファクトスタンダード。K8sと略記する(「ケーエイツ」、「ケーハチエス」と呼ぶ)。
* マニフェストと呼ばれるテキストファイルを使用してクラスタを操作。マニフェストはYAMLやJSON形式で宣言的に記述。

### Kubernetesクラスタ
* Kubernetesによって管理されるコンテナ化されたアプリケーションを実行するノードマシン群
* クラスタを構成する各マシンをノードと呼ぶ
* ノードには、ワーカーノードとマスターノードの2種がある
* Kubernetesクラスタはマスタとワーカーの2種類のノードから構成されるアーキテクチャ。ユーザーはkubectlなどを使ってマスターに命令を送り、マスターはその命令に従って、ワーカーを操作。

### K8sがコンテナを管理する単位

|単位|説明|
|----|----|
|ポッド|K8sがコンテナを管理するための最小単位。1つ以上のコンテナから構成。同じポッドに含まれるコンテナはライフサイクルが同じ。|
|レプリカセット|K8sがポッドを管理するための単位。対象とするポッドの複製(レプリカ)を指定した数だけ維持する機能。1つ以上のポッドから構成。|
|デプロイメント|1つ以上のレプリカセットから構成。自身に含まれるレプリカセットやポッドを自動で更新するためのしくみを備える。|

### サービス
* 役割はコンテナへアクセスするための窓口となるエンドポイントの提供と負荷分散の2つ
* 外部からコンテナへアクセスするには、直接アクセスはできず、エンドポイントを経由して間接的にアクセスする

|主なサービスのタイプ|説明|
|----|----|
|ClusterIP|クラスタ内部からのみアクセス可能な仮想IPアドレスを発行。クラスタ内部からのアクセスのみで十分な場合に利用。|
|NodePort|クラスタ内の全ノードへの指定ポートへのアクセスがコンテナへ転送される。クラスタ外部からもアクセス可能|

### コンテナ間の相互アクセス
#### ポッド内の通信
* 同じポッド内のコンテナはネットワークの名前空間を共有しているため、localhostで通信できる
* 1つのポッド内に複数コンテナを含める場合、ポートの競合が発生しないように調整が必要

#### ポッド間の通信
* ポッドにはユニークなIPアドレスが割り当てられるので、本IPアドレスを経由して外部からポッドに含まれるコンテナへアクセス可能

# その他参照資料
[Docker基本のキ再勉強
](https://zenn.dev/mosamosa/articles/c111de2df1424f)
[Kubernetes の導入時に考えるべきこと(Java Champion寺田さんのブログ)
](https://yoshio3.com/2019/07/20/appropriate-choice-of-k8s-environment/)