Kubernetes の認証とアクセス制御

今日は Kubernetes の認証とアクセス制御について、概念周りまとめていこうと思います。

バージョンは v1.10 の情報を基にしています。

Kubernetes の Api Server の認証とアクセス制御の挙動

Kubernetes では 実際のリソースへのアクセス時に以下のような手順で Api Server を経由してアクセスすることになります。

  1. CAを伴うTLS接続の認証(Certification)
  2. 認証モジュールによる認証(Authentication)
  3. 認可モジュールによる認可(Authorization)
  4. Admission Control による許可/拒否

f:id:naokirin:20180502205244p:plain

CAを伴うTLS接続時の認証

こちらは Api Server 自体へのTLS接続に対する認証です。

Api Server の CA は 一般的に /etc/kubernetes 以下にあります。 またクライアントの証明書は $HOME/.kube/config にあります。

認証モジュールによる認証

アカウントの認証方式は複数あり、それらを選択することができます。使用可能な各方式については以下のページに記載されています。これらの方式を必要に合わせて組み合わせることで Api Server への認証を設定できます。

https://kubernetes.io/docs/admin/authentication/#authentication-strategies

今回は特にユーザー認証とは別にデフォルトで有効になるサービスアカウント認証と、ユーザーアカウントでよく利用されるであろう X.509 による認証についてのみ書いておきます。

サービスアカウント認証

Kubernetes のサービスアカウントとは、Pod 内のプロセスによって使用されるアカウントです。そのため、名前空間に紐付いています。一方でユーザが使用するためのユーザーアカウントと言うものもあり、こちらは名前空間に限らずグローバルなものとして生成されます。

Kubernetes のサービスアカウント認証はデフォルトでは Base64 エンコードされたトークンによる認証です。サービスアカウントやデフォルトサービスアカウントによる名前空間生成時に Admission Control のプラグインにより自動的にトークンが生成され、Pod 内の secret がマウントされます。このサービスアカウントは Pod がクラスタとのやり取りをする際に使われます。

X.509 による認証

いわゆる OpenSSL による認証で利用するものです。

詳細な手順は省きますが、 openssl コマンドにより private key と .csr を生成し、クラスターのCAに配置します。これにより、OpenSSL を用いてリクエストを行うことができます。

-- 一般的な openssl による private key, .csr の生成と CA への配置
# openssl genrsa -out hoge.key 2048
# openssl req -new -key hoge.key -out hoge.csr -subj "/CN=hoge"
# openssl x509 -req -in hoge.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out hoge.crt -days 30

認可モジュールによる認可

Kubernetes では認可(Authorization)として以下をサポートしています。

  • ABAC(Attribute-based access control)
  • RBAC(Role-based access control)
  • Node 認証
  • Webhook

v1.6以前は ABAC がデフォルトだったようですが、現在では RBAC がデフォルトの認可モジュールとなっています。

ここでは現在主流である RBAC についてのみ詳細を書きます。その他については以下を参照してみてください。

https://kubernetes.io/docs/admin/authorization/

RBAC

RBAC では役割ベースのアクセス制御を行います。4つのリソースが存在し、Role、ClusterRole、RoleBinding、ClusterRoleBinding があります。

リソース 内容
Role/ClusterRole どのリソースにどのような操作を許可するかを定義するためのリソース
RoleBinding/ClusterRoleBinding どのRole/ClusterRole をどのユーザ/グループ/サービスアカウントに紐付けるかを定義するためのリソース

Role/RoleBinding は名前空間に属しており、一方 ClusterRole/ClusterRoleBinding は名前空間に属していません。

Role/ClusterRole は以下のように、APIバージョン、名前空間(Roleの場合)、ロール名と、アクセスできるAPIグループ、リソース、操作を設定します。

kind: Role
apiVersion: <apiVersion>
metadata:
  namespace: <namespace>
  name: <roleName>
rules:
- apiGroups: [<apiGroups>...]
  resources: [<resources>...]
  verbs: [<verbs>...]

また、RoleBinding/ClusterRoleBindingは以下のように設定します。 subjects にどのユーザ、グループ、サービスアカウントと紐付けるかを設定します。 roleRef でどのRole/ClusterRole を紐付けるかを設定します。

kind: RoleBinding
apiVersion: <apiVersion>
metadata:
  name: <bindingName>
  namespace: <namespace>
subjects:
- kind: (User|Group|ServiceAccount)
  name: <subjectName>
  apiGroup: <apiGroup>
roleRef:
  kind: Role
  name: <roleName>
  apiGroup: <apiGroup>

操作(verbs)

これらRole/ClusterRole で設定できる操作(verbs)のリストは以下となります。これらは一括で "*" で指定することができます。

verb HTTP 内容
get GET, HEAD 単一のリソースの取得
list GET リソースのリスト取得
create POST リソースの作成
update PUT リソースの置き換え
patch PATCH リソースの部分更新
delete DELETE 単一のリソースの削除
deletecollection DELETE リソースの一括削除
watch リソースの変更監視
proxy リソースへのproxy
redirect リソースへのRedirect

リソース

リソースに関してはかなりの量があり、列挙するのは現実的ではないため簡単な紹介にとどめます。

以下の API リファレンスの HTTP Requests の /*/**/{namespace}/ のあとに続く部分がリソース名となります( pods , deployments など)。またサブリソースも設定することができるため、細かくアクセス制御を行うこともできます( deployments/status など)。

https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.10/

API Groups

Kubernetes の APIAPI Groups というグループに分かれており、API リファレンスに書かれている Group の部分がそれに当たります。 core に属するものだけは "" で設定します。

https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.10/

Admission Control による許可/拒否

Admission Control では、Api Server 起動時のオプションとして、各プラグインを有効化することでリクエストを変化、または拒否することなどができます( --admission-control オプション)。

こちらも項目数が多いので以下のドキュメントを参考にしてみてください。

https://kubernetes.io/docs/admin/admission-controllers/