DUICUO

KubernetesポリシーエンジンであるKyvernoが使用される

KyvernoはNirmataが開発したオープンソースプロジェクトで、後にCNCFに寄贈されました。Kyvernoは、検証と変更機能を備えたKubernetesポリシーエンジンですが、リソース生成機能とAPIオブジェクトクエリ機能も備えています。元々Kubernetes向けに開発されたKyvernoは、オブジェクト生成を除き、専用言語を必要とせずにポリシーを記述できます。

同様に、Kyverno は Kubernetes クラスター内で動的アドミッションコントローラーとして動作します。Kyverno は、kube-apiserver から認証およびアドミッション変更の Webhook HTTP コールバックを受信し、一致するポリシーを適用し、アドミッションポリシーを適用するかリクエストを拒否するかの結果を返します。Kyverno のポリシーは、リソースの種類、名前、タグセレクターを使用してリソースをマッチングでき、名前にはワイルドカードがサポートされています。

ポリシーの適用はKubernetesイベントを介してキャプチャされ、Kyvernoは既存のリソースのポリシー違反も報告します。次の図は、Kyvernoの全体的なアーキテクチャを示しています。

キヴェルノ建築

高可用性のKyvernoインストールは、複数のレプリカを実行することで実現できます。各レプリカには、異なる機能を実行する複数のコントローラーが配置されます。WebhookはKubernetes APIServerからのAdmissionReviewリクエストを処理し、そのMonitorコンポーネントは必要な設定を作成および管理します。PolicyControllerはポリシーリソースを監視し、設定されたスキャン間隔に基づいてバックグラウンドスキャンを開始します。GenerateControllerは生成されたリソースのライフサイクルを管理します。

インストール

まず、Kubernetes クラスターのバージョンが v1.14 以降であることを確認する必要があります。インストールする必要があるバージョンも Kubernetes のバージョンによって異なります。

互換バージョン

すでにバージョン v1.26.x を使用しているため、最新バージョン 1.9.2 をインストールすることを選択できます。

次のコマンドを実行すると、最新バージョンのリソース リストから Kyverno を直接インストールすることを選択できます。

  kubectl create -f https://github.com/kyverno/kyverno/releases/download/v1.9.2/install.yaml

あるいは、Helm を使用してワンクリック インストールを行うこともできます。

  Helmリポジトリkyvernoを追加https://kyverno.github.io/kyverno/
helmリポジトリの更新
# Kyverno Helmチャート「kube-kyverno」という新しい名前空間インストールします
Helmアップグレード-- kyvernoをインストールしますkyverno / kyverno - n kube - kyverno -- create - namespace
リリース「kyverno」存在ません今すぐインストールします
名前kyverno
最終展開: 2023年4月11日(火) 15:51:30
名前空間: kube - kyverno
ステータス:展開済み
改訂1
注記:
チャートバージョン: 2.7.2
Kyvernoバージョン: v1.9.2

kyvernoをインストールしていただきありがとうございますリリースkyvernoです
⚠️警告:レプリカ数を3未満に設定すると、 Kyverno は可用性モード実行されませ

💡注意名前空間の除外に関して、どちらアプローチを取る決める際にはトレードオフありますリスクを理解するには、 https ://kyverno.io/docs/installation/#security-vs-operabilityドキュメントご覧ください

インストール後、kube-kyverno 名前空間が作成され、関連する CRD もいくつか含まれます。

  kubectlポッドを取得- n kube - kyverno
名前準備完了ステータス再起動年齢
kyverno - 8657 b8cfcf - mgtsr 1 / 1ランニング0 2 m25s
kyverno -クリーンアップ-コントローラー- 5 c964d77dc - 5 s5zp 1 / 1実行中0 2分25秒
kubectl で検証Webhook構成を取得します
名前ウェブフック年齢
kyverno -クリーンアップ-検証- webhook - cfg 1 44 m
kyverno -例外-検証- webhook - cfg 1 16 m
kyverno -ポリシー-検証- webhook - cfg 1 16 m
kyverno -リソース-検証- webhook - cfg 0 16 m
kubectl でmutatingwebhookconfigurationsを取得します
名前ウェブフック年齢
kyverno -ポリシー-変更- webhook - cfg 1 17 m
kyverno -リソース-変更- webhook - cfg 0 17 m
kyverno -検証-変化- webhook - cfg 1 17 m
kubectl でcrdを取得| grepカイバーノ
admissionreports.kyverno.io2023-04-11T07 : 51 : 33Z
背景スキャンレポートカイバーノイオ2023-04-11 T07 : 51 : 33Z
クリーンアップポリシーカイバーノイオ2023-04-11 T07 : 51 : 33Z
clusteradmissionreports . kyverno . io 2023-04-11 T07 : 51 : 33Z
クラスター背景スキャンレポート.kyverno.io 2023-04-11 T07 : 51 : 33Z
クラスタークリーンアップポリシー. kyverno . io 2023-04-11 T07 : 51 : 33Z
クラスターポリシーカイバーノイオ2023-04-11 T07 : 51 : 34Z
リクエストを生成しますカイバーノイオ2023-04-11 T07 : 51 : 33Z
ポリシーカイバーノイオ2023-04-11 T07 : 51 : 34Z
ポリシー例外カイバーノイオ2023-04-11 T07 : 51 : 33Z
更新リクエストカイバーノイオ2023-04-11 T07 : 51 : 33Z

ご覧のとおり、インストール後にいくつかの validatingwebhookconfiguration オブジェクトと mutatingwebhookconfigurations オブジェクトが作成されました。

戦略とルール

Kyverno の使用は、基本的にポリシーとルールの適用です。Kyverno ポリシーはルールの集合です。各ルールは、match ステートメント、オプションの exclude ステートメント、および validate、mutate、generate、または verifyImages ステートメントのいずれかで構成されます。各ルールには、validate、mutate、generate、または verifyImages サブステートメントを 1 つだけ含めることができます。

キベルノ戦略

ポリシーは、クラスター全体のリソース (ClusterPolicy) または名前空間レベルのリソース (Policy) として定義できます。

  • ポリシーは、定義されている名前空間内のリソースにのみ適用されます。
  • ClusterPolicy は、すべての名前空間にわたるリソースを一致させるために適用されます。

戦略の定義

ポリシーを記述することは、基本的に Policy または ClusterPolicy オブジェクトを定義することです。

リソースを確認する

検証ルールは、私たちが使用する最も一般的で実用的なルールタイプです。ユーザーまたはプロセスが新しいリソースを作成すると、Kyvernoは検証ルールに従ってリソースの属性をチェックします。検証に合格した場合、リソースの作成は許可されます。検証に失敗した場合、作成はブロックされます。例えば、すべてのポッドにkyvernoタグを含めることを要求するポリシーを追加してみましょう。

 # kyverno - require - label .yaml
apiバージョン: kyverno.io/v1
種類: ClusterPolicy
メタデータ
名前:要求-ラベル-ポリシー
仕様:
検証失敗アクション:強制
ルール
-名前:ラベルチェック
マッチ
リソース
種類:
-ポッド
検証:
メッセージ: 「ラベル 'kyverno' が必要です」
パターン
メタデータ
ラベル:
kyverno : "?*"

上記のポリシー ファイルには、`validatinotallow=[Audit, Enforce]` 属性が含まれています。

  • 監査モードでは、ルールセットの 1 つ以上のルールに違反するリソースが作成されるたびに、承認レビュー要求が許可され、結果がレポートに追加されます。
  • 強制モードの場合、リソースは作成後すぐにブロックされ、報告されません。

次は、`rules` 属性を使用して定義される一連のルールです。`match` は照合するリソースを指定するために使用され、`validate` は検証方法を指定します。ここでは、`kyverno: "?*"` のようなタグを定義して、そのようなタグキーが必須であることを示します。

上記の戦略オブジェクトを適用するだけです。

  kubectl apply -f kyverno -require -label .yaml
clusterpolicy.kyverno.io/require-label-policy作成まし
kubectl でクラスターポリシーを取得する
名前経歴検証アクション準備年齢
要求-ラベル-ポリシーtrue true強制4 m23s

次に、「kyverno」タグなしで Pod を追加してみましょう。

  kubectl run busybox -- image = busybox : 1.28 .3 -- restart = Never -- sleep 1000000
サーバーからのエラー:アドミッションWebhook 「validate.kyverno.svc-fail」リクエスト拒否しました:

リソース違反ポリシーPod / default / busybox :

要求-ラベル-ポリシー:
ラベルのチェック: '検証エラー: ラベル ' 'kyverno' ' が必要です。ルールラベルのチェック
パス/メタデータ/ラベル/ kyverno / '失敗しました

ご覧の通り、kyvernoタグが必要です。同様に、イベントセクションでポリシーがどのように適用されているかを確認できます。

  kubectlイベントを取得- A - w
……
for - labels が失敗しました:検証エラー:ラベル'kyverno'必要ですルールautogen - check - for - labels がパス/ spec / template / metadata / labels / kyverno /失敗しました
qdrant -システム51 s警告ポリシー違反pod / qdrant - 0ポリシーrequire - label - policy / check - for - labelsが失敗しました:検証エラー:ラベル'kyverno'必要ですルールcheck - for - labels がパス/ metadata / labels / kyverno /失敗しました
qdrant -システム50警告PolicyViolation statefulset / qdrantポリシーrequire - label - policy / autogen - check - for - labelsが失敗しました:検証エラー:ラベル'kyverno' が必要ですルールautogen - check - for - labels がパス/ spec / template / metadata / labels / kyverno /失敗しました

作成する Pod に kyverno タグが付いている場合は、通常どおり作成できます。

  kubectl run busybox -- image = busybox : 1.28 .3 -- labels kyverno = demo -- restart = Never -- sleep 1000000
ポッド/ビジーボックスが作成されました

validationFailureAction の値を Audit に変更すると、kyverno タグが付いていない場合でも、作成する Pod は正常に作成されます。ただし、対応する違反レポートは PolicyReport オブジェクトで確認できます。

  kubectlポリシーレポートを取得する
名前合格不合格警告エラースキップ年齢
cpol -要求-ラベル-ポリシー0 1 0 0 0 4分42秒
kubectl describe policyreports | grep "結果: \+fail" - B10
UID : def28081 - aa68-4e96 - bb43 - fdc73274df00
結果
メッセージ:検証エラー:ラベル'kyverno'必要ですパス/ metadata / labels / kyverno /ラベルルールチェック失敗しました
ポリシー:必須-ラベル-ポリシー
リソース
APIバージョン: v1
種類:ポッド
名前:ビジーボックス
名前空間:デフォルト
UID : 9667e83d - 62a3-4844 - b5d7 - da127e9cee2c
結果不合格

ポリシーに違反したリソース オブジェクトは、上記のレポート リソースから確認できます。

ルールを変える

ルールを変更すると、ルールに一致するリソースを変更できます (たとえば、ルールによってリソースのメタデータと結合できるメタデータ フィールドが設定されている場合)。つまり、設定したルールに従って対応するリソースが変更されます。

たとえば、nginx イメージを含むすべてのポッドにタグ (kyverno=nginx) を追加する、次のようなポリシーを追加します。

 # kyverno -変異-ラベル.yaml
apiバージョン: kyverno.io/v1
種類: ClusterPolicy
メタデータ
名前: nginx -ラベル-ポリシー
仕様:
ルール
-名前: nginx -ラベル
マッチ
リソース
種類:
-ポッド
変異する
パッチ戦略的マージ:
メタデータ
ラベル:
kyverno : nginx
仕様:
コンテナ):
- ( image ): "*nginx*" #コンテナイメージにnginxが含まれている必要があります

上記の戦略オブジェクトを適用するだけです。

  kubectl apply -f kyverno -mutate -label .yaml
clusterpolicy.kyverno.io/nginx-ラベル-ポリシー作成まし
kubectl でクラスターポリシーを取得する
名前経歴検証アクション準備年齢
nginx -ラベル-ポリシーtrue監査true 6

ここで、nginx イメージを使用して Pod を直接作成します。

  kubectl run --image = nginx : 1.7 .9 nginx
pod / nginxを作成しました
kubectl get pod nginx -- show -ラベル
名前準備完了ステータスが年齢ラベルを再開
nginx 1/1実行0 11kyverno = nginx run = nginx

ご覧の通り、Podは正常に作成され、kyverno=nginxタグが含まれています。kyvernoタグのおかげで上記の検証戦略は成功し、Podを正常に作成できます。

リソースを生成する

生成ルールは、名前空間の新しい RoleBinding や Secret の作成など、新しいリソースを作成したりソースを更新したりするときに追加のリソースを作成するために使用できます。

例えば、特定のシークレット(TLSキーやミラーリポジトリの認証情報など)を他の名前空間に同期する必要がある場合、これらのシークレットを手動でコピーするのは面倒です。Kyvernoを使用すれば、これらのシークレットを同期するための戦略を作成できます。例えば、デフォルトの名前空間にregcredというシークレットオブジェクトがあり、これを別の名前空間にコピーする必要がある場合、元のシークレットが変更されると、コピーされたシークレットも更新されます。

 # kyverno -生成-シークレット.yaml
apiバージョン: kyverno.io/v1
種類: ClusterPolicy
メタデータ
名前:同期-シークレット-ポリシー
仕様:
ルール
-名前:同期-イメージ-プル-シークレット
マッチ
リソース
種類:
-名前空間
generate : #生成されたリソースオブジェクト
種類:秘密
名前: regcred
namespace : "{{request.object.metadata.name}}" #対象の名前空間を取得する
同期: true
クローン:
名前空間:デフォルト
名前: regcred

まず、デフォルトの名前空間に Secret オブジェクトを準備します。

  kubectl create secret docker - registry regcred -- docker - server = DOCKER_REGISTRY_SERVER -- docker - username = DOCKER_USER -- docker - password = DOCKER_PASSWORD -- docker - email = DOCKER_EMAIL
secret / regcredが作成されました

次に、上記の同期された秘密戦略を適用します。

  kubectl apply -f kyverno -generate -secret .yaml
clusterpolicy.kyverno.io/sync - secrets -ポリシー作成れまし
kubectl でクラスターポリシーを取得する
名前背景アクション準備完了
同期-シークレット-ポリシーtrue監査true 9

次に、新しい名前空間を作成しましょう。

  kubectl nsテストを作成
名前空間/テストを作成しました
kubectlシークレットを取得- nテスト
名前タイプデータ年齢
kubernetes .io / dockerconfigjson 1 6を登録しました

新しく作成された名前空間に、regcred という名前の新しい Secret オブジェクトが作成されたことがわかります。

Kyvernoのポリシーは公式サイト(https://kyverno.io/policies)でご覧いただけます。ポリシーは種類、カテゴリ、テーマなどで絞り込むことができます。Kyvernoは柔軟性、パワー、使いやすさのバランスが取れています。多くの学習時間を必要とせず、便利な機能を提供します。公式サイトには様々なシナリオに対応した豊富な例が掲載されているため、ぜひ活用してみてください。

たとえば、NGINX Ingress のパス値を制限するには、次のようなポリシーを作成できます (CVE-2021-25745 セキュリティ問題、NGINX Ingress v1.2.0 で修正済み)。

 apiバージョン: kyverno.io/v1
種類: ClusterPolicy
メタデータ
名前:制限-入力-パス
注釈:
ポリシー.kyverno.io / title : NGINX Ingressパス制限する
ポリシー.kyverno.io /カテゴリ:セキュリティNGINX Ingress
ポリシー.kyverno.io /重大度:
ポリシー.kyverno.io /件名: Ingress
ポリシーカイバーノio / minversion : "1.6.0"
kyverno.io/kyverno-version : " 1.6.0 "
kyverno .io / kubernetes -バージョン「1.23」
ポリシーカイバーノio /説明: >-
このポリシーは ` spec.rules []. http.paths []. path`安全な制限することでCVE - 2021-25745軽減します
必要応じてパスを追加できますこの問題NGINX Ingress v1.2.0修正さました
詳細についてはCVE参照してください
仕様:
検証失敗アクション:強制
ルール
-名前:チェック-パス
マッチ
どれでも
-リソース
種類:
-ネットワーキング. k8s . io / v1 / Ingress
検証:
メッセージ: "spec.rules[].http.paths[].path 値は許可されていません"
拒否
条件
どれでも
-キー: "{{ request.object.spec.rules[].http.paths[].path.contains(@,'/etc') }}"
演算子: AnyIn
: [ true ]
-キー: "{{ request.object.spec.rules[].http.paths[].path.contains(@,'/var/run/secrets') }}"
演算子: AnyIn
: [ true ]
-キー: "{{ request.object.spec.rules[].http.paths[].path.contains(@,'/root') }}"
演算子: AnyIn
: [ true ]
-キー: "{{ request.object.spec.rules[].http.paths[].path.contains(@,'/var/run/kubernetes/serviceaccount') }}"
演算子: AnyIn
: [ true ]
-キー: "{{ request.object.spec.rules[].http.paths[].path.contains(@,'/etc/kubernetes/admin.conf') }}"
演算子: AnyIn
: [ true ]