[Instana] K8S/OCPクラスターに静的エージェントを入れてみた

# はじめに
Instana AgentをKubernetes/OpenShiftクラスタにインストールする場合、[ドキュメント][1]に導入方法が記載されていますが、いずれもデフォルトでは動的エージェントが導入されます。K8S/OCPの環境においては、環境自体が動的に更新されていく方が当たり前なのですが、エアギャップの環境や塩漬けの環境など理由があって静的エージェントが望ましい場合を想定して、実際に設定して試してみました。  

本手順は以下の環境で実施しています。
- クライアントPC: macOS
- イメージ準備サーバ: RHEL 7.9 (x86_64)
- Instana Backend: Instana SaaS Build 253
- Instana Agent: Openshift 4.10 (x86_64)
- プライベートイメージレジストリ: IBM Cloud Container Registry

[1]:https://www.ibm.com/docs/ja/instana-observability/current?topic=agents-installing-host-agent-kubernetes

# 本手順の対象・流れ
インターネット接続環境でコンテナイメージをダウンロードし、監視対象クラスタからアクセス可能なプライベートイメージレジストリに格納する手順となります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319123/6f9fbd0d-3127-1a66-bb04-4e10b0e804d3.png)

:::note info
イメージ準備サーバと静的エージェント導入先クラスタのWorkerノードが同じCPUアーキテクチャである必要がありますが、それが満たせれば作業端末(PC)での実施でも問題ないと思います。
:::

# 1. インストール用YAMLテンプレートのダウンロード

- Instana UIのエージェントのデプロイ画面からKubernetesまたはOpenShiftを選択
- テクノロジーはYAMLを選択
- 必要パラメータ（クラスター名、エージェント・ゾーン）を入力してダウンロード。
 
画面上は`instana-agent.yaml`となっていますが、ダウンロードファイルは`configuration.yaml`でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319123/c58016c8-d655-ce1e-e364-7518659c048c.png)


# 2. YAMLファイル内のimage定義を確認

ダウンロードしたYAMLファイル内で以下の２つのイメージが定義されていることを確認
- instana-agent: `icr.io/instana/agent:latest`
- leader-elector: `icr.io/instana/leader-elector:0.5.18`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319123/cf43fb24-b883-cfda-60a6-d5aaf1c100c7.png)

# 3. 静的エージェントのダウンロード
インターネット接続可能な端末（イメージ準備サーバ）にて静的エージェントのコンテナイメージをダウンロードします。
– Dockerサービスが起動している必要があります
– Instanaのエージェントキーを使用して`containers.instana.io`にログインします
– `docker pull`コマンドで必要なイメージをダウンロードします

:::note warn
Agent導入対象クラスタのWorkerノードと同じCPUアーキテクチャの端末で作業を実施してください。

Instana Agentのコンテナはマルチアーキテクチャに対応しており、例えば、Apple SiliconのMac PCで作業を実施すると、ダウンロードした コンテナイメージがARMアーキテクチャになります。（私はそれでハマりました。。）
:::


## 3-1. instana-agentコンテナ
静的エージェントは`containers.instana.io/instana/release/agent/static`からダウンロードします。最新の静的エージェントをダウンロードする場合は`latest`タグを指定します。`latest`以外のタグを指定することもできます。(後述)


```bash
 $ docker login containers.instana.io -u _ -p "<agent_key>"
WARNING! Using --password via the CLI is insecure. Use --password-stdin.
Login Succeeded
 $ docker pull containers.instana.io/instana/release/agent/static:latest
latest: Pulling from instana/release/agent/static
09621ddd6d8d: Pull complete 
c8ef4fa5342a: Pull complete 
c5eaf0b06fed: Pull complete 
9ea52ce0afa6: Pull complete 
4865285f5c29: Pull complete 
4f4fb700ef54: Pull complete 
fd6ea36fca97: Pull complete 
874a3f9c4188: Pull complete 
1a16a4f220f5: Pull complete 
f46f2702595b: Pull complete 
0749c9ead952: Pull complete 
d023daa171a1: Pull complete 
62f4dd6feb0b: Pull complete 
9a43ff3caa8a: Pull complete 
904b3e3a3161: Pull complete 
2c26a5e7d5c4: Pull complete 
13bedfa675ee: Pull complete 
Digest: sha256:cd2af32478d6769e7fff73b1cfc273dba42e35064cfdfb27bdc082d8a97dea12
Status: Downloaded newer image for containers.instana.io/instana/release/agent/static:latest
containers.instana.io/instana/release/agent/static:latest

What's Next?
  View summary of image vulnerabilities and recommendations → docker scout quickview containers.instana.io/instana/release/agent/static:latest
 $ 

```

`latest`タグの中身はどんどん更新されていきますので、バージョンを明示したい場合は`lastest`以外のタグを使用します。使用可能なタグはAPIで取得可能です。


```bash
$ curl https://icr.io/v2/instana/agent/tags/list | jq {
  "name": "instana/agent",
  "tags": [
     (省略)
    "1.252.0-j9",
    "1.252.0",
    "1.252.33-j9",
    "1.252.33",
    "1.252.41-j9",
    "1.252.41",
    "latest-amd64-dynamic-j9",
    "latest-amd64-dynamic",
    "latest-arm64-dynamic-j9",
    "latest-arm64-dynamic",
    "latest-j9",
    "latest-ppc64le-dynamic",
    "latest-s390x-dynamic",
    "latest"
] }
```



## 3-2. leader-electorコンテナ
leader-electorコンテナのタグは`2.`のYAMLで確認したものに合わせます

```bash
 $ docker pull containers.instana.io/instana/release/leader-elector:0.5.18
0.5.18: Pulling from instana/release/leader-elector
10f855b03c8a: Pull complete 
fe5ca62666f0: Pull complete 
fff4e558ad3a: Pull complete 
fcb6f6d2c998: Pull complete 
e8c73c638ae9: Pull complete 
1e3d9b7d1452: Pull complete 
4aa0ea1413d3: Pull complete 
7c881f9ab25e: Pull complete 
5627a970d25e: Pull complete 
738ab95077bc: Pull complete 
80ec95682aee: Pull complete 
f51c8fa85103: Pull complete 
bb225bf7de1d: Pull complete 
afd3e8980db3: Pull complete 
58b436490d5a: Pull complete 
Digest: sha256:8f971da85a4daea19ef7f73597669b0509e708276e3ca6f575ff02df749cf651
Status: Downloaded newer image for containers.instana.io/instana/release/leader-elector:0.5.18
containers.instana.io/instana/release/leader-elector:0.5.18

What's Next?
  View summary of image vulnerabilities and recommendations → docker scout quickview containers.instana.io/instana/release/leader-elector:0.5.18
 $ 
```

## 3-3. ダウンロードしたイメージの確認
こんな感じです。大体1GB弱です。
複数バージョン(タグ)をダウンロードすると、それだけ容量が必要となります。
```bash
 % docker images
REPOSITORY                                             TAG       IMAGE ID       CREATED        SIZE
containers.instana.io/instana/release/agent/static     latest    60f0c9514436   7 days ago     934MB
containers.instana.io/instana/release/leader-elector   0.5.18    bcbf2af90bfd   3 months ago   45.8MB
containers.instana.io/instana/release/agent/static     1.245.7   f8a7cb4a6389   3 months ago   888MB
```

# 4. ダウンロードしたイメージの転送
コンテナイメージをダウンロードした端末からプライベートイメージレジストリに直接アクセスできない場合は、別の作業端末(踏み台サーバ)にコンテナイメージを転送する必要があります。
- 転送元にて、イメージを転送するためにtarファイルで出力します – イメージを転送します。
- 転送先にて、tarファイルからイメージを読み込みます
同様に、dockerサービスが起動している必要があります(podmanでも可)

```bash
#転送元にて実行
$ docker save containers.instana.io/instana/release/agent/static:latest > static_agent_latest.tar 
$ docker save containers.instana.io/instana/release/leader-elector:0.5.18 > leader_elector.tar
$ scp static_agent*.tar leader_elector.tar "root@転送先サーバ":/tmp/
```

```bash
#転送先にて実行
$ docker load < static_agent_latest.tar
$ docker load < leader_elector.tar
```

# 5. プライベートイメージレジストリへのアップロード
プライベートイメージレジストリにアクセス可能な端末（踏み台サーバ）にて、静的エージェントのコンテナイメージをプッシュします。
- プライベートイメージレジストリにログインします (例ではIBM Cloud Container Registryを使用) 
- `docker tag`コマンドでプライベートイメージレジストリでの名前やタグを設定します
- `docker push`コマンドでプライベートイメージレジストリにアップロードします

```bash
$ ibmcloud login --sso –g "<Resource_Group>" 
$ ibmcloud cr login

$ docker tag containers.instana.io/instana/release/agent/static:latest jp.icr.io/aiops/instana-static:latest
$ docker tag containers.instana.io/instana/release/leader-elector:0.5.18 jp.icr.io/aiops/instana-leader-elector:0.5.18

$ docker push jp.icr.io/aiops/instana-static:latest
$ docker push jp.icr.io/aiops/instana-leader-elector:0.5.18

$ ibmcloud cr image-list | grep instana
jp.icr.io/aiops/instana-leader-elector                             0.5.18                           f2c0540fd5bc   aiops                 3 months ago    17 MB    -
jp.icr.io/aiops/instana-static                                     latest                           4ff2c13f8d30   aiops                 1 week ago      432 MB   -
 % 
```

# 6. YAMLファイルを書き換え
`2.`のYAMLで確認したものをプライベートイメージレジストリのものに書き換えます。
ここでは、新しいファイルを`static-agent.yaml`とします。

## 6.1 イメージ定義
Instana-agent DaemonSetにて2つのイメージ定義をプライベートイメージレジストリのものに書き換えます (以下はIBM Cloud Container Registry使用時の例)
- instana-agent: `jp.icr.io/aiops/instana-static:latest` or バージョン指定タグ
- leader-elector: `jp.icr.io/aiops/instana-leader-elector:0.5.18`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319123/56055fb0-07f3-e5f8-dc08-50db31e62c5a.png)

## 6.2 イメージプルシークレット
サービスアカウントにプライベートイメージレジストリの`ImagePullSecret`を設定します
 (以下はIBM Cloud Container Registry使用時の例)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319123/97f95cc6-0894-128e-3967-fb7aaed8148b.png)

# 7. 対象クラスタへ静的エージェントのインストール
クラスタにログイン可能な端末にてエージェントのインストールを行います。
- 端末にて対象クラスタにログインします
- OpenShiftの場合は、SCC(Security Context Constrains)の設定を行います
- `6.`で作成したYAMLファイルを適用し、エージェントをインストールします
- サービスアカウントがプライベートレジストリからイメージをプルできるように構成する必要があります。IBM Cloudのクラスタの場合は、default名前空間にあるシークレットをコピーし、 さらに、サービスアカウントにシークレットを紐づけます。

```bash
$ oc new-project instana-agent  
$ oc adm policy add-scc-to-user privileged -z instana-agent -n instana-agent     
clusterrole.rbac.authorization.k8s.io/system:openshift:scc:privileged added: "instana-agent"

$ oc get secret all-icr-io -n default -o yaml | sed 's/default/instana-agent/g' | oc create -n instana-agent -f -
secret/all-icr-io created

$ oc apply -f static-agent.yaml                                                  
Warning: resource namespaces/instana-agent is missing the kubectl.kubernetes.io/last-applied-configuration annotation which is required by oc apply. oc apply should only be used on resources created declaratively by either oc create --save-config or oc apply. The missing annotation will be patched automatically.
namespace/instana-agent configured
serviceaccount/instana-agent created
service/instana-agent created
service/instana-agent-headless created
secret/instana-agent created
configmap/instana-agent created
daemonset.apps/instana-agent created
clusterrole.rbac.authorization.k8s.io/instana-agent created
clusterrolebinding.rbac.authorization.k8s.io/instana-agent created
$
```

# 8. インストールの確認

## 8.1 CLIでの確認
イメージのプルが成功し、各WorkerノードにDaemonSet Podが作成されていることを確認します。また、PodのSTATUSがRunningになっていることを確認します

```bash
$ oc get events -n instana-agent                                                    
LAST SEEN   TYPE     REASON             OBJECT                    MESSAGE
8s          Normal   Scheduled          pod/instana-agent-brvrz   Successfully assigned instana-agent/instana-agent-brvrz to 192.168.1.6
8s          Normal   Pulling            pod/instana-agent-brvrz   Pulling image "jp.icr.io/aiops/instana-static:latest"
8s          Normal   Scheduled          pod/instana-agent-drkpd   Successfully assigned instana-agent/instana-agent-drkpd to 192.168.2.42
8s          Normal   Pulling            pod/instana-agent-drkpd   Pulling image "jp.icr.io/aiops/instana-static:latest"
8s          Normal   Scheduled          pod/instana-agent-j4clp   Successfully assigned instana-agent/instana-agent-j4clp to 192.168.3.27
8s          Normal   Pulling            pod/instana-agent-j4clp   Pulling image "jp.icr.io/aiops/instana-static:latest"
8s          Normal   Scheduled          pod/instana-agent-jqrvb   Successfully assigned instana-agent/instana-agent-jqrvb to 192.168.2.39
8s          Normal   Pulling            pod/instana-agent-jqrvb   Pulling image "jp.icr.io/aiops/instana-static:latest"
8s          Normal   Scheduled          pod/instana-agent-mjrbd   Successfully assigned instana-agent/instana-agent-mjrbd to 192.168.2.45
8s          Normal   Pulling            pod/instana-agent-mjrbd   Pulling image "jp.icr.io/aiops/instana-static:latest"
8s          Normal   Scheduled          pod/instana-agent-n9qkx   Successfully assigned instana-agent/instana-agent-n9qkx to 192.168.1.12
8s          Normal   Pulling            pod/instana-agent-n9qkx   Pulling image "jp.icr.io/aiops/instana-static:latest"
8s          Normal   Scheduled          pod/instana-agent-pjdrb   Successfully assigned instana-agent/instana-agent-pjdrb to 192.168.3.26
8s          Normal   Pulling            pod/instana-agent-pjdrb   Pulling image "jp.icr.io/aiops/instana-static:latest"
9s          Normal   SuccessfulCreate   daemonset/instana-agent   Created pod: instana-agent-mjrbd
9s          Normal   SuccessfulCreate   daemonset/instana-agent   Created pod: instana-agent-pjdrb
9s          Normal   SuccessfulCreate   daemonset/instana-agent   Created pod: instana-agent-j4clp
9s          Normal   SuccessfulCreate   daemonset/instana-agent   Created pod: instana-agent-drkpd
9s          Normal   SuccessfulCreate   daemonset/instana-agent   Created pod: instana-agent-jqrvb
9s          Normal   SuccessfulCreate   daemonset/instana-agent   Created pod: instana-agent-brvrz
9s          Normal   SuccessfulCreate   daemonset/instana-agent   Created pod: instana-agent-n9qkx
 % 
```

```bash
% oc get all
NAME                      READY   STATUS    RESTARTS   AGE
pod/instana-agent-6kcmx   2/2     Running   0          7m19s
pod/instana-agent-6xw5x   2/2     Running   0          7m19s
pod/instana-agent-czhxf   2/2     Running   0          7m19s
pod/instana-agent-ksl82   2/2     Running   0          7m19s
pod/instana-agent-shhks   2/2     Running   0          7m19s
pod/instana-agent-smd9p   2/2     Running   0          7m19s
pod/instana-agent-wwqj4   2/2     Running   0          7m19s

NAME                             TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)               AGE
service/instana-agent            ClusterIP   172.21.223.3   <none>        42699/TCP             7m20s
service/instana-agent-headless   ClusterIP   None           <none>        42699/TCP,42666/TCP   7m20s

NAME                           DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
daemonset.apps/instana-agent   7         7         7       7            7           <none>          7m19s
```


## 8.2 Instana UIでの確認
クラスタの情報が取得できていることを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319123/4459743b-eb2c-c512-7a5b-88527370ae47.png)

エージェントの詳細情報を確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319123/2ec8d32a-d1b0-37a9-94b1-d3ab9bed52a9.png)

# おわりに
K8S/OCPクラスターに静的エージェントを入れてみた内容をまとめました。
少しでも参考になれば幸いです。