コンテナ
OCIコンテナとその周辺
Linuxベースのコンテナイメージとそれを実行するためのランタイム、配布のための仕様などからなる
Open Container Initiative のコンテナ仕様
OCI Image Spec
OCI Runtime Specification
OCI Distribution Spec
DockerやPodman, Kubernetesの運用単位
マイクロサービスの最小単位
その他
App Container (appc) (今はメンテナンスのみ)
というのもあるらしい
VMとの違い
Linuxカーネル1つで複数コンテナが動作する (LinuxカーネルがホストOSまたはVMで1つだけ必要)
コントロールグループ(cgroups) という機能でリソースを分割
他のOS (Windows, Macなど)の場合はLinux VMを1つ作り、その中で複数コンテナ環境が構築できる (間違いやすい点)
Linux VMの実行方法は複数ある(Windowsの場合 WSL2, Hyper-Vなど)
Linuxカーネルはコンテナ専用ではなく親カーネルのリソース分割的な機能を使用する
コンテナはカーネル/systemd起動の時間がないので(ベースのカーネルが動いているところから)VMと比べて高速起動可能
環境のエミュレートなどが不要 (カーネルの機能で実現する/ファイルシステムなどは所有者など多少辻褄合わせをしたりする)
単一アプリのインストール済みのimageを元に配布される
imageにカーネルは含まない、最小ランタイム等で構成する
カスタマイズ(差分作成, パラメータ等変更)が容易
コンテナimageは別のコンテナimageを継承して拡張できる
アップデートはimageの交換で簡潔
コンテナ内で実行できるのは1プロセスだけ (Web, DB, などなど, ルール的な縛り)
コンテナ内にbashなどがあれば確認のために(execで)入ったり実行したりはできる
ログ出力は標準出力が推奨?
systemd, cron が利用できない (ルール無視すればできなくもない)
stop, start が可能 (systemctl などと同じような動作基準)
aptなどは適用済みのimageを使用する前提で更新には使えない
更新があれば元のimageから作り直す
データは明確に分離する
永続化が必要なデータはimageと別にvolumeまたは外のファイルシステムをマウントして保存する
分離しないとセキュリティアップデートなどのimageの更新で消える
直接IPを振ることもできるが基本的に仮想ネットワークで接続、ポート転送するので他のポートは外部からアクセスできない
内部で利用するサービス/コンテナは同じportを複数使ってもコンテナ毎に仮想IPが異なるので問題ない(DBなど)
外部から見えるIPアドレスは基本的に親の1つ、同じポートを使用するサービスは外部公開では別IP割り当てなどが必要(Webなど)
Dockerは基本的に外側のrootで動作する、Podmanなどがユーザ権限でも実行可能
コンテナオーケストレーション(分散環境?)前提で構築可能
VMとの共通点
どこでも使えるようバイナリをパッケージ化したもの(CPU毎に作る)
コンテナ毎にOSっぽいイメージ(Linuxのカーネル以外)を持っている (DebianとかAlpineとかCentOSとかいろいろある)
外部と別にOSほぼまるっと持っているのでライブラリの依存関係を気にしなくていい
複数言語、ライブラリなどのバージョンを別々のコンテナに標準の手順で封入して同じコンテナランタイム環境上で実行できる
apt なども使えるので不足コマンドなどは(image作成時に)追加可能
コンテナの外側には基本的にアクセスできない (マウントなどは設定が必要、ネットワークは中から外が可)
仮想ネットワークも使えるよ
状態
構築周期
親image からアプリ、コマンドを追加してカスタム image を作成する手順 Dockerfile を作成する
hub などに構成 (cpu, os, バージョン, リビジョン別などで複数構成)
最新パッチが当たった状態でbuild
image を hub などに配置する
実行周期
volume 永続ファイル領域 確保
create image から container の生成 (ファイル領域の確保)
start 隔離プロセスの起動
exec 別のプロセスで接続
stop プロセスの終了
rm container 破棄 (ファイル領域の開放)
volume 開放
run create + start
create から rm は start から stop と近いくらい短命
apt update などは OS系image構築の段階で行ったものから再構築することで利用する方がよいが更新頻度が低いものもある
という条件でLinuxカーネルの設定を絞って実行させる環境。VMではなくchroot的なもので複数コンテナを実行するのもLinuxカーネル一つでこなす
systemd + パッケージ管理でファイル空間を独立させた感じ? Dockerはsystemdが嫌いなのか
Windows/MacではWSL2などのLinux VM 1つが必要、VMのUbuntuなどの中で構築/実行することもできる
複数VMがあれば別々のコンテナ環境も使える、コンテナの中で別のコンテナの実行もできなくはない
環境もいろいろあり、共通化されていたりする
Docker 有償化の流れで互換環境も増えた
Docker
containers Podman (RedHat)
containerd nerdctl
Open Container Initiative https://opencontainers.org/
runc 単体コンテナ実行
コンテナを複数組み合わせることで複雑な環境も手軽に構築できる、仮想ネットワークで繋がるよ
Compose系
compose specification https://compose-spec.io/
The Compose Specification https://github.com/compose-spec/compose-spec/blob/master/spec.md
Docker Compose
Podman compose (Docker Compose をPodman用に利用するか、サードパーティーのものがある)
Pod系
Kubernetes (Google? CNCF)
OpenShift (RedHat)
Podman (RedHat)
Podman Quadlet
Kubernetesなど複数コンテナ環境(context?)で自動負荷分散させるものをオーケストレーションというらしい
Kubernetes
OpenShift
Docker Swarm
CRI (Container Runtime Interface)
CRI-O https://cri-o.io/
Docker Engine
OCIランタイム Container Runtime
runc Go言語で書かれたもの(Docker寄贈?)
crun C言語で書き直されたもの
Kata https://katacontainers.io/ マイクロOS カーネル分離型
gVisor Go言語 カーネル部分エミュ(Google?) https://gvisor.dev/
ネットワーク
CNI
Netavark (Podman)
イメージはレジストリ(Docker Hubなど)に登録して共有もできる
コンテナレジストリ
Containerfile / Dockerfile から構築する
コマンドのパラメータ指定が多いのでCompose側などで指定するものも多い
JavaからはMavenのJib pluginなどでコンテナをさくっと作れたりするらしい