Kubernetes Namespace入門:環境分離の基本から「運用で効く」使い方まで

Kubernetesの Namespace(名前空間) は、ひとことで言うと 「クラスタの中を論理的に区切る仕切り」 です。
同じクラスタ上で、開発/検証/本番や、チームごとのアプリを安全に共存させたいときに必須になります。

この記事では、Namespaceの役割と設計の考え方を押さえつつ、手を動かして以下をやります。

  • Namespaceを作る・切り替える
  • 同名リソースを別Namespaceに共存させる
  • kubectl の誤爆(本番にapplyしちゃった…)を防ぐ
  • ResourceQuota / LimitRange で「使いすぎ」を制限する
  • (発展)NetworkPolicy / RBAC で「通信・権限」も分離する

Namespaceで何が嬉しい?

1) “同じ名前”のリソースを共存できる

例:app というServiceやDeploymentを
devprod の両方に作れます(クラスタ全体での衝突を防げる)。

2) まとめて見れる・まとめて消せる

kubectl get all -n dev のように、環境単位で可視化できます。
不要になった環境を namespaceごと削除 も可能(※注意点あり)。

3) 権限・リソース上限・通信を“環境単位”で設定できる

  • RBAC(誰が何をできるか)
  • ResourceQuota / LimitRange(CPU/メモリの上限)
  • NetworkPolicy(通信制御)

Namespaceの基本ルール(ここだけ押さえればOK)

  • Namespaceは 多くのリソースのスコープ(Deployment/Service/ConfigMap/Secretなど)
  • 一方で クラスタスコープ のリソースもある
    例:Node / PersistentVolume / StorageClass / ClusterRole など
  • kubectl は何も指定しないと “現在のnamespace(contextの設定)” に対して操作する
    → ここが一番事故りやすいポイントです

ハンズオン:Namespaceを作って分離を体感する

以降、ローカルクラスタ(kind/minikube/Docker Desktop Kubernetesなど)で動きます。
kubectl が使える前提で進めます。


1) Namespaceを作る

kubectl create namespace dev
kubectl create namespace prod
kubectl get namespaces

2) 同じアプリ名を dev と prod に作って共存させる

app.yaml を作成(シンプルなWeb):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app
  template:
    metadata:
      labels:
        app: app
    spec:
      containers:
        - name: web
          image: nginxdemos/hello:plain-text
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: app
spec:
  selector:
    app: app
  ports:
    - port: 80
      targetPort: 80

devに適用:

kubectl apply -f app.yaml -n dev
kubectl get deploy,svc -n dev

prodにも同じものを適用:

kubectl apply -f app.yaml -n prod
kubectl get deploy,svc -n prod

確認(同じ名前 app が両方に存在する):

kubectl get svc -n dev
kubectl get svc -n prod

3) 「namespace指定し忘れ」を防ぐ:current namespace を固定する

毎回 -n dev を付けるのは忘れがちです。
contextにnamespaceをセットすると、安全度が上がります。

現在のcontext名を確認:

kubectl config current-context

dev用にnamespaceをセット:

kubectl config set-context --current --namespace=dev
kubectl config view --minify | grep namespace

以後、-n dev なしで dev を操作できます:

kubectl get pods

prodに切り替えたいときは:

kubectl config set-context --current --namespace=prod
kubectl get pods

コツ:本番クラスタでは “prod専用context” を作り、普段は触らない
さらに kubectl のエイリアス/プロンプトに namespace を表示すると誤爆が激減します。


4) Namespaceごとに「使いすぎ」を止める:ResourceQuota

チームや環境が増えると、誰かがリソースを食い潰します。
ResourceQuotaで Namespace単位の上限 を設定できます。

quota.yaml(devに上限を付ける例):

apiVersion: v1
kind: ResourceQuota
metadata:
  name: dev-quota
spec:
  hard:
    requests.cpu: "500m"
    requests.memory: "512Mi"
    limits.cpu: "1"
    limits.memory: "1Gi"
    pods: "5"

適用:

kubectl apply -f quota.yaml -n dev
kubectl describe resourcequota dev-quota -n dev

5) PodにCPU/メモリが書かれてない問題を潰す:LimitRange

ResourceQuotaを入れても、Pod側が requests/limits を書いてないと運用が崩れます。
LimitRangeで デフォルト値 を入れられます。

limitrange.yaml

apiVersion: v1
kind: LimitRange
metadata:
  name: dev-limits
spec:
  limits:
    - type: Container
      defaultRequest:
        cpu: 100m
        memory: 128Mi
      default:
        cpu: 200m
        memory: 256Mi

適用:

kubectl apply -f limitrange.yaml -n dev
kubectl describe limitrange dev-limits -n dev

これで、requests/limits を書いてないコンテナにもデフォルトが入ります。


6) よくある運用パターン(設計の指針)

パターンA:環境ごとにNamespace(dev / stg / prod)

  • 小〜中規模で分かりやすい
  • “同じマニフェスト” を環境ごとに適用しやすい

パターンB:チームごとにNamespace(team-a / team-b)

  • マイクロサービスが増えるとこちらが強い
  • ResourceQuota/RBACをチーム単位で持てる

パターンC:環境×チーム(dev-team-a など)

  • 最も安全だが運用が複雑になりやすい
  • Helm/Kustomize等の仕組みとセット推奨

発展:Namespace分離を「本当に効かせる」2つの追加要素

1) RBAC(誰が何をできるか)

  • devは全権、prodは閲覧のみ、などが可能
  • Role/RoleBinding(Namespaceスコープ)を基本にする

2) NetworkPolicy(どこに通信していいか)

  • Namespaceを分けただけでは 通信は遮断されません(多くの環境で)
  • NetworkPolicyで「devからprodへ直アクセス禁止」などを定義する

※NetworkPolicyはクラスタのCNI実装に依存するので、ローカル学習では動作条件を確認して使うのがおすすめです。


トラブルシュート(Namespace絡みあるある)

Q1. applyしたのにリソースが見えない

-n を付け忘れて違うNamespaceを見ていることが多いです。

kubectl get deploy --all-namespaces

Q2. いつも -n 付け忘れる

contextにnamespaceを固定:

kubectl config set-context --current --namespace=dev

Q3. Namespace削除したのに終わらない(Terminating)

Finalizerや残骸で詰まるケースがあります。
学習用途なら、まず kubectl get で残ってるリソースがないか確認が安全です。


片付け

kubectl delete namespace dev
kubectl delete namespace prod

次のステップ(ローカル学習向けおすすめ)

  1. Kustomizeで “dev/prod差分” を管理(Namespaceと相性抜群)
  2. RBAC入門(prod誤爆対策として強い)
  3. ResourceQuota + LimitRange を運用ルール化(チーム開発の土台)

希望があれば、次は 「Kustomizeで dev/prod を切り替える構成(namespace/replicas/imageタグの差分)」 のハンズオンを書きます。用途は「個人学習」か「チーム開発想定」どっち寄りですか?

RBAC入門の技術ブログを書いてください。その際にハンズオンも書いてください。

Kubernetes RBAC入門:権限事故を防ぐ「最小権限」の設計とハンズオン(Role / RoleBinding)

RBAC(Role-Based Access Control)は、Kubernetesで 「誰が」「何に対して」「何をしていいか」 を制御する仕組みです。
Namespaceを分けただけでは 操作の誤爆(prodにapply) は防げません。RBACを入れて初めて「本番は閲覧だけ」「devだけ更新OK」などの運用ができます。

この記事では、RBACの基本概念を押さえつつ、手を動かして権限を作って検証します。


RBACの登場人物(これだけ覚えればOK)

  • Subject(主体):誰に権限を付けるか
    例:User / Group / ServiceAccount
  • Role / ClusterRole(権限の定義):何ができるか(許可ルール)
    • Role:Namespace内に限定
    • ClusterRole:クラスタ全体 or 複数Namespaceで再利用
  • RoleBinding / ClusterRoleBinding(紐付け):主体と権限を結び付ける
    • RoleBinding:Namespace内に付与(ClusterRoleも束ねられる)
    • ClusterRoleBinding:クラスタ全体に付与

認証(Authentication: あなた誰?)と認可(Authorization: 何していい?)は別。
RBACは 認可 の担当です。


ハンズオン:ServiceAccountに「閲覧だけ」「更新OK」権限を付けて検証する

ゴール

  • dev ではアプリ更新OKのSA(ServiceAccount)を作る
  • prod では閲覧のみのSAを作る
  • kubectl auth can-i--as権限が効いている ことを確認する

前提

  • kubectl がクラスタに接続できる(kind / minikube / Docker Desktop Kubernetes など)

1) Namespace とテスト用アプリを用意

kubectl create namespace dev
kubectl create namespace prod

テスト用Deploymentを両方に作ります(手っ取り早い例):

kubectl create deploy web --image=nginx -n dev
kubectl create deploy web --image=nginx -n prod

2) ServiceAccount(主体)を作る

kubectl create serviceaccount dev-operator -n dev
kubectl create serviceaccount prod-viewer -n prod

3) Role(権限定義)を作る:prodは閲覧のみ

prod-readonly-role.yaml を作成:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: readonly
  namespace: prod
rules:
  - apiGroups: [""]
    resources: ["pods", "services", "configmaps", "endpoints"]
    verbs: ["get", "list", "watch"]
  - apiGroups: ["apps"]
    resources: ["deployments", "replicasets"]
    verbs: ["get", "list", "watch"]

適用:

kubectl apply -f prod-readonly-role.yaml

4) RoleBinding(紐付け)を作る:prod-viewer に readonly を付与

prod-readonly-binding.yaml を作成:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: readonly-binding
  namespace: prod
subjects:
  - kind: ServiceAccount
    name: prod-viewer
    namespace: prod
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: readonly

適用:

kubectl apply -f prod-readonly-binding.yaml

5) devは「更新OK」にする:Deploymentを変更できるRole

dev-deploy-editor-role.yaml を作成:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: deploy-editor
  namespace: dev
rules:
  - apiGroups: ["apps"]
    resources: ["deployments"]
    verbs: ["get", "list", "watch", "patch", "update"]
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "list", "watch"]

適用:

kubectl apply -f dev-deploy-editor-role.yaml

RoleBindingも作成:dev-deploy-editor-binding.yaml

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: deploy-editor-binding
  namespace: dev
subjects:
  - kind: ServiceAccount
    name: dev-operator
    namespace: dev
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: deploy-editor

適用:

kubectl apply -f dev-deploy-editor-binding.yaml

6) 権限チェック(超重要):kubectl auth can-i で検証

Kubernetesは 実際にやらなくても「できる/できない」を判定できます。

prod-viewer:prodのDeployment更新は “できない” はず

kubectl auth can-i patch deployments -n prod \
  --as=system:serviceaccount:prod:prod-viewer

期待:no

prodの閲覧は “できる” はず

kubectl auth can-i get deployments -n prod \
  --as=system:serviceaccount:prod:prod-viewer

期待:yes

dev-operator:devのDeployment更新は “できる” はず

kubectl auth can-i patch deployments -n dev \
  --as=system:serviceaccount:dev:dev-operator

期待:yes

ただし prod に対しては “できない” はず(Roleがdev限定なので)

kubectl auth can-i patch deployments -n prod \
  --as=system:serviceaccount:dev:dev-operator

期待:no


7) 実際に操作してみる(devは更新OK / prodは拒否)

dev(許可される)

kubectl -n dev set image deploy/web nginx=nginx:1.27

prod(本当は「prod-viewer」で操作させたい)

ここでは「できる/できない」の再現として、--as で試します。

kubectl -n prod set image deploy/web nginx=nginx:1.27 \
  --as=system:serviceaccount:prod:prod-viewer

期待:forbidden(権限不足)

--as は“なりすまし検証”なので、運用では「そのSAのkubeconfigを配る」形にします。


もう一段だけ理解を深める:ClusterRole を RoleBinding で使う

Kubernetesには便利な“組み込み”の ClusterRole(例:view, edit, admin)があります。
これを RoleBindingでNamespaceに限定して付与できます(クラスタ全体にしないのがコツ)。

例:prodの閲覧者に、組み込み view を prod だけに付与したい場合(Roleを自作しない)

kubectl create rolebinding prod-view \
  --clusterrole=view \
  --serviceaccount=prod:prod-viewer \
  -n prod

(この場合、さっき作った readonly Role は不要です)


設計の鉄則(運用で事故を減らす)

  • 最小権限(Least Privilege):必要なresourceとverbだけ許可
  • prodは原則 read-only:更新系はCI/CDに寄せる(人は触らない)
  • ClusterRoleBindingは最後の手段:多くはRoleBindingで足りる
  • namespace境界を越える権限は慎重に(特に secrets / pods/exec
  • pods/exec を与える=コンテナ内でコマンド実行できる(実質かなり強い)

よくある詰まりポイント

1) “できるはず” なのに forbidden

  • RoleBinding の subjects.namespace が違う
  • Role が作られている namespace と RoleBinding の namespace が違う
  • verbs(patch/update/create)が足りない

確認コマンド:

kubectl describe role -n dev deploy-editor
kubectl describe rolebinding -n dev deploy-editor-binding

2) listはできるのに get ができない

RBACは verb を個別に許可するので、get を入れ忘れがちです。

3) Secretを読めてしまう

閲覧ロールに secrets を入れるのは慎重に。基本は入れません。


片付け

kubectl delete namespace dev
kubectl delete namespace prod

投稿日

カテゴリー:

投稿者:

タグ:

コメント

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です