Zabbix 6.0 Kubernetes監視機能を使用してRed Hat OpenShiftを監視してみる

# はじめに
Zabbix 6.0 にて[Kubernetes監視機能](https://www.zabbix.com/jp/whats_new_6_0#kubernetes_monitoring)が追加され、Kubernetesインフラストラクチャを監視できるようになりました。
この記事では、Kubernetes監視機能をOpenShiftに対して適用した際の内容をまとめています。

#### Zabbix6.0 Kubernetes監視機能
Zabbix Helm Chartを使用してKubernetesクラスタにZabbixプロキシとZabbixエージェントをインストールし、KubernetesノードやPodに関する情報を収集します。
提供される以下のKubernetes監視用テンプレートを使用し、KubernetesノードとPodの自動検出と監視が行えます。
 - Kubernetes nodes by HTTP
 - Kubernetes cluster state by HTTP
 - Kubernetes API server by HTTP
 - Kubernetes Controller manager by HTTP
 - Kubernetes Scheduler by HTTP
 - Kubernetes kubelet by HTTP

### Prerequisites
Kuberbetes監視の前提条件は、以下の通りです。
 - Kubernetes cluster 1.18+
 - Helm 3.0+
 - Zabbix server 6.0+
 - kube-state-metrics 2.13.2+

# 今回使用した環境
・Zabbix Server6.0.1（以前[こちら](https://qiita.com/mi_h/items/73579506f13f296dbc12)で記事にした環境です）
・OpenShift（Red Hat OpenShift on IBM Cloud）：v4.8.26_1542

# 設定手順
#### 1. OpenShiftクラスターへのZabbix Helm Chartのインストール
##### 1.1 Helm 3 をインストール
前提となっているHelmが入っていない場合は、事前にインストールする必要があります。
```
# curl -fsSL -o get_helm.sh  https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
# chmod 700 get_helm.sh
# ./get_helm.sh
Downloading https://get.helm.sh/helm-v3.8.0-linux-amd64.tar.gz
Verifying checksum... Done.
Preparing to install helm into /usr/local/bin
helm installed into /usr/local/bin/helm
```
##### 1.2 リポジトリをクローン
```
# git clone https://git.zabbix.com/scm/zt/kubernetes-helm.git
Cloning into 'kubernetes-helm'...
remote: Enumerating objects: 125, done.
remote: Counting objects: 100% (125/125), done.
remote: Compressing objects: 100% (124/124), done.
remote: Total 125 (delta 70), reused 0 (delta 0)
Receiving objects: 100% (125/125), 33.44 KiB | 8.36 MiB/s, done.
Resolving deltas: 100% (70/70), done.
```
2022/08/21現在、branch/6.2が提供されています。必要に応じて最新のBranchを利用します。
本記事の環境では、branch/6.0を使用しています。

##### 1.3 Chartのデフォルト設定値をzabbix_values.yamlにエクスポート

```
# cd kubernetes-helm
# git checkout release/6.0
# helm show values . > ./zabbix_values.yaml
```

##### 1.4 Valueの編集
OpenShiftにデプロイする場合のみ、valueからsecurityContext設定を削除する必要があります。
※OpenShiftはvanillaのKubernetesに比べてuid, gidの扱いが厳格になっており、デフォルトで65535より小さいuid, gidの使用が禁止されている為
参考）[A Guide to OpenShift and UIDs](https://cloud.redhat.com/blog/a-guide-to-openshift-and-uids)

```
# vi zabbix_values.yaml
(以下を削除）
      securityContext:
        runAsUser: 65534
        runAsGroup: 65534
        fsGroup: 65534
```
##### 1.5 Zabbix用Namespaceの作成
今回は、zabbix-monitoringというNamespaceにしましたが、任意に設定可能です。
```
# oc new-project zabbix-monitoring
```
##### 1.6 Kubernetes Helmをインストール
```
# helm install zabbix . --dependency-update -f ./zabbix_values.yaml -n zabbix-monitoring

Getting updates for unmanaged Helm repositories...
...Successfully got an update from the "https://prometheus-community.github.io/helm-charts" chart repository
Saving 1 charts
Downloading kube-state-metrics from repo https://prometheus-community.github.io/helm-charts
Deleting outdated charts
W0316 19:54:07.223940  485684 warnings.go:70] policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
W0316 19:54:10.166080  485684 warnings.go:70] policy/v1beta1 PodSecurityPolicy is deprecated in v1.21+, unavailable in v1.25+
NAME: zabbix
LAST DEPLOYED: Wed Mar 16 19:54:06 2022
NAMESPACE: zabbix-monitoring
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
Thank you for installing zabbix-helm-chrt.


Your release is named zabbix.
Zabbix agent installed:  "zabbix/zabbix-agent2:alpine-6.0.2"
Zabbix proxy installed:  "zabbix/zabbix-proxy-sqlite3:alpine-6.0.2"


Annotations:
app.kubernetes.io/name: zabbix-zabbix-helm-chrt
helm.sh/chart: zabbix-helm-chrt-0.0.1
app.kubernetes.io/version: "trunk"
app.kubernetes.io/managed-by: Helm




Service account created:
    zabbix-service-account


To learn more about the release, try:


  $ helm status zabbix
  $ helm get all zabbix
```
以上で、インストールは完了です。


#### 2.デプロイされたリソースの確認
#### Pod
zabbix-agentがDaemonSetとしてデプロイされ（クラスターはWorkerNode3ノード）、zabbix-kube-state-metricsとzabbix-proxyがdeploymentでデプロイされました。
```
# oc get pod
NAME                                       READY   STATUS    RESTARTS   AGE
zabbix-agent-5spdn                         1/1     Running   0          60s
zabbix-agent-cgrrx                         1/1     Running   0          60s
zabbix-agent-ngnt2                         1/1     Running   0          60s
zabbix-kube-state-metrics-78868498-krr6t   1/1     Running   0          60s
zabbix-proxy-5d49c88d9b-tnzjx              1/1     Running   0          60s
```
#### サービスアカウント
```
# oc get sa
NAME                           SECRETS   AGE
builder                        2         6d21h
default                        2         6d21h
deployer                       2         6d21h
zabbix-agent-service-account   2         7m39s
zabbix-kube-state-metrics      2         7m39s
zabbix-service-account         2         7m39s

```
#### サービス
```
# oc get svc
NAME                            TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)     AGE
zabbix-kube-state-metrics       ClusterIP   172.21.211.142   <none>        8080/TCP    19d
zabbix-zabbix-helm-chrt-agent   ClusterIP   172.21.246.99    <none>        10050/TCP   19d
zabbix-zabbix-helm-chrt-proxy   ClusterIP   172.21.156.172   <none>        10051/TCP   19d
```
#### Endpoint

```
# oc get ep
NAME                            ENDPOINTS                                                    AGE
zabbix-kube-state-metrics       172.30.88.174:8080                                           29d
zabbix-zabbix-helm-chrt-agent   10.129.176.23:10050,10.129.176.27:10050,10.129.176.7:10050   29d
zabbix-zabbix-helm-chrt-proxy   172.30.17.208:10051                                          29d
```
### 3.Zabbix Server側の設定
テンプレートを適用し、ZabbixServerからOpenShiftのリソース情報を取得していきます。
#### 3.1 Zabbix Proxyの作成
管理>プロキシ>プロキシの作成 をクリックして、Zabbix-Proxyを追加します。
（当環境では、Proxyを経由しないとOpenShiftへのディスカバリーができなかったため構成しています。Proxyは、必須ではありません。）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1281123/01de873b-2750-dba0-298c-cdce90a6a66a.png)
#### 3.2 Kubernetes nodes by HTTP テンプレートの適用
ノード監視用テンプレート  "Kubernetes nodes by HTTP"を適用するため、ノードをホスト登録します。
設定>ホスト>ホストの作成 をクリックしてクラスタ-ノードのホストを追加します。
当環境は、フルマネージドOpenShiftの為MasterNodeはIBMCloud管理となっており、ここではWorkerNodeのひとつをホストとして指定しました。
- テンプレートは、"Kubernetes nodes by HTTP" を選択
- インターフェース > エージェント にWorkerNodeのIPを入力

作成したホストに対して、ホストマクロを設定します。
|　　　　マクロ|　　　　　　　　　　　　　値|
|:--|:--|
|{$KUBE.API.ENDPOINT}|\<scheme\>://\<host\>:\<port\>/api<br>当環境では<br>https://c100.private.jp-tok.containers.cloud.ibm.com:31403/api|
|{$KUBE.API.TOKEN}|zabbix-service-accountシークレットから取得する[※]

※Tokenは以下のコマンドで取得
```
#oc get secret zabbix-service-account -n monitoring -o jsonpath={.data.token} | base64 -d
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1281123/382f5786-c893-ba1e-3066-476e8f69ed65.png)


#### 3.3 Kubernetes cluster state by HTTP テンプレートの適用
クラスター監視用テンプレート "Kubernetes cluster state by HTTP"を適用するため、ノードをホスト登録します。
（3.2で"Kubernetes nodes by HTTP"テンプレートを適用したホストに、"Kubernetes cluster state by HTTP"を適用することはできません。ディスカバリーがバッティングし、エラーとなりますので、別のホストを設定する必要があります）

設定>ホスト>ホストの作成 をクリックしてクラスターノードのホストを追加します。
- テンプレートは、"Kubernetes cluster state by HTTP" を選択
- インターフェース > エージェント に DNSでzabbix-zabbix-helm-chrt-agentを入力
※当初IPアドレスで設定していたのですが、当環境ではいくつかのディスカバリーが失敗したため、DNS名による指定に変更しました。
- プロキシによる監視で、作成したProxyを指定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1281123/69753b2b-320a-f2ef-6088-637a84448d58.png)


作成したホストに対して、ホストマクロを設定します。
|　　　　マクロ|　　　　　　　　　　　　　値|
|:--|:--|
|{$KUBE.API.ENDPOINT}|\<scheme\>://\<host\>:\<port\>/api<br>当環境では<br>https://c100.private.jp-tok.containers.cloud.ibm.com:31403/api|
|{$KUBE.API.TOKEN}|zabbix-service-accountシークレットから取得
|{$KUBE.API.HOST}|当環境では、c100.private.jp-tok.containers.cloud.ibm.com|
|{$KUBE.API.PORT}|デフォルト6443<br>当環境の場合は31403を設定|
|{$KUBE.API_SERVER.PORT}|デフォルト6443<br>当環境の場合は31403を設定|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1281123/93085944-ae5c-d39f-9241-8ee56adf9c3e.png)

残りの以下のテンプレートは、手動でホストに適用する必要はありません。ディスカバリーされてきたリソースに対して、自動的に適用されます。
 - Kubernetes API server by HTTP
 - Kubernetes Controller manager by HTTP
 - Kubernetes Scheduler by HTTP
 - Kubernetes kubelet by HTTP
## 取得データの確認


設定完了後、OpenShiftに対するディスカバリー結果とアイテムデータの取得内容を確認してみます。
#### ノード情報
Node discoveryによりOpenShiftクラスターの全てのノード(当環境の場合、3WorkerNode)が検出されプロトタイプホストとして登録されていることが確認できます。

![スクリーンショット 2022-04-05 15.54.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1281123/5642a040-c8ce-aff8-b6b8-c561f3254feb.png)

ノードから取得されるアイテムデータ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1281123/10df1c67-e0f3-7518-aaca-b50b3a1a8dba.png)

#### Podデータ
OpenShiftクラスター上で稼働している全てのPodに対し、ステータス・リソース状況が取得されています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1281123/9558a796-0ae3-df58-2139-6d6f4443ca6f.png)
アイテムにはデフォルトでトリガーが適用されており、Podのステータス監視も自動で行われます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1281123/7f9f8466-68bb-9f79-219d-96fa052fa8ef.png)
CrashLoopBackOffも検知可能となっていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1281123/796e96d9-5fd6-ddcd-5d7b-c91058571b57.png)

#### その他リソースの検出とデータ取得
zabbixに連携されるOpenShiftクラスター上のリソースデータは大変多いため、全てをここに載せることはできませんが、概ね以下のコンポーネントを取得・監視できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1281123/eb2c31cf-6f5f-2a42-8535-205744f05ca5.png)


## Kubernetes監視機能をOpenShiftに適用して気づいた点
#### Zabbix Serverの負荷
当環境は、デプロイした直後の何もアプリケーションが稼働していない状態のOpenShiftクラスターを使用しましたが、それでもディスカバリーされてきたアイテム数は37185となりました。
ディスカバリーの実行と膨大なアイテムデータの取得負荷により、度々処理が間に合わずpollerがTimeoutを起こしアイテムデータを取得できなくなることもありました。また、DBも保管データの増加により10日ほどでパンクしてしまいました。
既存のZabbixServerにOpenShiftを監視対象として追加する場合は、ZabbixServerのリソース増強が必要となる可能性が高いです。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1281123/c67e4359-e8a8-8243-6c5e-6699a5f0c7ee.png)

#### 一部のコンポーネントが検出されない
Kubernetesクラスターの場合、ホストのプロトタイプとして、APIServer,Controller-Manager,Schedulerが検出＆自動登録されるのですが、当OpenShift環境では検出させることができませんでした。
また、Controller-ManagerとSchedulerに関しては、実際には稼働していますがステータスが正しく取得されずUnhealthyイベントが通知されました。
```
# oc get clusteroperator
NAME                                       VERSION   AVAILABLE   PROGRESSING   DEGRADED   SINCE
console                                    4.8.31    True        False         False      28d
csi-snapshot-controller                    4.8.31    True        False         False      28d
dns                                        4.8.31    True        False         False      28d
image-registry                             4.8.31    True        False         False      28d
ingress                                    4.8.31    True        False         False      28d
kube-apiserver                             4.8.31    True        False         False      28d
kube-controller-manager                    4.8.31    True        False         False      28d
kube-scheduler                             4.8.31    True        False         False      28d
```
ステータスが正しく取得できない点については、以下のコマンド出力となるOpenShift4.xの[既知の問題](https://access.redhat.com/solutions/5088341)に起因している可能性もあるのではないかと思われます。
```
 oc get cs
W0330 14:16:42.128291   15591 warnings.go:67] v1 ComponentStatus is deprecated in v1.19+
NAME                 STATUS      MESSAGE                                                                                       ERROR
controller-manager   Unhealthy   Get "http://127.0.0.1:10252/healthz": dial tcp 127.0.0.1:10252: connect: connection refused
scheduler            Unhealthy   Get "http://127.0.0.1:10251/healthz": dial tcp 127.0.0.1:10251: connect: connection refused
etcd-0               Healthy     {"health":"true"}
```

## おわりに
ZabbixのKubernetes監視機能については、Kubernetes cluster 1.18+が前提条件となっているのみで、OpenShiftのサポートについては明記されていません。
とは言え、テンプレートの[README](https://git.zabbix.com/projects/zt/repos/kubernetes-helm/browse)でOpenShiftについて触れられている為、おそらくサポート対象に含まれると考えられます。
今回フルマネージドのOpenShiftで使用してみた結果としては、残念ながら一部想定した検出・監視ができませんでしたが、ノードの自動検出、Podの稼働状態の監視は、問題なく実装することができました。