メインコンテンツへスキップ
このガイドでは、AgentEye の全スタックを専用の Kubernetes クラスターにデプロイします。
  • ClickHouse 24.8 — イベントおよびエバリュエーション分析の正規ストア(StatefulSet、100Gi 永続ボリューム)。必須:これがないとサーバーは起動しません。
  • PostgreSQL 16 — 組織、API キー、ユーザー、ダッシュボード、保存済みクエリ、認証のリレーショナル/メタデータストア(StatefulSet、50Gi 永続ボリューム)
  • Redis 7.2 — オプションの共有キャッシュおよびレート制限バックエンド。利用不可の場合もサーバーとダッシュボードはグレースフルに機能低下します
  • AgentEye Server — イベント取り込み、分析、キー管理用の Rust API(2 レプリカ)
  • AgentEye Dashboard — Next.js 製 Web UI(2 レプリカ)
  • AI アシスタント(エージェントサービス) — ポート 9100 で動作するダッシュボード内オプションの読み取り専用アシスタント。LLM エンドポイントが設定されるまで無効状態
  • Traefik(パブリック) — コレクタートラフィック用の Ingress コントローラー(mTLS 保護)
  • Traefik(ダッシュボード) — ダッシュボード用の Ingress コントローラー(VPN/IP 許可リストのみ)
  • cert-manager — TLS 証明書および mTLS CA
  • バックアップ CronJob — 毎日 UTC 03:00 に PostgreSQL と ClickHouse を同時にダンプ
  • 証明書更新モニター — クライアント証明書の有効期限が近づくとアラートを送信
推定所要時間: 初回デプロイで 60〜90 分。 Exosphere がこれらすべてをお客様に代わって管理するマネージドデプロイメントモデルについては、enterprise-docs/managed-deployment.md をご覧ください。

前提条件

開始前に各確認コマンドを実行してください。すべてのチェックがパスする必要があります。
要件最低バージョン確認コマンド期待される結果
Kubernetes クラスター1.27+kubectl versionServer Version >= v1.27
Kustomize(kubectl 同梱)Kustomize v1.14+(kubectl 1.27+ に内包)kubectl kustomize --help使用方法テキストが表示される
Helmv3helm versionVersion:"v3.x.x"
cluster-admin RBACkubectl auth can-i create namespacesyes
デフォルト StorageClasskubectl get storageclass(default) と表示された行が少なくとも 1 つある
LoadBalancer サポートクラウド依存(EKS、GKE、AKS はデフォルトで対応)
GitHub PATecho $AGENTEYE_TOKEN空でないこと(enterprise-docs/github-token.md 参照)
opensslopenssl versionOpenSSL 1.x または 3.x
クラウドストレージバケットPostgreSQL と ClickHouse のバックアップ用(S3、GCS、または Azure Blob)
クラスターサイジング: 最低 3 ノード、各ノード 4 vCPU / 8 GB RAM。全要件については enterprise-docs/managed-deployment.md を参照してください。

一括チェックの実行

デプロイメント構成

取り込みエンドポイントはお客様が管理するホスト名(例:ingest.your-company.example)で提供されます。cert-manager は HTTP-01 チャレンジにより Let’s Encrypt からパブリック信頼済み TLS 証明書を要求するため、コレクターはシステムトラストストアでサーバー証明書を検証します。カスタマーごとの CA ピン留めは不要です。 ダッシュボードエンドポイントも同様の仕組みです。お客様が管理する別のホスト名(例:agenteye.your-company.example)でダッシュボード Traefik LoadBalancer に向けて提供され、cert-manager がその LoadBalancer 経由で Let’s Encrypt 証明書を発行します。ブラウザには警告なしで信頼済み証明書が表示されます。
証明書の発行と更新は HTTP-01 チャレンジで検証されます。 そのため、両方の LoadBalancer がポート 80 でインターネットから到達可能である必要があります。ダッシュボード LoadBalancer を IP 制限する必要がある場合は、事前にサポートと連携して DNS-01 ソルバーを設定してください。そうしないと更新が無音で失敗し、証明書が期限切れになります。

マニフェストの取得

確認:
期待される結果:ファイルが存在すること。存在しない場合はクローンが失敗しています。AGENTEYE_TOKEN を確認してください。 ディレクトリ構造:
base にはフルデプロイメントに必要なすべてのリソースが含まれており、フェーズ 3.1 で設定する 2 つのパブリックホスト名の Let’s Encrypt 証明書も含まれています。overlay は特定の環境(カスタムイメージタグ、リソース制限、環境変数設定など)に合わせてベースにパッチを適用します。third-party ディレクトリには外部インフラ用の Helm バリューファイルが含まれています。
ヘルスモニタリング(オプション): サーバーの readiness プローブはすでに Postgres と ClickHouse のヘルス状態を反映しており、third-party/robusta/ を使用すると Kubernetes ネイティブのポッド障害アラートを Slack にオプトインで追加できます。enterprise-docs/health-monitoring.md を参照してください。

フェーズ 1 — サードパーティインフラストラクチャ(約 30 分)

1.1 cert-manager のインストール

cert-manager は HTTPS 用の TLS 証明書と、mTLS クライアント証明書に使用するプライベート CA を管理します。
確認:
期待される結果:3 つのポッドがすべて Running 状態 — cert-managercert-manager-cainjectorcert-manager-webhook
期待される結果:certificates.cert-manager.ioclusterissuers.cert-manager.ioissuers.cert-manager.io が少なくとも表示される。 失敗した場合: ポッドが CrashLoopBackOff 状態の場合は通常、CRD がインストールされていません。--set crds.install=true を付けて再実行してください。Webhook ポッドの readiness に失敗する場合は、30 秒待ってから再確認してください。起動に少し時間がかかる場合があります。

1.2 Traefik(パブリック取り込みコントローラー)のインストール

この Traefik インスタンスは外部 LoadBalancer でコレクタートラフィックを処理します。TLS を終端し、取り込みエンドポイントで mTLS(クライアント証明書の検証)を強制します。
確認:
期待される結果:1 つのポッドが Running 状態。
期待される結果:IngressClass が存在すること(デフォルトクラスではありません)。 失敗した場合: kubectl describe pod -n traefik-public <pod-name> でイメージプルエラーやリソース制約を確認してください。

1.3 Traefik(ダッシュボードコントローラー)のインストール

この Traefik インスタンスは専用の LoadBalancer でダッシュボードを提供し、IP 許可リストにより制限されます。
このインスタンスには 2 種類の許可リストメカニズムが含まれています。 このガイドでは values-dashboard.yaml を使用します。これはポータブルな service.loadBalancerSourceRanges フィールドでアクセスを制限します。service.beta.kubernetes.io/aws-load-balancer-source-ranges アノテーションを好む AWS 環境向けに、values-internal.yaml も並行して提供されています。どちらか一方を選択して一貫して使用してください。以下の手順では values-dashboard.yaml を前提としています。
インストール前にthird-party/traefik/values-dashboard.yaml を編集して許可する送信元 IP を設定してください。loadBalancerSourceRanges フィールドがダッシュボードへのアクセス可能な IP を制御します。デフォルトは 0.0.0.0/0(全 IP)です。VPN、オフィス、または既知の出口 IP に制限してください。

単一 IP の許可

複数 IP の許可

IP または CIDR ブロックごとに 1 エントリを追加します。/32 サフィックスは単一の IPv4 アドレスに一致し、CIDR ブロック(例:/24)は範囲に一致します。個別 IP と範囲を自由に組み合わせることができます。
リストを管理する際のヒント:
  • 1 行に 1 エントリを記載し、各 IP の所有者や用途を示す短い # コメントを追加してください。将来のオペレーターがそのエントリが引き続き必要かどうかを判断する際に役立ちます。
  • 常に CIDR 表記を使用してください。203.0.113.10 のような裸の IP はクラウドプロバイダーに拒否されます。203.0.113.10/32 のように記述してください。
  • IPv6 の場合は、同等の /128(単一アドレス)またはそれ以上の CIDR を使用してください(例:2001:db8::1/128)。IPv6 送信元範囲をサポートしていないクラウドプロバイダーもあります。プロバイダーの LoadBalancer ドキュメントを確認してください。
  • このリストは OR 条件です。送信元がいずれかのエントリに一致すればトラフィックが許可されます。
ファイルを編集したら、以下の helm install に進んでください。コントローラーがすでにインストールされている場合は、同じフラグで helm upgrade を実行するか、実行時に Service を直接パッチしてください(次のセクション)。

実行時の許可リスト更新

Helm アップグレードなしに、Service を直接パッチして許可 IP を変更できます。パッチはリスト全体を置き換えます。 新しい IP だけでなく、保持したい既存の IP もすべて含めてください。 リストを新しい IP セットで置き換えるには:
既存のエントリを失わずに IP を追記するには、まず現在のリストを確認してから、統合したセットでパッチします:
実行時のパッチは values-dashboard.yaml には反映されません。将来の Helm アップグレードでも変更を維持するには、バリューファイルも更新してコミットしてください。
インストール:
確認:
期待される結果:1 つのポッドが Running 状態。
期待される結果:IngressClass が存在すること。

1.4 LoadBalancer の待機

次のステップに進む前に、両方の Traefik インスタンスに外部 IP が割り当てられている必要があります。
確認: 両方のサービスに EXTERNAL-IP が表示されていること(<pending> でないこと)。 まだ pending の場合は、割り当てを待機します:
IP が表示されたら Ctrl+C を押してください。IP の割り当ては通常 2〜5 分かかります。 失敗した場合: 10 分経過しても <pending> の場合、クラウドプロバイダーが LoadBalancer をプロビジョニングできていない可能性があります。サブネットタグ(EKS では kubernetes.io/role/elb が必要)、VPC 設定、サービスクォータ、および内部インスタンスに正しい内部 LB アノテーションが設定されているかを確認してください。

フェーズ 2 — シークレットの作成(約 10 分)

すべてのシークレットはアプリケーションのデプロイ前に手動で作成します。これにより、機密情報がマニフェストファイルに含まれることがありません。

2.1 ネームスペースの作成

確認:
期待される結果:ステータスが Active

2.2 イメージプルシークレット

このシークレットは ghcr.io への認証に使用し、AgentEye コンテナイメージをプルします。PAT の生成方法については enterprise-docs/github-token.md を参照してください。
確認:
期待される結果:kubernetes.io/dockerconfigjson 詳細確認 — トークンが実際にイメージをプルできるかを検証します: オーバーレイの kustomization.yaml に固定されているサーバーイメージタグを使用してください(現在、バンドルされている acme オーバーレイとベースデプロイメントの両方で v0.0.1-beta.48)。リリース間でこのチェックがずれないよう、実際にデプロイするタグに置き換えてください:
期待される結果:ログに ok が出力される。 失敗した場合: ErrImagePull または 401 Unauthorized は PAT が無効か read:packages スコープがないことを意味します。enterprise-docs/github-token.md を再確認してください。

2.3 PostgreSQL 認証情報

重要: パスワードの生成には -hex-base64 ではなく)を使用します。Base64 出力には +/= が含まれる可能性があり、DATABASE_URL 接続文字列が壊れます。詳細は enterprise-docs/troubleshooting.md を参照してください。
POSTGRES_PASSWORD はすぐにシークレットマネージャーに保存してください。 バックアップからの復元やデータベースへの直接接続時に必要になります。
確認:
期待される結果:シークレットが存在すること。
期待される結果:48(24 hex バイト = 48 文字)。

2.4 管理者 API キー

管理者キーはブートストラップ用の認証情報です。サーバーは起動のたびに全権限付きでこのキーをアップサートします。フェーズ 7 でコレクター用のスコープ付きキーを作成する際に使用します。完全な権限モデルについては enterprise-docs/api-keys.md を参照してください。
ADMIN_KEY はすぐにシークレットマネージャーに保存してください。
確認:
期待される結果:シークレットが存在すること。

2.5 認証設定(ダッシュボードログイン)

ダッシュボードはユーザーログインにメール + OTP を使用します。このシークレットがなくてもサーバーは起動し、ADMIN_KEY の API パスは動作し続けますが、UI からユーザーがログインできなくなります すべてのキーはベースマニフェストで optional: true として参照されているため、一部のシークレット(またはシークレットがまったくない状態)でも問題ありません。サーバーはドキュメントに記載されたデフォルト値にフォールバックします。すべてを 1 つの agenteye-auth シークレットにまとめることで、認証情報を一箇所でローテーションできます。
キー用途
ADMIN_EMAILブートストラップ管理者ユーザー。起動のたびに全権限付きでアップサートされ、ダッシュボードからの削除/権限編集が保護されます。設定しない場合、管理者がシードされず最初のログインが不可能になります。
ALLOWED_EMAILSカンマ区切りの許可リスト。厳密なアドレス(user@example.com)とドメインワイルドカード(*@example.com)をサポートします。設定しない場合、どのユーザーもログインまたは作成できません
SMTP_HOSTSMTP_PORTSMTP_USERNAMESMTP_PASSWORDSMTP_FROMOTP コード送信用の SMTP リレー。SMTP_HOST が未設定の場合、OTP コードはメール送信の代わりにサーバーの stdout に記録されます(初回起動のスモークテストに便利)。実際のメール配信にはすべての SMTP キーを一緒に設定してください。
SMTP_TLSstarttls(デフォルト)、tls、または none のいずれか。
DEFAULT_ORG_NAMEDEFAULT_ORG_SLUGオプション。組み込みの default 組織にわかりやすい表示名と URL スラグを付けることで、/default の代わりに例えば /acme のような URL にできます。初回起動時のみ適用されます。agenteye-orgctl org rename で組織名を変更した後(§7.6 参照)はこれらの設定は無視されます。スラグは 1〜40 文字の小文字英数字で、内部ハイフンは 1 つまで使用できます。デフォルトの default のままにする場合は両方未設定のままにしてください。
SMTP 認証情報はシークレットマネージャーに保存してください。
確認:
期待される結果:設定したキーが出力に表示されること。

2.6 マルチテナント組織分離キー(オプション)

シングルテナントデプロイメントではスキップしてください。サーバーは組み込みの dev デフォルトで動作し、1 つの default 組織を問題なく提供します。2 番目の組織を作成する前に、強固で安定した ORG_CH_SECRET を設定してください。各組織の ClickHouse パスワードは HMAC(ORG_CH_SECRET, org_id) として導出されるため、公知の dev デフォルトを使用すると組織ごとの認証情報が公開的に導出可能になってしまいます。agenteye-orgctl org create コマンド(§7.6 組織のプロビジョニング参照)は、サーバーが組み込み dev デフォルトを使用している間は実行を拒否します。
サーバーはこれをオプションの secretKeyRef で読み取るため、このシークレットを作成しないシングルテナントクラスターでも正常に起動します。この値はすべてのレプリカで安定かつ一致させてください。ローテーションすると、起動時の調整で再プロビジョニングされるまで(値を一致させた状態でのローリング再起動で修復されます)、すべての組織の導出済み ClickHouse パスワードが無効になります。deploy/base/server/secret.example.yaml を参照してください。
ORG_CH_SECRET はシークレットマネージャーに保存し、安易にローテーションしないでください。

2.7 全シークレットの確認

期待される出力(デフォルトシークレットを含む):
続行前に 4 つのコアシークレット(agenteye-admin-keyagenteye-authagenteye-image-pullagenteye-postgres)が存在している必要があります。agenteye-org-ch-secret はマルチテナントデプロイメントでのみ必要です(§2.6 参照)。

フェーズ 3 — アプリケーションのデプロイ(約 5 分)

3.1 パブリックホスト名の設定

cert-manager が Let’s Encrypt 証明書を要求する前に、取り込みとダッシュボードのホスト名が必要です。テンプレートをコピーして両方を設定してください:
domain.env は gitignore されており、各デプロイメントにローカルに保存されます。いずれかのキーが欠けていると kustomize ビルドは明確にエラーとなります。
DNS は事前に解決できる状態にしてください。 まだ LB に DNS を向ける必要はありません(フェーズ 1.2 が完了するまで存在しないため)が、ステップ 3.2 の ACME 発行では各ホスト名がその LoadBalancer に解決されるまでリトライが続きます。フェーズ 1.4 で取得した LB ホスト名を使用して今すぐ DNS を設定するか、フェーズ 4 でレコードを追加することもできます。

3.2 マニフェストの適用

新規インストールの場合はベースを直接適用するか、この環境向けにオーバーレイを作成した場合はオーバーレイを適用してください(オーバーレイはイメージタグ、環境変数、リソース制限のみを設定し、ベースの証明書とルーティングを継承します):
オーバーレイはベースを自動的に含みます。両方を適用しないでください。

3.3 ポッドの起動待機

この待機はコアデータプレーンのポッドに限定されています。オプションの agent(AI アシスタント)と redis ポッドも同時に起動します。アシスタントは LLM エンドポイントを設定するまで無効状態(enterprise-docs/assistant.md 参照)で、Redis はベストエフォートのキャッシュです。そのため、どちらもプラットフォームがトラフィックを提供するために Ready 状態である必要はありません。 確認:
期待される結果(オプションの agentredis ポッドも表示され Running になります):
失敗した場合:
ポッドのステータス考えられる原因デバッグコマンド
ImagePullBackOffイメージプルシークレットまたは PAT が無効kubectl describe pod <name> -n agenteye
CrashLoopBackOff環境変数が不正(例:DATABASE_URL)kubectl logs <name> -n agenteye
PendingCPU/メモリ不足またはノードなしkubectl describe pod <name> -n agenteye(Events を確認)

3.4 ストレージの確認

期待される結果:両方が Bound ステータス:
PVC容量用途
postgres-data-postgres-050GiPostgreSQL リレーショナル/メタデータストア
clickhouse-data-clickhouse-0100GiClickHouse イベント + エバリュエーション分析ストア
オプションのキャッシュ用に redis-data-redis-0 PVC(1Gi)も表示されます。 失敗した場合: Pending はどの StorageClass もボリュームをプロビジョニングできないことを意味します。kubectl get storageclass でデフォルトが存在することを確認してください。本番環境では、高速 SSD StorageClass(AWS では gp3、GCP では pd-ssd)に ClickHouse ボリュームのオーバーレイを適用してください。低速ディスクではコンパクションのスループットが低下します。

3.5 証明書の確認

期待される結果:3 つの証明書がすべて Ready: True
名前発行者用途
mtls-caselfsignedmTLS クライアント証明書発行用のプライベート CA(有効期限 10 年)
ingest-tlsletsencrypt-prod取り込みエンドポイント用パブリック TLS 証明書(90 日、自動更新)
dashboard-tlsletsencrypt-prodダッシュボード用パブリック TLS 証明書(90 日、自動更新)
ingest-tls または dashboard-tls が Ready でない場合: kubectl describe certificate <name> -n agenteye を実行して Events を確認してください。一般的な原因:
  • DNS がまだ LB を向いていない。 Let’s Encrypt はホスト名を解決してポート 80 にアクセスして検証します。INGEST_DOMAIN はパブリック LB に、DASHBOARD_DOMAIN はダッシュボード LB に解決される必要があります。CNAME/Alias が伝播するまでオーダーは pending のままです。DNS が正しく設定されれば、cert-manager は自動的にリトライします(Certificate を削除する必要はありません)。
  • ホスト名が置換されていない。 dnsNamesINGEST_DOMAIN_PLACEHOLDER / DASHBOARD_DOMAIN_PLACEHOLDER のままの場合、ステップ 3.1 をスキップしています。base/certificates/domain.env を作成して再適用してください。
  • ダッシュボード Traefik がチャレンジを提供できないdashboard-tls のみ)。ダッシュボード Traefik インスタンスはバンドルされたバリューファイルでインストールされている必要があります(フェーズ 1.2)。このファイルは cert-manager の HTTP-01 ソルバーを提供するスコープ付き Ingress プロバイダーを有効にします。これなしでインストールされたインスタンスはチャレンジをルーティングできず、オーダーが永遠に pending のままになります。
mtls-ca が Ready でない場合: cert-manager 自体が不健全です。ステップ 1.1 の cert-manager ポッドを再確認してください。

3.6 CronJob の確認

期待される結果:
名前スケジュール用途
agenteye-backup0 3 * * *UTC 03:00 に Postgres と ClickHouse の日次バックアップ
cert-renewal-check0 3,15 * * *UTC 03:00 と 15:00 に証明書有効期限アラート

3.7 サーバーの起動確認

確認: サーバーがポート 8080 でリッスンしていることを示す起動ログを探してください。データベース接続エラーがないことを確認してください(サーバーは Ready と報告する前に PostgreSQL と ClickHouse の両方に到達できる必要があります)。 失敗した場合: 最も一般的な原因は、POSTGRES_PASSWORD に URL 安全でない文字が含まれており、DATABASE_URL が壊れていることです。enterprise-docs/troubleshooting.md を参照してください。

3.8 ダッシュボードのサーバー接続確認

確認: 出力に Ready が表示され、ECONNREFUSED などのエラーがないことを確認してください。 失敗した場合: server Service が存在すること(kubectl get svc server -n agenteye)と、ダッシュボードデプロイメントで AGENTEYE_SERVER_URLhttp://server:8080 に設定されていることを確認してください。

フェーズ 4 — ネットワークアクセス(約 5 分)

4.1 LoadBalancer アドレスの取得

AWS EKS では、LoadBalancer は IP の代わりにホスト名を返します。上記コマンドの .ip.hostname に置き換えてください。
確認:
両方が空でないこと。

4.2 LoadBalancer への DNS の向け先設定

base/certificates/domain.env のホスト名がそれぞれの LoadBalancer に解決されるように DNS レコードを作成してください。INGEST_DOMAINパブリック Traefik LB に、DASHBOARD_DOMAINダッシュボード Traefik LB に向けます:
  • AWS Route 53: Alias = YesA レコードで、ターゲットを LB ホスト名に設定。単純な A → IP は使用しないでください。ELB の IP はローテーションされます。
  • その他のプロバイダー: ホスト名から LB ホスト名への CNAME
確認:
それぞれ $PUBLIC_IP$INTERNAL_IP と同じアドレスが返されるはずです(EKS の場合は同じ *.elb.amazonaws.com ホスト名に解決)。 DNS が解決されると、cert-manager はフェーズ 3.5 の pending ACME オーダーを 1 分以内に完了します。ingest-tlsdashboard-tls の両方が Ready: True になるまで kubectl get certificates -n agenteye を再実行してください。

4.3 取り込みエンドポイントへの到達確認

パブリック取り込みエンドポイントは相互 TLS を強制するため、/health を含むすべてのリクエストにクライアント証明書が必要です。フェーズ 5 で最初のクライアント証明書を発行します。すでに持っている場合は今すぐ到達性を確認してください:
期待される結果:{"status":"ok"}-k は不要です。INGEST_DOMAIN のサーバー証明書はパブリック CA からチェーンされているため、システムトラストストアで検証されます。取り込みエンドポイントには、未加工の LoadBalancer の IP/ホスト名ではなく INGEST_DOMAIN ホスト名でアクセスしてください。 ダッシュボードエンドポイントは DASHBOARD_DOMAIN でパブリック信頼済み証明書により提供され、mTLS の背後にはありません。そのため -k もクライアント証明書も不要です:
証明書は DASHBOARD_DOMAIN にバインドされているため、未加工の LB アドレスで接続すると証明書名の不一致が発生します。ダッシュボードへはホスト名でアクセスしてください。 失敗した場合: curl がハングする場合は、ご利用のマシンから LB に到達できるかを確認してください(VPN、セキュリティグループ、ファイアウォールルール)。取り込みホスト名での certificate required ハンドシェイクエラーはクライアント証明書が提示されていないことを意味します。まずフェーズ 5 を完了してください。取り込みホスト名での TLS 検証エラーは、サーバー証明書の発行が完了していないことを意味します。フェーズ 3.5 に戻って問題を解決してください。

フェーズ 5 — mTLS クライアント証明書の発行(クラスターあたり約 10 分)

コレクターは2 要素で認証します。クライアント証明書(トランスポート層、認可されたクラスターからのリクエストであることを証明)と API キー(アプリケーション層、events:add 権限を持つコレクターからのリクエストであることを証明)です。流出したキーは証明書なしでは無効であり、盗まれた証明書は有効なキーなしでは無効です。

5.1 証明書の発行

コレクターを実行する各クラスターには固有のクライアント証明書が必要です。マニフェストのディレクトリから:
<cluster-name> を意味のある識別子(例:us-east-1-prodstaging)に置き換えてください。 確認: スクリプトが ==> Done! を出力し、出力ファイルの一覧が表示される。
期待される結果:Ready: True issued/<cluster-name>/ の出力ファイル:
ファイル用途
client.crtクライアント証明書(有効期限 90 日)
client.keyクライアント秘密鍵
ca.crtサーバー検証用 CA 証明書
collector-mtls-secret.yamlコレクタークラスター用の即適用可能な Kubernetes Secret

5.1b 代替配信方法:AWS Secrets Manager

証明書の使用者が client.crtclient.key をディスク上に必要とする Kubernetes Pod(アプリケーションポッドのサイドカーとして agenteye-collector を実行する典型的なケース)の場合は、証明書バンドルを AWS Secrets Manager にプッシュします。アプリケーションポッドは Secrets Store CSI Driver と IRSA を通じてマウントし、証明書のローテーションは完全に自動化されます。
再実行(更新)時、スクリプトは同じシークレットに対して PutSecretValue を呼び出すため、ARN と名前は安定したままです。CSI Driver は次のローテーションポーリング時に新しいバージョンを取得し、ポッド内のファイルを書き換えます。 前提条件:
  • AWS アカウントに認証済みの aws CLI v2。
  • jq がインストールされていること。
  • AWS_REGION 環境変数が設定されていること。
  • 呼び出し元の IAM 権限(Resourcearn:aws:secretsmanager:<region>:<account>:secret:agenteye/mtls-client/* にスコープ):
    • secretsmanager:CreateSecret
    • secretsmanager:DescribeSecret
    • secretsmanager:PutSecretValue
    • secretsmanager:TagResource
このモードでスクリプトが行うこと:
ステップアクション
1cert-manager を通じて証明書を発行/再抽出します(デフォルトモードと同じ)。
2agenteye/mtls-client/<cluster-name> に対して DescribeSecret を呼び出し、作成か更新かを判断します。
3初回実行時:3 キーの JSON ペイロード(client.crtclient.keyca.crt)で CreateSecret を実行し、AgentEyeCluster=<cluster-name> タグを付与。以降の実行時:PutSecretValue で新しいバージョンを発行し、TagResource でタグを更新。
4アップロード成功後のみ issued/<cluster-name>/ を削除します。失敗した場合はディレクトリが保持されるのでリトライできます。
シークレットが削除スケジュールされている場合、スクリプトはリトライ前に aws secretsmanager restore-secret --secret-id agenteye/mtls-client/<cluster-name> を実行するよう促す明確なエラーを表示して失敗します。 完全なポッドの配線(SecretProviderClass、IRSA セットアップ、ローテーション動作、トラブルシューティング)については enterprise-docs/single-pod-deployment.md を参照してください。

5.2 証明書の動作確認

発行した証明書を mTLS イングレスに対してテストします:
期待される結果:{"status":"ok"} 失敗した場合:
エラー原因対処法
certificate required証明書が提示されていないcurl コマンドのファイルパスを確認
bad certificateCA の不一致mtls-ca-issuer が証明書を発行したか確認:kubectl describe certificate mtls-client-<name> -n agenteye
connection refusedホスト名が誤っているか LB に到達できない/etc/hosts または DNS を確認

5.3 コレクタークラスターへの配信

collector-mtls-secret.yaml をコレクタークラスターを運用するチームに送付します。適用方法:
次に、シークレットをマウントして証明書パスを使用するようコレクターを設定します:
Kubernetes ボリュームマウントを含む完全なコレクターセットアップについては enterprise-docs/collector-installation.md を参照してください。 確認(コレクタークラスター内):
期待される結果:3 つのデータキー(client.crtclient.keyca.crt)を持つシークレットが存在すること。

5.4 証明書のライフサイクル

プロパティ
クライアント証明書の有効期限90 日
自動更新cert-manager が有効期限の 15 日前に更新
CA の有効期限10 年
有効期限アラートCronJob が有効期限の 30 日前にアラート(フェーズ 6)
cert-manager は AgentEye クラスター上の証明書を自動更新しますが、更新された証明書はコレクタークラスターに再配信する必要があります。古い証明書が期限切れになる前に issue-client-cert.sh を再実行して collector-mtls-secret.yaml を再適用してください。 --save-to aws-secrets-manager を使用している場合(§ 5.1b 参照)は、同じコマンドを再実行してください。スクリプトは同じシークレットに対して PutSecretValue を呼び出し、Secrets Store CSI Driver を通じてシークレットをマウントしているポッドは次のローテーションポーリング時(デフォルト:1 時間ごと)に新しいバージョンを取得します。ポッドの再起動は不要です。

5.5 証明書の失効

クラスターのコレクターアクセスを即座にブロックするには:
確認: ステップ 5.2 の curl コマンドが TLS ハンドシェイクエラーで失敗するようになる。

フェーズ 6 — 証明書更新モニタリング(約 2 分)

組み込みの CronJob が 12 時間ごと(UTC 03:00 と 15:00)に実行され、agenteye.io/cert-type=mtls-client ラベルの付いたすべてのクライアント証明書をチェックします。有効期限まで 30 日以内の証明書があるとアラートを送信します。

6.1 Slack 通知の有効化(オプション)

このシークレットがなくても、CronJob は実行され証明書のステータスを stdout にログ出力します。 確認:
期待される結果:シークレットが存在すること。

6.2 CronJob のテスト

期待される結果:有効期限ステータスを含む証明書の一覧が表示される。Slack Webhook が設定されている場合は、Slack チャンネルにアラートメッセージが届くことを確認してください。 失敗した場合: RBAC を確認してください。CronJob の ServiceAccount は cert-manager Certificate リソースへの get, list 権限が必要です。kubectl describe role cert-renewal-check -n agenteye で確認してください。 テスト用 Job のクリーンアップ:

フェーズ 7 — エンドツーエンドの検証

このフェーズでは、パイプライン全体が正常に動作することを確認します:ヘルスチェック、キー作成、イベント取り込み、ダッシュボード表示。
注: 以下の例では利便性のために未加工の LoadBalancer アドレス(${PUBLIC_IP})で取り込みエンドポイントにアクセスしているため、-k を使用します。サーバー証明書は LB IP ではなく INGEST_DOMAIN にバインドされているため、ホスト名チェックをスキップしています。取り込みエンドポイントはすべてのパスで相互 TLS を強制するため、すべての呼び出しにクライアント証明書(--cert/--key)も必要です。パブリック証明書も検証する場合は、${PUBLIC_IP} の代わりに https://ingest.your-company.example/... を対象にして -k を省略してください。

7.1 ヘルスチェック

期待される結果:HTTP 200 で {"status":"ok"}

7.2 スコープ付きコレクターキーの作成

管理者キーはブートストラップと管理用です。コレクター用の専用 events:add キーを作成してください:
確認: レスポンスに "id""name": "prod-collector""permissions": ["events:add"]"created_at" が含まれること。 確認: キーがキー一覧に表示されることを確認: