前回に続いて、AKSとAD(Active Directory)の連携機能を試してみたい。ADのグループのメンバーのクラスタの特定のネームスペースに対するアクセス制限をコンフィグレーションしてみる。KubernetesのRBAC(Role-based-access-control)を使用する。基本的には、下記の記事を理解しながら実施する
今回は、開発者と、SREの2つのロールの権限を設定します。
AD グループの作成
ADのグループの作成を行います。ポータルからも可能ですが、AzureCLIでサクッと作ります。まずは、開発者用のグループです。
APPDEV_ID=$(az ad group create --display-name appdev --mail-nickname appdev --query objectId -o tsv)
できたか確認してみる。
$ az ad group list --query '[*].displayName' -o tsv
Team5
appdev
既存のグループがあったみたいだが、appdev
が無事作成されている。ちなみに、Azure CLIのクエリーの文法は、JMSPath と言うものらしい。よく使うので、これから常に使えるようにしておこう。
ロールのアサイン
まず、現在の、クラスタのIDを取得する。
AKS_ID=$(az aks show \
--resource-group myResourceGroup \
--name myAKSCluster \
--query id -o tsv)
このIDの中身をみてみると、一意になるURLである。
$ echo $AKS_ID
/subscriptions/<<YOUR_SUBSCRIPTION>>/resourcegroups/UshioTestGroup/providers/Microsoft.ContainerService/managedClusters/tsushicluster
グループにロールをアサインしよう。クラスタに対してロールをアサインしただけで、まずは何の権限もない。
az role assignment create \
--assignee $APPDEV_ID \
--role "Azure Kubernetes Service Cluster User Role" \
--scope $AKS_ID
ポータルのADのページに行くと、新しいロールがアサインされていることがわかる。AKSのページのAccess Control(IAM) > Role assignments
同じノリで、SREのグループを作成して、ロールをアサインする。
OPSSRE_ID=$(az ad group create --display-name opssre --mail-nickname opssre --query objectId -o tsv)
az role assignment create \
--assignee $OPSSRE_ID \
--role "Azure Kubernetes Service Cluster User Role" \
--scope $AKS_ID
ポータルで確認すると、しっかり増えている。
グループへのメンバーの追加
メンバーのオブジェクトIDを与えて、グループに参加させる。ObjectIDはポータルからみることができる。appdev
opssre
それぞれ登録する。ポータルではなく、コマンドラインで実施したい場合は次の通り。
$ az ad user list --query '[*].[displayName, objectId]'
これで見つけたユーザのオブジェクトIDを下記のコマンドでグループに登録しよう。
az ad group member add --group appdev --member-id <<User ObjectId>>
確認してみる。
$ az ad group member list --group appdev --query '[*].displayName' -o tsv
Hacker Two
invincible:azure-voting-app-redis ushio$ az ad group member list --group opssre --query '[*].displayName' -o tsv
Hacker Six
しっかり入っている様子。
ネームスペースの割り当てとロールの割り当て
この作業はk8sの管理者ユーザで実施する。次のコマンドで管理者用のクレデンシャルを取得して、.kube/config
に設定することができる。
az aks get-credentials --resource-group $RESOURCE_GROUP --name $AKSNAME --admin
開発者用のNamespaceをK8S側で作成。
kubectl create ns dev
Kubernetes では、Role
を定義して、パーミッションを付与して、RoleBindings
を使って、ユーザやグループに紐付けるようになる。下記の設定では、dev-user-full-access
と言うロールを作成している。dev
のネームスペースに対して、全てのリソースに対して、全ての操作が行えるように設定されている。
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: dev-user-full-access
namespace: dev
rules:
- apiGroups: ["", "extensions", "apps"]
resources: ["*"]
verbs: ["*"]
- apiGroups: ["batch"]
resources:
- jobs
- cronjobs
verbs: ["*"]
rules以下に、APIグループごとに設定を行う。APIグループは、APIをグループ化したもので、""はcoreAPIを表す。下記のリファレンスページをみると各APIにグループが記載されている。また、下記のコマンドでも現在のグループを閲覧できる。
$ kubectl api-resources -o wide
NAME SHORTNAMES APIGROUP NAMESPACED KIND VERBS
bindings true Binding [create]
componentstatuses cs false ComponentStatus [get list]
configmaps cm true ConfigMap [create delete deletecollection get list patch update watch]
endpoints ep true Endpoints [create delete deletecollection get list patch update watch]
events ev true Event [create delete deletecollection get list patch update watch]
limitranges limits true LimitRange [create delete deletecollection get list patch update watch]
namespaces ns false Namespace [create delete get list patch update watch]
nodes no false Node [create delete deletecollection get list patch update watch]
persistentvolumeclaims pvc true PersistentVolumeClaim [create delete deletecollection get list patch update watch]
persistentvolumes pv false PersistentVolume [create delete deletecollection get list patch update watch]
pods po true Pod [create delete deletecollection get list patch update watch]
podtemplates true PodTemplate [create delete deletecollection get list patch update watch]
replicationcontrollers rc true ReplicationController [create delete deletecollection get list patch update watch]
resourcequotas quota true ResourceQuota [create delete deletecollection get list patch update watch]
secrets true Secret [create delete deletecollection get list patch update watch]
serviceaccounts sa true ServiceAccount [create delete deletecollection get list patch update watch]
services svc true Service [create delete get list patch update watch]
initializerconfigurations admissionregistration.k8s.io false InitializerConfiguration [create delete deletecollection get list patch update watch]
mutatingwebhookconfigurations admissionregistration.k8s.io false MutatingWebhookConfiguration [create delete deletecollection get list patch update watch]
validatingwebhookconfigurations admissionregistration.k8s.io false ValidatingWebhookConfiguration [create delete deletecollection get list patch update watch]
customresourcedefinitions crd,crds apiextensions.k8s.io false CustomResourceDefinition [create delete deletecollection get list patch update watch]
apiservices apiregistration.k8s.io false APIService [create delete deletecollection get list patch update watch]
controllerrevisions apps true ControllerRevision [create delete deletecollection get list patch update watch]
daemonsets ds apps true DaemonSet [create delete deletecollection get list patch update watch]
deployments deploy apps true Deployment [create delete deletecollection get list patch update watch]
replicasets rs apps true ReplicaSet [create delete deletecollection get list patch update watch]
statefulsets sts apps true StatefulSet [create delete deletecollection get list patch update watch]
tokenreviews authentication.k8s.io false TokenReview [create]
localsubjectaccessreviews authorization.k8s.io
:
どう言う操作が設定可能なのかは100%クリアではないですが、公式のcluster-roles.yamlが参考になるかも。だいたいこんなもの。抜粋してみた。
- create
- delete
- deletecollection
- patch
- update
- get
- list
- watch
リソースに関してはkubectl get api-resources
コマンドで一覧をみることができる。
解析できたので、Applyしておく
kubectl apply -f role-dev-namespace.yaml
RoleBindings
AD側のグループのオブジェクトIDを取得しておく。
az ad group show --group appdev --query objectId -o tsv
これで、オブジェクトIDが取得できるので、これを、RoleBindingsで使用する。groupObjectId
を書き換える。
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: dev-user-access
namespace: dev
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: dev-user-full-access
subjects:
- kind: Group
namespace: dev
name: groupObjectId
同じようにapplyしておく。
kubectl apply -f rolebinding-dev-namespace.yaml
同様に、SRE側の設定を実施アプライする。
kind: Role
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: sre-user-full-access
namespace: sre
rules:
- apiGroups: ["", "extensions", "apps"]
resources: ["*"]
verbs: ["*"]
- apiGroups: ["batch"]
resources:
- jobs
- cronjobs
verbs: ["*"]
groupId はADのグループのオブジェクトIdを貼り付けること。
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: sre-user-access
namespace: sre
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: sre-user-full-access
subjects:
- kind: Group
namespace: sre
name: groupObjectId
テストの実施
今回は、2つのユーザを使った。hacker2(dev) とhacker6(sre)。だ。今までは、hacker2を使っていたけど、hacker6を使ってログインし直す。方法は、クレデンシャルをアップデートする。
$ az aks get-credentials --resource-group $RESOURCE_GROUP --name $AKSNAME --overwrite-existing
すると、ログイン情報を聞かれるので、今回は、hacker6でログインする。
$ kubectl get pod --all-namespaces
To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code <<SOMEKEY>> to authenticate.
他リソースの閲覧の失敗
SREでログインしているので、sre ネームスペースのみが見えたり、操作できたりするはずである。 しっかり失敗する。
$ kubectl get pod --all-namespaces
No resources found.
Error from server (Forbidden): pods is forbidden: User "hacker609o@ABCDE.onmicrosoft.com" cannot list resource "pods" in API group "" at the cluster scope
閲覧可能なネームスペースの閲覧
しっかり閲覧できる。
$ kubectl get pod -n sre
NAME READY STATUS RESTARTS AGE
nginx-sre 1/1 Running 0 178m
devリソースの閲覧
当然の事ながら閲覧できない。
$ kubectl get pod -n dev
No resources found.
Error from server (Forbidden): pods is forbidden: User "hacker609o@ABCDE.onmicrosoft.com" cannot list resource "pods" in API group "" in the namespace "dev"
ハマったところ
最初に、設定の結果を、hacker2 でテストすると全てのリソースが見えてしまった。理由は、hacker2は、管理者ログインで使ったアカウントと同じだから、管理者扱いされた様子。だから、hacker6でログインし直すとしっかりRBACが有効であるのが確認できた。
終わりに
RoleとRoleBindings そして、前回のブログにあった通りに、クラスタを設定する事で、ADのグループと、RBACを連携させることができた。思ったよりずっと簡単だった。