OpenShift 4のアプリログをsyslogサーバーに転送する。ElasticSearch無しで。

OpenShiftにデプロイするマイクロサービスのログを一か所に集約したいが、小規模クラスターのためElasticSearchが導入できない場合というのがある。特にオンプレ環境で顕著で、日本ではほとんどだろう。クラウド上であればなにがしかのログ集約サービスが利用できるのだが。

そのような場合もOpenShift LoggingオペレーターのClusterLogForwarderを使ってSyslogサーバーにログを転送して集約、一元管理することは可能である。ClusterLogForwarderはOpenShift 4.6から使えるカスタムリソース。

以下手順を追って述べるが、OpenShiftクラスター環境としては[先日作ったマスター１台構成](https://qiita.com/rk05231977/items/ec1626c1223dddffc98a)のクラスターを前提に話を進める。

# rsyslogサーバーを作る
転送先のrsyslogサーバーを作る。とりあえず今回はbastionサーバーを使う。
（参考）https://sig9.hatenablog.com/entry/2019/10/08/000000

```
# sed -i -e 's/^#module(load="imudp")/module(load="imudp")/g' /etc/rsyslog.conf
# sed -i -e 's/^#input(type="imudp" port="514")/input(type="imudp" port="514")/g' /etc/rsyslog.conf

# cat >> /etc/rsyslog.conf << "EOF"
$template ClientMessage,"/var/log/rsyslog/%fromhost%/%$year%%$month%%$day%_messages.log"
*.*     -?ClientMessage
EOF

# systemctl restart rsyslog
```

# OpenShiftのログ転送を設定する
OpenShiftにElasticSearchオペレーター、OpenShift Loggingオペレーターを導入する。ElasticSearchオペレーターは、無いとFluentdが起動しないので導入するが、インスタンスは作らない。

１．「Operators」＞「OperatorHub」から「Elastic Search」オペレーターを導入する。
https://access.redhat.com/documentation/ja-jp/openshift_container_platform/4.6/html/logging/cluster-logging-deploying#cluster-logging-deploy-console_cluster-logging-deploying

２．「Operators」＞「OperatorHub」から「Cluster Logging」オペレーターを導入する。

３．Cluster Loggingのインスタンスを作る。
CRは以下の内容で。ElasticSearch、Kibanaは作らない。

```yaml:ClusterLogging.yaml
apiVersion: logging.openshift.io/v1
kind: ClusterLogging
metadata:
  name: instance
  namespace: openshift-logging
spec:
  managementState: Managed
  collection:
    logs:
      type: fluentd
      fluentd: {}
  logStore:
    elasticsearch:
      nodeCount: 0
    type: elasticsearch
  visualization:
    kibana:
      replicas: 0
    type: kibana
  curation:
    type: curator
    curator:
      schedule: 30 3 * * *

```

３．Cluster Log Forwarderのインスタンスを作る。
CRは以下の内容で。
（参考）https://access.redhat.com/documentation/ja-jp/openshift_container_platform/4.6/html/logging/cluster-logging-external#cluster-logging-collector-log-forward-syslog_cluster-logging-external
この例で転送先は１か所のみだが、宛先を複数とすることもできる。

```yaml:ClusterLogForwarder.yaml
apiVersion: logging.openshift.io/v1
kind: ClusterLogForwarder
metadata:
  name: instance 
  namespace: openshift-logging 
spec:
  outputs:
  - name: output-syslog
    type: syslog 
    syslog: 
      facility: local0
      rfc: RFC3164
      severity: informational
    url: 'udp://192.168.1.1:514' 
  pipelines:
  - name: pipeline-syslog
    inputRefs: 
    - application
    outputRefs: 
    - output-syslog

```

```inputrefs: - application```のところを以下の様にすれば、OpenShiftクラスターの全てのログが送られてくるようになるのだが、マスター１台構成でも毎秒1MB超のログが送られてくるため、ちょっとうんざりする。

```
    inputRefs: 
    - application
    - audit
    - infrastructure
```

# 動作確認
bastionサーバーのコマンドプロンプトから以下を実行し、httpdのPodを３つ作ってみる。
注意点として、defaultネームスペースにデプロイするとそのPodはinfrastructureカテゴリに入ってしまうのでapplicationのみを拾っている場合はログが転送されない。（[参考](https://access.redhat.com/documentation/ja-jp/openshift_container_platform/4.6/html/logging/cluster-logging-external#cluster-logging-collector-log-forwarding-about_cluster-logging-external)）

```
# oc new-project httpd
# oc adm policy add-scc-to-user anyuid -z default -n httpd
# oc new-app httpd -n httpd
# oc scale deploy httpd -n httpd --replicas=3
# oc delete project httpd
```

所々は端折るが、以下が```/var/log/rsyslog/master1～_messages.log```ファイルに出力される。
"container_id"や"pod_name"の値から、３つのPodからログが送られている事が分かる。

```:/var/log/rsyslog/master1.ocp.example.com/20210112_messages.log
Jan 12 22:57:56 fluentd-fj9pg fluentd: docker:{"container_id"=>"3873adeff9bb1d2f2a131fd85d35ad8011dafc7de44ae248244e324ec770eadb"}#011kubernetes:{"container_name"=>"httpd", "namespace_name"=>"httpd", "pod_name"=>"httpd-5fd6d9fbd9-tdjkb", "pod_id"=>"4b7936f1-7609-425b-a22c-d705fa5d85e9", "host"=>"master1", "master_url"=>"https://kubernetes.default.svc", "namespace_id"=>"39381d2d-da61-466d-94a1-13dbef77c7c8", :flat_labels=>["deployment=httpd", "pod-template-hash=5fd6d9fbd9"]}#011message:---> Generating SSL key pair for httpd...#011level:unknown#011hostname:master1#011pipeline_metadata:{"collector"=>{"ipaddr4"=>"192.168.1.3", "inputname"=>"fluent-plugin-systemd", "name"=>"fluentd", "received_at"=>"2021-01-12T22:57:55.337795+00:00", "version"=>"1.7.4 1.6.0"}}#011@timestamp:2021-01-12T22:57:54.937907+00:00#011viaq_index_name:app-write#011viaq_msg_id:YjAzNTM4Y2YtNDE0NS00ZTMxLWFmMzAtMTcxNjI0ZGZiMGM4
...
Jan 12 22:59:21 fluentd-fj9pg fluentd: docker:{"container_id"=>"0db5e35b5f1ddfceea7b12142b1f75112170f20d17272b835976b09e8dc48c93"}#011kubernetes:{"container_name"=>"httpd", "namespace_name"=>"httpd", "pod_name"=>"httpd-5fd6d9fbd9-4pgh9", "container_image"=>"registry.redhat.io/rhel8/httpd-24@sha256:62cfaa2a199641010aab4c4f3fba24cb4040729dd31420438380a4b791f69861", "container_image_id"=>"registry.redhat.io/rhel8/httpd-24@sha256:62cfaa2a199641010aab4c4f3fba24cb4040729dd31420438380a4b791f69861", "pod_id"=>"3307af72-2704-4320-b127-bae778b29e2e", "host"=>"master1", "master_url"=>"https://kubernetes.default.svc", "namespace_id"=>"39381d2d-da61-466d-94a1-13dbef77c7c8", :flat_labels=>["deployment=httpd", "pod-template-hash=5fd6d9fbd9"]}#011message:---> Generating SSL key pair for httpd...#011level:unknown#011hostname:master1#011pipeline_metadata:{"collector"=>{"ipaddr4"=>"192.168.1.3", "inputname"=>"fluent-plugin-systemd", "name"=>"fluentd", "received_at"=>"2021-01-12T22:59:20.308588+00:00", "version"=>"1.7.4 1.6.0"}}#011@timestam
...
Jan 12 22:59:47 fluentd-fj9pg fluentd: docker:{"container_id"=>"de69d2ba3a2913949ac9b90c90d0971f28833a79603798ece4e8b598506c909a"}#011kubernetes:{"container_name"=>"httpd", "namespace_name"=>"httpd", "pod_name"=>"httpd-5fd6d9fbd9-4pz8x", "container_image"=>"registry.redhat.io/rhel8/httpd-24@sha256:62cfaa2a199641010aab4c4f3fba24cb4040729dd31420438380a4b791f69861", "container_image_id"=>"registry.redhat.io/rhel8/httpd-24@sha256:62cfaa2a199641010aab4c4f3fba24cb4040729dd31420438380a4b791f69861", "pod_id"=>"fc189720-3ee6-4999-be41-208d0b620dfb", "host"=>"master1", "master_url"=>"https://kubernetes.default.svc", "namespace_id"=>"39381d2d-da61-466d-94a1-13dbef77c7c8", :flat_labels=>["deployment=httpd", "pod-template-hash=5fd6d9fbd9"]}#011message:[Tue Jan 12 22:59:45.588715 2021] [mpm_event:notice] [pid 1:tid 140399073938880] AH00491: caught SIGTERM, shutting down#011level:unknown#011hostname:master1#011pipeline_metadata:{"collector"=>{"ipaddr4"=>"192.168.1.3", "inputname"=>"fluent-plugin-systemd", "name"=>"fluentd", "received
```

まあ、まともに読むにはawkとかjqを駆使した加工処理は必要だろう。