GKEでRBACを使ってアクセス可能なnamespaceを限定する

# はじめに
RBACをあまり触ってなかったので、自分用メモのレベルだけど動作を確認してみた。
今回は特定のNamespaceにて`get pod`できるようにするroleを作成する。

## 環境
GKE master version 1.11.2-gke.15

## RBACについて
RBAC API はロールには一連のアクセス許可を表すルールが含まれている。パーミッションは純粋にadditive。(拒否ルールはない)。
Roleは、Roleを持つ名前空間内で定義することも、ClusterRoleを使用してクラスタ全体に定義することもできる。
Roleは単一のnamespace内のリソースへのアクセスを許可するためにのみ使用できる。

以下が参考になる
https://github.com/GoogleCloudPlatform/gke-rbac-demo

## やってみる

### IAMの作成
今回、2つのIAMを作成すると仮定する。

1. sakon
2. ukon

#### 権限
**sakon**にはOWNER権限を付与する
**ukon**にはクラスタにアクセスするための、最低限の権限を付与する
`container.apiServices.get`,`container.apiServices.list`,`container.clusters.get`,`container.clusters.getCredentials`


### クラスタ作成

```
gcloud beta container --project "YOUR-PRJ-NAME" clusters create "standard-cluster-1" 
--zone "asia-northeast1-a" --username "admin" --cluster-version "1.11.2-gke.15" 
--machine-type "n1-standard-1" --image-type "COS" --disk-type "pd-standard" --disk-size "100" 
--scopes "https://www.googleapis.com/auth/devstorage.read_only","https://www.googleapis.com/auth/logging.write","https://www.googleapis.com/auth/monitoring","https://www.googleapis.com/auth/servicecontrol","https://www.googleapis.com/auth/service.management.readonly","https://www.googleapis.com/auth/trace.append" 
--num-nodes "1" --enable-cloud-logging --enable-cloud-monitoring --network "projects/YOUR-PRJ-NAME/global/networks/default" --addons HorizontalPodAutoscaling,HttpLoadBalancing 
--enable-autoupgrade --enable-autorepair
```

### クレデンシャルの取得

```
gcloud container clusters get-credentials rbac-test --zone asia-northeast1-a --project YOUR-PRJ-NAME

Fetching cluster endpoint and auth data.
kubeconfig entry generated for rbac-test.
```

### Namespaceの確認

```
$ kubectl get namespace
NAME          STATUS    AGE
default       Active    11m
kube-public   Active    11m
kube-system   Active    11m
```

### Namespaceの作成

```yaml:namespace.yml
apiVersion: v1
kind: Namespace
metadata:
  name: sakon

---

apiVersion: v1
kind: Namespace
metadata:
  name: other-sakon
```

```
$ kubectl apply -f namespace.yml
namespace "sakon" created
namespace "other-sakon" created
```

```
$ kubectl get namespaces
NAME          STATUS    AGE
default       Active    1h
kube-public   Active    1h
kube-system   Active    1h
other-sakon   Active    2m
sakon         Active    2m
```

### Role,RoleBindingの作成
sakonアカウントで以下の`Role`と`RoleBinding`を`kubectl apply -f role-rolebinding.yml`にて適用する

```yaml:role-rolebinding.yml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: other-sakon
  name: pod-reader
rules:
- apiGroups: [""]
  verbs: ["get", "list"]
  resources: ["pods"]

---

kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: pod-readers
  namespace: other-sakon
subjects:
- kind: User
  name: ukon@example.com
  apiGroup: rbac.authorization.k8s.io
roleRef:
  kind: Role
  name: pod-reader
  apiGroup: rbac.authorization.k8s.io
```

### nginxのpodを起動する

`sakon`アカウントにて以下を実行する。

```
kubectl run nginx-sakon --image=nginx --namespace=sakon
kubectl run nginx-other-sakon --image=nginx --namespace=other-sakon
```

### podを確認する
#### `sakon`アカウントにて確認する

```
$ kubectl get pod --all-namespaces
NAMESPACE     NAME                                                  READY     STATUS    RESTARTS   AGE
kube-system   event-exporter-v0.2.1-7978ddf677-fng9b                2/2       Running   0          18h
kube-system   fluentd-gcp-scaler-5d85d4b48b-g4hcn                   1/1       Running   0          18h
kube-system   fluentd-gcp-v3.1.0-7fxfk                              2/2       Running   0          18h
kube-system   heapster-v1.6.0-beta.1-75fddb9f56-c7ksx               3/3       Running   0          18h
kube-system   kube-dns-548976df6c-6tstm                             4/4       Running   0          18h
kube-system   kube-dns-autoscaler-67c97c87fb-n5wjh                  1/1       Running   0          18h
kube-system   kube-proxy-gke-rbac-test-default-pool-f55e6fa5-t2jw   1/1       Running   0          18h
kube-system   l7-default-backend-5bc54cfb57-xksmz                   1/1       Running   0          18h
kube-system   metrics-server-v0.2.1-fd596d746-tfd2r                 2/2       Running   0          18h
other-sakon   nginx-other-sakon-6ffd7dcddb-gl748                    1/1       Running   0          16h
sakon         nginx-sakon-55868f6d8-9hfcs                           1/1       Running   0          16h
```

#### `ukon`アカウントで確認する。
`other-sakon`NamespaceのPodしかGet出来ない事がわかる。

```
$ kubectl get pod --all-namespaces
Error from server (Forbidden): pods is forbidden: User "ukon@example.com" cannot list pods at the cluster scope: Required "container.pods.list" permission.

$ kubectl get pod -n sakon
Error from server (Forbidden): pods is forbidden: User "ukon@example.com" cannot list pods in the namespace "sakon": Required "container.pods.list" permission.

$ kubectl get pod -n other-sakon
NAME                                 READY     STATUS    RESTARTS   AGE
nginx-other-sakon-6ffd7dcddb-gl748   1/1       Running   0          1d
```