この記事について
Instana Agentをインターネットに直接接続させたくないホストに導入し、Instana SaaSとのバックエンド通信だけをフォワードプロキシ経由にする構成を、ゼロから実機検証した記録です。
Squidとエージェント側のproxy.*設定についてはIBM公式のInstana Maturity Modelサイトに分かりやすくまとまっているので、そちらもぜひ参照してください。この記事はその内容と重ならないよう、インターネットに出られないホストへ、Agent自体をどう導入するかという、一歩手前の工程にフォーカスしています。実際にRHEL9で検証していく中で、RHELのサブスクリプション用リポジトリ(RHUI)との競合や、公式のワンライナー導入スクリプトが厳格なネットワーク制限とは相性が悪いことなど、いくつかの実践的なハマりどころに遭遇したので、それも合わせて共有します。
構成はAWSで検証していますが、内容自体はオンプレミス環境でもそのまま使えるよう、クラウド固有の要素(VPC、セキュリティグループ等)は説明から切り離しています。
前提とする構成
- 監視対象ホストは直接インターネットに出られない
- プロキシサーバーは監視対象ホストからの接続だけを受け付け、宛先はInstana SaaSのエンドポイントだけに絞る
- Instana Agentは静的(static)エージェントを使う(理由は後述)
なぜ静的(static)エージェントなのか
Instana Agentには動的(dynamic)エージェントと静的(static)エージェントの2種類があります。
IBM公式ドキュメント(Instana agent requirements)によると、動的エージェントはセンサーやエージェント自体の自動更新のために、バックエンド通信(ingress-*.instana.io)に加えてhttps://artifact-public.instana.io(443番)への継続的な外部アクセスが必要です。
一方、静的エージェントは全コンポーネントを内蔵していて自動更新の仕組みを持たないため、この通信が不要です。
「Instana SaaSとの通信だけに絞りたい」という今回の要件には、静的エージェント一択です。プロキシのACLをingress-*.instana.ioだけに絞る場合、動的エージェントを選ぶとAgentの自動更新が失敗し続けることになります。
Part 1: プロキシサーバーの設定(Squid)
多くのLinuxディストリビューションでSquidは標準リポジトリに含まれています(RHEL9ではAppStreamリポジトリに含まれており、追加のリポジトリ登録は不要でした)。
sudo dnf install -y squid
既存の設定ファイルをバックアップしてから、新しい設定を書きます。
sudo cp -p /etc/squid/squid.conf /etc/squid/squid.conf.bak.$(date +%Y%m%d)
sudo bash -c "cat > /etc/squid/squid.conf << 'EOF'
# 待受ポート
http_port 3128
# 監視対象ホストのサブネットからのみ接続を許可
acl monitored_net src 10.0.2.0/24
# Instana SaaS宛のみ許可(エージェント⇔バックエンド通信専用プロキシにする)
acl instana_dst dstdomain ingress-orange-saas.instana.io
# CONNECTメソッド(TLSトンネル)を許可するポート
acl SSL_ports port 443
acl Safe_ports port 443
acl CONNECT method CONNECT
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
# 許可ルール: 監視対象ホストから、かつInstana SaaS宛のみ
http_access allow monitored_net instana_dst
http_access deny all
# キャッシュ無効化(可観測性データを保持しない)
cache deny all
access_log /var/log/squid/access.log squid
EOF"
文法チェックをしてから起動します。
sudo squid -k parse
sudo systemctl enable --now squid
bashのヒストリ展開機能により、!Safe_portsのような!を含む設定をヒアドキュメントで書き込もうとするとevent not foundエラーになることがあります。作業セッションの最初にset +Hを実行してヒストリ展開を無効化しておくと安全です。
Part 2: Instana Agentの導入(ローカルダウンロード方式)
ここが本題です。監視対象ホストが外部に一切出られない前提なので、RPMパッケージリポジトリ経由のインストールは使わず、RPMファイルを事前に入手してホストへ転送し、ローカルインストールする方式を取ります。
2-1. Agent RPMとGPG鍵を事前ダウンロード
Instana UIの「エージェントとコレクター」→「エージェントのインストール」→「Linux - Packages (DEB, RPM)」から、Packaging: Static、Mode: RPM、対象ホストのCPUアーキテクチャ(uname -mで事前確認)に合わせてダウンロードします。
GPG鍵もインターネットにアクセスできる端末から取得しておきます。
curl -o Instana.gpg https://packages.instana.io/Instana.gpg
2-2. 監視対象ホストへ転送
scpやファイル共有などで、RPMとGPG鍵を監視対象ホストへ転送します(プロキシサーバーを踏み台にする構成の場合はProxyJumpを使うと便利です)。
2-3. ローカルインストール
sudo rpm --import Instana.gpg
sudo dnf install -y instana-agent-static*.rpm --disablerepo="*"
ここが最初のハマりどころです。 --disablerepo="*"を付けずに実行すると、dnfはローカルRPMのインストールであっても有効な全リポジトリのメタデータ更新を試みます。RHEL9のRHUIリポジトリ(サブスクリプション経由のパッケージ取得先)への通信がプロキシのACLで許可されていないため、コマンドが進捗表示のまま固まったように見えます。ローカルファイルをインストールするだけなら、全リポジトリを無効化して進めるのが確実です。
2-4. Backend.cfgの設定
RPMインストール時に、com.instana.agent.main.sender.Backend.cfgがテンプレートから自動生成されますが、中身は環境変数プレースホルダー(${env:INSTANA_HOST}等)を含む形式になっています。
sudo cat /opt/instana/agent/etc/instana/com.instana.agent.main.sender.Backend.cfg
host=${env:INSTANA_HOST}
port=${env:INSTANA_PORT}
...
## Proxy Server
# proxy.host=
# proxy.port=
# proxy.type=
# proxy.dns=true
...
key=${env:INSTANA_KEY}
ファイル全体を上書きするより、公式テンプレートの構造(コメント含む)を保つために、該当行だけをsedで書き換えるのがおすすめです。
sudo cp -p /opt/instana/agent/etc/instana/com.instana.agent.main.sender.Backend.cfg /opt/instana/agent/etc/instana/com.instana.agent.main.sender.Backend.cfg.bak.$(date +%Y%m%d)
sudo sed -i -e 's|^host=\${env:INSTANA_HOST}|host=ingress-orange-saas.instana.io|' -e 's|^port=\${env:INSTANA_PORT}|port=443|' -e 's|^key=\${env:INSTANA_KEY}|key=<Agent Key>|' -e 's|^# proxy.host=|proxy.host=<プロキシのIP>|' -e 's|^# proxy.port=|proxy.port=3128|' -e 's|^# proxy.type=|proxy.type=http|' -e 's|^# proxy.dns=true|proxy.dns=true|' /opt/instana/agent/etc/instana/com.instana.agent.main.sender.Backend.cfg
複数行に分けたsed -i \ + 改行継続のコマンドをターミナルに貼り付けると、環境によっては改行やインデントが崩れて-eが個別コマンドとして誤解釈され、-bash: -e: command not foundのようなエラーが出ることがあります。1行にまとめたコマンドの方が事故が起きにくいです。
Agent Keyは特にコピーミスに注意してください。Instana UI上でマスク表示のままコピーすると、途中までしか取得できないことがあります。「目のアイコン」でフル表示させてからコピーし、以下で文字数を確認すると安心です。
sudo grep '^key=' /opt/instana/agent/etc/instana/com.instana.agent.main.sender.Backend.cfg | cut -d= -f2 | wc -c
設定できたら起動します。
sudo systemctl enable --now instana-agent
sudo tail -f /opt/instana/agent/data/log/agent.log
以下のようなログが、403を伴わずに継続して出ていれば成功です。
Connecting using http proxy <proxy_ip>:3128
HANDSHAKEN: protocol:TLSv1.3 cipher suite:TLS_AES_128_GCM_SHA256
Connected using HTTP/2 to ingress-orange-saas.instana.io:443
403 Forbidden ... agent key is most likely wrong or not valid anymore.が出る場合は、ほぼ間違いなくAgent Keyのコピーミスです。
Part 3: 動作確認
プロキシなしでは届かないこと(陰性確認)と、プロキシ経由なら届くこと(陽性確認)の両方を確認しておくと、意図通りの構成になっているか確信を持てます。
# 陰性確認: プロキシを指定しない場合はタイムアウトするはず
curl -v --max-time 5 https://ingress-orange-saas.instana.io
# 陽性確認: プロキシ経由なら届くはず
curl -v --max-time 10 -x http://<プロキシのIP>:3128 https://ingress-orange-saas.instana.io
# Instana SaaS以外は拒否されることの確認(ACLの絞り込みが機能しているか)
curl -v --max-time 10 -x http://<プロキシのIP>:3128 https://www.google.com
3つ目のコマンドで403 Forbiddenが返れば、プロキシのACLが意図通り「Instana SaaS宛のみ」に絞られていることが確認できます。
プロキシサーバー側のアクセスログでも、実際に通過したリクエストを確認できます。
sudo tail -f /var/log/squid/access.log
CONNECT ingress-orange-saas.instana.io:443 ... TCP_TUNNEL/200のようなログが記録されていれば、経路は正しく確立しています。
おまけ: ワンライナー導入スクリプトを使う場合の注意点
Instanaにはsetup_agent.shというワンライナー導入スクリプトが公式に提供されており、多くの環境では手軽で便利な方法です。ただ、今回のようにネットワークを絞り込んだ環境で使う場合は、いくつか追加の考慮が必要になることが分かりました。
curl -o setup_agent.sh https://setup.instana.io/agent && chmod 700 ./setup_agent.sh && sudo -E ./setup_agent.sh -a <Agent Key> -t static -e ingress-orange-saas.instana.io:443 -s
このスクリプトは内部でdnfのリポジトリ経由インストールを行うため、Part 2で触れた「dnfが有効な全リポジトリ(RHUI含む)のメタデータ更新を試みる」問題がそのまま起きます。回避するには--disablerepoをスクリプト内部のdnf呼び出しに割り込ませる必要がありますが、それは公式スクリプトの外側からは難しく、結局「プロキシのACLをpackages.instana.ioやsetup.instana.ioにも広げる」か「RHUIリポジトリもプロキシ許可する」といった、当初の「Instana SaaSとの通信だけに絞りたい」という要件を緩める選択を迫られます。
「バックエンド通信だけをプロキシ経由にしたい、それ以外は一切外に出したくない」という要件がある場合は、Part 2のローカルダウンロード方式の方が、ネットワークの絞り込みをそのまま維持しやすいと感じました。
まとめ
- Instana SaaSとの通信だけに絞ったプロキシ構成を作るなら、静的(static)エージェント一択
- Agent自体の導入も、パッケージリポジトリ経由ではなくローカルダウンロード+転送+
--disablerepo="*"でのローカルインストールにすると、ネットワークの絞り込みを崩さずに済む -
dnf installのハング、ヒストリ展開の!エラー、sed貼り付け崩れ、Agent Keyのコピーミスなど、実機ならではのハマりどころは事前に知っておくと詰まらずに進められる
同じような要件で構成を組む方の参考になれば幸いです。