コンテンツにスキップ

13. Role-Based Access Control

Role-Based Access Controlで誰が何に対して何をできるかを定義できる。

Service Account

Service AccountはKubernetesにおけるユーザーの単位を定義する。

k8s/cicd-service-account.yaml
1
2
3
4
5
apiVersion: v1
kind: ServiceAccount
metadata:
  name: cicd-deploy
  namespace: app

RoleBinding

RoleBindingで誰に権限を与えるかを定義する。

RoleBindingはRoleとService Accountを紐づけているだけである。(無意味な感じがするが、このリソースがあることで同じRoleを複数のServiceAccountに与えたいとき、RoleBindingを増やすだけで対応できる)

k8s/cicd-role-binding.yaml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: cicd-deploy
  namespace: app
subjects:
  - kind: ServiceAccount
    name: cicd-deploy
    namespace: app
roleRef:
  kind: Role
  name: cicd-deploy
  apiGroup: rbac.authorization.k8s.io

Role

Roleで与える権限を定義する。

cicd-deploy-role.yaml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: cicd-deploy
  namespace: app
rules:
  - apiGroups: ["apps"] # 分類Deployment, StatefulSet, ReplicaSetなどはapps
    resources: ["deployments", "statefulsets"] # Kubernetesのリソースの種類
    verbs: ["get", "list", "watch", "create", "update", "patch"] # できること
  - apiGroups: [""] # Pod, Service, ConfigMap, Secret などコアリソース
    resources: ["pods", "services", "configmaps"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
  - apiGroups: ["autoscaling"]
    resources: ["horizontalpodautoscalers"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
  - apiGroups: ["cert-manager.io"]
    resources: ["certificates"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
  - apiGroups: ["gateway.networking.k8s.io"]
    resources: ["gateways", "httproutes"]
    verbs: ["get", "list", "watch", "create", "update", "patch"]
verb 意味
get 1件取得
list 一覧取得
watch 変化を監視
create 作成
update 更新
patch 部分更新
delete 削除

パイプラインに適用する

k8s/cicd-token.yaml
1
2
3
4
5
6
7
8
apiVersion: v1
kind: Secret
metadata:
  name: cicd-deploy-token
  namespace: app
  annotations:
    kubernetes.io/service-account.name: cicd-deploy
type: kubernetes.io/service-account-token

パイプライン実行後、クラスター側で以下のコマンドを実行しトークンを取得する。

1
$ kubectl get secret cicd-deploy-token -n app -o jsonpath='{.data.token}' | base64 --decode

GiteaのKUBECONFIG_CONTENTを更新する。

KUBECONFIG_CONTENT
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion: v1
clusters:
  - cluster:
      certificate-authority-data: # 略
      server: # 略
    name: default
contexts:
  - context:
      cluster: default
      user: default
    name: default
current-context: default
kind: Config
users:
  - name: default
    user:
      client-certificate-data: # 略
      client-key-data: # 略
  - name: cicd-deploy
    user:
      token: # 上記のトークン

権限を超えたクラスター操作ができないことを確認する。Minikubeのkubeconfigを見直す。

~/.kube/config
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion: v1
clusters:
  - cluster:
      certificate-authority-data: # 略
      server: # 略
    name: default
contexts:
  - context:
      cluster: default
      user: cicd-deploy
    name: rpi5
current-context: default
kind: Config
users:
  - name: default
    user:
      client-certificate-data: # 略
      client-key-data: # 略
  - name: cicd-deploy
    user:
      token: # 略
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 禁止されている操作
$ kubectl get nodes --context=rpi5
Error from server (Forbidden): nodes is forbidden: User "system:serviceaccount:app:cicd-deploy" cannot list resource "nodes" in API group "" at the cluster scope

# 許可されている操作
$ kubectl get pods -n app --context=rpi5
NAME                         READY   STATUS    RESTARTS       AGE
app-767848d855-9bp5t         1/1     Running   0              14m
app-nginx-676887c8bd-gwlvm   1/1     Running   4 (3d7h ago)   13d
db-0                         1/1     Running   1 (3d7h ago)   3d18h
db-6b59878f65-ntqkw          0/1     Unknown   5              14d