KyvernoをEKSで超簡単に動かしてみた

kyvernoというポリシーエンジンを試してみます。kyvernoはpodなどのリソースをデプロイするときに作成したポリシーに沿っているかを確認してくれるというものです。例えば外部からのコンテナイメージを使ってのデプロイを禁止するとか、特権を使うpodはデプロイできないとかそのようなルール付けを行い、セキュリティを確保するものです。

以下簡単に試してみましたのでどうぞ。

前提

  • AWSアカウントをお持ちであること
  • AWS CLIがインストールされ、aws configure済みであること もしくはcloudshellでも可能です。(記事ではcloudshellでやってみます)
  • kubectlコマンドラインツールがインストールされていること
  • (任意)eksctlがインストールされていること(クラスターを作成するだけなのでGUIやTerraformで作成するだけでもOKです。)

記事中のコマンドはLinuxを想定しています。

EKSクラスターの作成

既にEKSクラスターがある場合は、このステップをスキップしてください。ここでは、eksctlを使って最小限の構成でクラスターを作成する例を示します。

# 1. EKSクラスターの作成(例:ap-southeast-2リージョン)
eksctl create cluster \
--name my-eks-cluster \
--version 1.30 \
--region ap-southeast-2 \
--nodegroup-name my-eks-nodes \
--node-type t3.medium \
--nodes 2 \
--nodes-min 2 \
--nodes-max 3

# 作成完了後、コンテキストを確認
kubectl config get-contexts

kubectl config get-contextsで、my-eks-clusterと表示されるコンテキストがアクティブであればOKです。これでEKSクラスターに対してコマンドを発行できるようになりました。

Kyvernoの導入

Kyvernoは、以下のいずれかの方法で導入できます。

  1. Helm を使用
  2. YAMLマニフェスト を使用 (kubectl apply -f https://...)

本記事ではHelmを使用する方法を紹介します。

Helmのインストール(未導入の場合)

Helmがまだインストールされていない場合は、以下の手順でインストールしてください。

curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.sh

# バージョン確認
helm version

Kyvernoのインストール

Kyvernoの公式Helmリポジトリを追加してインストールします。

# 1. リポジトリを追加
helm repo add kyverno https://kyverno.github.io/kyverno/

# 2. リポジトリ情報を更新
helm repo update

# 3. Kyvernoをインストール
helm install kyverno kyverno/kyverno -n kyverno --create-namespace

成功すれば、kyvernoというDeploymentなどのリソースがkyverno名前空間に作成されます。下記のようにリソースが作成されていればインストール完了です。

# インストール確認
kubectl get pods -n kyverno

kyvernoと名前がついたPodがRunningになっていればOKです。

Kyvernoポリシーの基本

Kyvernoでは、以下の3つの機能を主に扱います。

  1. Validate(バリデーション)
    • Kubernetesリソースの設定を検証し、ルールに合っているかチェックします。
  2. Mutate(リソースの変更)
    • リソースが作成・更新されるタイミングで、自動的に設定を変更します。
  3. Generate(リソースの生成)
    • リソースが作成された際、自動的に関連する別のリソースを生成します。

ポリシーはすべてClusterPolicyまたは Policy(Kyvernoが提供するCRD)として定義します。クラスタ全体に適用したい場合はClusterPolicy、名前空間単位で適用したい場合はPolicyを使います。

簡単なポリシー例(Validate機能)

「ラベル必須」ポリシー

例えば、「Deploymentを作成する際に、必ず app.kubernetes.io/name というラベルがついていること」を強制したい場合、以下のようなポリシーが書けます。ClusterPolicyを使った例です。

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-app-label
spec:
validationFailureAction: enforce
background: true
rules:
- name: check-app-label
match:
resources:
kinds:
- Deployment
validate:
message: "A label 'app.kubernetes.io/name' is required."
pattern:
metadata:
labels:
app.kubernetes.io/name: "?*"
  • validationFailureActionenforceにすると、ルールを満たさないリソースの作成・更新を拒否します。
  • background: trueにより、既存リソースにも適用されます。
  • patternmetadata.labels.app.kubernetes.io/name に任意の文字列(?*)が入っていることを要求しています。

このファイルを require-app-label.yaml などの名前で保存し、以下のようにデプロイします。cloudshellの場合は少しコピペで書式が崩れそうな感じがあったのでyamlをローカルで保存してアップロードしました。

そのあとこのyamlをapplyするとkyvernoポリシーが作成されます。

kubectl apply -f require-app-label.yaml

ポリシーのテスト

作成したポリシーの動作を試すため、あえてラベルのないDeploymentを作成してみます。

#app-test.yamlとして保存
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
# ここに app.kubernetes.io/name: "myapp" がない
spec:
selector:
matchLabels:
run: myapp
replicas: 1
template:
metadata:
labels:
run: myapp
spec:
containers:
- name: nginx
image: nginx:1.19

#以上を保存して以下で実行
kubectl apply -f app-test.yaml

上記のDeploymentを適用しようとすると、Kyvernoがラベルをチェックし、以下のようなエラーが発生してリソースの作成が拒否されます(Forbidden)。

Error from server: error when creating "...": admission webhook "validate.kyverno.svc" denied the request:
A label 'app.kubernetes.io/name' is required.

次に、正しいラベルを付けて再度作成してみます。

apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
labels:
app.kubernetes.io/name: "myapp"
spec:
selector:
matchLabels:
run: myapp
replicas: 1
template:
metadata:
labels:
run: myapp
spec:
containers:
- name: nginx
image: nginx:1.19

今度はポリシー違反がなく、Deploymentが正常に作成されます。これでValidate機能の動作確認が完了です。

Amazon EKS での Kyverno によるワンツースリーのように簡単なポリシー管理 | Amazon Web Services
本記事は、Easy as one-two-three policy management with Kyver

AWS公式でも導入記事があり、こちらには特権使用のコンテナを拒否するというポリシーの例があるので参考になると思います。

簡単なポリシー例(Mutate機能)

次に、KyvernoのMutate機能を使って、ポッド作成時に自動でラベルを付与する例を紹介します。

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: add-default-label
spec:
rules:
- name: mutate-add-label
match:
resources:
kinds:
- Pod
mutate:
patchStrategicMerge:
metadata:
labels:
owner: "team-xyz"

このポリシーを適用すると、新たにPodが作成されるタイミングで、自動的に labels.owner=team-xyz が付与されます。
(デフォルトではvalidationFailureActionaudit扱いとなり、「違反を検知してログに記録はするが拒否はしない」動作になりますが、Mutateルールそのものは実行されます。)

  1. add-default-label.yamlとして上記のYAMLを保存
  2. kubectl apply -f add-default-label.yaml

ポリシーを適用後、試しにラベルを何も付けないPodを作ってみます。

apiVersion: v1
kind: Pod
metadata:
name: sample-pod
spec:
containers:
- name: nginx
image: nginx:1.19

Pod作成後にkubectl get pod sample-pod -o yamlでmetadataを確認すると、labels.owner=team-xyzが自動的に付与されています。

簡単なポリシー例(Generate機能)

Generate機能では、あるリソースを作成・更新した際に、自動で別のリソースを生成(または更新)できます。たとえば、以下のようにネームスペースが作成されたら、そのネームスペースに必ず default-network-policy というNetworkPolicyを自動生成する、といったことが可能です。

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: generate-default-networkpolicy
spec:
rules:
- name: gen-default-np
match:
resources:
kinds:
- Namespace
generate:
kind: NetworkPolicy
name: default-network-policy
namespace: "{{request.object.metadata.name}}"
data:
spec:
podSelector: {}
policyTypes:
- Ingress
- Egress

上記を適用すると、新しくNamespaceを作成するたびに、そのNamespace内にdefault-network-policyというNetworkPolicyが自動生成されます。

ポリシーの管理・確認

Kyvernoでは、適用済みのポリシーを以下のように確認できます。

# クラスタ全体に適用されているポリシー(ClusterPolicy)の一覧
kubectl get clusterpolicies

# 名前空間単位(Policy)の一覧(例:default名前空間)
kubectl get policies -n default

また、Kyverno本体のログを確認するには、kyverno名前空間のPodログを参照します。

# admission-controllerのログの例
kubectl logs -n kyverno -l app.kubernetes.io/component=admission-controller -f --tail=50

ポリシーが正常に動いていない場合や、思わぬエラーが出ている場合は、kyvernoログをチェックしてみてください。

まとめと次のステップ

本記事では、EKS上でKyvernoを導入し、簡単なポリシーを作成・適用する方法を紹介しました。Kyvernoを活用することで、セキュリティ対策や標準化をKubernetesの仕組みに統合しやすくなり、継続的かつ効率的にポリシーを管理できます。

次のステップ

  1. より高度なValidateポリシーの作成
    • イメージレジストリの制限
    • PodSecurityContextの強制設定
    • さまざまな条件(when 句など)を組み合わせた複雑なルール
  2. CICDパイプラインとの連携
    • KyvernoのCLI(kyverno-cli)を使って、ローカルやCI環境でポリシーをテスト
  3. 監査(Audit)モードでの運用
    • validationFailureAction: auditでまずはモニタリングしてからenforceに切り替える
  4. ポリシーのバージョン管理・GitOps
    • ArgoCDやFluxなどを使い、Gitリポジトリでポリシーを管理し自動適用

Kubernetesやコンテナの運用で実装すべきさまざまなルールがあると思いますが、Kyvernoで標準的なポリシーの枠組みを作り、チーム全体で共通ルールを持つことで、オペレーションをより安全かつスムーズにしてみてください。

というわけでした。kyvernoなどのポリシーエンジンは大規模なクラスター運用で効果を発揮しやすそうですね。また勉強したいと思います。

タイトルとURLをコピーしました