はじめに
Kubernetesのユーザーについてざっくりまとめて、実際にユーザーを作成(?)してみました。
Kubernetesでのユーザー
Kubernetesには以下の2種類のユーザーがあります。
- ユーザー(いわゆる通常のユーザー)
- サービスアカウント(Service Account)
それぞれができる操作はRBAC(Role-Based Access Control)という仕組みで制御します。
ユーザー
ユーザーは、クラスタ外からKubernetesの操作が可能です。
公式ドキュメントで下記のように記載されているように、Kubernetesでは通常のユーザーのオブジェクトはありません。
Kubernetesは通常のユーザーアカウントを表すオブジェクトを持ちません。
ただし、Kubernetes側で認証ができたユーザーがクラスタ外から操作できるようになっています。
認証方法はいくつか用意されており、以下のような認証方法があります。
- X509クライアント証明書
- 静的なトークンファイル
- サービスアカウントトークン
- OpenID Connectトークン
- Webhookトークン認証
- 認証プロキシー
サービスアカウント
サービスアカウント(Service Account)は、Kubernetes内で管理されているアカウントで、Podと紐づけることでPodからKubernetesAPIを操作できるようになります。
通常のユーザとは異なり実際にKubernetes内に作成します。
通常のユーザーで認証してみる
実際にユーザーで認証してみます。いわゆるユーザーの追加のようなことをします。
今回は、X509クライアント証明書での認証をしたいと思います。
秘密鍵の作成
まずは、2048ビットの秘密鍵masa.key
を生成します。
❯ openssl genrsa -out masa.key 2048
Generating RSA private key, 2048 bit long modulus
.....................+++
..........................................................+++
e is 65537 (0x10001)
CSRの作成
秘密鍵masa.key
をもとに証明書署名要求(CSR)masa.csr
を作成します。Common Name(CN)がユーザ名、Organizationがグループ名になります。
❯ openssl req -new -key masa.key -out masa.csr -subj "/CN=masa"
CSRの登録
Base64でエンコードします。
❯ cat masa.csr | base64 | tr -d "\n"
CSRを登録するcsr.yml
を作成して、エンコードしたCSRをrequest
に記入します。
apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
name: masa
spec:
request: LS0tLS1CRUdJTi....... # エンコードしたCSR
signerName: kubernetes.io/kube-apiserver-client
usages:
- client auth
マニフェストを反映します。
❯ kubectl apply -f csr.yml
certificatesigningrequest.certificates.k8s.io/masa created
CSRを確認してみます。
ステータスがPendingであることがわかります。
❯ kubectl get csr
NAME AGE SIGNERNAME REQUESTOR CONDITION
masa 29s kubernetes.io/kube-apiserver-client docker-for-desktop Pending
CSRの承認
CSRを承認します。
❯ kubectl certificate approve masa
certificatesigningrequest.certificates.k8s.io/masa approved
確認するとステータスが承認されたことがわかります。
❯ kubectl get csr
NAME AGE SIGNERNAME REQUESTOR CONDITION
masa 109s kubernetes.io/kube-apiserver-client docker-for-desktop Approved,Issued
証明書masa.crt
を取得します。
❯ kubectl get csr masa -o jsonpath='{.status.certificate}'| base64 -d > masa.crt
ロールの作成
クラスタ全体で有効なPodを読み取れるClusterRoleを作成します。
❯ kubectl create clusterrole pod-reader --verb=get,list,watch --resource=pods
clusterrole.rbac.authorization.k8s.io/pod-reader created
ClusterRoleをユーザに紐づけるためのClusterRoleBindingを作成します。
❯ kubectl create clusterrolebinding pod-reader-binding --clusterrole=pod-reader --user=masa
clusterrolebinding.rbac.authorization.k8s.io/pod-reader-binding created
kubeconfig
kubeconfigにユーザー情報を設定します。
まずは、ユーザーを追加します。
❯ kubectl config set-credentials masa --client-key=masa.key --client-certificate=masa.crt --embed-certs=true
User "masa" set.
コンテキスト(context)を作成します。
コンテキストとは、クラスタとユーザーとnamespaceからなるものです。
❯ kubectl config set-context masa@docker-desktop --cluster=docker-desktop --user=masa
Context "masa@docker-desktop" created.
コンテキストを変更することで、利用するユーザーが変更されます。
❯ kubectl config use-context masa@docker-desktop
Switched to context "masa@docker-desktop".
試しにPodとDeploymentを取得してみると、新しく作成したユーザーにはPod取得のロールしか割り当てていないので、Podは取得できて、Deploymentは取得できていないことがわかります。
❯ kubectl get deployments --all-namespaces
Error from server (Forbidden): deployments.apps is forbidden: User "masa" cannot list resource "deployments" in API group "apps" at the cluster scope
❯ kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system coredns-558bd4d5db-9k9lx 1/1 Running 0 25m
:
:
:
最後に設定を確認すると、コンテキストとユーザーが追加されていることが確認できます。
❯ kubectl config view
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: DATA+OMITTED
server: https://kubernetes.docker.internal:6443
name: docker-desktop
contexts:
- context:
cluster: docker-desktop
user: docker-desktop
name: docker-desktop
- context:
cluster: docker-desktop
user: masa
name: masa@docker-desktop
current-context: masa@docker-desktop
kind: Config
preferences: {}
users:
- name: docker-desktop
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
- name: masa
user:
client-certificate-data: REDACTED
client-key-data: REDACTED
まとめ
- ユーザー自体のオブジェクトは存在しない
- ユーザーの認証方法は複数ある