【Kubernetes】クラスター接続用ユーザーを作成する方法
目次 [非表示]
こんにちは!
株式会社ビヨンド大阪オフィスのラーメン王、ヒデです。
今回が14回目の投稿です。
前回はCloudflare Workers で Basic認証する設定方法について書きました!
設定方法は比較的簡単にできますが、設定箇所を間違えると最悪サイトが見れなくなる可能性はあります。
失敗しないようにわかりやすく設定方法を紹介しているので気になる人はぜひ、確認してみてくださいね。
概要
kubernetesクラスターに接続するユーザーを別途作成したいけどわからない。。。。
ユーザに与える権限も調整したいけどマジでわからない。。。
あっ?これ、もう詰んだわ?
上記のようなことは思ったことありませんでしょうか?
私もクラスターに接続するユーザーを別途作成できることは知っていましたが、調べたら調べるほど難しかった。。。
色々と試行錯誤するとついに作成することができたので、作成したい方はぜひ参考にしてくださいね!
それではやってみましょう!!
注意事項
この手順では基本的なKubernetesの概念やリソースの説明などは行いません。
また、EKSやGKEなどの各クラウドのマネージドKubernetesクラスターの場合は、ユーザーを追加する方法が違う可能性がございます。
クラウドでKubernetesを運用されている方は、各リファレンスをご確認ください。
手順
1.鍵を作成してエンコード
1-1.秘密鍵・公開鍵を作成
*{username}にユーザ名を入力してください
1 2 3 | cd .kube/ openssl genrsa -out {UserName}.key 2048 openssl req -new -key {UserName}.key -out {UserName}.csr -subj "/CN={UserName}" |
例:ユーザー名がexample-testの場合
1 2 | openssl genrsa -out example-test.key 2048 openssl req -new -key example-test.key -out example-test.csr -subj "/CN=example-test" |
1-2.base64でエンコードする
1 | cat {UserName}.csr | base64 | tr -d "\n" |
⇒エンコードした値が出力されるので控えておく
例:
1 2 | [example-test@bastion01 ~]$ cat example-test.csr | base64 | tr -d "\n" xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
2.作成したcsrをapplyして設定する
2-1.yamlファイルを作成
*{UserName
}にユーザ名を入れる
*{EncodeValue}の部分にエンコードした値を入れる
1 2 3 4 5 6 7 8 9 10 11 | vi {UserName}-csr.yaml apiVersion: certificates.k8s.io/v1 kind: CertificateSigningRequest metadata: name: {UserName} spec: request: {EncodeValue} signerName: kubernetes.io/kube-apiserver-client usages: - client auth |
例:
1 2 3 4 5 6 7 8 9 10 11 | vi example-test-csr.yaml apiVersion: certificates.k8s.io/v1 kind: CertificateSigningRequest metadata: name: example-test spec: request: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx signerName: kubernetes.io/kube-apiserver-client usages: - client auth |
2-2.yamlファイルをapply
1 | kubectl apply -f {UserName}-csr.yaml |
例:
1 2 | [example-test@bastion01 ~]$ kubectl apply -f example-test-csr.yaml certificatesigningrequest.certificates.k8s.io/example-test created |
2-3.applyされたか確認
*csrを承認していないのでステータスがPendingになっています
*NAMEに出力された値を控える
1 | kubectl get csr |
例:
1 2 3 | [example-test@bastion01 ~]$ kubectl get csr NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION example-test 12s kubernetes.io/kube-apiserver-client xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 〈none〉 Pending |
2-4.csrを承認する
*{CsrName}に先ほど控えたNAMEの値を入れてください
1 | kubectl certificate approve {CsrName} |
例:
1 2 | [example-test@bastion01 ~]$ kubectl certificate approve example-test certificatesigningrequest.certificates.k8s.io/example-test approved |
2-5.csrの承認を確認する
*CONDITIONの欄がapprovedになっていれば、承認されています
1 | kubectl get csr |
例:
1 2 3 | [example-test@bastion01 ~]$ kubectl get csr NAME AGE SIGNERNAME REQUESTOR REQUESTEDDURATION CONDITION example-test 14m kubernetes.io/kube-apiserver-client xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx 〈none〉 Approved,Issued |
2-6.crtを作成する
*{CsrName}に先ほど控えたNAMEの値を入れてください
1 | kubectl get csr {CrtName} -o jsonpath='{.status.certificate}' | base64 -d > {CrtName}.crt |
3.UserとContextを追加
3-1.Userと証明書の情報を追加
*{UserName}にユーザ名を入れてください
1 | kubectl config set-credentials {UserName} --client-key={UserName}.key --client-certificate={UserName}.crt --embed-certs=true |
例:
1 2 | [example-test@bastion01 ~]$ kubectl config set-credentials example-test --client-key=example-test.key --client-certificate=example-test.crt --embed-certs=true User "example-test" |
*下記のように自動で.kube/configに設定が追加されます
1 | cat ~/.kube/config |
1 2 3 4 | - name: example-test user: client-certificate-data: xxxxxxxxxxxxxxxxxxxxx client-key-data: xxxxxxxxxxxxxxxxxxxxxx |
3-2.クラスター名を控える
1 | cat ~/.kube/config |
例:
*nameがクラスター名になります
1 2 3 4 5 6 | apiVersion: v1 clusters: - cluster: certificate-authority-data: xxxxxxxxxxxxxxxxxxxxxxx server: https://xxxxxxxxxxxxxxxxxxxxxxx name: xxxxxxxxxxxxxxx |
3-3.contextに追加
*{UserName}にはユーザー名を入れてください
*{ClusterName}は先ほど控えた値を入れてください
1 | kubectl config set-context {UserName} --cluster={ClusterName} --user={UserName} |
例:
1 2 | [example-test@example-testbastion01 ~]$ kubectl config set-context example-test --cluster=xxxxxxxxxxxx --user=example-test Context "example-test" created. |
*下記のように自動で.kube/configに設定が追加されます
1 2 3 4 5 6 7 8 9 | contexts: - context: cluster: xxxxxxxxxxx user: xxxxxxxxxxxxxx name: xxxxxxxxxxxxxxx - context: cluster: xxxxxxxxxxxxxx user: example-test name: example-test |
4.権限を付与
新しいクラスターロールを作成して任意の権限を与える場合
1.ClusterRoleを作成
*{ClusterRoleName}には クラスターロール名を入れてください
*{VerbName} ・{ResourceName}には、以下表を参考に設定してください
1 | kubectl create clusterrole {ClusterRoleName} --verb={VerbName} --resource={ResourceName} |
*主なresource名・verb名一覧
resource名 | namespace | nodes | pods | services | ingress | sercrets | configmaps |
verb名 | 備考 |
get | リソースを取得 |
list | リソースの一覧取得 |
create | リソースを作成 |
update | リソースを更新 |
patch | リソースを部分的に更新 |
delete | リソースを削除 |
deletecollection | リソースを一括削除 |
watch | リソースの変更を監視 |
例:Podに対してのReadOnly権限
1 2 | [example-test@bastion01 ~]$ kubectl create clusterrole pod-readonly --verb=get,list,watch --resource=pods clusterrole.rbac.authorization.k8s.io/pod-readonly created |
2.作成したクラスターロールを確認
*{ClusterRoleName}には クラスターロール名を入れてください
1 | kubectl describe clusterrole {ClusterRoleName} |
例:
1 2 3 4 5 6 7 8 | [example-test@bastion01 ~]$ kubectl describe clusterrole pod-readonly Name: pod-readonly Labels: <none> Annotations: <none> PolicyRule: Resources Non-Resource URLs Resource Names Verbs --------- ----------------- -------------- ----- pods [] [] [get list watch] |
3.作成したクラスターロールの権限をユーザーに付与
*{ClusterRoleName}には クラスターロールバインディング名を入れてください
*{UserName}にはユーザー名を入れてください
1 | kubectl create clusterrolebinding {ClusterRoleBindingName} --clusterrole={ClusterRoleName} --user={UserName} |
例:
1 2 | [example-test@bastion01 ~]$ kubectl create clusterrolebinding pod-readonly-binding --clusterrole=pod-readonly --user=example-test clusterrolebinding.rbac.authorization.k8s.io/pod-readonly-binding created |
4.権限を付与を確認
*Subjectsにuserで指定したユーザー名があれば問題なし
1 | kubectl describe clusterrolebinding {ClusterRoleBindingName} |
例:
1 2 3 4 5 6 7 8 9 10 11 | [example-test@bastion01 ~]$ kubectl describe clusterrolebinding pod-readonly-binding Name: pod-readonly-binding Labels: <none> Annotations: <none> Role: Kind: ClusterRole Name: pod-readonly-binding Subjects: Kind Name Namespace ---- ---- --------- User example-test |
事前定義済みのクラスターロールを与える場合
1.事前定義済みのクラスターロールの権限をユーザーに付与
*{ClusterRoleName}には クラスターロールバインディング名を入れてください
*{ClusterRoleName}には クラスターロール名を入れてください
*{UserName}にはユーザー名を入れてください
1 | kubectl create clusterrolebinding {ClusterRoleBindingName} --clusterrole={ClusterRoleName} --user={UserName} |
例:
1 2 | [example-test@bastion01 ~]$ kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin --user=example-test clusterrolebinding.rbac.authorization.k8s.io/cluster-admin-binding created |
*事前定義済みのクラスターロール一覧
デフォルトのClusterRole | デフォルトのClusterRoleBinding | 説明 |
cluster-admin | system:masters group | スーパーユーザーが任意のリソースで任意のアクションを実行できるようにします。 ClusterRoleBindingで使用すると、クラスター内およびすべてのNamespace内のすべてのリソースを完全に制御できます。 RoleBindingで使用すると、Namespace自体を含む、RoleBindingのNamespace内のすべてのリソースを完全に制御できます。 |
admin | None | RoleBindingを使用してNamespace内で付与することを想定した、管理者アクセスを許可します。 RoleBindingで使用した場合、Namespace内にRoleとRoleBindingを作成する機能を含め、Namespaceのほとんどのリソースへの読み取り/書き込みアクセスを許可します。 このRoleは、リソースクォータまたはNamespace自体への書き込みアクセスを許可しません。 |
edit | None | Namespace内のほとんどのオブジェクトへの読み取り/書き込みアクセスを許可します。このRoleは、RoleまたはRoleBindingの表示または変更を許可しません。ただし、このRoleでは、Secretsにアクセスして、Namespace内の任意のServiceAccountとしてPodsを実行できるため、Namespace内の任意のServiceAccountのAPIアクセスレベルを取得するために使用できます。 |
view | None | Namespace内のほとんどのオブジェクトを表示するための読み取り専用アクセスを許可します。 RoleまたはRoleBindingは表示できません。Secretsの内容を読み取るとNamespaceのServiceAccountのクレデンシャルにアクセスできるため、このRoleではSecretsの表示は許可されません。これにより、Namespace内の任意のServiceAccountとしてAPIアクセスが許可されます(特権昇格の形式)。 |
2.権限を付与を確認
*Subjectsにuserで指定したユーザー名があれば問題なし
1 | kubectl describe clusterrolebinding {ClusterRoleBindingName} |
例:
1 2 3 4 5 6 7 8 9 10 11 | [example-test@bastion01 ~]$ kubectl describe clusterrolebinding cluster-admin-binding Name: cluster-admin-binding Labels: <none> Annotations: <none> Role: Kind: ClusterRole Name: cluster-admin Subjects: Kind Name Namespace ---- ---- --------- User example-test |
5.動作確認
5-1.contextの変更
*{UserName}にはユーザー名を入れてください
*ここで使用するユーザーが切り替ります
1 | kubectl config use-context {UserName} |
例:
1 2 | [example-test@bastion01 ~]$ kubectl config use-context example-test Switched to context "example-test". |
5-2.context(使用中のユーザー)の確認
1 | kubectl config current-context |
例:
1 2 | [example-test@bastion01 ~]$ kubectl config current-context example-test |
5-3.kubectlでコマンドを実行
*Podに対してのReadOnly権限を与えている場合は以下のようになります
1 2 3 | [example-test@bastion01 ~]$ kubectl get po NAME READY STATUS RESTARTS AGE xxxx-f5p2t 1/1 Ready 0 261d |
1 2 | [example-test@bastion01 ~]$ kubectl get node Error from server (Forbidden): nodes is forbidden: User "example-test" cannot list resource "nodes" in API group "" at the cluster scope |
まとめ
いかかがでしたでしょうか?
Kubernetesでクラスターへの接続ユーザーを作成すれば、自由にユーザー権限を管理できます。
cluster-admin権限のユーザーを使い回すと運用中に思わぬ事故に繋がる可能性もあり、
複数人で運用する場合は、特にユーザーはできるだけLinuxユーザーのように作成することをおすすめします!
Kubernetesを運用する際は、ぜひ参考にしてくださいね!