このページは Apigee と Apigee ハイブリッドに適用されます。
Apigee Edge のドキュメントを表示する
このページでは、バージョン 1.17.0 以降を実行している既存の Apigee ハイブリッド クラスタで Model Context Protocol(MCP)を有効にする方法について説明します。この手順を完了すると、クラスタで新しいクラスタ内 MCP データプレーンが実行され、Message Processor は MCP ツール呼び出しをそのデータプレーンに転送する準備が整います。共有の MCP クイックスタートに沿って、最初の MCP Discovery Proxy をデプロイできます。
Apigee と Apigee ハイブリッドで共有される MCP のコンセプト、アーキテクチャ、機能の詳細については、Apigee の MCP の概要をご覧ください。
この手順の概要
Apigee ハイブリッド クラスタで MCP を有効にすると、次の変更が行われます。
- Apigee コントロール プレーンの MCP 構成に対する
apigee-watcherID アクセス権を付与します。Apigee 組織のcontrolPlaneAccessリソースのwatcher_identitiesリストにapigee-watcherサービス アカウントを追加します。これにより、MCP サイドカーは Apigee コントロール プレーンから MCP 構成バンドルを取得できます。これは、Apigee 組織にスコープ設定されたコントロール プレーンの変更であり、その組織をサービス提供するクラスタの数に関係なく、組織ごとに 1 回限りの手順です。 - 新しいクラスタ内 MCP データプレーンを追加します。Apigee ハイブリッドがインストールされている同じ Kubernetes Namespace(デフォルトは
apigee)に、新しい MCP Pod のセットが作成されます。また、それらの実行に必要な Kubernetes リソース(Service、Horizontal Pod Autoscaler、RBAC)も作成されます。MCP ツールの呼び出しは、これらの Pod によって処理されます。 - MCP データプレーンにアクセスするようにメッセージ プロセッサを構成します。Apigee オペレーターは、MP が MCP ツール呼び出しを新しいクラスタ内 MCP データプレーンにルーティングするように、Message Processor Pod 仕様を更新します。この変更を適用すると、メッセージ プロセッサ(
ApigeeDeploymentコントローラによって管理される)の段階的なカナリア リリースがトリガーされます。新しい Pod がReadyになるまで、以前の Pod はトラフィックの処理を続けます。リリースは、有効化と無効化の遷移でのみ発生し、進行中の MCP アクティビティや定常状態の MCP トラフィックでは発生しません。承認済みのメンテナンスの時間枠でこの手順を実行し、リリースが完了するまで待ってから続行します。
ステップ 1: overrides.yaml を編集する
Apigee ハイブリッド Helm チャートに使用する overrides.yaml ファイルを開きます。ファイルのトップレベルに、次のコードを追加します。
enableMcpServer: true
これは、MCP を有効にするために必要な最小限の構成です。apigee-org チャートの組み込みのデフォルトを使用します。2 つの MCP データプレーン レプリカが CPU 使用率 70% で 10 個に自動スケーリングされ、MCP データプレーン コンテナのリソース リクエストは 500m CPU と 512Mi メモリ、上限は 2000m CPU と 1Gi メモリです。レプリカ数、リソース リクエスト、MCP サービス アカウントをカスタマイズするには、このページの後半にあるリファレンス: overrides.yaml の MCP フィールドをご覧ください。
統合された overrides.yaml の完全な例を以下に示します。認証スタイルごとに 1 つずつあります。既存のベース インストールの構成方法に一致する例を使用します。MCP 固有の行はコメントでハイライト表示されており、3 つのバリアントすべてで同じです。
ベース インストールで Apigee コンポーネントを Google Cloud に対して認証する方法に一致するタブを選択します。この選択は、このページのすべてのバリアント スコープのコードブロックに適用されます。
Workload Identity(GKE)
このバリアントは、ベース インストールで GKE Workload Identity を介して Apigee コンポーネントを Google Cloud に対して認証する場合に使用します(ディスクにサービス アカウント キーファイルはありません)。
instanceID: "my-hybrid-instance" namespace: APIGEE_NAMESPACE gcp: region: us-central1 projectID: my-hybrid-project workloadIdentity: enabled: true gsa: apigee-non-prod@my-hybrid-project.iam. k8sCluster: name: my-cluster region: us-central1 org: my-org envs: - name: my-env # ---- MCP: minimum required ------------------------------------------------- enableMcpServer: true # ---- MCP: optional customization (all fields default when omitted) --------- # mcpServer: # replicaCountMin: 2 # replicaCountMax: 10 # targetCPUUtilizationPercentage: 70 # resources: # requests: { cpu: 500m, memory: 512Mi } # limits: { cpu: 2000m, memory: 1Gi } # sidecar: # resources: # requests: { cpu: 200m, memory: 128Mi } # limits: { cpu: 500m, memory: 512Mi } # annotations: {} # ----------------------------------------------------------------------------
ファイルベースのサービス アカウント キー
このバリアントは、ベース インストールで、各クラスタに配布するサービス アカウント キーファイルを使用して Apigee コンポーネントを Google Cloud に対して認証する場合に使用します。
instanceID: "my-hybrid-instance" namespace: APIGEE_NAMESPACE gcp: region: us-central1 projectID: my-hybrid-project k8sCluster: name: my-cluster region: us-central1 org: my-org envs: - name: my-env serviceAccountPaths: synchronizer: ./service-accounts/apigee-non-prod.json runtime: ./service-accounts/apigee-non-prod.json # ---- MCP: minimum required ------------------------------------------------- enableMcpServer: true # ---- MCP: optional customization (all fields default when omitted) --------- # mcpServer: # replicaCountMin: 2 # replicaCountMax: 10 # targetCPUUtilizationPercentage: 70 # resources: # requests: { cpu: 500m, memory: 512Mi } # limits: { cpu: 2000m, memory: 1Gi } # sidecar: # resources: # requests: { cpu: 200m, memory: 128Mi } # limits: { cpu: 500m, memory: 512Mi } # annotations: {} # ----------------------------------------------------------------------------
Workload Identity 連携(AKS/EKS)
ベース インストールが AKS または EKS にあり、Workload Identity 連携を介して Google Cloud に対して認証を行う場合は、このバリアントを使用します。MCP は、apigee-watcher がクラスタですでに使用している WIF ベースの ID を継承します。MCP 固有の ID 構成は追加しません。
既存の WIF overrides.yaml に MCP 最上位キーを追加します。
# ---- MCP: minimum required ------------------------------------------------- enableMcpServer: true # ---- MCP: optional customization (all fields default when omitted) --------- # mcpServer: # replicaCountMin: 2 # replicaCountMax: 10 # targetCPUUtilizationPercentage: 70 # resources: # requests: { cpu: 500m, memory: 512Mi } # limits: { cpu: 2000m, memory: 1Gi } # sidecar: # resources: # requests: { cpu: 200m, memory: 128Mi } # limits: { cpu: 500m, memory: 512Mi } # annotations: {} # ----------------------------------------------------------------------------
mcpServer.gsa と mcpServer.serviceAccountPath は未設定のままにします。MCP サイドカーは同じ ID を取得し、WIF を介して解決します。apigee-watcher
ステップ 2: コントロール プレーンの MCP 構成に対する watcher ID のアクセス権を付与する
MCP サイドカーは、apigee-watcher コンポーネントの Google Cloud サービス アカウント(ステップ 1 で選択した ID)を使用して、Apigee コントロール プレーンから構成バンドルを取得します。MCP Pod が起動する前に、そのサービス アカウントを Apigee 組織の controlPlaneAccess リソースの watcher_identities リストに追加します。この権限付与がないと、MCP 構成参照を取得するための MCP サイドカーの apigee.googleapis.com への呼び出しは 404 Not Found を返し、MCP データプレーンはツール トラフィックを処理する準備が整いません。
これは組織ごとに 1 回限りの手順です(クラスタごとではありません)。同じ Apigee 組織内の以前のクラスタにすでにアクセス権を付与している場合は、この手順をスキップしてください。
- API 呼び出しに使用するシェル変数を設定します。インストールから値を再利用します。
export ORG_NAME=YOUR_ORG_NAME export PROJECT_ID=YOUR_GCP_PROJECT_ID export WATCHER_SA=apigee-watcher@${PROJECT_ID}. export TOKEN=$(gcloud auth print-access-token)
ここで
YOUR_ORG_NAMEは Apigee ハイブリッド組織の名前です。YOUR_GCP_PROJECT_IDは、Apigee ハイブリッド組織をホストする Google Cloud プロジェクトです。WATCHER_SAは、apigee-watcherサービス アカウントのメールアドレスです。overrides.yamlでwatcher.gsaをオーバーライドした場合は、デフォルトのapigee-watcher@${PROJECT_ID}.ではなく、その値を使用します。
- updateControlPlaneAccess API を呼び出して、ウォッチャー サービス アカウントを
watcher_identitiesリストに追加します。データ所在地を使用しない場合
curl -X PATCH -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ "https://apigee.googleapis.com/v1/organizations/${ORG_NAME}/controlPlaneAccess?update_mask=watcher_identities" \ -d "{\"watcher_identities\": [\"serviceAccount:${WATCHER_SA}\"]}"データ所在地
curl -X PATCH -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ "https://${CONTROL_PLANE_LOCATION}-apigee.googleapis.com/v1/organizations/${ORG_NAME}/controlPlaneAccess?update_mask=watcher_identities" \ -d "{\"watcher_identities\": [\"serviceAccount:${WATCHER_SA}\"]}"ここで、
CONTROL_PLANE_LOCATIONは Apigee ハイブリッド インストールでデータ所在地を使用する場合のコントロール プレーン データのロケーションです。使用可能なロケーションのリストについては、使用可能な Apigee API コントロール プレーンのリージョンをご覧ください。この呼び出しは、長時間実行オペレーションを返します。完了するまで待ってから、以下の確認手順を実行します。
- 付与が完了したことを確認します。getControlPlaneAccess を呼び出し、レスポンスの
watcherIdentitiesフィールドにウォッチャー サービス アカウントが表示されることを確認します。データ所在地を使用しない場合
curl -X GET -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ "https://apigee.googleapis.com/v1/organizations/${ORG_NAME}/controlPlaneAccess"データ所在地
curl -X GET -H "Authorization: Bearer $TOKEN" \ -H "Content-Type: application/json" \ "https://${CONTROL_PLANE_LOCATION}-apigee.googleapis.com/v1/organizations/${ORG_NAME}/controlPlaneAccess"レスポンスには、ウォッチャー サービス アカウントを含む
watcherIdentities配列が含まれている必要があります。次に例を示します。{ "synchronizerIdentities": [ ... ], "analyticsPublisherIdentities": [ ... ], "watcherIdentities": [ "serviceAccount:apigee-watcher@YOUR_GCP_PROJECT_ID." ] }
レスポンスに
watcherIdentitiesがない場合や、レスポンスにウォッチャー サービス アカウントが含まれていない場合は、PATCH コマンドを再実行し、エラーがないかオペレーション ステータスを確認してから続行します。
ステップ 3: apigee-operator グラフをアップグレードする
オペレーター チャートを最初にアップグレードします。オペレーター チャートは新しい MCP リソースのスキーマを所有し、組織チャートはそれらを参照します。アップグレードの順序が間違っていると、helm upgrade は成功しますが、MCP Pod は作成されません。
helm upgrade APIGEE_OPERATOR_RELEASE_NAME apigee-operator/ \ --namespace APIGEE_NAMESPACE \ --atomic \ -f overrides.yaml
コマンドは 1 分以内に完了します。新しいイメージでオペレータの Deployment が完全にロールアウトされていることを確認します(apigee-controller-manager
Deployment は ApigeeDeployment ではなく、バニラ Kubernetes リソースであるため、ここでは kubectl rollout status deploy が正しいコマンドです)。
kubectl rollout status deploy -n APIGEE_NAMESPACE apigee-controller-manager --timeout=2m
予想される出力:
deployment "apigee-controller-manager" successfully rolled out
ステップ 4: apigee-org チャートをアップグレードする
helm upgrade APIGEE_ORG_RELEASE_NAME apigee-org/ \ --namespace APIGEE_NAMESPACE \ --atomic \ -f overrides.yaml
2 つの調整ループが並行して実行されるようになりました。
- Apigee オペレーターは、MCP Deployment、Service、HPA、ServiceAccount、Role、RoleBinding を作成します。MCP Pod は一度に 2 つずつ起動します(Kubernetes スケジューリングの対象)。各 Pod のサイドカー コンテナは、起動後すぐに Apigee コントロール プレーンから最初の構成を取得します。
- Apigee オペレーターは
hostAliasesエントリを Message Processor Pod 仕様に挿入します。これにより、apigee-runtimeApigeeDeploymentのリリースがトリガーされます。
ステップ 5: インストールを確認する
MCP データプレーンが実行されていることを確認する
オペレーターが作成した MCP 関連の 4 つのリソースを調べます。リソース名には組織由来の接尾辞が含まれます。以降のサンプルでは、その接尾辞のプレースホルダとして ORG_CR_SUFFIX を使用します。Pod の接尾辞と Service ClusterIP は環境によって異なります。
MCP Pod(デフォルトは 2。負荷に応じて 10 まで自動スケーリング):
kubectl get pod -n APIGEE_NAMESPACE -l app=apigee-mcp-server
NAME READY STATUS RESTARTS AGE apigee-mcp-server-default-ORG_CR_SUFFIX-6d4c8-abc12 2/2 Running 0 2m apigee-mcp-server-default-ORG_CR_SUFFIX-6d4c8-def34 2/2 Running 0 2m
すべての Pod の READY 列に 2/2 が表示されている必要があります。各 Pod の 2 つのコンテナは次のとおりです。
apigee-mcp-server- MP Pod が接続する MCP データプレーン コンテナ。apigee-mcp-server-config- Apigee コントロール プレーンから構成バンドルを取得し、MCP データプレーン コンテナが読み取る共有ボリュームに書き込む構成サイドカー(apigee-watcherバイナリのモード)。
MCP ApigeeDeployment(Kubernetes カスタム リソース。標準の Deployment ではありません):
kubectl get apigeedeployment -n APIGEE_NAMESPACE -l app=apigee-mcp-server
NAME STATE NESTEDSTATE AGE apigee-mcp-server-default-ORG_CR_SUFFIX running 2m
想定される状態は running です。基盤となる Pod が 2/2
Running であることも確認します。
kubectl get pod -n APIGEE_NAMESPACE -l app=apigee-mcp-server
NAME READY STATUS RESTARTS AGE apigee-mcp-server-default-ORG_CR_SUFFIX-REV-POD_HASH 2/2 Running 0 2m
MCP サービス:
kubectl get svc -n APIGEE_NAMESPACE -l app=apigee-mcp-server
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE apigee-mcp-server-default-ORG_CR_SUFFIX ClusterIP 10.96.42.17 <none> 80/TCP,443/TCP,15021/TCP,15000/TCP 2m
MCP HorizontalPodAutoscaler:
kubectl get hpa -n APIGEE_NAMESPACE | grep apigee-mcp-server
MINPODS が overrides.yaml(デフォルトは 2)の mcpServer.replicaCountMin と一致し、MAXPODS が mcpServer.replicaCountMax(デフォルトは 10)と一致していることを確認します。TARGETS、REPLICAS、AGE の各列は、ライブ指標とクラスタの状態によって異なります。
Message Processor Pod が hostAliases エントリを受信したことを確認する
すべての MP Pod に挿入されたエントリが表示されている必要があります。1 つでも Pod に表示されていない場合、その Pod は MCP ツール呼び出しをルーティングできません。すべての MP Pod とその hostAliases を一覧表示します。
kubectl get pods -n APIGEE_NAMESPACE -l app=apigee-runtime \ -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.hostAliases}{"\n"}{end}'
出力例: すべての MP Pod に、前の手順の MCP Service ClusterIP を指す 2 つのホスト名を含むエントリが 1 つ含まれた hostAliases 配列がリストされます(2 番目のホスト名は小文字の組織名を使用します)。メッセージ プロセッサ Pod の名前は apigee-runtime-TRUNCATED_ORG-ENV_GROUP_HASH-REV-POD_HASH というテンプレートに従います。ここで、TRUNCATED_ORG は組織名(組織名が長い場合は Kubernetes の 63 文字の名前制限に合わせて切り捨てられます)、ENV_GROUP_HASH は環境ごとのデプロイ グループ ハッシュ、REV は現在のリリース リビジョン番号(4 桁、例: 1170)、POD_HASH は Pod ごとのランダムな接尾辞です。次に例を示します。
apigee-runtime-myorg-env1-abc12-1170-def34 [map[hostnames:[mcp.apigee.internal myorg.mcp.apigee.internal] ip:10.96.42.17]] apigee-runtime-myorg-env1-abc12-1170-ghi56 [map[hostnames:[mcp.apigee.internal myorg.mcp.apigee.internal] ip:10.96.42.17]]
Pod の hostAliases 値が空の場合、Message Processor ApigeeDeployment が更新された Pod 仕様を完全に取得していません。現在の Message Processor Pod を削除して、新しいステージングされたカナリア リリースを強制的に実行します。ApigeeDeployment コントローラは、現在の仕様(hostAliases エントリを含む)から Pod を再レンダリングします。
kubectl delete pod -n APIGEE_NAMESPACE -l app=apigee-runtime
ApigeeDeployment コントローラは、1 分以内に Pod を再作成します。Message Processor は Deployment ではなく ApigeeDeployment カスタム リソースとしてデプロイされるため、kubectl rollout restart deploy(バニラ Kubernetes コマンド)は Message Processor では機能しません。
インストールが完了しました
上記の 3 つのチェックをすべて行うことで、MCP データプレーンが実行され、MP アドレス指定可能であることを確認できます。
- すべての MCP Pod は
2/2 Runningです。オペレータ発行の TLS 証明書が読み込まれておらず、サイドカーが初期 MCP 構成をまだ読み込んでいない場合、MCP データプレーン コンテナはポート15021で Kubernetes 準備プローブに失敗します。そのため、ReadyPod には両方の前提条件が満たされています。 - すべての MP Pod の仕様には、
mcp.apigee.internalとORG_NAME.mcp.apigee.internalを MCP Service ClusterIP に固定するhostAliasesエントリが含まれています。そのため、MP Pod は MCP プロキシ ターゲット エンドポイントをクラスタ内の MCP データプレーンに解決できます。 - MP Pod は、挿入された
hostAliasesエントリを介してmcp.apigee.internalを MCP Service ClusterIP に解決します。
最初の MCP Discovery Proxy をデプロイした後、共有の MCP クイックスタートの一環として、エンドツーエンドの MCP ツール トラフィック(Apigee 上り(内向き)を介した実際の MCP initialize または tools/list 呼び出し)を検証します。
前の 3 つのチェックのいずれかが失敗した場合は、クイックスタートに進む前に、MCP デプロイのトラブルシューティングを参照してください。
ステップ 6: 残りのクラスタで MCP を有効にする
特定のホスト名に対する MCP リクエストは、対応する Apigee 環境グループを処理する任意のクラスタにルーティングできます。同じ環境グループ内のクラスタの一部で MCP が有効になっていて、他のクラスタで有効になっていない場合、MCP が有効になっていないクラスタにルーティングされる MCP リクエストは失敗します(通常、クライアントに 503 Service Unavailable として返されます)。
同じ環境グループを処理するすべてのクラスタで MCP を均一に有効にします。追加のクラスタごとに、ステップ 1、3、4、5 を繰り返します。ステップ 2(監視対象の ID アクセス権を付与する)を繰り返す必要はありません。この権限付与は Apigee 組織にスコープ設定され、同じ組織内のすべてのクラスタに適用されます。
ロールバック
クラスタで MCP を無効にするには、overrides.yaml で enableMcpServer: false を設定(またはフィールドを完全に削除)してから、apigee-org チャートをアップグレードします。
helm upgrade APIGEE_ORG_RELEASE_NAME apigee-org/ \ --namespace APIGEE_NAMESPACE --atomic -f overrides.yaml
enableMcpServer フィールドは apigee-org グラフでのみ使用されるため、無効化中にオペレーター グラフをアップグレードする必要はありません。Apigee オペレーター(変更なし)は、ApigeeOrganization カスタム リソースから構成の変更を取得し、MCP リソースを削除して、Message Processor Pod 仕様から hostAliases エントリを削除します。これにより、apigee-runtime ApigeeDeployment のリリースがトリガーされます。承認されたメンテナンスの時間枠でロールバックします。
ロールバック後、Apigee 環境にデプロイした MCP ディスカバリ プロキシは Apigee コントロール プレーンに存在しますが、その環境グループのクラスタは MCP トラフィックを処理しません。MCP Discovery Proxy をデプロイ解除して機能を完全に元に戻すか、デプロイしたままにして、後でクラスタで MCP を再度有効にします。
参照: overrides.yaml の MCP フィールド
次の表に、バージョン 1.17.0 で MCP の動作を制御する Apigee ハイブリッド overrides.yaml フィールドをすべて示します。enableMcpServer のみが必須です。他のすべてのフィールドには、ほとんどのインストールに適した安全なデフォルト値が設定されています。
フィールド定義は、ハイブリッド 1.17.0 の apigee-org Helm チャートのデフォルトと一致します。
| フィールド | タイプ | デフォルト | 推奨されるチューニング |
|---|---|---|---|
enableMcpServer |
ブール値 | false |
必須。このクラスタで MCP を有効にするには、true に設定します。このフィールドを切り替えると、Message Processor の段階的なカナリア リリースがトリガーされます。メンテナンスの時間枠内でのみ切り替え、リリースが完了するまで待ってから続行します。 |
mcpServer.replicaCountMin |
integer | 2 |
HA の場合は 2 にします。MCP トラフィックのベースラインが高い場合にのみ増やします。HPA は CPU 負荷に応じて自動的にスケールアップします。シグナル: replicaCountMax で HPA が持続し、CPU が目標値を上回っている。 |
mcpServer.replicaCountMax |
integer | 10 |
ピーク時に HPA が 10 で上限に達している場合は、増やします。シグナル: kubectl top pods -l app=apigee-mcp-server は、ピーク時に CPU 上限に近いすべての Pod を示します。metrics-server がインストールされていない場合は、kubectl get hpa -n APIGEE_NAMESPACE | grep apigee-mcp-server を使用して、REPLICAS 列が MAXPODS の上限に達しているかどうかを確認します。 |
mcpServer.targetCPUUtilizationPercentage |
integer | 70 |
レイテンシの影響を受けやすいワークロードの場合は、50~60 に下げます(スケーリングが早くなります)。80~85 に引き上げて、費用に敏感なクラスタのレプリカ数を減らします。シグナル: p95 リクエスト レイテンシは Pod あたりの CPU と相関関係があります。 |
mcpServer.resources.requests |
ResourceList | cpu: 500m, memory: 512Mi |
ポッドが定常状態で頻繁に OOMKilled または CPU スロットリングされる場合は、リクエストを増やします。シグナル: kubectl describe pod は OOMKilled またはスロットリングされた状態を示します。 |
mcpServer.resources.limits |
ResourceList | cpu: 2000m, memory: 1Gi |
p95 レイテンシが高いが、全体的な QPS が低い(高コストのリクエストが少ない)場合は、レプリカ数を増やす前に CPU 上限を引き上げます。OOMKill が発生した場合にのみ、メモリ上限を引き上げます。 |
mcpServer.sidecar.resources.requests |
ResourceList | cpu: 200m, memory: 128Mi |
チューニングはほとんど必要ありません。サイドカーは構成バンドルを定期的に作成して書き込みます。定常状態の CPU は最小限です。 |
mcpServer.sidecar.resources.limits |
ResourceList | cpu: 500m, memory: 512Mi |
調整はほとんど必要ありません。メモリを増やすのは、単一の検出プロキシに異常に多くの MCP ツールをデプロイする場合のみです。 |
mcpServer.terminationGracePeriodSeconds |
integer | 30 |
チューニングはほとんど必要ありません。ポッドのドレイン中に、処理中の MCP リクエストの完了に時間がかかる場合は、この値を増やします。 |
mcpServer.annotations |
地図 | {} |
クラスタで追加の Pod アノテーションが必要な場合は、追加します。 |
mcpServer.serviceAccountPath |
文字列 | 未設定 | コンポーネントごとに ID を分離する必要がある場合を除き、設定しないでください。設定されていない場合、MCP は watcher.serviceAccountPath にフォールバックし、次に envs[].serviceAccountPaths.runtime にフォールバックします。apigee-watcher ID には、MCP サイドカーに必要な権限がすでに付与されています。オーバーライドを行う場合は、Google Cloud サービス アカウント キーの JSON ファイルへのパス。mcpServer.gsa とは相互に排他的です。可能な限り Workload Identity(GKE)または Workload Identity 連携(AKS/EKS)を使用する。ファイルベースのサービス アカウント キーは、ローテーション、安全な保存、すべてのクラスタへの配布が必要であり、サポート アーティファクトへの漏洩の最も一般的な原因です(サポートケースを参照)。 |
mcpServer.gsa |
文字列 | 未設定 | コンポーネントごとに ID を分離する必要がある場合を除き、設定しないでください。設定されていない場合、MCP は watcher.gsa にフォールバックし、次に gcp.workloadIdentity.gsa にフォールバックします。apigee-watcher ID には MCP サイドカーに必要な権限がすでに付与されているため、この ID を再利用することをおすすめします。組織が監査上の理由で MCP サイドカーに個別の ID を必要とする場合にのみ、専用の Google Cloud サービス アカウントのメールアドレスでオーバーライドします。 |
mcpServer.serviceAccountRef |
文字列 | 未設定 | 高精度MCP サイドカーの Google Cloud サービス アカウント キーを保持する、Apigee Namespace 内の既存の Kubernetes Secret の名前。これは、Apigee Helm チャートの外部でサービス アカウント キーのシークレットを管理する場合にのみ使用します。mcpServer.serviceAccountPath、mcpServer.gsa とは相互に排他的です。 |
mcpServer.podDisruptionBudget |
地図 | 未設定 | MCP Pod の PodDisruptionBudget(省略可)。minAvailable または maxUnavailable(整数またはパーセンテージ文字列)を指定します。両方ではなく、いずれか 1 つを設定します。クラスタに明示的な予算を必要とする厳格な自発的停止ポリシーがある場合を除き、設定しないでください。 |
mcpServer.tolerations |
list | unset(最上位の tolerations にフォールバック) |
MCP Pod の標準 Kubernetes toleration。他の Apigee コンポーネントが許容しないテイントを MCP Pod が許容する必要がある場合にのみ設定します。 |
mcpServer.image.pullPolicy |
文字列 | IfNotPresent |
MCP サーバー コンテナのイメージ pull ポリシー。変更されることはほとんどありません。 |
mcpServer.sidecar.image.pullPolicy |
文字列 | IfNotPresent |
MCP サイドカー コンテナのイメージ pull ポリシー。変更されることはほとんどありません。 |
MCP ツールの容量を見積もる
Apigee ハイブリッドでは、組織あたりの MCP ツールの最大数は固定されていません。代わりに、ツールの容量は、デプロイ時またはリクエスト時に適用される 4 つのハードサイズ上限によって制限されます。特定の数のツールが適合するかどうかは、各ツールのサイズによって異なります。各ツールのサイズは、ツールを定義する OpenAPI 仕様から導出されます。
一般的な容量
ほとんどの OpenAPI 仕様(パラメータ数、リクエスト本文のサイズ、説明の長さが異なるツールの組み合わせで、ほとんどのツールが小規模から中規模の範囲に収まる)では、通常、デフォルトの tools/list レスポンス サイズの制限で、組織ごとに 10,000 個の MCP ツールを収容できます。
実際の容量は、OpenAPI 仕様の特定の形状によって異なります。仕様が、パラメータが多いツール、リクエスト ボディが大きいツール、説明が長いツールで占められている組織は、以下の 4 つのハードリミットのいずれかに達する前に、比例して少ない数のツールしか適合しません。特定の仕様の容量を検証するには、以下の仕様の容量を見積もるをご覧ください。
ハードリミット
Apigee ハイブリッド バージョン 1.17.0 では、4 つのサイズ上限が適用されます。適用可能な最も低い上限が適用されます。上限を引き上げても、他の上限は引き上げられません。
| 上限 | 値 | 範囲 | 障害モード |
|---|---|---|---|
| OpenAPI 仕様ファイルのサイズ | 3 MiB | .yaml ファイルあたり |
プロキシの検証時に 400 |
| MCP プロキシ バンドルのサイズ(解凍後) | 50 MiB | MCP ディスカバリ プロキシごと | プロキシの検証時に 400 |
tools/list レスポンス サイズ |
10 MiB(デフォルト) | ホスト名ごと | TooBigBodyの502 |
| 環境グループあたりのホスト名 | 100 | 環境グループあたり | 環境グループの更新時の 400 |
ツールごとのサイズを決定する要素
ツールごとのサイズは、ツールの inputSchema でほぼ構成されています。これは、OpenAPI 仕様のオペレーションの parameters と requestBody から派生したものです。最も重要な 3 つのプロパティは次のとおりです。
- パラメータの数。各パラメータ エントリは、
tools/listレスポンスのツールのサイズに約 100 バイト追加されます。 - リクエスト本文のプロパティの数。リクエスト本文の各プロパティは、約 100 バイトを占有します。したがって、リクエスト本文を含むオペレーション(通常は
POSTとPUT)は、リクエスト本文を含まないオペレーション(通常はGETとDELETE)よりも大幅に大きくなります。 - 説明の長さ。オペレーションの説明はほぼそのままツールにコピーされるため、説明が長くなるとツールのサイズが直接大きくなります。
レスポンス スキーマはサイズ バジェットにカウントされません。parameters と requestBody のみが MCP 構成に到達します。したがって、OpenAPI ファイルのサイズだけで容量をサイジングすると、コストが過大評価される傾向があります。これは、ほとんどの実際の OpenAPI 仕様には、ツールのサイズに影響しないレスポンス スキーマ定義が含まれているためです。
仕様の容量を見積もる
OpenAPI 仕様のツール容量を最も正確に推定する方法は、代表的なサブセットを測定することです。
- 公開する予定のツールの代表的なサブセット(たとえば、完全な仕様のパラメータ数、リクエスト本文のサイズ、説明の長さの組み合わせを反映した 50 ~ 100 個のツール)を参照する MCP 検出プロキシをデプロイします。
- デプロイされたプロキシに対して
tools/listを呼び出し、レスポンスのサイズ(バイト単位)と返されたツールの数を記録します。 - レスポンス サイズをツールの数で割って、仕様のツールあたりの平均サイズを取得します。
- 該当する
tools/listレスポンス サイズの上限(デフォルトでは 10 MiB)をその平均値で割って、この形状の仕様で 1 つのホスト名に収まるツールの最大数を推定します。
容量の増加
次の 2 つのメカニズムにより、ツールの容量がデフォルトを超えて増加します。
- ホスト名間でツールをシャーディングします。
tools/listレスポンスの上限はホスト名ごとです。同じ環境グループ内の複数のホスト名にツールを分割すると、ホスト名あたりのヘッドルームが乗算されます(環境グループあたりのホスト名数の上限は 100 個です)。シャーディングによってプロキシごとのバンドル上限が引き上げられることはありません。50 MiB のバンドル上限は、単一の MCP Discovery Proxy のすべてのホスト名に引き続き適用されます。 tools/listレスポンス サイズの上限を引き上げます。デフォルトの上限はホスト名あたり 10 MiB です。最大 30 MiB まで増やすことができます。少なくとも、overrides.yamlでenvs.components.runtime.resources.limits.memory、envs.components.runtime.resources.requests.memory、envs.components.runtime.cwcAppend.bin_setenv_max_memを設定し、apigee-orgグラフでhelm upgradeを実行する必要があります。環境ごとのバリアントとインストール全体のバリアント、Message Processor のヒープサイズ設定のガイダンス、完全なoverrides.yamlの例など、完全な手順については、Apigee ハイブリッドで大規模なメッセージ ペイロードのサポートを構成するをご覧ください。レスポンスの上限を引き上げても、50 MiB の MCP プロキシ バンドル サイズの上限には影響しません。容量がその上限によって制限されている場合は、この変更は役に立ちません。
セキュリティ
信頼境界
MCP データプレーンは、独自の Kubernetes クラスタ内で実行されます。Google はデータプレーンにランタイム アクセスできません。Apigee コントロール プレーンは、OpenAPI 仕様から派生した MCP 構成を提供しますが、MCP リクエスト トラフィックは監視しません。保存時の構成データは、Apigee テナント プロジェクトにスコープ設定された Apigee 管理の Cloud Storage バケットに保存され、MCP サイドカーがそのアンビエント Google Cloud サービス アカウントを使用して取得します。
Apigee オペレータは、MCP データプレーン ServiceAccount 用に、Apigee Namespace(APIGEE_NAMESPACE)に MCP スコープの Kubernetes Role と RoleBinding をプロビジョニングします。このロールは読み取り専用アクセス権を付与します。
- コア API グループの
servicesのget、list、watch。 apigee.cloud.google.comAPI グループのapigeeroutesに対するget、list、watch。
この Role は、書き込み動詞と Secrets、ConfigMaps、Pod ステータスへのアクセス権を付与しません。監査担当者は、次のコマンドを使用して、クラスタから正確なルールを直接確認できます。
APIGEE_ORG_CR=$(kubectl get apigeeorganization -n APIGEE_NAMESPACE \ -o jsonpath='{.items[0].metadata.name}') kubectl get role,rolebinding -n APIGEE_NAMESPACE \ --field-selector metadata.name=apigee-mcp-server-$APIGEE_ORG_CR -o yaml
apigee-mcp-server-APIGEE_ORG_CR Role と RoleBinding は MCP スコープの RBAC リソースです。これらの名前には、ApigeeOrganization カスタム リソースの完全な名前が含まれます(Apigee 組織名と短いハッシュから派生します)。リソースレベルで app=apigee-mcp-server ラベルは付いていないため(Pod のみ)、ラベルベースのルックアップでは結果が返されません。上記のフィールド セレクタ コマンドが何も返さない場合は、次のコマンドを使用して、名前空間内の MCP 関連のすべての RBAC リソースを一覧表示します。
kubectl get role,rolebinding -n APIGEE_NAMESPACE | grep apigee-mcp-server
Message Processor と MCP データプレーン間の TLS
Message Processor Pod は、https://mcp.apigee.internal/ または https://ORG_NAME.mcp.apigee.internal/ で MCP データプレーンにダイヤルします。これらのホスト名は、挿入された hostAliases エントリを介して MCP Service ClusterIP に解決されます。MCP データプレーン コンテナは、Apigee オペレーターがプロビジョニングした発行者(apigee-ca-issuer という名前の ClusterIssuer)によって署名された TLS 証明書を提示します。証明書のサブジェクト代替名には両方のホスト名が含まれます。
MCP サービスへのインバウンド アクセスを制限する
Apigee ハイブリッド 1.17.0 では、MCP データプレーンは呼び出し元を個別に認証しません。受信したリクエストは、Message Processor で実行されている Apigee MCP プロキシによってすでに認証されていると想定しています。MCP サービスの呼び出し元は Message Processor のみです。TCP 443 で MCP サービス ClusterIP にアクセスできるクラスタ内の他のワークロードは、認証チェックなしで MCP ツールを呼び出すことができます。
プラットフォームのクラスタ Ingress ポリシー エンジン(Kubernetes NetworkPolicy、Cilium、Calico、Istio AuthorizationPolicy など)を使用して、MCP Pod へのインバウンド アクセスを Message Processor Pod のみに制限します。制限事項:
- 同じ Namespace 内の
app=apigee-runtimeというラベルの Pod から、NamespaceAPIGEE_NAMESPACEのapp=apigee-mcp-serverというラベルの Pod への TCP443での上り(内向き)のみを許可します。 - ラベル
app=apigee-mcp-serverの Pod への TCP443の他のすべての上り(内向き)を拒否します。 - ラベル
app=apigee-mcp-serverの Pod への TCP15021のクラスタ内上り(内向き)をすべて拒否します。ポート15021は、kubelet が準備状況のプローブに使用する未認証のプレーン HTTP/healthz/readyエンドポイントを提供します。kubelet は Pod IP で直接到達するため、他のクラスタ内ワークロードが15021で MCP Pod に到達することはありません。
この制限は、MCP クイックスタートを完了し、開発環境以外の環境に最初の MCP 検出プロキシをデプロイする前に適用します。
構成の更新頻度の契約
MCP サイドカーが構成のプルを正常に完了すると、MCP データプレーン コンテナは取得したバンドルを読み込み、次のプルが正常に完了するまでサービスを続行します。後続の pull が失敗した場合(Apigee コントロール プレーンにアクセスできない、Cloud Storage にアクセスできない、watcher サービス アカウントで IAM 権限が削除された、または pull パイプラインの他のステージでエラーが発生した場合)、サイドカーは最後に正常に動作したバンドルを無期限に提供し続けます。1.17.0 には組み込みの古さの上限はありません。Pod は Ready のままで、MCP ツール トラフィックは古いバンドルに対して引き続き処理されます。構成の更新が停止したことを示すシグナルは、consecutive_failures カウンタを含む ERROR レベルのサイドカー ログ行です(サイドカーが障害ステージごとに発行する特定のメッセージについては、MCP デプロイのトラブルシューティングをご覧ください)。
規制対象の本番環境の場合、このカウンタの増分が繰り返されるページ。最小限の実行可能なアラートは、MCP サイドカー コンテナが consecutive_failures が設定したしきい値に達した ERROR レベルのログ行を出力したときにページングされるアラートです。しきい値は、古さの許容範囲に基づいて設定します。値が上昇している場合は、サイドカーが構成の更新を停止したことを示します。その間、サイドカーは最後に成功したバンドルを引き続き提供します。
サイドカーが構成の更新を停止した場合は、サイドカーログから障害モードを調査します。MCP デプロイのトラブルシューティングをご覧ください。MCP Pod を再起動しても、新しく作成された Pod が同じフェッチパスにヒットするため、根本的なフェッチの問題は解決しません。
送信ネットワークの要件
MCP サイドカー(各 MCP Pod 内の構成コンテナ)には、TCP 443 の次のエンドポイントへのアウトバウンド ネットワーク アクセスが必要です。Apigee 組織でデータ所在地を使用しているかどうかに応じて、該当するタブを選択します。必要なエンドポイントが異なります。
データ所在地を使用しない場合
| エンドポイント | 用途 |
|---|---|
apigee.googleapis.com |
構成が更新されるたびに、組織の現在の MCP 構成リファレンスを Apigee コントロール プレーンから取得します。 |
storage.googleapis.com |
Google Cloud Storage から組織の MCP 構成をダウンロードします。 |
データ所在地
Apigee 組織でデータ所在地を使用している場合、MCP サイドカーはリージョン Apigee コントロール プレーン エンドポイント(他の Apigee ハイブリッド コンポーネントが使用する同じエンドポイント。overrides.yaml の contractProvider グラフ値を使用して構成)にアクセスします。CONTROL_PLANE_LOCATION は、組織のコントロール プレーンのロケーション(us、eu など)に置き換えます。
| エンドポイント | 用途 |
|---|---|
CONTROL_PLANE_LOCATION-apigee.googleapis.com |
構成が更新されるたびに、組織の現在の MCP 構成リファレンスをリージョン Apigee コントロール プレーン エンドポイントから取得します。 |
storage.googleapis.com |
Google Cloud Storage から組織の MCP 構成をダウンロードします。バケットは組織のリージョンにあります。Cloud Storage は自動的にバケットにルーティングします。 |
また、サイドカーは、Pod が実行されるアンビエント認証情報(Workload Identity またはファイルベースのサービス アカウント キーを使用)の Google Cloud アクセス トークンを取得できる必要があります。特定トークン交換エンドポイントは認証パスによって異なり、クラスタ内の他の Apigee ハイブリッド コンポーネントがすでに使用しているものと同じです。この名前空間から Google Cloud API への既存の Apigee ハイブリッド トラフィックが成功すると、MCP サイドカーのトークン交換も成功します。
また、サイドカーは、ライブネスと準備完了の状態を公開するために、Kubernetes API サーバーへのクラスタ内アクセス(標準のクラスタ内サービス アドレス経由)が必要です。このトラフィックがクラスタから送信されることはありません。
トラブルシューティング
診断チェックリストの完全なリストについては、MCP デプロイのトラブルシューティングをご覧ください。これには、Apigee ハイブリッドの クラスタ側の診断チェックリストが含まれています。
インストールが失敗する一般的な原因
| 症状 | 原因と解決策 |
|---|---|
helm upgrade は完了したが、MCP リソースが表示されない。 |
組織図はオペレーター図よりも前にアップグレードされました。まず helm upgrade APIGEE_OPERATOR_RELEASE_NAME apigee-operator/ を実行し、次に helm upgrade APIGEE_ORG_RELEASE_NAME apigee-org/ を再実行します。 |
MCP Pod が ContainerCreating または 1/2 Ready のままになっている。 |
一般的な原因は 2 つあります。MCP の cert-manager Certificate がまだ発行されていないか、コンテナ イメージの pull が失敗しています。影響を受ける Pod で kubectl describe pod を実行して、正確な理由を確認します。 |
サイドカー(apigee-mcp-server-config)ログは、ポーリングごとに no MCP config from CP yet; skipping tick, pod stays Ready via seed をレポートします。 |
組織に MCP 検出プロキシがまだデプロイされていない場合の定常状態。Apigee コントロール プレーンは空の構成参照を返し、MCP データプレーンにはポート 15021 に Kubernetes 準備完了リスナーのみが読み込まれます。MCP リクエスト ポート 8443 にはまだリスナーがなく、https://mcp.apigee.internal/mcp へのリクエストは接続拒否を受け取ります。サービング状態に移行するには、MCP クイックスタートに沿って、このクラスタで提供される環境グループの環境に MCP Discovery Proxy をデプロイします。 |
サイドカーログは、埋め込み HTTP 403 または PermissionDenied を含む CP fetch failed を報告します。 |
Apigee ウォッチャーの Google Cloud サービス アカウントが、Apigee テナント プロジェクトで roles/apigee.runtimeAgent ロール(サイドカーに必要な apigee.runtimeconfigs.get 権限を付与するロール)を失いました。ベースの Apigee ハイブリッド インストールでは、このロールが自動的に付与されます。IAM 自動化スイープによって削除された場合は、apigee-watcher Google Cloud サービス アカウントに再適用します。 |
サイドカーログに context deadline exceeded、DNS エラー、TLS エラーとともに CP fetch failed が報告されます。 |
サイドカーがクラスタ内から apigee.googleapis.com または storage.googleapis.com にアクセスできない。上記のアウトバウンド ネットワークの要件に記載されている 3 つのエンドポイントに対して、下り(外向き)を確認します。 |
helm upgrade 後に Message Processor Pod が再起動しなかった。 |
すべての MP Pod に hostAliases エントリが存在することを確認します。
kubectl get pods -n APIGEE_NAMESPACE -l app=apigee-runtime -o
jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.hostAliases}{"\n"}{end}'Pod が空の場合は、Pod(kubectl delete pod -n APIGEE_NAMESPACE -l app=apigee-runtime)を削除して、新しいレンダリングを強制します。ApigeeDeployment コントローラは、hostAliases エントリを含む現在の仕様から Pod を再作成します。kubectl rollout restart deploy は使用しないでください。ApigeeDeployment には適用されません。 |
MP Pod ログには、MCP ツール トラフィックがクイックスタートを介して流れ始めた後、https://mcp.apigee.internal/ または https://ORG_NAME.mcp.apigee.internal/ をダイヤルする TLS ハンドシェイク エラーが表示されます。 |
MCP データプレーン コンテナが、サブジェクトの代替名(SAN)に MP がダイヤルしたホスト名が含まれていない証明書を提供している。証明書を確認します。
kubectl get cert -n APIGEE_NAMESPACE | grep apigee-mcp-server、kubectl get cert -n APIGEE_NAMESPACE CERT_NAME -o yaml の順にタップします。証明書の dnsNames には、mcp.apigee.internal と小文字の ORG_NAME.mcp.apigee.internal の両方を含める必要があります。一致しない場合は、MCP Certificate リソースを削除して、cert-manager に再発行させます。 |
次のステップ
- MCP クイックスタートに沿って、最初の MCP Discovery Proxy をデプロイし、MCP クライアントから MCP ツールを呼び出します。
- API プロダクトを使用して MCP ツールのアクセスを管理する方法を確認する。
- MCP トラフィックをモニタリングして分析する方法を確認する。
- 高度な診断については、MCP トラブルシューティング ガイドをご覧ください。