インフラエンジニアの羅針盤

インフラエンジニア1〜3年目のための技術ガイド

CKA編⑧ RBACとResourceQuota・HPA

公開更新

新卒インフラエンジニア向け「Kubernetes 実践教科書 ② CKA クラスタ構築・運用編」(全16回)の第8回です。前回は「どの Pod をどのノードに載せるか」を制御しました。本回は視点を変え、クラスタを複数の人・チームで安全に共用するための統制(ガバナンス)を学びます。本番クラスタでは、①誰がどの Namespace で何をできるか(RBAC)、②どれだけ資源を使えるか(ResourceQuota / LimitRange)、③負荷に応じて自動で増やす(HPA)――この 3 つを揃えて初めて、1 つのクラスタを安心して分け合えます。中でも RBAC は CKA 最重要ドメイン D1 の筆頭項目で、試験でも実務でも頻出です。本回は RBAC を主軸に据えて手を動かします。

操作はすべて作業端末 k8s-ops192.168.1.122)から kubectl で行います。プロンプトの $ は一般ユーザー developer を表します。第4回で配布した admin.confcluster-admin(全権)なので、本回の RBAC・Quota・LimitRange の作成もこの権限で行えます。本回で作る YAML は k8s-ops の developer のホーム配下に作業ディレクトリを作ってまとめます(ファイルの所有者は developersudo は使いません)。

実行コマンド(k8s-ops・developer):

$ mkdir -p ~/governance && cd ~/governance
目次
  1. 今ここマップ(全 16 回中の現在地)
  2. この回のゴール
  3. RBAC の全体像(管理者視点)
  4. RBAC を作って付与する(read-only な developer ロール)
  5. 権限を検証する(auth can-i と impersonation)
  6. ServiceAccount に権限を委譲する(CI 用 SA)
  7. metrics-server を入れる(HPA の前提)
  8. HPA で自動スケールする
  9. ResourceQuota(Namespace の総量制限)
  10. LimitRange(Pod 単位の既定と上限)
  11. やってみよう
  12. まとめ
  13. 理解度チェック(○×形式・全 9 問)
  14. 次回予告

今ここマップ(全 16 回中の現在地)

本シリーズは 6 部構成です。現在地は第2部「ワークロード管理」の第8回です。

  • 第1部 クラスタ構築(第1〜5回)
  • 第2部 ワークロード管理(第6〜8回)← 今ここ
  • 第3部 ネットワーク(第9〜11回)
  • 第4部 ストレージ(第12回
  • 第5部 監視・運用(第13〜14回)
  • 第6部 トラブルシュート(第15〜16回)
  • Kubernetes v1.36.2
  • kubectl v1.35.6(作業端末)
  • metrics-server v0.8.1
  • AlmaLinux 10.2
  • RBAC の APIrbac.authorization.k8s.io/v1)と HPA の API(autoscaling/v2)はいずれも安定版で、マイナー番号が変わっても同じ
  • 確認日 2026-07-13

この回のゴール

本回を終えると、次のことができるようになります。到達できたかは記事末の「やってみよう」と「理解度チェック」で確認します。

  • Role / ClusterRole / RoleBinding / ClusterRoleBinding の違いを理解し、最小権限で設計・付与できる(管理者視点)
  • kubectl auth can-i --as で「その人が何をできるか」を検証できる
  • ServiceAccount にロールを紐付け、CI などに安全に権限を委譲できる
  • ResourceQuota で Namespace のリソース総量を、LimitRange で Pod 単位の既定・上限を設定できる
  • metrics-server を導入し、HPA で CPU 負荷に応じた自動スケールを実機で確認できる

RBAC の全体像(管理者視点)

RBAC(Role-Based Access Control)は「誰が・どの範囲で・何をできるか」を制御する仕組みです。登場するリソースは 4 つで、「許可の内容」を定義する 2 つと、それを「誰に」結びつける 2 つに分かれます。

  • Role:特定の Namespace 内での許可を定義する
  • ClusterRole:クラスタ全体、または全 Namespace 共通の許可を定義する(node・PV などのクラスタ資源も対象にできる)
  • RoleBinding:Role(または ClusterRole)を「誰に」特定の Namespace 内で紐付ける
  • ClusterRoleBinding:ClusterRole をクラスタ全体で紐付ける

「誰に」当たる主体(subjects)は 3 種類です。User(人。kubeadm では証明書の CN)、Group(証明書の O)、ServiceAccount(Pod や自動処理)。許可の粒度は apiGroups(API グループ)×resources(リソース種別)×verbsget/list/watch/create/update/patch/delete など)で表します。重要なのは、RBAC には「拒否(deny)」ルールが無いことです。許可を積み上げるだけなので、最小権限(必要な許可だけを与える)で設計するのが原則になります。

RBAC の関係図。左に主体(User・Group・ServiceAccount)、中央に RoleBinding / ClusterRoleBinding、右に Role(Namespace スコープ)/ ClusterRole(クラスタスコープ)を置き、Binding が主体と Role を結ぶ。Role の中身は apiGroups × resources × verbs の許可の積み上げで、deny は無いことを示した図
図1:RBAC の関係(主体 — Binding — Role / ClusterRole)

第1巻第15回でも RBAC を扱いましたが、あれは「開発者が自分のアプリ用 ServiceAccount に最小権限を付ける」開発者視点でした。本回で扱うのは「管理者が、クラスタの利用者(人や SA)に、どの範囲で何を許すかを設計・付与・検証する」管理者視点で、踏み込みが別物です。第4回で配布した admin.conf は cluster-admin の全権でした。これを全員に配るわけにはいかない――だからこそ、利用者ごとに最小権限を設計する必要がある、というのが本回の出発点です。

RBAC を作って付与する(read-only な developer ロール)

具体的なシナリオで作ります。「developer は fanclub Namespace の Pod を見られる(ログも読める)が、消せない」という権限を設計します。まず「Pod の参照だけ」を許す Role を作ります。マニフェストを pod-reader-role.yaml として保存します。

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: fanclub
  name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods", "pods/log"]
  verbs: ["get", "list", "watch"]

apiGroups: [""] は「コア API グループ」(Pod・Service・ConfigMap など)を指します。verbsdelete を含めていないので、この Role では削除はできません。次に、この Role を developer という User に紐付ける RoleBinding を作ります。マニフェストを pod-reader-binding.yaml として保存します。

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: read-pods-developer
  namespace: fanclub
subjects:
- kind: User
  name: developer
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io

実行コマンド(k8s-ops・developer):

$ kubectl apply -f pod-reader-role.yaml
$ kubectl apply -f pod-reader-binding.yaml

実行結果:

role.rbac.authorization.k8s.io/pod-reader created
rolebinding.rbac.authorization.k8s.io/read-pods-developer created

ここでの developer は「クラスタ利用者の名前」です。実際にその名前の kubeconfig を持つ人がいるかどうかとは別に、RBAC のルールとして先に用意できます(作った権限は次節の impersonation で検証します)。念のため、作業端末で今 kubectl を叩いている実体は、第4回で配布した cluster-admin の admin.conf であって、この developer ではありません。

試験では時間短縮のため、同じものを命令形(imperative)で素早く作ることもあります。参考までに、上と等価なコマンドは次のとおりです(今回は YAML で作成済みなので実行は不要)。

$ kubectl create role pod-reader --verb=get,list,watch --resource=pods,pods/log -n fanclub
$ kubectl create rolebinding read-pods-developer --role=pod-reader --user=developer -n fanclub

なお、この権限は fanclub Namespace の中だけで有効です。もし「すべての Namespace で Pod を見たい」「node や PV などクラスタ資源を見たい」なら、Role ではなく ClusterRole を使い、ClusterRoleBinding(全体)または RoleBinding(特定 Namespace だけに絞って ClusterRole を再利用)で紐付けます。「1 つの Namespace に閉じるなら Role、横断・クラスタ資源なら ClusterRole」と覚えておきます。

権限を検証する(auth can-i と impersonation)

RBAC は「作ったら必ず検証する」のが鉄則です。作った権限が意図どおりか、kubectl auth can-i で確認します。--as=<ユーザー>(impersonation=なりすまし)を付けると、そのユーザーになったつもりで「できる/できない」を判定できます。これは cluster-admin だけが使える強力な検証手段で、CKA でも頻出です。

実行コマンド(k8s-ops・developer):

$ kubectl auth can-i get pods --as=developer -n fanclub
$ kubectl auth can-i delete pods --as=developer -n fanclub

実行結果:

yes
no

狙いどおり、Pod の参照は yes、削除は no です。付与直後にこの 2 つを打つだけで、「見られるが消せない」が実現できたと確認できます。もう一段踏み込んで、そのユーザーが持つ許可の一覧も出せます。

実行コマンド(k8s-ops・developer):

$ kubectl auth can-i --list --as=developer -n fanclub

実行結果(抜粋):

Resources                                       Non-Resource URLs   Resource Names   Verbs
selfsubjectreviews.authentication.k8s.io        []                  []               [create]
selfsubjectaccessreviews.authorization.k8s.io   []                  []               [create]
selfsubjectrulesreviews.authorization.k8s.io    []                  []               [create]
pods/log                                        []                  []               [get list watch]
pods                                            []                  []               [get list watch]
                                                [/healthz]          []               [get]
                                                [/version]          []               [get]
...

私たちが付けたのは podspods/logget list watch だけだと読み取れます。上の selfsubject... の 3 行や、下の URL 行(/healthz など・... で省略)は、どのユーザーにも既定で与えられる「自分の権限を確認する」用途とヘルスチェック用の許可です。「作った RBAC が意図どおりか」を、付与のたびにこの型で検証する習慣を付けてください。

ServiceAccount に権限を委譲する(CI 用 SA)

権限を渡す相手は人だけではありません。CI パイプラインや Operator など自動処理には ServiceAccount(SA)を使います。ここでは「CI が fanclub の Deployment を更新できる」SA を作ります。まず SA を作成します。マニフェストを ci-deployer.yaml として保存します。

apiVersion: v1
kind: ServiceAccount
metadata:
  name: ci-deployer
  namespace: fanclub

次に「Deployment を参照・更新できる」Role と、それを SA に紐付ける RoleBinding を作ります。マニフェストを ci-deployer-rbac.yaml として保存します(1 ファイルに --- 区切りで 2 つ書きます)。

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: deployment-manager
  namespace: fanclub
rules:
- apiGroups: ["apps"]
  resources: ["deployments"]
  verbs: ["get", "list", "watch", "update", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: ci-deployer-binding
  namespace: fanclub
subjects:
- kind: ServiceAccount
  name: ci-deployer
  namespace: fanclub
roleRef:
  kind: Role
  name: deployment-manager
  apiGroup: rbac.authorization.k8s.io

実行コマンド(k8s-ops・developer):

$ kubectl apply -f ci-deployer.yaml
$ kubectl apply -f ci-deployer-rbac.yaml

SA の権限も impersonation で検証できます。SA を指すときは system:serviceaccount:<namespace>:<name> の形式を使います。

実行コマンド(k8s-ops・developer):

$ kubectl auth can-i update deployments --as=system:serviceaccount:fanclub:ci-deployer -n fanclub
$ kubectl auth can-i delete deployments --as=system:serviceaccount:fanclub:ci-deployer -n fanclub

実行結果:

yes
no

更新はできるが削除はできない CI 用 SA ができました。ちなみに、稼働中の fanclub-api も chart 同梱の SA・Role・RoleBinding で動いています。管理者視点で「このアプリはどんな権限で動いているか」を読み解いてみます。

実行コマンド(k8s-ops・developer):

$ kubectl get sa,role,rolebinding -n fanclub

実行結果:

NAME                             AGE
serviceaccount/ci-deployer       20s
serviceaccount/default           17h
serviceaccount/fanclub-backend   17h

NAME                                                    CREATED AT
role.rbac.authorization.k8s.io/deployment-manager       2026-07-13T07:40:32Z
role.rbac.authorization.k8s.io/fanclub-backend-reader   2026-07-12T05:18:55Z
role.rbac.authorization.k8s.io/pod-reader               2026-07-13T07:40:06Z

NAME                                                                   ROLE                          AGE
rolebinding.rbac.authorization.k8s.io/ci-deployer-binding              Role/deployment-manager       20s
rolebinding.rbac.authorization.k8s.io/fanclub-backend-reader-binding   Role/fanclub-backend-reader   17h
rolebinding.rbac.authorization.k8s.io/read-pods-developer              Role/pod-reader               3m

自分で作った pod-readerci-deployer などに加えて、最初から fanclub-backend 用の SA・Role・RoleBinding が用意されていると分かります(AGE が 17h の 3 つ)。アプリが必要最小の権限で動くよう、chart を作る側があらかじめ設計しているわけです。

metrics-server を入れる(HPA の前提)

ここから自動スケール(HPA)に移ります。HPA は「CPU 使用率が高くなったら Pod を増やす」仕組みですが、その CPU 使用率を測るには metrics-server が必要です。metrics-server は kind にも kubeadm にも同梱されないため、自分で導入します(第1巻第6回で kind に入れたのと同じものです)。まず公式マニフェストを適用します。

実行コマンド(k8s-ops・developer):

$ kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.8.1/components.yaml

このままだと、metrics-server が各ノードの kubelet に接続する際、kubelet の自己署名証明書を検証できずに起動しきりません。検証をスキップする --kubelet-insecure-tls を引数に追加します(学習環境向けの設定です)。

実行コマンド(k8s-ops・developer):

$ kubectl patch deployment metrics-server -n kube-system --type=json \
  -p='[{"op":"add","path":"/spec/template/spec/containers/0/args/-","value":"--kubelet-insecure-tls"}]'

1 分ほど待って metrics-server が Ready になったら、kubectl top で数値が返ることを確認します。

実行コマンド(k8s-ops・developer):

$ kubectl top nodes

実行結果:

NAME        CPU(cores)   CPU(%)   MEMORY(bytes)   MEMORY(%)
k8s-cp-01   106m         5%       1374Mi          38%
k8s-cp-02   119m         5%       1301Mi          36%
k8s-cp-03   114m         5%       1321Mi          37%
k8s-wl-01   120m         3%       1200Mi          16%
k8s-wl-02   45m          1%       798Mi           10%

各ノードの CPU・メモリの実使用量が取れました。これで HPA が判断材料を得られます。

HPA で自動スケールする

HPA(Horizontal Pod Autoscaler)は、CPU 使用率(requests に対する割合)が目標値を超えたらレプリカを増やし、下がったら減らします。ここでは、負荷をかけると CPU を消費する使い捨ての Deployment を default Namespace に用意して実演します。マニフェストを php-apache.yaml として保存します。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: php-apache
spec:
  replicas: 1
  selector:
    matchLabels:
      run: php-apache
  template:
    metadata:
      labels:
        run: php-apache
    spec:
      containers:
      - name: php-apache
        image: registry.k8s.io/hpa-example
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: 200m
          limits:
            cpu: 500m
---
apiVersion: v1
kind: Service
metadata:
  name: php-apache
spec:
  selector:
    run: php-apache
  ports:
  - port: 80

requests.cpu: 200m が HPA の判定基準になります。適用してから、この Deployment に HPA を付けます。HPA は CPU 70%・最小 1・最大 5 とします。マニフェストを hpa.yaml として保存します。

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: php-apache
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: php-apache
  minReplicas: 1
  maxReplicas: 5
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70

試験では、同じ HPA を命令形で素早く作ることもあります(kubectl autoscale deployment php-apache --cpu-percent=70 --min=1 --max=5)。YAML と命令形のどちらでも同じ HPA ができます。ここでは YAML で作ります。

実行コマンド(k8s-ops・developer):

$ kubectl apply -f php-apache.yaml
$ kubectl apply -f hpa.yaml
$ kubectl get hpa php-apache

実行結果:

NAME         REFERENCE               TARGETS       MINPODS   MAXPODS   REPLICAS   AGE
php-apache   Deployment/php-apache   cpu: 0%/70%   1         5         1          15s

負荷が無いので 0%/70%・レプリカ 1 です。なお HPA を作った直後は、metrics-server がまだこの Pod の値を集めていないため cpu: <unknown>/70% と表示されることがあります。1 分ほど待つと数値に変わるので、慌てずに待ってください。別の Pod から連続アクセスして負荷をかけます。生成した負荷 Pod は load-generator という名前で作ります。

実行コマンド(k8s-ops・developer):

$ kubectl run load-generator --image=busybox:1.37 --restart=Never \
  -- /bin/sh -c "while true; do wget -q -O- http://php-apache; done"

HPA を -w(watch)で観察します。CPU が上がり、レプリカが 1 から増えていきます。

実行コマンド(k8s-ops・developer):

$ kubectl get hpa php-apache -w

実行結果(時間経過で更新される。抜粋):

NAME         REFERENCE               TARGETS         MINPODS   MAXPODS   REPLICAS   AGE
php-apache   Deployment/php-apache   cpu: 0%/70%     1         5         1          1m
php-apache   Deployment/php-apache   cpu: 250%/70%   1         5         1          2m
php-apache   Deployment/php-apache   cpu: 250%/70%   1         5         4          2m
php-apache   Deployment/php-apache   cpu: 87%/70%    1         5         5          3m
php-apache   Deployment/php-apache   cpu: 82%/70%    1         5         5          4m

CPU が 70% を超えると、HPA がレプリカを増やし、最大 5 まで到達しました。負荷を止めると、しばらくして(縮小はクールダウンがあり数分かかります)レプリカは 1 に戻ります。確認できたら、負荷 Pod・HPA・Deployment・Service を片付けます。

実行コマンド(k8s-ops・developer):

$ kubectl delete pod load-generator
$ kubectl delete hpa php-apache
$ kubectl delete -f php-apache.yaml

同じ手法で fanclub-backend も自動スケールできます。ただし fanclub Namespace には次に見る ResourceQuota が効いており、backend が増やせるのはその上限の範囲内までです(HPA と Quota はこのように関係します)。

ResourceQuota(Namespace の総量制限)

RBAC が「誰が」を制御するなら、ResourceQuota は「どれだけ」を制御します。1 つの Namespace がクラスタ資源を食い潰さないよう、CPU・メモリ・Pod 数などの総量に上限を設けます。fanclub Namespace には、chart 同梱の Quota(fanclub-quota)と、後述の LimitRange(fanclub-limits)が最初から効いています。

本書の演習を通して同じ結果になるよう、ここで chart 同梱のこの 2 つ(Namespace のガードレール)を本書の基準値に整えておきます。第1巻から引き継いだ chart は、環境や更新のタイミングでこれらの値が少し違っていることがあります。本回の演習だけでなく、第14回(Kustomize の overlay で本番だけ quota を引き上げる)・第16回(Quota 超過で Pod が作られない切り分け)も、この基準値を前提に進みます。まず ~/fanclub-chart/templates/limitrange.yaml を次の内容にします。

apiVersion: v1
kind: LimitRange
metadata:
  name: fanclub-limits
  namespace: {{ .Values.namespace }}
spec:
  limits:
  - type: Container
    default:
      cpu: "500m"
      memory: 512Mi
    defaultRequest:
      cpu: "50m"
      memory: 64Mi
    max:
      cpu: "2"
      memory: 1Gi

続いて ~/fanclub-chart/templates/resourcequota.yaml を次の内容にします。

apiVersion: v1
kind: ResourceQuota
metadata:
  name: fanclub-quota
  namespace: {{ .Values.namespace }}
spec:
  hard:
    requests.cpu: "1500m"
    requests.memory: 2Gi
    limits.cpu: "3"
    limits.memory: 4Gi
    pods: "12"
    persistentvolumeclaims: "2"

2 つを保存したら、chart を適用し直します。

実行コマンド(k8s-ops・developer):

$ helm upgrade fanclub ~/fanclub-chart --namespace fanclub --set gateway.enabled=false --set frontend.image.tag=1.0.0

整えたら、いま効いている Quota を読んでみます。

実行コマンド(k8s-ops・developer):

$ kubectl describe resourcequota fanclub-quota -n fanclub

実行結果(抜粋):

Resource                Used     Hard
--------                ----     ----
limits.cpu              2        3
limits.memory           1792Mi   4Gi
persistentvolumeclaims  1        2
pods                    5        12
requests.cpu            520m     1500m
requests.memory         832Mi    2Gi

Used / Hard で使用量と上限が並びます(使用量は稼働中の Pod によって多少前後します)。limits.cpu は 2(=2000m)使用・上限 3(=3000m)なので、残りは 1000m しかありません。先ほど「fanclub-backend を HPA で増やすと Quota の範囲内まで」と書いたのはこのためで、新しい backend レプリカ 1 つ分の limits.cpu を確保できず、Quota が上限として効きます。Quota は HPA より優先される――これは実務で覚えておきたい関係です。

次に、自分で Quota を作ってみます。新しい staging Namespace を作り、そこに総量制限をかけます。マニフェストを staging-quota.yaml として保存します。

apiVersion: v1
kind: ResourceQuota
metadata:
  name: staging-quota
  namespace: staging
spec:
  hard:
    requests.cpu: "2"
    requests.memory: 2Gi
    limits.memory: 4Gi
    pods: "10"

実行コマンド(k8s-ops・developer):

$ kubectl create namespace staging
$ kubectl apply -f staging-quota.yaml

Quota のある Namespace では、requests / limits を指定しない Pod は作成が拒否されます(どれだけ使うか宣言していない Pod は許可できないため)。試しに、リソース指定なしの Pod を staging に作ろうとすると失敗します。

実行コマンド(k8s-ops・developer):

$ kubectl run test --image=nginx:1.27-alpine -n staging

実行結果:

Error from server (Forbidden): pods "test" is forbidden: failed quota: staging-quota: must specify limits.memory for: test; requests.cpu for: test; requests.memory for: test

「requests / limits を明示せよ」と拒否されました。毎回 Pod に細かくリソースを書くのは大変です。これを解決するのが、次の LimitRange です。

LimitRange(Pod 単位の既定と上限)

LimitRange は、Namespace 内の Pod/コンテナに対して requests / limits の既定値を自動で与え、さらに単一コンテナの上限・下限も決めます。これを敷いておくと、リソース指定を省いた Pod にも既定値が付くので、Quota 環境でも作れるようになります。staging に LimitRange を作ります。マニフェストを staging-limitrange.yaml として保存します。

apiVersion: v1
kind: LimitRange
metadata:
  name: staging-limits
  namespace: staging
spec:
  limits:
  - type: Container
    default:
      cpu: 500m
      memory: 512Mi
    defaultRequest:
      cpu: 100m
      memory: 128Mi
    max:
      cpu: "1"
      memory: 1Gi

default が limits の既定、defaultRequest が requests の既定、max が 1 コンテナの上限です。適用してから、先ほど失敗したリソース指定なしの Pod を、もう一度作ってみます。

実行コマンド(k8s-ops・developer):

$ kubectl apply -f staging-limitrange.yaml
$ kubectl run test --image=nginx:1.27-alpine -n staging
$ kubectl get pod test -n staging

実行結果:

pod/test created
NAME   READY   STATUS    RESTARTS   AGE
test   1/1     Running   0          6s

今度は作れました。LimitRange の既定値(requests cpu 100m / memory 128Mi、limits cpu 500m / memory 512Mi)が自動で付与され、Quota の要求を満たしたためです。kubectl describe pod test -n stagingLimitsRequests 欄で、既定値が入っていることを確認できます。確認できたら staging Namespace ごと片付けます。

実行コマンド(k8s-ops・developer):

$ kubectl delete namespace staging

Namespace を消すと、その中の Quota・LimitRange・Pod もまとめて消えます。RBAC で作った Role・RoleBinding・ServiceAccount は fanclub Namespace に残ります。学習用なので、気になれば次のように削除しておいてかまいません(metrics-server は以降の回でも使うため、そのまま残します)。

実行コマンド(k8s-ops・developer):

$ kubectl delete -n fanclub role/pod-reader role/deployment-manager
$ kubectl delete -n fanclub rolebinding/read-pods-developer rolebinding/ci-deployer-binding
$ kubectl delete -n fanclub sa/ci-deployer

やってみよう

read-only な developer ロールを作って検証する

fanclub Namespace に「Pod を get/list/watch できるが delete はできない」Role と、それを User developer に紐付ける RoleBinding を作り、kubectl auth can-i get pods --as=developer -n fanclub=yes、delete pods=no を確認してください。

CI 用 ServiceAccount に権限を委譲する

SA ci-deployer を作り、Deployment を update できる Role を紐付け、kubectl auth can-i update deployments --as=system:serviceaccount:fanclub:ci-deployer -n fanclub=yes、delete deployments=no を確認してください。

HPA で 1→5 のスケールアウトを観察する

metrics-server を導入(--kubelet-insecure-tls パッチ込み)→ default に php-apache(requests.cpu 200m)を作り HPA(70%・min1/max5)を付与 → load-generator で負荷 → kubectl get hpa -w でレプリカが 1 から 5 まで増えることを確認してください。確認後は一式を削除します。

ResourceQuota と LimitRange

staging Namespace に ResourceQuota を作り、リソース指定なし Pod が拒否されること → LimitRange を追加すると同じ Pod が作れるようになること(既定値が付与される)を確認してください。確認後は staging を削除します。

まとめ

本回では、クラスタを複数チームで安全に共用するための Namespace ガバナンスを学びました。三本柱は、RBAC(誰が)=Role/ClusterRole と Binding で最小権限を設計し auth can-i --as で必ず検証する、ResourceQuota / LimitRange(どれだけ)=Namespace の総量と Pod 単位の既定・上限を決める、HPA(自動スケール)=metrics-server を前提に CPU 負荷でレプリカを増減する、でした。とくに RBAC は CKA ドメイン D1 の筆頭で、「作ったら auth can-i --as で検証」という型を身につけたことが大きな一歩です。あわせて、Quota が HPA の上限として効くという実務的な関係も確認しました。

理解度チェック(○×形式・全 9 問)

次の各文が正しいか(○)誤りか(×)を判断してください。下の「解答と解説」を開くと答え合わせができます。

  1. RBAC には「拒否(deny)」ルールがあり、特定の操作を明示的に禁止できる。
  2. Role は Namespace スコープ、ClusterRole はクラスタスコープの許可を定義する。
  3. kubectl auth can-i --as=<user> で、そのユーザーになったつもりで権限を検証できる。
  4. ClusterRole は、RoleBinding を使って特定の 1 つの Namespace に絞って紐付けることもできる。
  5. HPA は metrics-server が無くても CPU 使用率で動作する。
  6. HPA は Pod の requests.cpu に対する使用率で増減を判断する。
  7. ResourceQuota のある Namespace では、requests/limits 未指定の Pod も作成できる。
  8. LimitRange で既定値を敷けば、requests/limits 未指定の Pod にも既定が付き、Quota 環境でも作成できる。
  9. ServiceAccount を主体にするときは system:serviceaccount:<ns>:<name> の形式で指定する。
解答と解説

1=×(deny は無い。許可の積み上げのみ)/2=○(Role=NS・ClusterRole=クラスタ)/3=○(impersonation による検証)/4=○(ClusterRole を RoleBinding で特定 NS に再利用できる)/5=×(metrics-server が必要)/6=○(requests に対する使用率)/7=×(未指定 Pod は拒否。LimitRange で既定を敷けば可)/8=○(既定付与で Quota を満たせる)/9=○(system:serviceaccount:<ns>:<name>

次回予告

次回・第9回からは第3部「ネットワーク」に入ります。まずは Service の詳細(ClusterIP/NodePort/LoadBalancer/ExternalName の使い分けと kube-proxy の仕組み)と、オンプレでも LoadBalancer タイプを使えるようにする MetalLB を扱います。

前の記事
次の記事