#概要
openshift上で稼働するアプリケーションのログをfluentdサイドカーコンテナで取得し、ログサーバーに転送する検証を実施したのでその際のメモをまとめました。
###Fluentdとは
Fluentdはオープンソースのデータコレクターです。主な機能は以下の通りです。
- Unified Logging with JSON
- Fluentdは、データを可能な限りJSONとして構造化します。これによりFluentdは、ログデータ処理のすべての側面(複数のソースと宛先にわたるログの収集、フィルタリング、バッファリング、出力)を単一化しています。 JSONを使用すると、柔軟なスキーマを維持しながらアクセスできるため、ダウンストリームのデータ処理が簡単になります。
- Pluggable Architecture
- Fluentdには、柔軟なプラグインシステムがあります。コミュニティが提供する500以上のプラグインは、数十のデータソースとデータ出力を接続可能にします。
- Minimum Resources Required
- FluentdはC言語とRubyの組み合わせで書かれており、必要なシステムリソースはごくわずかです。
- Built-in Reliability
- Fluentdは、ノード間のデータ損失を防ぐために、メモリベースおよびファイルベースのバッファリングをサポートしています。
###作業の流れ
1.ログサーバーへのFluetndの導入
2.Fluentdコンテナ・イメージの作成
3.サンプルアプリのコンテナ・イメージの作成(Optional)
4.ROKSクラスターにデプロイ
5.ログサーバーにおけるFluentdの設定
###作業の前提
- 本検証ではFluentdサイドカー用のコンテナと、Fluentdサイドカーでログを取得するためのサンプルアプリ用コンテナを作成し、1つのpodに入れてデプロイしています。
###1.ログサーバーへのFluetndの導入
- 以下から対応する環境に合わせて導入します。
- 本検証時は以下のガイドに従い導入しました。
###2.Fluentdコンテナ・イメージの作成
- Fluentd公式サイトに記載のGitHubより、以下のファイルを手元にダウンロードし、全てのファイルをDocekrfileと同じ階層に配置します。
-
https://github.com/fluent/fluentd-docker-image
- Dockerfile
- fluent.conf
- entrypoint.sh
-
https://github.com/fluent/fluentd-docker-image
- Dockerfileを編集します。
- コンテナ起動時の権限エラー回避のため、下から7行目に以下を追記します。
- RUN ["chmod", "+x", "/bin/entrypoint.sh"]
- コンテナ起動時の権限エラー回避のため、下から7行目に以下を追記します。
# AUTOMATICALLY GENERATED
# DO NOT EDIT THIS FILE DIRECTLY, USE /Dockerfile.template.erb
FROM alpine:3.9
LABEL maintainer "Fluentd developers <fluentd@googlegroups.com>"
LABEL Description="Fluentd docker image" Vendor="Fluent Organization" Version="1.10.4"
# Do not split this into multiple RUN!
# Docker creates a layer for every RUN-Statement
# therefore an 'apk delete' has no effect
RUN apk update \
&& apk add --no-cache \
ca-certificates \
ruby ruby-irb ruby-etc ruby-webrick \
tini \
&& apk add --no-cache --virtual .build-deps \
build-base linux-headers \
ruby-dev gnupg \
&& echo 'gem: --no-document' >> /etc/gemrc \
&& gem install oj -v 3.8.1 \
&& gem install json -v 2.3.0 \
&& gem install async-http -v 0.50.7 \
&& gem install ext_monitor -v 0.1.2 \
&& gem install fluentd -v 1.10.4 \
&& gem install bigdecimal -v 1.4.4 \
&& apk del .build-deps \
&& rm -rf /tmp/* /var/tmp/* /usr/lib/ruby/gems/*/cache/*.gem
RUN addgroup -S fluent && adduser -S -g fluent fluent \
# for log storage (maybe shared with host)
&& mkdir -p /fluentd/log \
# configuration/plugins path (default: copied from .)
&& mkdir -p /fluentd/etc /fluentd/plugins \
&& chown -R fluent /fluentd && chgrp -R fluent /fluentd
COPY fluent.conf /fluentd/etc/
COPY entrypoint.sh /bin/
RUN ["chmod", "+x", "/bin/entrypoint.sh"]
ENV FLUENTD_CONF="fluent.conf"
ENV LD_PRELOAD=""
EXPOSE 24224 5140
USER fluent
ENTRYPOINT ["tini", "--", "/bin/entrypoint.sh"]
CMD ["fluentd"]
- イメージをビルドします。
- Dockerfileの配置してあるディレクトリで以下を実行します。
$ docker build -t fluentd .
- ローカルにイメージが作成されたことを確認します。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
fluentd latest a91e23972d8d 38 seconds ago 38.7MB
- コンテナが起動できることを確認します。
$ docker run fluentd
- コンテナへタグ付けを行います。
- Container Registryに合わせて実施します。
- $ docker tag (現在のイメージ名): (ver) (ContainerRegistryパス)/(namespace)/(イメージ名):(ver)
$ docker tag fluentd:latest us.icr.io/test/fluentd:v1
- DockerイメージをContainer RegistryにPushします。
- $ docker push <タグ付けしたイメージ名>
$ docker push us.icr.io/test/fluentd:v1
- Container RegistryにイメージがPushできたことを確認します。
- 以下はIBM Cloud Container Registryの場合の確認方法です。それぞれのContainer Registryに合わせて確認を実施します。
$ ibmcloud cr image-list | grep fluentd
###3.サンプルアプリのコンテナ・イメージの作成(Optional)
-
検証用のサンプルアプリとしてubuntuコンテナを用意します。別のアプリコンテナがある場合はそちらを使用してください。
-
Dockerfileを用意します。
FROM ubuntu:18.04
RUN apt-get update \
&& apt-get install -y \
wget \
curl \
&& rm -rf /var/lib/apt/lists/*
RUN apt-get update \
&& apt-get upgrade -y
- イメージをビルドします。
- Dockerfileの配置してあるディレクトリで以下を実行します。
$ docker build -t ubuntu-sample .
- ローカルにイメージが作成されたことを確認します。
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
ubuntu-sample latest 91245ab45e54 40 seconds ago 174MB
- コンテナが起動できることを確認します。
$ docker run -it ubuntu-sample /bin/bash
- コンテナへタグ付けを行います。
$ docker tag ubuntu-sample:latest us.icr.io/test/ubuntu-sample:v1
- DockerイメージをContainer RegistryにPushします。
$ docker push us.icr.io/test/ubuntu-sample:v1
- Container RegistryにイメージがPushできたことを確認します。
$ ibmcloud cr image-list | grep ubuntu-sample
###4.ROKSクラスターにデプロイ
参考:イメージ・プル・シークレットを使用してデフォルト以外の OpenShift プロジェクトから他の IBM Cloud アカウントまたは外部プライベート・レジストリーにあるイメージにアクセスする方法
- ROKSへログインし、namespaceを作成します。
$ oc login
$ oc new-project <Project名>
以下「*****」で区切った手順については該当する場合のみ実施します。
*********************************************
*イメージを外部Container Registryに配置している場合のみ以下のsecretの作成手順を実施します。内部レジストリ利用の場合は省略してください。
- イメージを外部Container RegistryからOCP上にpullするためのSecretを作成します。
- default namespaceにあるsecretをコピーし新たなsecretを作成する手順を記載しています。
$ oc get secrets -n default | grep icr
- us-icr.io接続用Secretを作成します
- $ oc get secret default-us-icr-io -n default -o yaml | sed 's/default/(namespace)/g' | oc -n (namespace) create -f -
$ oc get secret default-us-icr-io -n default -o yaml | sed 's/default/test/g' | oc -n test create -f -
- secretが作成できたことを確認します
$ oc get secrets -n (namespace)
*アプリケーションがroot起動の場合は、ServiceAccountを作成し、権限を付与します。
参考:SCC (Security Context Constraints) の管理
- ServiceAccount用ファイルを作成します。
apiVersion: v1
kind: ServiceAccount
metadata:
name: fluentd-sidecar-role
namespace: test
labels:
k8s-app: ubuntu-sample
version: v1
- ServiceAccountを適用します。
$ oc create -f fluentd-sidecar-sa.yaml
- ServiceaccountにSCCを付与します。
- oc adm policy add-scc-to-user (scc_name) (user_name)
$ oc adm policy add-scc-to-user privileged system:serviceaccount:test:fluentd-sidecar-role
- SCCを確認します。(Access>Usersに追記されたことを確認)
$ oc describe scc privileged
- Serviceaccountにimage pull用のsecret情報を追加します。
- oc patch -n serviceaccount/
-p '{"imagePullSecrets":[{"name": ""}]}'
- oc patch -n serviceaccount/
$ oc patch -n test serviceaccount/fluentd-sidecar-role -p '{"imagePullSecrets":[{"name": "test-us-icr-io"}]}'
- image pull用のsecretの情報が追加されたことを確認します。
$ oc describe serviceaccount fluentd -n (namespace名)
*********************************************
- Configmapを作成します。
- Fluentdの設定ファイルの詳細なオプションについてはFluentd公式マニュアルを参照してください。
apiVersion: v1
kind: ConfigMap
metadata:
name: fluentd-sidecar-cm
namespace: test
data:
fluent.conf: |
<source>
@type tail
path /fluentd/log/*.log
pos_file /test/log/ubuntu-sample.pos
tag test.log
read_from_head true
format none
time_format %Y-%m-%dT%H:%M:%S.%NZ
</source>
<filter **>
@type record_transformer
<record>
cluster_name "#{ENV['CLUSTER_NAME']}"
node_name "#{ENV['NODE_NAME']}"
pod_name "#{ENV['POD_NAME']}"
namespace "#{ENV['POD_NAMESPACE']}"
pod_ip "#{ENV['POD_IP']}"
pod_service_account "#{ENV['POD_SERVICE_ACCOUNT']}"
</record>
</filter>
<match **>
@type forward
@id out_fwd
<server>
host "#{ENV['FLUENT_FOWARD_HOST']}"
port "#{ENV['FLUENT_FOWARD_PORT']}"
</server>
</match>
- ConfigMap用yamlファイルを適用します。
$ oc create -f fluentd-configmap.yaml
- Deploymentを作成します。
- 環境変数として「ログサーバーのIP」「ログサーバーのFluentdのPORT」等を取得したい場合はenvの情報を記載します。
apiVersion: apps/v1
kind: Deployment
metadata:
name: ubuntu-fluentd-sidecar
namespace: test
spec:
replicas: 1
selector:
matchLabels:
app: ubuntu-sample
template:
metadata:
labels:
app: ubuntu-sample
spec:
serviceAccount: fluentd-sidecar-role
serviceAccountName: fluentd-sidecar-role
containers:
- name: ubuntu-sample
image: us.icr.io/test/ubuntu-sample:v1
volumeMounts:
- name: varlog
mountPath: /var/log
- name: fluentd
image: us.icr.io/test/fluentd:v1
env:
- name: FLUENT_FOWARD_HOST
value: "<ログサーバーのIP>"
- name: FLUENT_FOWARD_PORT
value: "<ログサーバーのFluentdのPORT>"
- name: CLUSTER_NAME
value: "<クラスター名 >"
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
- name: POD_SERVICE_ACCOUNT
valueFrom:
fieldRef:
fieldPath: spec.serviceAccountName
volumeMounts:
- name: varlog
mountPath: /fluentd/log
- name: config-volume
mountPath: /fluentd/etc
securityContext:
privileged: true
imagePullSecrets:
- name: test-us-icr-io
volumes:
- name: varlog
emptyDir: {}
- name: config-volume
configMap:
name: fluentd-sidecar-cm
- Deployment用yamlファイルを適用します。
$ oc create -f ubuntu-fluentd-sidecar-deployment.yaml
- デプロイできたことを確認します。
$ oc get all -n (namespace)
- アプリケーションのログを表示します。
$ oc logs (pod名) -n (namespace名) -c (container名)
- Fluentdサイドカーの稼働確認を行います。
$ oc exec (pod名) -c fluentd -n (namespace) -i -t -- /bin/sh
- ubuntuサイドカーの稼働確認を行います。
$ oc exec (pod名) -c ubuntu-sample -i -t -- bash
- ubuntu-sampleコンテナでログを書き出します。
- deploymentのubuntu-sampleコンテナ定義内volumeMounts>mountPathに記載したパスにログファイルを作成しログを書き込む設定をしています。
- ここではubuntu-sampleコンテナ内の/var/log配下にログ書き出し用のファイルを作成し書き込見ます。
- ubuntuコンテナ内で以下を実行します。
cd /var/log
touch test.log
echo aaaaaa >> test.log
- FluentdサイドカーコンテナでvolumeMounts>mountPathに記載したパスで、ubuntu-sampleコンテナのファイル(test.log)が参照できることを確認します。
- tailをしながら再度ubuntu-sampleコンテナでファイルに内容を書き込みし、ログが書き出されることを確認します。
- ここではfluentdコンテナ内の/fluentd/log配下に移動し、test.logファイルが参照できることを確認します。
- fluentdコンテナ内で以下を実行します。
cd /fluentd/log
ls -l
tail /fluentd/log/test.log
###5.ログサーバーにおけるFluentdの設定
-
Fluentdサイドカーコンテナで転送したログをログサーバーのtd-agentで受け取り、ファイルに書き出す設定を行います。
-
この設定ではログサーバーのFluentdが受け取ったすべてのログを1ファイルに書き出す設定を記載しています。
-
ログのメッセージ内に、ログ送信元podのpod名やnamespace情報もログに書き出されるため、適宜必要な情報を抽出して確認することができます。
-
ログサーバーの設定ファイル(/etc/td-agent/td-agent.conf)を編集します。
<source>
@type forward
port 24224
bind 0.0.0.0
</source>
<match **>
@type file
path /var/log/td-agent/sidecar-test
append true
<buffer>
@type file
path /var/log/td-agent/sidecar-test-buffer
flush_mode interval
flush_interval 10s
</buffer>
</match>
-
上記の設定の場合/var/log/td-agent/sidecar-test.YYYYMMDD.log形式で1日毎にファイルが追加作成されます。
-
バッファーファイルのディレクトリは事前に作成しておく必要があります。(権限は755 td-agent:td-agent)
-
Fluentdを再起動します。
$ systemctl stop td-agent
$ systemctl start td-agent
- 稼働確認を行います。
- サンプルアプリコンテナにログインしてログを書き出します。
- ログサーバーにログインし、ログファイル(/var/log/td-agent/XXXXXXX.log)にログが書き出されていることを確認します。
- ログ転送が成功した場合、ログサーバー側/var/log/td-agent/XXXXXXX.logファイルにログが出力されていることを確認できます。