前回のDay 01では、DockerがVMと何が違うのか、そしてGitとの組み合わせがなぜ強力なのかの全体像を掴んでいただきました。
第2回となる本日は、Hyper-VやVMware、あるいはオンプレミスの物理サーバーを長年設計・運用してきたベテランエンジニアの皆様に向けて、Dockerの核心である「プロセス分離(Namespace / cgroups)」の正体を徹底解剖します!
① 導入・本日の達成目標
「ゲストOSを起動していないのに、どうして他のアプリとポート番号やファイルが干渉しないのか?」
「Windows上で開発しているC#アプリが、なぜLinuxコンテナの上で爆速に動くのか?」
これらは、従来の「OSを1台丸ごと立ててIISを動かす」というインフラ常識を持っている方ほど強く疑問に感じるポイントです。 本講義をマスターすれば、以下の3つの目標を完全にクリアできます。
- コンテナの真の姿=「隔離壁を立てられたただのLinuxプロセス」であることを論理的に腹落ちさせる。
- プロセス分離を実現するLinuxカーネルの2大機能「Namespace(名前空間分離)」と「cgroups(リソース制御)」の仕組みを完全理解する。
- 従来のWindows Server/IIS構築手順書(Excel文化)から、C# × Linuxコンテナ(Kestrel)のIaC運用への転換ノウハウを掴む。
② 物理・VM技術者のための「プロセス分離」とは?
Hyper-VやVMware ESXiなどの仮想化技術(ハイパーバイザー型)では、CPUやメモリ、ディスクといったハードウェアを仮想的にエミュレートし、その上で独立したWindows ServerやCentOSの「ゲストOS」を丸ごとブートさせていました。
しかし、DockerコンテナにはゲストOSの起動プロセス(BIOS起動、カーネルロード、デーモン初期化等)が一切存在しません。
ホストOSのLinuxカーネル(Windows環境ではWSL2の軽量Linuxカーネル)の上で、「あたかも自分専用のOS環境が与えられているかのように錯覚させた普通のプロセス」として直接実行されます。
📊 構造の違いによる決定的な動作差分
③ Linuxカーネルの秘密:Namespace と cgroups
では、なぜ同じカーネルを共有しているのに、他のプロセスとポートやファイルが混ざらないのでしょうか?
それを可能にしているのが、Linuxカーネルに組み込まれた「Namespace(名前空間)」と「cgroups(コントロールグループ)」という2大基盤技術です。
[1] Namespace(見え方の隔離=目隠しの壁)
Namespaceは、プロセスに対して「見える世界(名前空間)」を個別・独立に切り出す技術です。
- PID Namespace(プロセスIDの隔離): コンテナ内のプロセスは自分自身を「PID 1(初期プロセス)」として認識します。ホストOS上の他の無数のプロセスは見えません。
- NET Namespace(ネットワークの隔離): コンテナごとに固有の仮想ネットワークインターフェース(IPアドレスやルーティングテーブル)が割り振られます。そのため、複数のコンテナが同時に「ポート8080」をリッスンしても衝突しません。
- MNT Namespace(マウント/ファイルシステムの隔離): コンテナには専用のルートファイルシステム(
/)が見え、ホストOSのファイルシステムとは完全に分離されます。 - IPC / UTS / USER Namespace: プロセス間通信、ホスト名、ユーザーID(root権限の分離)もそれぞれ個別に隔離されます。
[2] cgroups(資源の制限=厳格なメーター)
cgroups(Control Groups)は、「CPU、メモリ、ディスクI/O、ネットワーク帯域」などの物理リソース消費に厳格な上限枠を設定する技術です。
「このコンテナには最大でCPU 1コア、メモリ512MBまで」と指定しておけば、万が一個別のアプリがメモリリークや無限ループを起こしても、ホストOS全体や隣のコンテナを巻き込んでダウンする事故を100%防ぐことができます。
④ Windowsコンテナ vs Linuxコンテナ(C#開発者の常識シフト)
長年.NET Frameworkを使ってきたエンジニアにとって、最大の関心事は「C#はWindowsで動かすものじゃないの?」という点でしょう。
かつての .NET Framework(4.x系)は Windows OS および IIS(Internet Information Services)に密結合していました。 しかし、現在の .NET Core 以降(.NET 8 / .NET 9)は完全なクロスプラットフォーム設計です。
- Kestrel Webサーバーの超高速性: IISの重厚なパイプラインを通さず、C#純正の軽量・高スループットサーバー「Kestrel」が直接リクエストを捌く。
- 極小のイメージサイズ: Windowsコンテナ(OSイメージ数GB)に対し、Alpine Linuxベースの.NETランタイムならわずか 100MB前後。
- WSL2(Windows Subsystem for Linux 2)との親和性: 開発用Windows PCでも、裏側で本番と同じLinuxカーネルが動くため、環境差分が完全にゼロになる。
⑤ C# / .NET 現場での実践アプローチ
Linuxコンテナ上で動く最小構成の ASP.NET Core Web API と、プロセス分離を実感するためのCLI操作を見ていきましょう。
[A] 高速・安全なマルチステージ Dockerfile
# 1. 実行環境(超軽量なLinux .NET 8 ASP.NETランタイム) FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base WORKDIR /app EXPOSE 8080 ENV ASPNETCORE_URLS=http://+:8080 # 2. ビルド環境(SDKイメージ) FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build WORKDIR /src COPY ["OrderService.csproj", "./"] RUN dotnet restore "OrderService.csproj" COPY . . RUN dotnet publish "OrderService.csproj" -c Release -o /app/publish /p:UseAppHost=false # 3. 最終成果物(SDKを除外し、バイナリのみを配置) FROM base AS final WORKDIR /app COPY --from=build /app/publish . ENTRYPOINT ["dotnet", "OrderService.dll"]
[B] コンテナプロセスの正体を確認するコマンド(PowerShell)
# 1. リソース制限(cgroups)を指定してコンテナを起動 # --cpus 1.5 : CPUを1.5コアに制限 # --memory 512m : メモリを最大512MBに制限 docker run -d -p 8080:8080 --cpus="1.5" --memory="512m" --name order_api orderservice:v1 # 2. コンテナ内部で動いているプロセス一覧を確認(Namespaceによる隔離を確認) docker top order_api # 3. リソース使用量(CPU/メモリのリアルタイム計測)を確認 docker stats order_api --no-stream
[C] 4大AIエージェントへの指示プロンプト例
「この.NET 8 Web APIプロジェクトのDockerfileをレビューし、非rootユーザー(appuser)での実行設定を追加してセキュリティを強化してください。また、cgroups制限(メモリ512MB、CPU 1コア)を明記したdocker-compose.ymlを作成し、Gitコミットしてください。」
⑥ 手順書文化からコード管理(IaC)への脱却
オンプレミスやVM全盛期、私たちは「WordやExcelで書かれた50ページの手順書」を片手に、サーバー構築作業を行ってきました。
しかし手順書運用には「画面のボタン位置が変わった」「ライブラリの更新で動かなくなった」「作業者のタイポ」といった人的リスクが常に付きまといます。
Dockerでは、あらゆる設定がDockerfileという数行のテキストファイルに凝縮されます。 Gitリポジトリで管理されたDockerfileがあれば、コマンド1発で誰でも、どのPCでも、寸分狂わず同一の実行環境を1秒で立ち上げることが可能です。
「Windows統合認証(Active Directory)やレジストリ依存をそのまま持ち込もうとする罠」
従来のオンプレミスASP.NETでは、IISのWindows認証やActive Directoryドメイン参加、Windowsレジストリの設定に依存した設計が多く見られました。
Linuxコンテナへ移行する際は、認証を JWT(JSON Web Token)や OpenID Connect / OAuth2.0 に刷新し、設定値はレジストリではなく 環境変数(Environment Variables)や appsettings.json 経由で注入するのがモダン開発の鉄則です。
- コンテナの正体は「ゲストOSを持たない隔離されたLinuxプロセス」である。
- Namespace(壁・視界遮断)とcgroups(メーター・資源制限)が安全な分離を保証する。
- 現代のC#/.NETはLinuxコンテナ+Kestrelで動かすことで、極小サイズ・秒速起動・高集約を実現する。
『「私のPCでは動くのに」問題の根本原因とDockerによる解決』〜イミュータブルインフラストラクチャの衝撃〜
コメント
コメントを投稿