kubernetesのapiserverはauthentication(認証), authorization(認可)の機能が実装されており、これを利用することでユーザとリソースが管理出来るようになっています。
今回はService Account Tokens方式で認証を行い、ABAC方式で認可を行います。
authenticationについて
kubernetesではいくつかの認証方式が用意されています。
https://kubernetes.io/docs/admin/authentication/#authentication-strategies
それぞれざっと見た感じで説明すると。
X509 Client Certs
SSL証明書のcommon nameでユーザを定義する。SSLクライアント証明書の管理めんどそう。Static Token File / Static Password File
ユーザの認証情報が書かれたファイルを用意する方式。ファイルの再読込はapiserverの再起動が必要。クラスタ構成にしているときのファイルの管理とか大変そう。Service Account Tokens
デフォルトで有効になっている認証方式。kubernetesで管理されるservice accountのNameとTokenを使って認証をする。今回はこれを取り扱う。OpenID Connect Tokens
OpenID providerに認証を委譲してTokenを使って認証する方法。OpenIDのproviderがそもそもないので使えない。Webhook Token Authentication
名前の通り。webhookで認証をする方法。Authenticating Proxy
Proxyした時に認証してproxy後のheaderに認証情報を付与する方法。Keystone Password
OpenStackの認証、ポリシー管理をする機能に連携させて認証する。
今回はデフォルトで有効になっているService Account Tokens方式を使って認証をしてみます。
authorizationについて
認可の方式もいくつかあります。
https://kubernetes.io/docs/admin/authorization/
認証方式はapiserverに--authorization-mode=
で指定します。カンマ区切りで複数指定でき、1つでもOKになれば認可されます。
AlwaysDeny / AlwaysAllow
名称のままです。常に拒否と常に許可します。ABAC
認可policyを書いたファイルを用意してファイルに従い認可を実行します。今回はこの方式を試してみます。RBAC
ABACと設定出来る内容は同じです。こちらはファイルを使わず、policyをkubectl create
するので状態はetcdの中で保持します。ABACを使うのであればRBACを使ったほうが良いです。Webhook
webhookでやり取りした値で認可を行います。どこにwebhookするのかを記述する設定ファイルを用意する必要があります。
apiserverの設定
前に書いたKubernetesのClusterをインストールするでKubernetesのClusterがインストールされている前提で記述します。
authenticationの設定
まず、--insecure-bind-address
を使っている場合は認証が行われないので--bind-address
の設定を追加して、対応するportの設定も追加します。
/etc/kubernetes/apiserver
に以下の設定を追加します。
# The address on the local server to listen to. |
--insecure
な設定は認証が行われないので注意が必要です。minionのkubeletなど認証が不要なものはinsecureに接続して、認証が必要なユーザからの接続はbind-addressで指定したhttps://0.0.0.0:6443
に接続させるように制御が必要です。ここでは特に設定しませんがFWで適切に設定する必要があります。
service accountにsecret(token)が付与されるように設定します。
https://kubernetes.io/docs/admin/authentication/#service-account-tokens
apiserverの--service-account-key-file
に設定する鍵を生成します。
$ mkdir /etc/kubernetes/ssl |
apiserverだけでなく、controller-managerに含まれるtoken-manegerが使う鍵の設定も必要なので合わせて設定します。controller-managerのtoken-managerがsecretsのTokenを割り当てているようです。
https://kubernetes.io/docs/admin/service-accounts-admin/
$ cat /etc/kubernetes/apiserver |
再起動して設定を適用します。
$ systemctl restart kube-apiserver.service |
適当なServiceAccountを作成してTokenを確認します。
$ kubectl create sa test |
正しく動作している場合はTOKENが表示されます。
また、この時点でToken無しでapiserverに接続すると認証情報を求められるようになります。apiserverが自動生成した自己署名証明書を使っているので--insecure-skip-tls-verify
の設定が必要です。設定しない場合は以下の様にエラーが表示されます。Unable to connect to the server: x509: certificate is valid for kubernetes.default.svc, kubernetes.default, kubernetes, not centos-master-1
$ kubectl get sa --server=https://centos-master-1:6443 \ |
testユーザのtokenを設定すると認証が行われて内容を表示することができます。
$ kubectl get sa --server=https://centos-master-1:6443 \ |
authorizationの設定
次にapiserverにABACの設定を追加します。
https://kubernetes.io/docs/admin/authorization/#abac-mode
$ cat /etc/kubernetes/apiserver |
Policyファイルを追加します。
$ cat /etc/kubernetes/abac-policy.jsonl |
“誰が”、”何を”といったPolicyを記述します。kubernetesのsaを指定する場合はsystem:serviceaccount:(namespace):(username)
という形式で設定する必要があります。上記の設定では、ishiisユーザはnamespace:ishiis-nsの全てを操作出来るようになります。
再起動して設定を適用させます。$ systemctl restart kube-apiserver.service
試しに上で書いたユーザを作成してリソースの表示が出来るか確認してみます。
$ kubectl create ns ishiis-ns |
作成したユーザのTokenを確認します。
$ kubectl describe secret ishiis --namespace=ishiis-ns |
上記のtokenを設定してservice accountを確認します。
$ kubectl get sa --server=https://centos-master-1:6443 \ |
namespaceを指定していないのでdefaultのservice accountを表示しようとしていますが拒否されていることが確認できます。
次にnamespace=ishiis-nsとして確認してみます。
$ kubectl get sa --server=https://centos-master-1:6443 \ |
ishiis-nsはpolicyで許可されているのでアクセス出来ることが確認できます。
最後に、毎回コマンドに設定するのは面倒なのでkubectl config
で割り当てられたtokenを使うように設定します。
$ kubectl config view |
いい感じですね。
おわり。