← CS/SE Fundamentals
OS とインフラストラクチャ (OS & Infrastructure)
はじめに
アプリケーションコードは OS の上で動き、インフラストラクチャの上にデプロイされる。この「土台」を理解することで、パフォーマンス問題の診断、適切なリソース設計、そして安定した運用が可能になる。
OS の基礎概念
プロセスとスレッド
プロセス (Process): OS が管理するプログラムの実行単位。独立したメモリ空間を持つ。
スレッド (Thread): プロセス内の実行単位。同じプロセス内のスレッドはメモリ空間を共有する。
プロセス A プロセス B
┌──────────────────┐ ┌──────────────────┐
│ メモリ空間 A │ │ メモリ空間 B │
│ ┌──────┐┌──────┐ │ │ ┌──────┐ │
│ │Thread││Thread│ │ │ │Thread│ │
│ │ 1 ││ 2 │ │ │ │ 1 │ │
│ └──────┘└──────┘ │ │ └──────┘ │
└──────────────────┘ └──────────────────┘
メモリを共有 独立したメモリ
Web アプリケーションとの関連:
- Node.js: シングルスレッド + イベントループ。CPU バウンドな処理はワーカースレッドを使う
- Java/Go: マルチスレッドが標準的
- Python: GIL (Global Interpreter Lock) の制約。マルチプロセスで並列化
並行性 (Concurrency) と 並列性 (Parallelism)
- 並行性: 複数のタスクを「交互に」進める (1つの CPU コアでも可能)
- 並列性: 複数のタスクを「同時に」進める (複数の CPU コアが必要)
実務での影響: Web サーバーが同時に多数のリクエストを処理する仕組みを理解する上で重要。
メモリ管理
仮想メモリ: 各プロセスに独立したアドレス空間を提供する仕組み。物理メモリより大きなメモリを使えるように見せかける。
スタックとヒープ:
- スタック: 関数のローカル変数。自動的に確保・解放。高速だがサイズ制限あり
- ヒープ: 動的に確保するメモリ。GC (Garbage Collection) やプログラマが管理
メモリリーク: 不要になったメモリが解放されず蓄積する問題。GC のある言語でも、参照が残っていると発生する。
// メモリリークの例: グローバルなキャッシュが無限に成長
const cache: Map<string, any> = new Map();
function processRequest(key: string, data: any) {
cache.set(key, data); // 削除されない → メモリリーク
}
// 対策: TTL 付きキャッシュや LRU キャッシュを使う
ファイルシステム
- ファイルディスクリプタ: OS がファイルやソケットを管理する番号。上限がある (
ulimit -n) - ファイルのパーミッション: 読み取り (r)、書き込み (w)、実行 (x)
- シンボリックリンク: ファイルやディレクトリへの参照
コンテナ技術
Docker
アプリケーションとその依存関係をパッケージ化し、どこでも同じように実行できるようにする技術。
従来の仮想化: コンテナ:
┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐
│App A│ │App B│ │App A│ │App B│ │App C│
├─────┤ ├─────┤ ├─────┤ ├─────┤ ├─────┤
│Guest│ │Guest│ │ Container Runtime │
│ OS │ │ OS │ │ (Docker Engine) │
├─────┴─┴─────┤ ├──────────────────────┤
│ Hypervisor │ │ Host OS │
├─────────────┤ ├──────────────────────┤
│ Hardware │ │ Hardware │
└─────────────┘ └──────────────────────┘
重い (GB 単位) 軽い (MB 単位)
主要概念:
| 概念 | 説明 |
|---|---|
| Image | コンテナの設計図。レイヤー構造で構成 |
| Container | Image から作成された実行インスタンス |
| Dockerfile | Image のビルド手順を記述するファイル |
| Registry | Image の保管場所 (Docker Hub, ECR) |
| Volume | コンテナの外部にデータを永続化する仕組み |
# Dockerfile の例
FROM node:20-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci --production
COPY . .
EXPOSE 3000
CMD ["node", "dist/server.js"]
Docker のベストプラクティス:
- マルチステージビルドで Image サイズを最小化
.dockerignoreで不要なファイルを除外rootユーザーでの実行を避ける- レイヤーキャッシュを活用するために
COPYの順序を工夫
Docker Compose
複数のコンテナを定義・管理するツール。ローカル開発環境の構築に便利。
# docker-compose.yml の例
services:
app:
build: .
ports:
- "3000:3000"
environment:
DATABASE_URL: postgres://user:pass@db:5432/app
depends_on:
- db
- redis
db:
image: postgres:16
volumes:
- pgdata:/var/lib/postgresql/data
environment:
POSTGRES_PASSWORD: pass
redis:
image: redis:7-alpine
volumes:
pgdata:
コンテナオーケストレーション
本番環境で複数のコンテナを管理する仕組み。
- Kubernetes (K8s): 業界標準のオーケストレーションプラットフォーム。強力だが複雑
- AWS ECS: AWS ネイティブのコンテナ管理サービス。K8s より学習コストが低い
- AWS Fargate: サーバーレスでコンテナを実行。インフラ管理不要
クラウド (AWS) の主要概念
ネットワーク
VPC (Virtual Private Cloud): AWS 上の仮想ネットワーク。自分専用のネットワーク空間。
VPC (10.0.0.0/16)
├── Public Subnet (10.0.1.0/24)
│ ├── ALB (ロードバランサー)
│ └── NAT Gateway
├── Private Subnet (10.0.2.0/24)
│ └── ECS Tasks (アプリケーション)
└── Private Subnet (10.0.3.0/24)
└── RDS (データベース)
- Public Subnet: インターネットからアクセス可能
- Private Subnet: インターネットからの直接アクセスを遮断
- Security Group: インスタンスレベルのファイアウォール
- NACL: サブネットレベルのファイアウォール
コンピューティング
| サービス | 説明 | 使いどころ |
|---|---|---|
| EC2 | 仮想サーバー | 柔軟な制御が必要な場合 |
| ECS | コンテナ管理 | Docker ベースのアプリケーション |
| Fargate | サーバーレスコンテナ | インフラ管理を最小化 |
| Lambda | サーバーレス関数 | イベント駆動の処理 |
ストレージ
| サービス | 説明 | 使いどころ |
|---|---|---|
| S3 | オブジェクトストレージ | ファイル、画像、バックアップ |
| EBS | ブロックストレージ | EC2 のディスク |
| RDS | マネージド DB | PostgreSQL, MySQL |
| ElastiCache | マネージドキャッシュ | Redis, Memcached |
IAM (Identity and Access Management)
AWS リソースへのアクセス制御。
- ユーザー: 人間のアカウント
- ロール: サービスやアプリケーションに付与する権限
- ポリシー: 「何に対して」「何ができるか」を定義する JSON
- 最小権限の原則: 必要最小限の権限のみを付与
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject"],
"Resource": "arn:aws:s3:::raica-patient-documents/*"
}
]
}
Infrastructure as Code (IaC)
インフラをコードで定義・管理する手法。手動操作によるミスを防ぎ、再現性を確保する。
主要ツール
| ツール | 特徴 |
|---|---|
| Terraform | クラウド非依存。宣言的な HCL で記述 |
| AWS CDK | プログラミング言語 (TypeScript 等) で AWS リソースを定義 |
| CloudFormation | AWS ネイティブ。YAML/JSON で記述 |
| Pulumi | プログラミング言語で記述。マルチクラウド対応 |
# Terraform の例: ECS サービスの定義
resource "aws_ecs_service" "app" {
name = "raica-app"
cluster = aws_ecs_cluster.main.id
task_definition = aws_ecs_task_definition.app.arn
desired_count = 2
launch_type = "FARGATE"
network_configuration {
subnets = [aws_subnet.private_a.id, aws_subnet.private_c.id]
security_groups = [aws_security_group.app.id]
}
load_balancer {
target_group_arn = aws_lb_target_group.app.arn
container_name = "app"
container_port = 3000
}
}
IaC の原則
- すべてをコードで管理: 手動でのコンソール操作を避ける
- バージョン管理: Terraform ファイルも Git で管理
- 環境の分離: dev / staging / production を同じコードから作成
- 状態管理: Terraform の state ファイルはリモート (S3) で管理
監視とオブザーバビリティ
三本柱
| 柱 | 説明 | ツール例 |
|---|---|---|
| Metrics | 数値データの時系列 (CPU 使用率、リクエスト数) | CloudWatch, Datadog |
| Logs | イベントの記録 | CloudWatch Logs, ELK Stack |
| Traces | リクエストのシステム横断的な追跡 | X-Ray, Jaeger |
アラートの設計
- ユーザー影響に基づく: CPU 使用率ではなく、エラーレートやレイテンシでアラート
- アクショナブル: アラートを受けた人が何をすべきか明確に
- アラート疲れを避ける: 重要度に応じた段階的な通知
Agent-first 開発においてこれが重要な理由
インフラの知識は、エージェントに実行環境の制約と要件を正しく伝えるために不可欠だ。
- Dockerfile の最適化を指示できる: 「マルチステージビルドを使って」「非 root ユーザーで実行して」と具体的に指示できる
- リソース制約を伝えられる: 「Fargate のメモリは 512MB なので、メモリ効率を意識して」と制約を明示できる
- IaC のレビューができる: エージェントが生成した Terraform コードのセキュリティや設計を評価できる
- 運用上の問題を予見できる: 「この設計だとデプロイ時にダウンタイムが発生する」といった問題を事前に指摘できる
インフラは「動いているうちは見えない」が、問題が起きたときに知識の有無が対応速度を大きく左右する。
Further Reading
- Docker Documentation - Docker 公式ドキュメント
- AWS Well-Architected Labs - AWS のハンズオン
- Terraform: Up & Running (書籍) - Terraform の実践ガイド
- The Linux Command Line (書籍/Web) - Linux の基礎
- SRE Book (Google) - Site Reliability Engineering の教科書