Documentation

/

White Papers

Kubernetesクラスターの安全な運用のためのアクセス制御

david

2024年11月22日

Kubernetesクラスターの安全な運用のためのアクセス制御

序文

Kubernetesクラスターの導入と利用が拡大する中で、クラスターのセキュリティと運用効率を確保するために、アクセス制御の重要性がますます高まっています。しかし、Kubernetesが標準で提供するRBAC(Role-Based Access Control)機能は強力なアクセス制御をサポートしているものの、その設定や管理が複雑であるため、実際に積極的に活用している組織は多くありません。

Introduction

共有されたAdmin権限は、全てのユーザーに無制限の権限を付与するため、誤操作によるリソースの削除や変更のリスクが大幅に増加します。これによりサービス障害が発生する可能性があり、問題が起きた際に誰がどの作業を行ったのかを追跡・監査するのが非常に困難になります。そのため、Kubernetesクラスターの安全で効率的な運用には、ユーザーごとに明確なアクセス制御ポリシーを策定することが不可欠です。

こうした課題に対処するために、多くの組織がKubernetesのRBAC(Role-Based Access Control)の導入を検討します。しかし、RBACには機能上の制約や管理の難しさがあり、積極的に活用している組織は多くありません。実際、Kubernetes RBACにはどのような難点があるのでしょうか?また、それを解決し、安全にKubernetesクラスターを運用するにはどうすれば良いのでしょうか?

これらの課題を解決するために開発された、Kubernetesアクセス制御製品の機能や開発で採用された技術について詳しくご紹介します。

問題定義

Kubernetesには、RBAC(Role-Based Access Control)というロールベースのアクセス制御機能が既に組み込まれています。このRBACを活用することで、クラスター内のリソースごとにアクセス権限を分けてロールを作成し、そのロールを必要なユーザーに付与する形で管理することが可能です。例えば、ユーザーごとにクラスター内のnamespaceを分割し、それぞれのユーザーが自分のnamespace内のリソースにのみアクセスできるように設定できます。

このためには、ユーザーごとの認証情報を含むkubeconfigを作成し、各ユーザーに配布します。以下の図を例にすると、Davidは "David"namespace内のリソースにのみアクセスでき、AndrewやSamもそれぞれのnamespace内のリソースにのみアクセス可能な仕組みです。このように、ユーザーごとにkubeconfigを管理することで、一定の権限管理とクラスター内リソースの衝突問題を解決することができます。

Challenges

しかし、Kubernetes RBACを適用すれば運用が楽になるのでしょうか?実際にKubernetes RBACを導入した方々の意見を聞いてみると、運用上の不便さを挙げる方が多いです。

Challenges

どのような課題があるのでしょうか?まず、kubeconfigの管理について考えてみましょう。クラスターでユーザーごとにRBACを適用する場合、クラスター管理者が行わなければならない作業は予想以上に多岐にわたります。まず、どのリソースに対してどのようなアクションを許可するのかを定義するRoleを作成する必要があります。その後、作成したRoleを各ユーザーにRoleBindingで割り当てます。さらに、ユーザーがそのRoleを使ってクラスターにアクセスできるように、X.509証明書やトークンを使用してユーザーごとのkubeconfigを生成しなければなりません。つまり、クラスター管理者はユーザーごと、さらにRoleごとに細かく管理を行う必要があり、この運用の煩雑さが大きな負担となっています。

Challenges

サービスの規模が拡大し、マルチクラスターを運用するケースが増えるとどうなるでしょうか?管理しなければならないクラスターが1つではなく複数になる場合、クラスター管理者の負担はさらに増加します。先ほど説明したように、Roleの作成、Roleのバインディング、ユーザーごとのkubeconfig管理を各クラスターごとに繰り返し実行しなければなりません。クラスターやユーザーの数が増えるにつれて、運用リソースの負担も比例して増大していくのです。

Challenges

Kubernetesの監査ログは、誰がいつどのリソースにアクセスしたかを記録します。しかし、このログを管理するには、クラスター管理者が各クラスターごとに監査設定を行う必要があるという負担があります。さらに、監査時に特定のユーザーの操作を調査する必要がある場合、各クラスターの監査ログを1つずつ検索する必要があります。そのため、監査ログの設定作業とログデータの管理に大きな課題があります。

Challenges

kubeconfigや監査ログの管理だけでなく、Kubernetes RBACにはいくつかの機能的な制約があります。その中の1つが、Kubernetes RBAC仕様で拒否ルール(Deny Rule)をサポートしていない点です。例えば、上記の図のように「nginx Podを除くすべてのリソースにアクセス権を与えたい」と仮定します。この場合、Kubernetes RBACのRole設定をどうすればよいでしょうか?

Challenges

KubernetesのRole仕様は許可ルールのみをサポートしているため、上記の図のように、Role仕様にnginxを除外したすべてのリソース名を1つずつ追加する必要があります。もし追加すべきリソースが3~4個程度であればまだしも、10個や20個に増えた場合はどうすれば良いでしょうか。また、リソースが頻繁に追加・削除される場合にはどう対応すれば良いでしょうか。そのたびにRole仕様を管理するのは、運用の負担を増大させることになるでしょう。

Challenges

2つ目の残念な点は、RBAC設定時にパターンマッチングをサポートしていない部分です。例えば、Pod名が”david”で始まる複数のPodがあると仮定します。この場合、”david”で始まるPodのみにアクセス権限を付与したい場合、どのように設定すれば良いでしょうか?

Challenges

残念ながら、現在のKubernetes Role仕様ではリソース名にパターンマッチングを指定することはできません。つまり、”david”で始まるPodをパターンで設定する方法が存在しないのです。そのため、ご覧の通り、david-1david-2david-3といったようにPod名を1つずつ全て手動で記載する必要があります。これもまた、クラスター管理者にとっては煩雑な作業となります。

さらに、Kubernetesのアクセス制御機能には、RBACとABACを同時に使用したい場合に設定が複雑になることや、Podリストの表示時にアクセス権のあるPodだけをフィルタリングしてユーザーに表示する機能が欠けているといった不足点もあります。

目標設定

これまでに説明したKubernetes標準のRBAC機能の不足を補い、クラスター管理者のアクセス制御に関する運用負担を軽減するため、新たなKubernetesアクセス制御製品を開発するという目標を立てました。そして、この新しいKubernetesアクセス制御製品を導入する際、ユーザーが抵抗を感じないよう、従来のKubernetesの使いやすさをそのまま維持するという目標も設定しました。

ソリューション概要

Kubernetes アクセス制御製品(以下、KAC)は、クライアントとKubernetes APIサーバーの間にKACプロキシサーバーを配置してアクセス制御を行う仕組みです。

Solution Overview

クライアントとKubernetes APIサーバーの間で、ユーザーリクエストが含まれるKubernetes APIリクエストを傍受して動作します。傍受したAPIリクエストを分析し、どのリソースにどのアクションを実行しようとしているのかを確認します。その後、そのユーザーが該当する権限を持っているかをチェックします。また、将来的な監査のために、誰が、いつ、どのリソースに対してどのアクションを実行したのかを記録する監査ログ機能を標準で提供しています。

その後、APIリクエストの種類に応じてさまざまな追加機能を提供します。例えば、Pod execのようにコンテナ内部に接続するリクエストの場合、ユーザーがコンテナ内で入力したコマンドや出力内容を記録し、後で再生できるようにしました。また、Podリストを取得する場合には、Kubernetes APIサーバーの応答をフィルタリングし、実際にユーザーが権限を持つPodのみを表示する機能も提供しています。さらに、これらの機能を提供する際にも、既存のKubernetesクライアントツールがそのまま使用できるように設計されています。このため、KAC Proxyサーバーは透過的(transparent)に設計され、ユーザーのクライアントツールからはKAC Proxyサーバーの存在を意識することなく利用できます。

技術的説明

KACのアクセス制御機能がどのように動作するのか、技術的な観点からステップごとに説明します。基本的に、クラスター内のリソースへのアクセスの許可とブロックは、KAC Proxyサーバーで処理されます。

Technical Description

クライアントがリクエストを送信すると、KACプロキシサーバーはそのリクエストに対する権限をチェックします。ポリシーチェックの結果、権限がある場合はユーザーのリクエストをKubernetes APIサーバーに転送しますが、権限がない場合は、クライアントに対してリクエスト権限がない旨のエラーメッセージを返します。