Kubernetesアーキテクチャの主要コンポーネント
Kubernetesクラスターを構成する核心的な要素について、その役割と連携関係を理解します。
コントロールプレーンコンポーネント
- APIサーバー:クラスター全体の統合的なエントリーポイント。すべての操作はこのコンポーネントを介して行われ、etcdとの連携により状態を管理します。
- スケジューラー:新規Podの配置先ノードを決定する意思決定エンジン。リソース要件や制約条件に基づいて最適なノードを選択します。
- コントローラーマネージャー:複数のコントローラープロセスを統合管理。ReplicaSetやDeploymentなどのコントローラーを実行し、望ましい状態を維持します。
- etcd:分散型キーバリューストア。Raftコンセンサスアルゴリズムにより高い一貫性を保証し、WAL(Write-Ahead Logging)とスナップショット機能でデータ永続化を実現します。
ノードレベルコンポーネント
- kubelet:各ノード上で動作するエージェント。CRI(Container Runtime Interface)を通じてコンテナランタイムと連携し、Podのライフサイクルを管理します。
- kube-proxy:サービス抽象化を実現するネットワークプロキシ。IPTablesまたはIPVSルールを動的に生成・管理し、Pod間の通信経路を確立します。
アドオンツール
- CoreDNS:クラスター内のサービスディスカバリーを担当。サービス名とIPアドレスの名前解決を提供します。
- Ingressコントローラー:HTTP/HTTPSレイヤー7のルーティングを実現。NginxやTraefikなどの実装が存在します。
- Prometheus:クラスターおよびアプリケーションの監視・メトリクス収集プラットフォーム。
- ELKスタック:Elasticsearch、Logstash、Kibanaによるログ集約・分析基盤。
Pod:最小スケジュール単位
PodはKubernetesにおける基本的なデプロイ単位であり、1つ以上のコンテナをまとめて管理します。
Podの分類
- 自律型Pod:手動で作成・管理されるPod。削除後は自動的に復旧されません。
- コントローラー管理Pod:Deploymentなどのコントローラーにより管理され、常に指定されたレプリカ数が維持されます。
Pauseコンテナの役割
すべてのPodには隠しのPauseコンテナが含まれており、以下のリソースをPod内コンテナ間で共有します:
- ネットワーク名前空間(IPアドレス、ポート範囲)
- ストレージボリューム
- IPC名前空間
注意点:Pod内のコンテナは同一ネットワークスタックを使用するため、ポート競合に注意が必要です。
ワークロードコントローラーの詳細
異なるユースケースに対応するための複数のコントローラータイプを理解しましょう。
DeploymentとReplicaSet
ステートレスアプリケーション向けの主要コントローラーです。
ReplicaSetの特性
- 指定されたレプリカ数のPodを常に維持
- ラベルセレクターを使用して管理対象Podを識別
- 従来のReplicationControllerよりも柔軟なセレクターをサポート
Deploymentの機能
DeploymentはReplicaSetを管理することで間接的にPodを制御します(Deployment → ReplicaSet → Pod)。
# デプロイメントのスケーリング例
kubectl scale deployment webapp-deployment --replicas=5
# オートスケーリングの設定例
kubectl autoscale deployment webapp-deployment --min=2 --max=10 --cpu-percent=75
# イメージの更新例
kubectl set image deployment/webapp-deployment main-container=nginx:1.21
# ロールアウト操作例
kubectl rollout status deployment/webapp-deployment
kubectl rollout history deployment/webapp-deployment
kubectl rollout undo deployment/webapp-deployment --to-revision=3
kubectl rollout pause deployment/webapp-deployment
Deploymentは以下の機能を提供します:
- 宣言的なアプリケーション管理
- ローリングアップデートとロールバック
- アップデート途中のPod数制御(maxUnavailable: 25%、maxSurge: 25%)
- リビジョン履歴の管理(revisionHistoryLimitで制御可能)
Horizontal Pod Autoscaler(HPA)
メトリクスに基づいてPod数を自動調整する独立リソース。
- CPU利用率に基づくスケーリング(v1)
- カスタムメトリクス(メモリ、HTTPリクエスト数など)に基づくスケーリング(v2)
- 適用対象:Deployment、ReplicaSet、StatefulSet
DaemonSet
特定のノード(または全ノード)で常に1つのPodを実行するコントローラー。
主な用途:
- ログ収集エージェント(Fluentd、Filebeat)
- 監視エージェント(Node Exporter、Datadog Agent)
- クラスターストレージデーモン(Ceph、Portworx)
JobとCronJob
バッチ処理ワークロード向けのコントローラー。
Jobの特性
- 1回限りのタスク実行を保証
- RestartPolicyはNeverまたはOnFailureのみ有効
- spec.completionsで成功要件数を指定
- spec.parallelismで並行実行数を制御
- spec.activeDeadlineSecondsでタイムアウトを設定
CronJobの特性
# CronJob定義例
apiVersion: batch/v1
kind: CronJob
metadata:
name: backup-job
spec:
schedule: "0 2 * * *" # 毎日午前2時
jobTemplate:
spec:
template:
spec:
containers:
- name: backup
image: backup-tool:latest
command: ["/bin/sh", "-c", "backup.sh"]
restartPolicy: OnFailure
concurrencyPolicy: Forbid # 前回ジョブが完了するまで次回実行を禁止
successfulJobsHistoryLimit: 3
failedJobsHistoryLimit: 1
StatefulSet
ステートフルアプリケーション向けコントローラー。
- 安定したストレージ:PVCを通じてPod再スケジュール後も同じデータにアクセス
- 安定したネットワークID:Headless ServiceによりPod名とホスト名が維持
- 順序付きデプロイ:0からN-1の順でPodが起動
- 順序付き削除:N-1から0の順でPodが削除
- DNS形式:$(podname).(headless-service).$(namespace).svc.cluster.local
Podのライフサイクルと状態管理
Podフェーズ
- Pending:Podが承認されたが、コンテナ作成前の状態(イメージダウンロード中やスケジューリング中)
- Running:少なくとも1つのコンテナが実行中、開始中、または再起動中
- Succeeded:すべてのコンテナが正常終了し、再起動予定なし
- Failed:すべてのコンテナが終了し、少なくとも1つが異常終了
- Unknown:Pod状態を取得できない(通常はノード通信障害)
アプリケーションの分類
- ステートレス:データ永続化が不要。例:Webサーバー、APIゲートウェイ
- ステートフル:データ永続化が必須。例:MySQL、MongoDB、Kafka
初期化コンテナとヘルスチェック
Init Container
メインアプリケーションコンテナの前に実行される特殊コンテナ。
- 必ず成功完了するまで実行
- 複数定義可能(順次実行)
- Pod再起動時は全Init Containerが再実行
- ユースケース:設定ファイル生成、データベースマイグレーション、依存サービス待機
プローブ(Probe)
kubeletによるコンテナの定期的な診断チェック。
プローブタイプ
- ExecAction:コンテナ内でコマンド実行。終了コード0で成功
- HTTPGetAction:指定URLへのHTTP GETリクエスト。200-399のステータスコードで成功
- TCPSocketAction:指定ポートへのTCP接続確認。接続成功で成功
プローブの用途
- Readiness Probe:Podがトラフィックを受け入れる準備ができたか判定。失敗時はServiceからエンドポイント削除
- Liveness Probe:コンテナが動作中か判定。失敗時はコンテナ再起動
リソース制限と要求
Kubernetesはcgroupを通じてリソースを制限します。
リクエストとリミット
# Podのリソース定義例
apiVersion: v1
kind: Pod
metadata:
name: resource-demo
spec:
containers:
- name: app-container
image: nginx:latest
resources:
requests:
cpu: "100m" # 0.1コア
memory: "128Mi" # 128メガバイト
limits:
cpu: "500m" # 0.5コア
memory: "512Mi" # 512メガバイト
- requests:スケジューリング時に保証される最小リソース量
- limits:コンテナが使用可能な最大リソース量
- CPUは圧縮可能リソース(超過時はスロットリング)
- メモリは非圧縮可能リソース(超過時はOOM Killer)
ネットワークアーキテクチャ
通信パターン
- 同一Pod内:localhost経由で直接通信(Pauseコンテナのネットワーク名前空間共有)
- Pod間通信:CNIプラグインによるオーバーレイネットワーク(Flannel、Calico、Ciliumなど)
- Pod-Service間:kube-proxyが管理するIPTables/IPVSルール経由
- 外部-Service間:NodePort、LoadBalancer、Ingressを通じてアクセス
Flannelの動作原理
- 各ノードに一意のサブネットを割り当て
- etcdにサブネット情報を保存
- UDP/VXLANでカプセル化通信
- ホスト間のルーティングテーブルを動的に管理
リソースマニフェスト
YAML形式の定義ファイルでKubernetesオブジェクトを宣言的に管理します。
必須フィールド
| フィールド | 型 | 説明 |
|---|---|---|
| apiVersion | string | 使用するKubernetes APIのバージョン(例: v1, apps/v1) |
| kind | string | 作成するオブジェクトの種類(Pod, Deploymentなど) |
| metadata.name | string | オブジェクトの一意識別名 |
| spec | object | オブジェクトの詳細仕様 |
コンテナ定義の主要フィールド
| フィールド | 型 | 説明 |
|---|---|---|
| containers[].name | string | コンテナ名(Pod内で一意) |
| containers[].image | string | 使用するコンテナイメージ |
| containers[].imagePullPolicy | string | Always, Never, IfNotPresentのいずれか |
| containers[].command[] | list | コンテナ起動コマンド(ENTRYPOINT上書き) |
| containers[].args[] | list | コンテナ起動引数(CMD上書き) |
| containers[].env[] | list | 環境変数定義 |
| containers[].ports[] | list | 公開ポート定義 |
| containers[].resources | object | リソース要求と制限 |
| containers[].volumeMounts[] | list | ボリュームマウント設定 |
Podレベル設定
| フィールド | 型 | 説明 |
|---|---|---|
| spec.restartPolicy | string | Always(デフォルト), OnFailure, Never |
| spec.nodeSelector | object | ノード選択ラベル(key: value形式) |
| spec.hostNetwork | boolean | trueでホストネットワークを直接使用 |
| spec.volumes[] | list | Podレベルボリューム定義 |
ServiceとIngress
Serviceのタイプ
- ClusterIP:クラスター内のみアクセス可能な仮想IP(デフォルト)
- NodePort:各ノードの特定ポートでServiceを公開
- LoadBalancer:クラウドプロバイダーのロードバランサーと連携
- ExternalName:外部サービスをクラスター内で参照可能に
Headless Service
spec.clusterIPを"None"に設定することで、kube-proxyによるロードバランシングをバイパスします。DNS経由で直接Pod IPにアクセス可能になります。
kube-proxyの動作モード
- iptablesモード:IPTablesルールでパケット転送(Kubernetes 1.10以前のデフォルト)
- ipvsモード:IPVSカーネルレベルロードバランサーを使用(1.11以降推奨)
- nftablesモード:iptablesの後継となるnftablesを使用(実験的)
Ingressの役割
HTTP/HTTPSレイヤー7のルーティングを提供します。
# Ingress定義例
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: webapp-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: app.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 8080
- path: /static
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 80
ストレージ管理
ConfigMap
設定データをPodに注入するためのリソース。
# ディレクトリから作成
kubectl create configmap webapp-config --from-file=./config/
# ファイルから作成
kubectl create configmap db-settings --from-file=./config/database.conf
# リテラル値から作成
kubectl create configmap feature-flags --from-literal=cache.enabled=true --from-literal=log.level=debug
# ConfigMapの使用例
apiVersion: v1
kind: Pod
metadata:
name: configmap-demo
spec:
containers:
- name: app
image: nginx:latest
env:
- name: CACHE_ENABLED
valueFrom:
configMapKeyRef:
name: feature-flags
key: cache.enabled
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: db-settings
更新動作:
- ボリュームマウントの場合:約10秒で自動反映
- 環境変数の場合:ConfigMap更新後もPod再起動が必要
- アノテーション変更によるローリングアップデートで強制反映可能
Secret
機密情報(パスワード、トークン、鍵)を安全に管理します。
Secretのタイプ
- Opaque:Base64エンコードされた汎用データ(デフォルト)
- kubernetes.io/dockerconfigjson:Dockerレジストリ認証情報
- kubernetes.io/service-account-token:ServiceAccount用トークン(自動マウント)
# DockerレジストリSecret作成
kubectl create secret docker-registry regcred \
--docker-server=private.registry.io \
--docker-username=admin \
--docker-password=secretpass \
--docker-email=admin@example.com
# Secretの使用例
apiVersion: v1
kind: Pod
metadata:
name: secret-demo
spec:
containers:
- name: db-client
image: mysql-client:latest
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: password
Volumeタイプ
emptyDir
Podのライフサイクルに紐づく一時的なストレージ。
- Pod作成時に空のディレクトリを生成
- コンテナクラッシュ時もデータ保持(Pod削除時に消滅)
- 用途:一時作業領域、チェックポイントデータ、コンテナ間データ共有
hostPath
ノードのファイルシステムをPodにマウントします。
| タイプ | 動作 |
|---|---|
| DirectoryOrCreate | 指定パスが存在しない場合、空ディレクトリを作成(パーミッション755) |
| Directory | 指定パスがディレクトリであることを要求 |
| FileOrCreate | 指定パスが存在しない場合、空ファイルを作成(パーミッション644) |
| File | 指定パスがファイルであることを要求 |
PersistentVolume(PV)とPersistentVolumeClaim(PVC)
- PV:クラスター管理者がプロビジョニングするストレージリソース
- PVC:ユーザーが要求するストレージ
- Binding:PVとPVCの一対一のマッピング
- StorageClass:動的プロビジョニングのためのストレージテンプレート
# PVC定義例
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-data
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: fast-ssd
# Podでの使用例
apiVersion: v1
kind: Pod
metadata:
name: mysql-pod
spec:
containers:
- name: mysql
image: mysql:8.0
volumeMounts:
- name: data-volume
mountPath: /var/lib/mysql
volumes:
- name: data-volume
persistentVolumeClaim:
claimName: mysql-data
スケジューリングメカニズム
ノードアフィニティ
Podを特定のノードに割り当てるためのルール。
# ノードアフィニティ例
apiVersion: v1
kind: Pod
metadata:
name: affinity-demo
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-type
operator: In
values: ["compute", "gpu"]
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: zone
operator: In
values: ["asia-northeast1-a"]
containers:
- name: app
image: nginx:latest
Podアフィニティ/アンチアフィニティ
Pod間の配置関係を制御します。
- PodAffinity:特定のPodと同じノードに配置
- PodAntiAffinity:特定のPodと異なるノードに配置(高可用性確保に有効)
Taint(汚染)とToleration(容認)
ノードが特定のPodを排斥または許可するメカニズム。
Taintの設定
# Taintの付与
kubectl taint nodes node1 workload=high-priority:NoSchedule
# Taintの削除
kubectl taint nodes node1 workload:NoSchedule-
# Taintの効果
# NoSchedule: 新規Podのスケジューリングを拒否
# PreferNoSchedule: 可能な限りスケジューリングを回避
# NoExecute: 新規スケジューリング拒否 + 既存Podの追い出し
Tolerationの設定
# PodでのToleration定義例
apiVersion: v1
kind: Pod
metadata:
name: tolerant-pod
spec:
tolerations:
- key: "workload"
operator: "Equal"
value: "high-priority"
effect: "NoSchedule"
tolerationSeconds: 3600 # NoExecute時の猶予時間(秒)
containers:
- name: app
image: nginx:latest
スケジューラーの動作フロー
- Filtering(Predicate):条件を満たさないノードを除外
- リソース要件チェック(PodFitsResources)
- ノードセレクターマッチング(PodSelectorMatches)
- ポート競合チェック(PodFitsHostPorts)
- ストレージ競合チェック(NoDiskConflict)
- Scoring(Priority):適格ノードに優先度を付けてソート
- リソース使用率(LeastRequestedPriority)
- リソースバランス(BalancedResourceAllocation)
- イメージローカル性(ImageLocalityPriority)
- Binding:最も高いスコアのノードにPodを割り当て
セキュリティモデル
認証(Authentication)
クライアントIDの検証方法。
- クライアント証明書:TLSクライアント証明書による認証(最も一般的)
- ベアラートークン:サービスアカウントトークン(JWT形式)
- HTTP基本認証:ユーザー名/パスワード(非推奨)
認可(Authorization)
RBAC(Role-Based Access Control)がデファクトスタンダードです。
RBACリソース
- Role:名前空間レベルの権限定義
- ClusterRole:クラスターレベルの権限定義
- RoleBinding:Roleを特定のユーザー/グループ/SAに紐付け(名前空間内)
- ClusterRoleBinding:ClusterRoleをクラスター全体に紐付け
# Role定義例
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: production
name: pod-reader
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "watch", "list"]
# RoleBinding定義例
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: production
subjects:
- kind: User
name: jane
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
ServiceAccount
PodからAPIサーバーにアクセスするためのID。
- 各名前空間にデフォルトのServiceAccountが存在
- Pod作成時に自動マウント(/var/run/secrets/kubernetes.io/serviceaccount/)
- 必要に応じてカスタムServiceAccountを作成・割り当て可能
アドミッションコントローラー
オブジェクト永続化前にリクエストを検証・変更するプラグイン。
- NamespaceLifecycle:終了中の名前空間へのオブジェクト作成を拒否
- LimitRanger:デフォルトリソース制限の適用
- ResourceQuota:名前空間レベルのリソース使用量制限
- PodSecurityPolicy:Podのセキュリティコンテキスト制限
- MutatingAdmissionWebhook:外部Webhookによるリクエスト変更
パッケージ管理:Helm
HelmはKubernetesアプリケーションのパッケージマネージャーです。
- Chart:アプリケーションのパッケージ化定義
- Release:クラスターにデプロイされたChartのインスタンス
- Repository:Chartの公開・共有のためのリポジトリ
# Chartインストール例
helm install my-app ./my-chart --namespace production
# リリースアップグレード例
helm upgrade my-app ./my-chart --set image.tag=2.0
# リリースロールバック例
helm rollback my-app 1
# リポジトリ追加例
helm repo add stable https://charts.helm.sh/stable
高可用性設計
- コントロールプレーンは最低3ノードの奇数構成を推奨(クォーラム維持のため)
- etcdはSSDストレージ上に配置し、バックアップを定期実施
- マスターノードは物理的に分散配置(異なるラック/ゾーン)
- LoadBalancerまたはVIPでAPIサーバーの冗長化
- kubeadmによる証明書の有効期限はデフォルト1年→10年に延長可能
# 証明書有効期限の確認
kubeadm certs check-expiration
# 証明書の手動更新
kubeadm certs renew all