aarch64 アーキテクチャに対応した Amazon Linux2 向け Zabbix Agent 6.0の RPM パッケージをビルドする

# はじめに
みなさん、Zabbixでサーバ監視していますか？
昨今様々なサーバー監視ツールが普及していますが、私は Zabbix を使ってサーバ監視をしていることが多いです。

今回は aarch64 アーキテクチャ向けの Amazon Linux2 向けの Zabbix Agent 6.0 の RPM パッケージをビルドするための方法を調べましたので共有します。

## 作成しようとした理由
そもそも、Amazon Linux2 に対応した Zabbix Agent は正式に利用できないといわれているものの、x86_64 アーキテクチャであれば、Red Hat Enterprise Linux(以下、RHEL) 7 の x86_64 アーキテクチャ版を利用することで動作させることができました。

昨今、aarch64 アーキテクチャに対応した OS AMI も公開されており、x86_64 向けの EC2 と比較すると利用料金も安価に済ませることができます。
しかし、aarch64 アーキテクチャ向けの RHEL 向け Zabbix Agent は Zabbix 開発元では提供されていません。

ただ、Zabbix は OSS であるため、ソースコードやパッケージ化に必要な情報はあるから、なければ作ればいいじゃないという精神で今回は aarch64 アーキテクチャに対応した Amazon Linux2 向けの RPM パッケージをビルドすることにしました。

## 注意・免責事項
以下で紹介する手順は Zabbix 開発元において公開されているソースコード (SRPM パッケージファイル) の内容を基に作成しています。
今回紹介した手順で生成した RPM パッケージを利用し、何らかの問題等が発生しても、筆者は責任を負うことはできません。
利用できるか否かは利用者の皆様にて充分なテストを行い、ご判断いただくようお願いします。
なお、この手順では Zabbix Agent2 のパッケージは生成されません。 [^zabbix-agent-2]

[^zabbix-agent-2]: ビルドしようとしてみたのですが、go 言語のランタイム環境などで問題が発生し、うまくビルドが行えませんでした。

# ビルド方法
## 用意するもの
* aarch64 アーキテクチャで動作する Amazon Linux2 EC2 環境
    * 筆者は　t4g.micro インスタンスの EC2 環境を用意しました
* インターネット接続環境
    * Zabbix の SRPM パッケージファイルを取得する際に必要になります

## 前準備
### RPM をビルドするために必要なパッケージを準備する
今回、RPM のビルドに [Mock](https://rpm-software-management.github.io/mock/) を利用します。
このツールは、systemd-nspawn というコンテナ環境を用いて、ビルド時にクリーンな環境を用意しパッケージビルドを行います。
Mock は `amazon-linux-extras` レポジトリで利用可能ですので、以下のようにインストールを行います。

```bash
$ sudo amazon-linux-extras install mock2
Installing mock
 :
Installed:
  mock.noarch 0:2.9-1.amzn2.0.1
 :
Complete!
  0  ansible2                 available    [ =2.4.6  =2.8  =stable ]
  1  httpd_modules            available    [ =1.0  =stable ]
  2  memcached1.5             available    \
        [ =1.5.1  =1.5.16  =1.5.17 ]
  4  postgresql9.6            available    [ =9.6.8  =stable ]
  5  postgresql10             available    [ =10  =stable ]
  7  R3.4                     available    [ =3.4.3  =stable ]
  8  rust1                    available    [ =stable ]
 14  libreoffice              available    [ =5.3.6.1  =stable ]
 16  docker=latest            enabled      \
        [ =18.06.1  =18.09.9  =stable ]
 17  mate-desktop1.x          available    [ =stable ]
 18  GraphicsMagick1.3        available    \
        [ =1.3.29  =1.3.32  =1.3.34  =stable ]
 19  tomcat8.5                available    \
        [ =8.5.32  =8.5.38  =8.5.40  =8.5.42  =8.5.50  =stable ]
 20  epel                     available    [ =7.11  =stable ]
 21  testing                  available    [ =1.0  =stable ]
 22  ecs                      available    [ =stable ]
 23  corretto8                available    \
        [ =1.8.0_202  =1.8.0_212  =1.8.0_222  =1.8.0_232  =1.8.0_242
          =stable ]
 24  golang1.11               available    \
        [ =1.11.3  =1.11.11  =1.11.13  =stable ]
 25  squid4                   available    [ =4  =stable ]
 27  java-openjdk11           available    [ =11  =stable ]
 28  lynis                    available    [ =stable ]
 29  kernel-ng                available    [ =stable ]
 30  BCC                      available    [ =0.x  =stable ]
 31  nginx1                   available    [ =stable ]
 32  ruby2.6                  available    [ =2.6  =stable ]
  _  mock                     available    [ =stable ]
 34  postgresql11             available    [ =11  =stable ]
 35  php7.4                   available    [ =stable ]
 36  python3.8                available    [ =stable ]
 37  lustre2.10               available    [ =stable ]
 38  haproxy2                 available    [ =stable ]
 39  collectd                 available    [ =stable ]
 40  R4                       available    [ =stable ]
  _  kernel-5.4               available    [ =stable ]
 42  selinux-ng               available    [ =stable ]
 43  php8.0                   available    [ =stable ]
 44  tomcat9                  available    [ =stable ]
 45  unbound1.13              available    [ =stable ]
 46  mariadb10.5              available    [ =stable ]
 47  kernel-5.10=latest       enabled      [ =stable ]
 48  redis6                   available    [ =stable ]
 49  ruby3.0                  available    [ =stable ]
 50  postgresql12             available    [ =stable ]
 51  postgresql13             available    [ =stable ]
 52  mock2=latest             enabled      [ =stable ]
 53  dnsmasq2.85              available    [ =stable ]
 54  aws-nitro-enclaves-cli   available    [ =stable ]
 55  livepatch                available    [ =stable ]
 56  kernel-5.15              available    [ =stable ]
 57  postgresql14             available    [ =stable ]

```

インストール後、上記のように `mock` パッケージがインストールされており、mock2 レポジトリが有効になっていることを確認します。

### 一般ユーザーで `mock` コマンドを利用可能にする
インストールが完了したら、`mock` コマンドを一般ユーザーで利用可能にします。

```bash
$ sudo usermod -aG mock $(whoami)
```

ログイン中のユーザーに対して、グループの更新を行っていますので、いったんログアウト/ログインを行います。
その後、groups コマンドで `mock` グループが追加されていることを確認します。

```bash
sh-4.2$ groups $(whoami)
ssm-user : ssm-user mock
```

※ 筆者は Systems Manager のセッションマネージャーを利用しているため、上記出力では `ssm-user` に `mock` グループが追加されています。

### Amazon Linux2 向けのビルド設定を修正する
`mock` パッケージに含まれている Amazon Linux2 向けのパッケージビルド設定では、Zabbix Agent をビルドするためのパッケージが不足しているため、下記のように `/etc/mock/templates/amazonlinux-2.tpl` ファイルを修正します。

```diff
diff -uNrp /etc/mock/templates/amazonlinux-2.tpl{.orig,}
--- /etc/mock/templates/amazonlinux-2.tpl.orig  2021-02-22 18:25:48.000000000 +0000
+++ /etc/mock/templates/amazonlinux-2.tpl       2022-06-20 06:27:08.082535598 +0000
@@ -1,4 +1,4 @@
-config_opts['chroot_setup_cmd'] = 'install @buildsys-build yum'
+config_opts['chroot_setup_cmd'] = 'install @buildsys-build @develop yum java-1.8.0-amazon-corretto-devel openldap-devel libcurl-devel'
 config_opts['dist'] = 'amzn2' # only useful for --resultdir variable subst
 config_opts['plugin_conf']['ccache_enable'] = False
 config_opts['package_manager'] = 'yum'
@@ -23,4 +23,14 @@ mirrorlist=http://amazonlinux.default.am
 gpgcheck=1
 gpgkey=file:///usr/share/distribution-gpg-keys/amazon-linux/RPM-GPG-KEY-amazon-linux-2
 enabled=1
+
+[amzn2extra-corretto8]
+enabled = 1
+name = Amazon Extras repo for corretto8
+mirrorlist = http://$amazonlinux.default.amazonaws.com/$releasever/extras/corretto8/latest/$basearch/mirror.list
+gpgcheck = 1
+gpgkey = file:///etc/pki/rpm-gpg/RPM-GPG-KEY-amazon-linux-2
+priority = 10
+skip_if_unavailable = 1
+report_instanceid = yes
 """
```

### Zabbix の SRPM を入手する

ビルドに必要な SRPM パッケージファイルは [Zabbix Official Repository](http://repo.zabbix.com/) から入手することができます。
wget などでダウンロードします。
この記事を書いている時は [zabbix-6.0.5-1](http://repo.zabbix.com/zabbix/6.0/rhel/7/SRPMS/zabbix-6.0.5-1.el7.src.rpm) が最新であるため、このパッケージをダウンロードして利用します。

```bash
$ wget http://repo.zabbix.com/zabbix/6.0/rhel/7/SRPMS/zabbix-6.0.5-1.el7.src.rpm
--2022-xx-xx xx:xx:xx--  http://repo.zabbix.com/zabbix/6.0/rhel/7/SRPMS/zabbix-6.0.5-1.el7.src.rpm
Resolving repo.zabbix.com (repo.zabbix.com)... 178.128.6.101, 2604:a880:2:d0::2062:d001
Connecting to repo.zabbix.com (repo.zabbix.com)|178.128.6.101|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 33325118 (32M) [application/x-redhat-package-manager]
Saving to: ‘zabbix-6.0.5-1.el7.src.rpm’

100%[========================================================================================================================================================================>] 33,325,118  80.7MB/s   in 0.4s

2022-xx-xx xx:xx:xx (80.7 MB/s) - ‘zabbix-6.0.5-1.el7.src.rpm’ saved [33325118/33325118]
```

## ビルドする
ビルド時は以下のコマンドを実行するだけです。あとは、パッケージビルド用の環境が構築され、ビルドが始まります。
新しいバージョンがリリースされているのであれば、`--rebuild` オプションの引数を適宜変更すれば OK です。
ビルド中、環境構築時やパッケージビルド中のログが出力されていくので眺めていきます。

```bash
$ mock -r amazonlinux-2-aarch64 --rebuild zabbix-6.0.5-1.el7.src.rpm -D "build_with_mysql 0" -D "build_with_pgsql 0" -D "build_with_sqlite 0"
INFO: mock.py version 2.9 starting (python version = 3.7.10, NVR = mock-2.9-1.amzn2.0.1)...
Start(bootstrap): init plugins
INFO: selinux disabled
Finish(bootstrap): init plugins
Start: init plugins
INFO: selinux disabled
Finish: init plugins
INFO: Signal handler active
Start: run
INFO: Start(zabbix-6.0.5-1.el7.src.rpm)  Config(amzn-2-aarch64)
 :
Finish: rpmbuild zabbix-6.0.5-1.el7.src.rpm
Finish: build phase for zabbix-6.0.5-1.el7.src.rpm
INFO: Done(zabbix-6.0.5-1.el7.src.rpm) Config(amazonlinux-2-aarch64) 1 minutes 15 seconds
INFO: Results and/or logs in: /var/lib/mock/amzn-2-aarch64/result
Finish: run
```

できました！1分少々ほどでビルドができました。
ビルドが完了すると、`/var/lib/mock/amzn-2-aarch64/result` 配下にパッケージやログが生成されているようなので、確認してみます。

```bash
$ ls -1 /var/lib/mock/amzn-2-aarch64/result/
build.log
hw_info.log
installed_pkgs.log
root.log
state.log
zabbix-6.0.5-1.amzn2.src.rpm
zabbix-agent-6.0.5-1.amzn2.aarch64.rpm
zabbix-debuginfo-6.0.5-1.amzn2.aarch64.rpm
zabbix-get-6.0.5-1.amzn2.aarch64.rpm
zabbix-java-gateway-6.0.5-1.amzn2.aarch64.rpm
zabbix-selinux-policy-6.0.5-1.amzn2.aarch64.rpm
zabbix-sender-6.0.5-1.amzn2.aarch64.rpm
```

生成されたパッケージやログを適宜保全し、生成されたパッケージ `zabbix-agent-6.0.5-1.amzn2.aarch64.rpm` をインストールすれば OK です。[^sign-to-rpm]
なお、`zabbix-agent` パッケージに依存するパッケージは特にありません。そのため、生成した `zabbix-agent` パッケージを目的のサーバへ転送し、`rpm` もしくは `yum` コマンドを用いてインストールすることができます。

[^sign-to-rpm]: 今回は個人利用のみで配布はしないため、GPG キーによるサイン処理などは省略しています。

# おわりに
今回は Zabbix 開発元が提供している SRPM を元に、aarch64 アーキテクチャに対応した Amazon Linux2 向け Zabbix Agent 6.0 の RPM パッケージをビルドしてみました。
必要なパッケージをインストール、設定を行い、SRPM ファイルを準備すればパッケージビルドは容易に行えます。
[注意・免責事項](#注意免責事項) でも述べたとおり、この手順で生成されたパッケージを利用する場合は充分なテストを実施したうえで、利用するかどうかご判断ください。