zaki work log

作業ログやら生活ログやらなんやら

[Ansible / AWX / AAP] ログアグリゲーター設定でジョブの実行ログをLogstash経由でsyslogサーバーへ転送する

ロギング設定にログアグリゲーターを指定して、リモートのsyslogへジョブの実行履歴を転送してみます。

通常AWX・AAPではDBに記録されたジョブの実行履歴などはスケジュールのCleanup Job Scheduleで設定された期限が過ぎたら削除されるので、基本的にはUIで参照したりAPIで取得する必要があります。
そこでログのアグリゲーター機能を使ってログをリモート転送することで、(転送先でログの監視と通知を行うことで)リアルタイムでエラーに対するアラートを上げたりできるようになります。
(画面でジョブ起動するだけなら不要だと思うけど、スケジュール機能でバックグラウンドで動作させたりする場合はあぐりゲーターなしだと一定間隔でAPIを叩いたりして見に行く必要がある)

AWXで指定可能なログアグリゲーターは以下。

  • Logstash
  • Splunk
  • Loggly
  • Sumo Logic
  • other (詳細不明)

本エントリではELKスタックの一つとして利用されるLogstashをAWXをデプロイしているKubernetesクラスタ上へでHelmを使ってデプロイし、プラグインのsyslog outputでリモートのsyslogサーバーにジョブ履歴を転送してみます。
※ 本記事では機能的に疎通を確認してるレベルまでで、チューニングとかはやってません。

www.elastic.co

www.elastic.co

Syslogプラグイン入りLogstashイメージのビルド

LogstashをK8sに標準構成で一度デプロイしたあとに気づいたんですが、デフォルトではSyslog output pluginは含まれていません。

Installation

For plugins not bundled by default, it is easy to install by running bin/logstash-plugin install logstash-output-syslog.

https://www.elastic.co/guide/en/logstash/current/plugins-outputs-syslog.html#_installation_49

www.elastic.co

なので、Syslog output pluginを入れたコンテナイメージを作成します。

FROM docker.elastic.co/logstash/logstash:8.5.1

RUN bin/logstash-plugin install logstash-output-syslog

イメージをビルドし、使えるレジストリへpush

docker build . -t zakihmkc/logstash-syslog:8.5.1
docker push zakihmkc/logstash-syslog:8.5.1 

一応ここに置いてます。
https://hub.docker.com/r/zakihmkc/logstash-syslog

Logstashのデプロイ

AWXをデプロイしてるK8sクラスターにHemlを使ってデプロイします。

Logstash単体のHelmチャートのリポジトリはここにあるけど、現在メンテナンスされておらず、ECK(Elastic on Kubernetes)を使うのが推奨されています。
ECKのHelmチャートのリポジトリの追加はこの辺りを参照。

helm repo add elastic https://helm.elastic.co
helm repo update

あとはリポジトリelastic/logstashがあるので、これをデプロイします。(values.yamlファイルについては後述)

[zaki@cloud-dev2 logstash]$ helm upgrade --install sample-logstash elastic/logstash -f values.yaml --create-namespace -n logging
Release "sample-logstash" does not exist. Installing it now.
NAME: sample-logstash
LAST DEPLOYED: Sun Jan 21 14:41:22 2024
NAMESPACE: logging
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
1. Watch all cluster members come up.
  $ kubectl get pods --namespace=logging -l app=sample-logstash-logstash -w
[zaki@cloud-dev2 logstash]$ helm ls -n logging
NAME            NAMESPACE       REVISION        UPDATED                                 STATUS          CHART           APP VERSION
sample-logstash logging         1               2024-01-21 14:41:22.146914228 +0900 JST deployed        logstash-8.5.1  8.5.1      
[zaki@cloud-dev2 logstash]$ 
[zaki@cloud-dev2 logstash]$ 
[zaki@cloud-dev2 logstash]$ kubectl get pod -n logging -w
NAME                         READY   STATUS    RESTARTS   AGE
sample-logstash-logstash-0   0/1     Running   0          20s
sample-logstash-logstash-0   1/1     Running   0          80s

readyになるまでに若干時間がかかります。

values.yamlの説明

デプロイに使ったvalues.yamlファイルは以下の通り。

---
logstashConfig:
  logstash.yml: |
    http.host: "0.0.0.0"

logstashPipeline:
  logstash.conf: |
    input {
      http {
        port => 9601
      }
    }
    output {
      syslog {
        host => "192.168.0.16"
        port => 514
      }
    }

image: "zakihmkc/logstash-syslog"
imageTag: "8.5.1"

service:
  type: ClusterIP
  ports:
    - name: http
      port: 9601
      protocol: TCP
      targetPort: 9601

logstashConfig

/usr/share/logstash/config 以下のファイル(settings)を定義(override)します。
Docker版はlogstash.ymlファイルがデフォルトで以下の内容になっており、そのままだとoutputプラグインにsyslogを使用してもhttp://elasticsearch:9200へのリクエストが発生して名前解決エラーなどが延々記録されるので上書き削除します。

$ cat config/logstash.yml 
http.host: "0.0.0.0"
xpack.monitoring.elasticsearch.hosts: [ "http://elasticsearch:9200" ]

ただしコメントにもある通りhttp.host: 0.0.0.0が無いとpodのliveness probeで条件(/へのHTTP GET)を満たさないのでこれだけ定義します。

logstashPipeline

/usr/share/logstash/pipeline以下のパイプライン設定(conf)を定義(override)します。
AWXからのアクセスはHTTPで受信し、リモートのsyslogへ送信するため、http input pluginsyslog output pluginを指定します。

Http input plugin

Logstash本体が9600でListenするので、適当だけどプラグインとしては9601でListenするように設定。

Syslog output plugin

最低限必須のパラメタとして、syslogサーバーのIPアドレスとポート番号を指定。
ここでは192.168.0.16で動作してる外部のLinuxサーバーのsyslogをUDP受付するようにしてるのでそれを指定。

ちょっと古いけど参考 zaki-hmkc.hatenablog.com

imageとimageTag

前述のとおり、Syslogプラグイン入りのカスタムイメージを指定

service

デフォルトではLogstash本体用のServiceリソースしか作成されないので、http input plugin用のService定義を追加。
外部アクセスは不要でクラスター内のAWXからアクセスできればOKなので、ClusterIPで定義。

AWXロギング設定

左側設定メニューの「ロギング設定」(englishだと"Logging settings")で以下の内容を設定します。

項目 項目(ja)
Enable External Logging 外部ログの有効化 On
Logging Aggregator ログアグリゲーター (1)
Logging Aggregator Port ログアグリゲーターポート (2)
Logging Aggregator Type ログアグリゲーターのタイプ logstash
Logging Aggregator Protocol ログアグリゲータープロトコル HTTPS/HTTP
  • (1) ログアグリゲーターにLogstashのURLを入力。http://<service名>.<namespace名>.svc.cluster.local
    • アドレスのみを入力するとHTTPS接続になるため、今回の構成のようにHTTPの場合は http:// から入力
    • 本記事のデプロイ手順であれば、namespaceがlogging、リリース名はsample-logstashなので、URLはhttp://sample-logstash-logstash.logging.svc.cluster.local
  • (2) ポート番号はhttp input plugin用のserviceがListenするポート番号
    • 本記事のvalues.yaml定義の内容であれば9601 (podのlistenする番号とserviceのポートを同じにしている)

これでAWXでジョブ実行した際のログがまずLogstashへ転送され、そこからさらにsyslogサーバーへ転送されます。

AAPの場合

上の構成のLogstashをLoadBalancer Serviceで外部公開して、同様の設定をいれればログを転送できます。
(Ansible Automation Platform Controller 4.4.8で確認)

要確認ポイント

  • デフォルト設定の「ログアグリゲーターレベルのしきい値」を「INFO」にするとタスク単位でログが記録されるので膨大になりがち
    • 閾値を「WARN」にするとエラー時のログから記録されるが、タスクのエラーで発生するエラーメッセージは記録されないぽいので、結局は大元のログの確認が必要
  • outputプラグインでsyslogを使用しても、stdoutへは受信したログを出力されるらしくpodのログとしても記録される
    • fluentbitを使ったpodログ収集を行うと二重にロギングしてしまうので、除外設定をするか、Logstashではsyslog転送せずにfluentbitに転送処理を寄せるのもアリかも

参考リンク (1/27追加)


アグリー! (これが言いたかっただけ)