開発環境がローカルではそろそろつらくなってきたので、複数人でノードを共有して開発をするようにしたいと思いました。
namespaceで分けるのかな?とか漠然と考えていますが、まずはk8sのユーザーを作成せねばならんということで、手順です。
k8sにはUserAccountとServiceAccountと2種類アカウントの種類があるようです。UserAccountは人間用、ServiceAccountはPod等で実行されるプロセス用だそうです。
また方式もX509 Client Certs, Token, Password, OpenID Connectなどいろいろあるみたいです。
TL;DR
X509 Client CertsでUserAccountを作成し、ClusterRoleBindingに追加しています。
https://kubernetes.io/docs/tasks/tls/managing-tls-in-a-cluster/
公式Documents: https://kubernetes.io/docs/reference/access-authn-authz/authentication/#x509-client-certs
今回は、Linuxユーザーのmurataユーザーが管理者、deroriがUserAccountを作るユーザーとします。
秘密鍵を作る
追加したいユーザーで秘密鍵を作ります。
[derori@murata ~]$ openssl genrsa -out derori-tester.pem 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
.................................+++++
........+++++
e is 65537 (0x010001)
CSRを作る
CNにユーザ名を付けてCSRを作成します。
RoleBindingやRoleについては別途ググってください。
OにはGroup名が入れられるみたいです。
[derori@murata ~]$ openssl req -new -key derori-tester.pem -out derori-tester.csr -subj "/CN=derori-tester"
[derori@murata ~]$ openssl req -noout -text -in derori-tester.csr
Certificate Request:
Data:
Version: 1 (0x0)
Subject: CN = derori-tester
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public-Key: (2048 bit)
Modulus:
00:cc:69:23:97:07:9e:f8:54:79:f4:a0:48:c7:5f:
d5:44:63:23:8e:2f:0b:80:8c:ac:ac:7e:a4:7e:bc:
~~snip;
base64にしてk8sにマニフェスト食わせる
k8sに証明書をリクエストします。
[derori@murata ~]$ cat derori-tester.csr | base64 | tr -d '\n'
LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFV~~SNIP;
↓ここからk8sにアクセスできるユーザーでやる。(murataユーザー
cat <<EOF | kubectl apply -f -
apiVersion: certificates.k8s.io/v1beta1
kind: CertificateSigningRequest
metadata:
name: request-user-account-derori
spec:
groups:
- system:authenticated
request: <上のbase64化したCSRを貼り付ける。>
usages:
- digital signature
- key encipherment
- client auth
EOF
murata:~ $ cat <<EOF | kubectl apply -f -
> apiVersion: certificates.k8s.io/v1beta1
> kind: CertificateSigningRequest
> metadata:
> name: request-user-account-derori
> spec:
> groups:
> - system:authenticated
> request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ2RqQ0NBVjRDQVFB
khYOVZFWXlPT0x3dUFqS3lzZnFSK3ZQYVZjejB1d01qRW4ydmxqQ3liZUhFTDJzTHcKVmtpUEZoV2lMcn
6Ti9HcnpmWENWSno5aS9hd0swMnNGMHNPc3pZUGNqRExDVDl1ZWRFMUh6b3NrU21KSlF5RUMKektnT3Zm
UhqUGthUHhaVTZIT2s3R2FCc25KaEpTRUxmelZxVkVTblZ0akxzUGFzOGNvZ1pqVFRDWjBpVHRMdWYKQj
xUGFsVkgzcDBwRkRRR3Z0TlVzMTJUeE5DTU05YktwMXNzSkZic2d2RXB0M3h5MVpNajczWnlMYWJYZ0F2
> usages:
> - digital signature
> - key encipherment
> - client auth
> EOF
certificatesigningrequest.certificates.k8s.io/request-user-account-derori created
Pendingなcsrが追加されている。
murata:~ $ kubectl get csr
NAME AGE REQUESTOR CONDITION
request-user-account-derori 66s kubernetes-admin Pending
k8s側で承認する
murata:~ $ kubectl certificate approve request-user-account-derori
certificatesigningrequest.certificates.k8s.io/request-user-account-derori approved
murata:~ $ kubectl get csr
NAME AGE REQUESTOR CONDITION
request-user-account-derori 7m31s kubernetes-admin Approved,Issued
できた証明書を取得する
CRTをファイルに保存
murata:~ $ kubectl get csr request-user-account-derori -o jsonpath='{.status.certificate}' | base64 -d > derori-tester.crt
crtをderoriユーザーに渡す。(今回は同じサーバなのでcpで)
murata:~ $ sudo cp derori-tester.crt /home/derori/
kubectlの設定をする
deroriユーザーのkubectlの設定をします。
test-uaというcontextを作成します。--server=https://172.16.203.33:6443
には $ kubectl describe configmap/cluster-info -n kube-public
のserverセクションを見れば書いてあります。
[derori@murata ~]$ kubectl config set-cluster test-ua --insecure-skip-tls-verify=true --server=https://172.16.203.33:6443
Cluster "test-ua" set.
derori-testerユーザーの証明書を設定します。
[derori@murata ~]$ kubectl config set-credentials derori-tester --client-certificate=derori-tester.crt --client-key=derori-tester.pem --embed-certs=true
User "derori-tester" set.
contextをderori-testerユーザーに紐づけて作成します。
[derori@murata ~]$ kubectl config set-context test-ua --cluster=test-ua --user=derori-tester
Context "test-ua" created.
contextをtest-uaに切り替えます。
[derori@murata ~]$ kubectl config use-context test-ua
Switched to context "test-ua".
~/.kube/configファイルがこんな感じに作成されます。
[derori@murata ~]$ cat ~/.kube/config
apiVersion: v1
clusters:
- cluster:
insecure-skip-tls-verify: true
server: https://172.16.203.33:6443
name: test-ua
contexts:
- context:
cluster: test-ua
user: derori-tester
name: test-ua
current-context: test-ua
kind: Config
preferences: {}
users:
- name: derori-tester
user:
client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FUR
mFNREV4RnpBVkJnTlZCQW9URG5ONWMzUmxiVHB0WVhOMFpYSnpNUll3RkF
2N3kvVmk0bWwvWWkrTXJUdnlHTEd0OUtaYVZWTXg4aWhKME5IdXcwbUxvM
jN6TVBzSDk5WFlBblQ3K0ZVYzNYYWg3S3NkS243dndsRGl5NWI4TDRJV0t
WZgpQbm5qc2JQZkpOOHdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBSlJnY
3VEMnJvKwpMRUdjTXduUmU2b2VhcXlJYXZsZXBBeXhURFU5UGRpUDcyd0F
waGxjU289Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktL
DlZK21uVWNHU1gxYURSMXFON2dNUXZtdWhiemZtRmYraU1BWXFrdVRqV1N
zazcyOXdRdWJ0RXdrcURtOHFaWU8rYmRCMkE5Z1FJREFRQUJBb0gvQU14b
01HL21nNWZkeUJ4YTVBZkZKb2tQQ2JqNGgzNGRhdEkydlU5VlpLN0dNZ2N
KTFNveEFvR0JBT1VkTU9KbTlMbWNyakpoYTZNMlFSYVRvQ3ZaVnVRdUNXN
DFnTUUKNmFTM2RYTWRZaUZocFJwTnNEd0duYm9ab1BOU0JKSS9ZWGlzYnV
PUDBBVUtqT0oKcWZoUHlLVUc1VEVnQjM0ellTU08vS1Vubytjbnl6azl4Y
TlTajI2NFp6Mnk0UCsKNDRKQWZJQVFVeE5ZQ2l4L01NeElHZzR2NitlVW5
6TWUyK2tNYkJRZFU1Q3BGZmoKN2pRdjJxdVJiMStENGJ4aWZCTlJtU21EK
まだロールを与えていないので拒否されます。
[derori@murata ~]$ kubectl get all
Error from server (Forbidden): pods is forbidden: User "derori-test
Error from server (Forbidden): replicationcontrollers is forbidden:
Error from server (Forbidden): services is forbidden: User "derori-
Error from server (Forbidden): daemonsets.apps is forbidden: User "
Error from server (Forbidden): deployments.apps is forbidden: User
Error from server (Forbidden): replicasets.apps is forbidden: User
Error from server (Forbidden): statefulsets.apps is forbidden: User
Error from server (Forbidden): horizontalpodautoscalers.autoscaling
Error from server (Forbidden): jobs.batch is forbidden: User "deror
Error from server (Forbidden): cronjobs.batch is forbidden: User "d
ClusterRoleBinding編集
ClusterRoleBindingのcluster-adminに作ったユーザーを追加します。
参考: https://kubernetes.io/docs/reference/access-authn-authz/rbac/#role-binding-examples
murata:~ $ kubectl edit clusterrolebinding cluster-admin
subjectにkind:userで追加します。
- apiGroup: rbac.authorization.k8s.io
kind: User
name: derori-tester
こんな感じ。
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
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: "13568718"
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
- apiGroup: rbac.authorization.k8s.io
kind: User
name: derori-tester
とれるようになりました。
[derori@murata ~]$ kubectl get pod -n kube-system
NAME READY STATUS RESTARTS AGE
canal-lvw4h 1/2 CrashLoopBackOff 255 73d
coredns-5644d7b6d9-z5ql9 1/1 Running 1 73d
coredns-5644d7b6d9-z9kxf 1/1 Running 1 73d
etcd-murata.dev.mercury.local 1/1 Running 1 88d
kube-apiserver-murata.dev.mercury.local 1/1 Running 1 88d
kube-controller-manager-murata.dev.mercury.local 1/1 Running 1 88d
kube-proxy-g6cnt 1/1 Running 1 73d
kube-scheduler-murata.dev.mercury.local 1/1 Running 1 88d
metrics-server-f6d856bdf-29cwl 1/1 Running 1 12d
ユーザーの消し方
csrを消しても無駄です。
ClusterRoleBindingのsubject: Kind: Userを消せばおkみたいです。(ユーザー自体を消す方法はあるのか?)
まとめ
ServiceAccountを追加する方法はよく出てくるのだが、UserAccountを追加するドキュメントがいまいちないなと思いました。
正解なのか不安なところがあるので何かあれば気軽にコメントください。
参考
公式Documents: https://kubernetes.io/docs/reference/access-authn-authz/authentication/#x509-client-certs
ユーザアカウント用に証明書を設定する
https://kubernetes.io/docs/tasks/tls/managing-tls-in-a-cluster/