---
title: "clickhousectl によるエージェント型インフラストラクチャ: 3大陸にまたがる分散 ClickStack"
date: "2026-10-05T07:23:56.448Z"
author: "Oussama Chakri"
category: "Community"
excerpt: "コーディングエージェントが clickhousectl を使用して米国、欧州、日本にまたがる分散 ClickStack を構築し、リージョンごとの取り込みと単一のグローバルビューを実現した方法をご紹介します。"
---

# clickhousectl によるエージェント型インフラストラクチャ: 3大陸にまたがる分散 ClickStack

前回の記事では、コーディングエージェントと ClickHouse スタックを使って、フルスタックの小売向けアプリ [ClickShop](https://clickhouse.com/blog/agentic-coding-app) を構築しました。あのプロジェクトはアプリケーションコードを書くことが目的でした。今回のテーマは異なり、本番環境のインフラを立ち上げて運用することです。

エージェントには、単一のコマンドラインツール [`clickhousectl`](https://clickhouse.com/docs/ja/concepts/features/interfaces/cli) と、1 つの目標を与えました。それは、米国、欧州、日本の 3 か所に ClickHouse Cloud サービスを配置し、それぞれが OpenTelemetry のログ、トレース、メトリクスを取り込み、欧州に単一のグローバルビューを備えたマルチリージョンのオブザーバビリティプラットフォームを構築することです。

ここで共有したいのは、構築された結果そのものというよりも、それを構築したプロセスと体験です。プラットフォームが明確で扱いやすい CLI を備えていれば、エージェントはコードを編集するのと同じ感覚でインフラを操作できます。コマンドを実行し、返ってきた JSON を読み取り、次の手順を判断します。これによって、マルチリージョンのセットアップが半日の作業で完了しました。

## ユースケース

SA として、ユーザー企業の現場でいつも同じような出発点を目にします。それは、アプリケーションがすでに分散配置されているという点です。レイテンシの改善やコンプライアンス上の理由から、米国、欧州、アジアのユーザーに近い場所でシステムが稼働しています。そして、アプリが分散した瞬間に、そのテレメトリも分散します。東京からすべてのログを 1 つの中央クラスターに転送するのは低速でコストがかかり、そもそも規制上許可されないことも少なくありません。

そのため、常にジレンマを抱えることになります。各リージョンで生成されたログ、トレース、メトリクスはその場で保持しなければならない一方で、オンコールエンジニアは「システム全体がすべての場所で正常に稼働しているか」という 1 つの問いに答えられる単一の画面を必要としています。

このプロジェクトの目的は、そのどちらか一方を選ぶ必要はないと示すことでした。検証シナリオは意図的に小規模に抑えています。

* 米国(`us-east-1`)、欧州(`eu-west-1`)、日本(`ap-northeast-1`)にそれぞれ 1 つずつの ClickHouse Cloud サービス。  
* 各サービスは自リージョンの OpenTelemetry データを取り込みます。  
* 欧州は 3 つすべてのリージョンを束ねる統合ビューを 1 つ保持し、そのビューが実際にクエリされたときにのみ他のリージョンにアクセスします。

![image2.png](https://clickhouse.com/uploads/image2_36e14dcc08.png)

*図 1. 分散ストレージと単一のグローバルビュー。各リージョンはテレメトリをローカルに保持し、欧州はオンデマンドでクエリされ ClickStack UI から参照される単一のビューを提供します。*

## アーキテクチャ

データの取り込みはリージョン内で完結します。各リージョンで、アプリはローカルのコレクターに OTel データを送信し、コレクターは隣接する ClickHouse サービスに書き込みます。書き込み経路でデータがリージョン境界を越えることはありません。

欧州側では、追加の役割を 1 つ担っています。3 つのリージョンを単一のテーブル群として見せる小さな `otel_global` データベースをホストし、ClickStack UI はそこからデータを読み取ります。通常の ClickHouse の 2 つの機能がすべての処理を行います。

* `remoteSecure()` は、別サービス上のテーブルを安全に参照するポインタです。それ自体にはデータを保持せず、経由して読み取ると、ClickHouse はクエリ実行時にリモートリージョンから行を取得します。  
* `Merge` エンジンは、複数のテーブルを 1 つに見せます。欧州では、ローカルの EU テーブルと 2 つのリモートポインタをマージしているため、単一の `SELECT` で 3 つの大陸をまたいだクエリを実行できます。

EU データに対するクエリは欧州内にとどまり、米国と日本のサービスにアクセスするのは、クエリがそれらを真に必要とする場合だけです。

![image1.png](https://clickhouse.com/uploads/image1_f6618db4eb.png)

*図 2. 全体構成。各リージョンは独自の OpenTelemetry コレクターを介してローカルの ClickHouse サービスにデータを取り込み、欧州は ClickStack UI の背後で remoteSecure と Merge エンジンを用いて 3 つのリージョンを統合します。*

---

## 今すぐ始める

ClickHouse が手元のデータでどのように機能するか試してみませんか？わずか数分で ClickHouse Cloud を利用開始でき、300 ドル分の無料クレジットも獲得できます。

[サインアップ](https://console.clickhouse.cloud/signUp?loc=blog-cta-2505&utm_blogctaid=2505)

---

## `clickhousectl` の実践

`clickhousectl` は、エージェントがノート PC 上でローカルにプロトタイプを作成し、ClickHouse Cloud 上に本番インフラを立ち上げられるようにする [ClickHouse local および Cloud 向けの CLI](https://clickhouse.com/blog/introducing-clickhousectl-official-cli-for-clickhouse-local-and-cloud) です。

サービスが 1 つだけなら、Cloud コンソールをポチポチ操作して済ませたかもしれません。しかし、3 つのリージョンにまたがる 3 つのサービスがあり、それぞれ固有の接続情報と実行すべき SQL がある場合、クリック操作は適切な手段ではありません。CLI を備えたエージェントなら、一連のフロー全体をはるかに高速に実行できます。サービスの作成、待機、接続情報の読み取り、SQL の実行、すべての破棄といった構築に必要なすべてのステップが 1 つのコマンドで完結し、どのコマンドも JSON で応答を返せます。

```shell
# Install the ClickHouse Agent Skills to give agents a headstart
clickhousectl skills
# authenticate (an API key is what an agent or a CI job uses)
clickhousectl cloud auth login --api-key <KEY> --api-secret <SECRET>

# create, inspect, and query a service, each able to answer in JSON
clickhousectl cloud service create --org-id <ORG_ID> --name otel-eu \
  --provider aws --region eu-west-1 --num-replicas 1 --json
clickhousectl cloud service get <SERVICE_ID> --json
clickhousectl cloud service query --name otel-eu --query "SELECT count() FROM otel_logs"
```

## ステップ・バイ・ステップでの構築

以下は実際に使用したプロンプトで、要点だけに絞り込んでいます。先ほどと同様に、同僚に指示するようにエージェントに状況を説明し、要求の中にドメイン知識を組み込むことがコツです。

### 3 つのサービスのプロビジョニング

> 「`clickhousectl` を使って、米国東部、西欧、日本の各リージョンに 1 つずつ、計 3 つの Cloud サービスを作成してください。後続のステップで再利用できるように、各サービスの ID と接続情報を保持しておいてください」

エージェントは 3 つのリージョンを巡回する短いループを書き、`service create` を呼び出し、次に必要となるフィールドを正確に抽出するために `jq` でレスポンスを解析しました。

```shell
out=$(clickhousectl cloud service create \
  --org-id "$ORG_ID" --name "$name" --provider aws --region "$region" \
  --num-replicas 1 --json)

sid=$(echo  "$out" | jq -r '.service.id')
host=$(echo "$out" | jq -r '.service.endpoints[] | select(.protocol=="https") | .host')
```

その後、次のステップに進む前に各サービスが `running` を報告するまで `service get` をポーリングしました。これにより、準備が整っていないサービスに対して後続の処理が開始されるのを防げます。このスクリプト自体がドキュメントとなりました。再実行すれば、同じ 3 つのサービスが得られます。

### 各リージョンへの OpenTelemetry の送信

> 「各リージョンで、アプリケーションに OpenTelemetry のインストルメンテーションを施し、そのコレクターが該当リージョンの ClickHouse サービスを向くように設定してください。アプリは相互に関連するログ、トレース、メトリクスを出力する一連のマイクロサービス(frontend、cart、payment)で構成され、各サービスには `frontend-us` のようにリージョンがタグ付けされているものとします」

コレクターは自律的に OTel テーブルを作成します。各サービスは、サービスマップがレンダリングされるように適切なクライアントおよびサーバースパンを出力し、同一のトレース ID を含むログ、そして一致するラベルを持つメトリクスを出力します。リージョンごとの挙動も同一ではありません。それぞれ異なるエラー率で動作しており、アラートを発生させる価値のあるストーリーをデータが語るのに十分な差異があります。

### グローバルビュー

> 「EU サービス上に `otel_global` を作成してください。各 OTel テーブルについて、US サービスと JP サービスへの `remoteSecure` ラッパーを追加し、ローカルの EU テーブルにそれらのラッパーを加えた `Merge` テーブルを作成してください」

エージェントは `clickhousectl cloud service query` を使って全体を実行しました。

```sql
CREATE TABLE otel_global.otel_logs_us AS
  remoteSecure('<US_HOST>:9440', 'default', 'otel_logs', 'default', '<US_PASSWORD>');

CREATE TABLE otel_global.otel_logs_jp AS
  remoteSecure('<JP_HOST>:9440', 'default', 'otel_logs', 'default', '<JP_PASSWORD>');

CREATE TABLE otel_global.otel_logs_all
  ENGINE = Merge(REGEXP('^(default|otel_global)$'), '^otel_logs(_us|_jp)?$');
```

`otel_logs_all` にクエリを実行すると、ClickHouse はローカルで EU の行を読み取り、安全な接続を介して他の 2 つのリージョンのデータをその場で取得します。データレジデンシーとグローバルビューが、わずか数行の平易な SQL で実現しました。

### 3 大陸を 1 つの画面で

ヨーロッパにある ClickStack UI の接続先を `otel_global.*_all` テーブルに向けました。それらのテーブルがすでに各リージョンをマージしているため、UI 側はトポロジーを把握する必要が一切ありません。オンコールエンジニアからは単一のバックエンドのように見えます。1 回の検索で 3 つのリージョンすべてからログが返され、サービスマップには `frontend-us`、`cart-eu`、`payment-jp` が一緒に表示され、あるリージョンで始まったトレースがエンドツーエンドで追跡されます。

続いて、2 つの形式でアラートを作成するよう指示しました。1 つは SQL ルールの一式(リージョンごとのエラー率、支払い失敗、レイテンシ、在庫切れの急増、および応答が途絶えたリージョンに対するデッドマンスイッチ)と、それを cron や CI で評価するための小さなスクリプトです。もう 1 つは、毎分実行されるネイティブな [ClickStack](https://clickhouse.com/docs/ja/clickstack/overview) アラートとしての同一ルールです。あえて 1 つのリージョンで他のリージョンよりもノイズが多くなるようにしているため、アラートは即座にトリガーされます。デモにおいてはまさにこれが必要な動作です。

## なぜ CLI が重要だったのか

プラットフォームがどのようなインターフェースを公開しているかによって、エージェントにどれだけの作業を任せられるかが決まります。Web コンソールは、人間が 1 回限りの作業を行うために作られています。エージェントはそれをループ処理することも、ボタンを読み取ることも、クリック操作をスクリプトに組み込むこともできません。タスクが 3 つのリージョンにまたがり、後日も再実行したいセットアップとなった瞬間、コンソールはボトルネックに変わります。

3 つの要素が `clickhousectl` をエージェントへ委ねやすいものにしました。まず、デフォルトで安全である点です。エージェントはブラウザログインから読み取りアクセスを取得しますが、何かを作成または削除するには人間が付与する API キーが必要です。次に、ノート PC から本番環境まで単一のツールであるため、エージェントがローカルとクラウドの作業間でコンテキストを切り替える必要がありません。そして、手動で実行したコマンドが、間に手を入れることなくそのまま午前 3 時にパイプラインで実行できるコマンドと同じであるため、自動化に自然と溶け込む点です。

これによって、エージェントはインフラをコードベースの単なる一部として扱い、予期せぬ挙動に悩まされることなくスクリプト化、レビュー、再実行を行えるようになりました。

## ターミナルから構築する

この取り組みは、分散アーキテクチャをユーザーにお見せする方法として始まりました。最終的には、最高のエージェント体験とは洗練された UI ではなく、クリーンな JSON と明確なエラーを返す適切に設計されたコマンドラインツールであることが多い、と再認識する結果となりました。

環境に最適な方法で [`clickhousectl`](https://clickhouse.com/docs/ja/concepts/features/interfaces/cli) をインストールしてください。

```
curl https://clickhouse.com/cli | sh
# or
npm install -g clickhousectl
# or
pip install clickhousectl
# or
pipx install clickhousectl
# or
uv tool install clickhousectl
# or
cargo install clickhousectl
```

次に API キーで認証を行い、エージェントにサービスの作成を依頼してみてください。ブラウザを一度も開くことなく、コマンドを実行し、エンドポイントを読み取り、接続する様子を確認できます。あとは本番さながらの環境を指定して、残りの作業をスクリプト化させるだけです。