KubernetesでServiceAccountを追加する

/etc/kubernetes/admin.conf を~/.kube/configにコピーすれば使えてしまうのだが配った人全員がkubernetes-adminユーザーになってしまう。それでは何なので、ServiceAccountを作成する。
UserAccount / ServiceAccountがユーザー、
Role / ClusterRoleがロール、
RoleBinding / ClusterRoleBindingでユーザーとロールを紐づける。

といった感じになる。これを称してRBAC(Role-based access control)という。まぁよくあるタイプだよね。
Role/Bindingはnamespace別、Clusterがつくとクラスタ全体に響く設定になる。
とりあえず設定するを目的としているので、詳しくはググってくれ。死ぬほど出てくる。

# TL;DR

ServiceAccount Tokenを利用したServiceAccountを作成してClusterRoleのedit権限を付けちゃいます。

ServiceAccountはpodなどのシステム用で、UserAccountは人につけるものだということが書いてあるが、とりあえずServiceAccountを追加してみる。

```
murata:~ $ kubectl version
Client Version: version.Info{Major:"1", Minor:"16", GitVersion:"v1.16.2", GitCommit:"c97fe5036ef3df2967d086711e6c0c405941e14b", GitTreeState:"clean", BuildDate:"2019-10-15T19:18:23Z", GoVersion:"go1.12.10", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"16", GitVersion:"v1.16.2", GitCommit:"c97fe5036ef3df2967d086711e6c0c405941e14b", GitTreeState:"clean", BuildDate:"2019-10-15T19:09:08Z", GoVersion:"go1.12.10", Compiler:"gc", Platform:"linux/amd64"}
```


# ServiceAccount作成

```
murata:~ $ kubectl create serviceaccount derorisan
serviceaccount/derorisan created
```

```
murata:~ $ kubectl describe serviceaccount derorisan
Name:                derorisan
Namespace:           default
Labels:              <none>
Annotations:         <none>
Image pull secrets:  <none>
Mountable secrets:   derorisan-token-4xswb
Tokens:              derorisan-token-4xswb
Events:              <none>
```

Namespace defaultにdeorirsanアカウントが作成されました。


# Token確認

describeのMountable secretsかTokenのところにあるのがsecretです。そこにTokenが記載されています。

```
murata:~ $ kubectl describe secret derorisan-token-4xswb
Name:         derorisan-token-4xswb
Namespace:    default
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: derorisan
              kubernetes.io/service-account.uid: d8e2d357-9b5d-4dfc-9035-ac25784dd35c

Type:  kubernetes.io/service-account-token

Data
====
token:      eyJhbGciOiJSUzI1NiIsImtpZCI6IkJFb1BFd1U0MFlIWDFoWXZ2RHE2OGFKUHZxNEdTaEh1d
udC9zZWNyZXQubmFtZSI6ImRlcm9yaXNhbi10b2tlbi00eHN3YiIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFj
WMiLCJzdWIiOiJzeXN0ZW06c2VydmljZWFjY291bnQ6ZGVmYXVsdDpkZXJvcmlzYW4ifQ.JX1o9pPOoI9HHq4
EVqrjTHJ9T1AYWDqc0at3wFFMkEUuAqaY1bkwTpJzwIkfhzgpGvf_30Pq9pHJhZaBSF6HXYEvlJiespa3Q3i9
ca.crt:     1025 bytes
namespace:  7 bytes
```
※tokenが長いので右端は切ってあります。



# クライアントに設定

とりあえず先に認証だけ通るようにします。linuxユーザーをderoriユーザーに切り替えてやります。

~/.kube/configにclusterを設定します。(serverは `$ kubectl describe configmap/cluster-info -n kube-public` のserverセクションを見れば書いてあります。)
--insecure-skip-tls-verifyはいらないかも。

```
[derori@murata ~]$ kubectl config set-cluster test-sa --insecure-skip-tls-verify=true --server=https://172.16.203.33:6443
Cluster "test-sa" set.
```

configにderorisanユーザーの設定を追加します。

```
[derori@murata ~]$ kubectl config set-credentials derorisan --token=eyJhbGciOiJSUzI1NiIsImtpZ
User "derorisan" set.
```
※Tokenが長いので右端切っています。

test-saにはderorisanユーザーを使うように設定します。

```
[derori@murata ~]$ kubectl config set-context test-sa --cluster=test-sa --user=derorisan
Context "test-sa" created.
```

切り替えます。

```
[derori@murata ~]$ kubectl config use-context test-sa
Switched to context "test-sa".
```

全部~/.kube/configの中身をコマンドに書いてもらっただけです。


でpodを取得しようとしてみましょう。ユーザーは作ったけどroleはバインディングしていないのでエラーになります。

```
[derori@murata ~]$ kubectl get pod
Error from server (Forbidden): pods is forbidden: User "system:serviceaccount:default:derorisan" cannot list resource "pods" in API group "" in the namespace "default"
```

# ClusterRoleのバインディング作成

既存のClusterRoleのeditにderorisanアカウントをtest-rolebindingという名前でバインディングします。(deororiユーザーから戻ります。)

```
murata:~ $ kubectl create clusterrolebinding test-rolebinding --clusterrole=edit --serviceaccount=default:derorisan
clusterrolebinding.rbac.authorization.k8s.io/test-rolebinding created
```

```
murata:~ $ kubectl describe clusterrolebinding test-rolebinding
Name:         test-rolebinding
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  ClusterRole
  Name:  edit
Subjects:
  Kind            Name       Namespace
  ----            ----       ---------
  ServiceAccount  derorisan  default
```


# アクセス確認

deroriユーザーにて。

```
[derori@murata ~]$ kubectl get pod
No resources found in default namespace.
```
おっとpodはなかった。

```
[derori@murata ~]$ kubectl get all
NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   90d
```

おｋおｋ。ちなみにClusterRoleBindingであれば別のNamespaceも問題なくいじれます。

# ServiceAccount削除

削除すればアクセスできなくなる。(secretだけ消しても別のTokenが復活します。


```
murata:~ $ kubectl delete sa derorisan
serviceaccount "derorisan" deleted
murata:~ $ kubectl get sa
NAME      SECRETS   AGE
default   1         90d
test-sa   1         54m
murata:~ $ kubectl get secret
NAME                  TYPE                                  DATA   AGE
default-token-tlqfr   kubernetes.io/service-account-token   3      90d
test-sa-token-9lj42   kubernetes.io/service-account-token   3      46m
```

```
[derori@murata ~]$ kubectl get all
error: You must be logged in to the server (Unauthorized)
error: You must be logged in to the server (Unauthorized)
error: You must be logged in to the server (Unauthorized)
error: You must be logged in to the server (Unauthorized)
error: You must be logged in to the server (Unauthorized)
error: You must be logged in to the server (Unauthorized)
error: You must be logged in to the server (Unauthorized)
error: You must be logged in to the server (Unauthorized)
error: You must be logged in to the server (Unauthorized)
error: You must be logged in to the server (Unauthorized)
```

おｋです。



# おまけ

既存のRoleBindingに作ったServiceAccountを追加することもできます。

```
murata:~ $ kubectl edit clusterrolebinding cluster-admin
```

一番下のsubjectsに追加します。

```
- kind: ServiceAccount
  name: derorisan
  namespace: default
```

こんな感じ

```
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  annotations:
    rbac.authorization.kubernetes.io/autoupdate: "true"
  creationTimestamp: "2019-11-13T11:36:43Z"
  labels:
    kubernetes.io/bootstrapping: rbac-defaults
  name: cluster-admin
  resourceVersion: "13564650"
  selfLink: /apis/rbac.authorization.k8s.io/v1/clusterrolebindings/cluster-admin
  uid: dbc698e6-4aff-4b24-a2db-05fd1cf90d63
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: Group
  name: system:masters
- kind: ServiceAccount
  name: derorisan
  namespace: default

```


# まとめ


k8sの認証/認可はいろいろな方法があって混乱しました。(覚えきれないまん)
とりあえずServiceAccountを使ってユーザーを作成してみました。
おそらくコンソールなどからのアクセスはServiceAccountではなくUserAccountでやるのが正解なのでしょうが、~~それはまた別の機会に。~~
UserAccountの追加はこちら https://qiita.com/murata-tomohide/items/15807a4740b1ea3b92da



参考 as below:

[Managing Service Accounts](https://kubernetes.io/docs/reference/access-authn-authz/service-accounts-admin/)
[https://kubernetes.io/docs/reference/access-authn-authz/rbac/](https://kubernetes.io/docs/reference/access-authn-authz/rbac/)
[Kubernetes道場 20日目 - Role / RoleBinding / ClusterRole / ClusterRoleBindingについて](https://cstoku.dev/posts/2018/k8sdojo-20/)
[KubernetesのService Accountについて調べてみた](https://qiita.com/knqyf263/items/ecc799650fe247dce9c5)