はじめに
「namespace」という用語は、Linux環境とKubernetes環境の両方で頻繁に登場しますが、これらは全く異なる概念です。本記事では、両者の違いを明確にし、それぞれの役割と特徴を技術的に正確に解説します。
対象読者
- Linuxコンテナ技術を学習している開発者
- Kubernetesを使い始めた運用エンジニア
- 両者の違いに混乱している実務者
TL;DR(要約)
| 項目 | Linuxのnamespace | Kubernetesのnamespace |
|---|---|---|
| レイヤー | OSカーネルレベル | Kubernetes APIレベル |
| 目的 | プロセスのリソース分離 | クラスターリソースの論理的分割 |
| スコープ | 単一ホストマシン | Kubernetesクラスター全体 |
| 分離対象 | PID、ネットワーク、マウントポイント等 | Pod、Service、Deployment等のK8sリソース |
| 実装 | カーネルのシステムコール | Kubernetes APIオブジェクト |
1. Linuxのnamespace
1.1 定義と目的
【事実】 namespaceは、カーネルリソースを分割し、あるプロセスセットが1つのリソースセットを見る一方で、別のプロセスセットが異なるリソースセットを見るようにします1。
1.2 7種類のnamespace
【事実】 Linux kernel では以下の7種類のnamespaceが存在します1:
| TYPE | 説明 |
|---|---|
| PID namespace | プロセスIDの分離 |
| NET namespace | ネットワークスタックの分離 |
| MNT namespace | マウントポイントの分離 |
| UTS namespace | ホスト名とドメイン名の分離 |
| IPC namespace | プロセス間通信の分離 |
| USER namespace | ユーザーIDとグループIDの分離 |
| CGROUP namespace | cgroupルートディレクトリの分離 |
1.3 システムコールによる制御
【事実】 namespaceは、以下のシステムコールで作成・操作されます1:
-
clone()- 新しいプロセスを作成し、新しいnamespaceに配置 -
unshare()- 既存のプロセスを新しいnamespaceに移動 -
setns()- プロセスを既存のnamespaceに参加させる -
ioctl()- namespaceに関する情報を取得・設定
1.4 実際の確認方法
【検証可能な手順】 以下のコマンドで、システム上のnamespaceを確認できます:
# 現在のnamespaceを確認
lsns
# 現在のプロセスのnamespaceを確認
ls -la /proc/$$/ns/
# 現在動いているすべてのプロセスを確認
ps aux
# 特定プロセスのnamespaceを確認
ls -la /proc/<PID>/ns/
【期待される出力例】
lrwxrwxrwx 1 root root 0 Dec 15 10:00 cgroup -> 'cgroup:[4026531835]'
lrwxrwxrwx 1 root root 0 Dec 15 10:00 ipc -> 'ipc:[4026531839]'
lrwxrwxrwx 1 root root 0 Dec 15 10:00 mnt -> 'mnt:[4026531840]'
lrwxrwxrwx 1 root root 0 Dec 15 10:00 net -> 'net:[4026531992]'
lrwxrwxrwx 1 root root 0 Dec 15 10:00 pid -> 'pid:[4026531836]'
lrwxrwxrwx 1 root root 0 Dec 15 10:00 user -> 'user:[4026531837]'
lrwxrwxrwx 1 root root 0 Dec 15 10:00 uts -> 'uts:[4026531838]'
1.5 namespace間の通信
- デフォルト状態: 異なるNET namespace内のプロセスは完全に分離されており、互いに通信できません2。
- 意図的な接続: veth(virtual ethernet)ペアを使うことで、異なるnamespace間を接続し、通信を可能にできます2。
確認手順の例:
# ステップ1: 新しいNET namespaceを2つ作成
sudo ip netns add ns1
sudo ip netns add ns2
# ステップ2: 各namespaceの状態を確認
sudo ip netns exec ns1 ip addr
# 出力: loopbackインターフェースのみ存在
sudo ip netns exec ns2 ip addr
# 出力: loopbackインターフェースのみ存在
# ステップ3: この時点では通信できないことを確認
# ns1からns2への到達性をテスト(まだIPアドレスもないので失敗する)
sudo ip netns exec ns1 ip link
# 出力: loのみ存在、他のnamespaceとの接続なし
# ステップ4: vethペアを作成して2つのnamespaceを接続
sudo ip link add veth0 type veth peer name veth1
sudo ip link set veth0 netns ns1
sudo ip link set veth1 netns ns2
# ステップ5: vethは作成されたが、まだIPアドレスが未設定で通信不可
sudo ip netns exec ns1 ip addr show veth0
# 出力: veth0が存在するがIPアドレスなし、状態はDOWN
# ステップ6: IPアドレスを設定してインターフェースを起動
sudo ip netns exec ns1 ip addr add 10.0.0.1/24 dev veth0
sudo ip netns exec ns2 ip addr add 10.0.0.2/24 dev veth1
sudo ip netns exec ns1 ip link set veth0 up
sudo ip netns exec ns2 ip link set veth1 up
# ステップ7: 設定後の状態を確認
sudo ip netns exec ns1 ip addr show veth0
# 出力: veth0に10.0.0.1/24が設定され、状態はUP
# ステップ8: これで通信可能になったことを確認
sudo ip netns exec ns1 ping -c 3 10.0.0.2
# 出力: 3パケット送信、3パケット受信、0% packet loss ✓
# ステップ9: 逆方向の通信も確認
sudo ip netns exec ns2 ping -c 3 10.0.0.1
# 出力: 3パケット送信、3パケット受信、0% packet loss ✓
# クリーンアップ
sudo ip netns delete ns1
sudo ip netns delete ns2
1.6 コンテナ技術との関係
【事実】 Dockerなどのコンテナランタイムは、Linuxのnamespaceを使用してコンテナの分離を実現しています3。
2. Kubernetesのnamespace
2.1 定義と目的
【事実】 Kubernetesのnamespaceは、Kubernetes APIによって実装される論理的な構成概念であり、単一クラスター内のリソースグループを分離するメカニズムです4。
【事実】 namespaceはクラスターリソースを複数のユーザー、チーム、プロジェクト間で分割する方法を提供します5。
2.2 スコープと制約
【事実】 Kubernetesのnamespaceには以下の特徴があります4:
- リソース名はnamespace内で一意である必要がありますが、namespace間では重複可能
- namespaceは入れ子にできません
- 各Kubernetesリソースは1つのnamespaceにのみ所属可能
【事実】 以下のリソースはnamespaceスコープ外(クラスター全体)です4:
- Node
- PersistentVolume
- StorageClass
- Namespace自体
2.3 デフォルトnamespace
【事実】 Kubernetesは初期状態で以下のnamespaceを作成します45:
$ kubectl get namespaces
NAME STATUS AGE
default Active 11d
kube-node-lease Active 11d
kube-public Active 11d
kube-system Active 11d
- default: 明示的にnamespaceを指定しない場合のデフォルト
- kube-system: Kubernetes制御プレーンのコンポーネント用
- kube-public: 全ユーザーが読み取り可能
- kube-node-lease: ノードのハートビート用Leaseオブジェクト
2.4 実際の使用方法
【検証可能な手順】 以下のコマンドでnamespaceを操作できます:
# namespace作成
kubectl create namespace my-app
# 特定namespace内のリソースを確認
kubectl get pods -n my-app
# 特定namespaceにPodをデプロイ
kubectl run nginx --image=nginx --namespace=my-app
2.5 分離の実態
【重要な事実】 Kubernetesのnamespaceは、デフォルトではネットワーク分離を提供しません67。
【検証可能な事実】 異なるnamespace間のPodは、デフォルトで相互に通信可能です:
# namespace "one" のPodから namespace "two" のServiceへアクセス可能
curl http://service-name.two.svc.cluster.local
【セキュリティ上の注意】 ネットワーク分離を実現するには、Network Policyの明示的な設定が必要です8910。
3. 両者の決定的な違い
3.1 レイヤーの違い
【考察】 Kubernetesのnamespaceは、内部的にコンテナランタイムを通じてLinuxのnamespaceを間接的に利用していますが、両者は異なるレイヤーで動作する独立した概念です1112。
3.2 実装レベルの違い
【事実】 実装方法の比較:
| 側面 | Linuxのnamespace | Kubernetesのnamespace |
|---|---|---|
| 作成方法 | システムコール(clone, unshare, setns) | Kubernetes API(kubectl, YAML) |
| 管理単位 | プロセス単位 | Kubernetesリソース単位 |
| 永続性 | プロセスのライフサイクルに依存 | クラスターに永続化(etcdに保存) |
| 確認方法 |
lsns, /proc/<PID>/ns/
|
kubectl get namespaces |
4. セキュリティと分離の実態
4.1 Linuxのnamespaceのセキュリティ
【事実】 Linuxのnamespaceは強力な分離を提供しますが、完全ではありません:
- 提供する分離: プロセス、ネットワーク、ファイルシステムの視界の分離
- 提供しない分離: カーネル脆弱性からの保護、リソース使用量の制限(cgroupsが必要)
【セキュリティ補足】 USER namespaceを使用することで、コンテナ内のroot権限がホスト上では非特権ユーザーとしてマッピングされ、コンテナブレイクアウトの影響を軽減できます13。
4.2 Kubernetesのnamespaceのセキュリティ
【重要な事実】 Kubernetesのnamespaceは、デフォルトでは以下を提供します67:
✅ 提供するもの:
- API リソースレベルでの分離(RBACと組み合わせて)
- リソース名の衝突回避
- リソースクォータの適用範囲
❌ デフォルトで提供しないもの:
- ネットワーク分離(Network Policyが必要)
- ノードレベルの分離
- 完全なセキュリティ境界
【セキュリティベストプラクティス】 適切な分離を実現するには:
# 1. Network Policyで通信を制限
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-from-other-namespaces
namespace: my-app
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- podSelector: {} # 同じnamespace内のPodのみ許可
# 2. ResourceQuotaでリソース使用量を制限
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-quota
namespace: my-app
spec:
hard:
requests.cpu: "10"
requests.memory: 20Gi
limits.cpu: "20"
limits.memory: 40Gi
# 3. RBACでアクセスを制限
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: my-app
name: developer
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
5. まとめ
5.1 主要な違いの再確認
Linuxのnamespace:
- カーネルレベルの実装
- プロセス単位の実際のリソース分離
- コンテナ技術の基盤
- システムコールで制御
Kubernetesのnamespace:
- APIレベルの論理的構成概念
- クラスターリソースの組織化とアクセス制御
- RBAC、リソースクォータと連携
- 宣言的なYAMLで管理
5.2 両者の関係性
【結論】 Kubernetesのnamespaceは、コンテナランタイム(containerd/CRI-O)を通じてLinuxのnamespaceを間接的に利用していますが、両者は異なる目的と異なるレイヤーで動作する独立した概念です1112。
混同を避けるためには、以下のように理解すると良いでしょう:
- Linuxのnamespace: 「技術的な分離メカニズム」
- Kubernetesのnamespace: 「管理上の組織化概念」
参考文献
本記事は以下の公式ドキュメントと技術記事を参照しています:
-
Digging into Linux namespaces - part 1 - Quarkslab's blog ↩ ↩2
-
Kubernetes namespaces isolation - what it is, what it isn't, life, ↩ ↩2
-
Achieving Network, Namespace, and Cluster Isolation in Kubernetes - Part 1 ↩ ↩2
-
Kubernetes Network Policies for Isolating Namespaces | Loft Labs ↩
-
A walk through Kubernetes namespaces | by Carlosalbertoalvesscorreia | Medium ↩ ↩2
-
Kubernetes 1.30: Beta Support For Pods With User Namespaces | Kubernetes ↩