EfK(Elasticsearch+fluent-bit+Kibana)が必要になったので構築した時の手順をメモ化する。
今更感は非常にあるが、Helmの手順はあまり見なかったので誰かの参考になれば幸いである。
なお、動けばいいレベルでの構築であり、ベストプラクティスなどには一切沿っていない点は注意。
検証環境
以下の環境・条件で検証する。
- EKS
- Ingress ControllerはKong Ingress Controllerを使用
- TLSはIngress終端とし、ES、KibanaはTLS化しない
- TLSの証明書は自己署名証明書とし、cert-managerで発行する
作業するにあたり、Ingress
で使用するドメインを以下で定義しておく。
export MYDOMAIN="aws.hogehoge.info"
また、リソースを展開するNamespaceを作成しておく。
kubectl create ns efk
自己署名証明書の準備
自己署名証明書を作成するためにIssuer
とCertificate
を作成する。
cat <<EOF > ./cert.yaml
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: selfsigned-issuer-efk
namespace: efk
spec:
selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: efk-ca
namespace: efk
spec:
commonName: "*.$MYDOMAIN"
secretName: efk-ca
issuerRef:
name: selfsigned-issuer-efk
kind: Issuer
EOF
kubectl apply -f ./cert.yaml
作成するとcert-managerがTLSの証明書を自動生成してSecret
化してくれる。
Secret
名はCertificate
のspec.secretName
で指定した名前となる。
$ kubectl get secret -n efk efk-ca
NAME TYPE DATA AGE
efk-ca kubernetes.io/tls 3 5h19m
ElasticsearchとKibanaの構築
ElasticsearchとKibanaはElastic Cloud on Kubernetes(ECK)を使う。
まず最初にHelmでOperatorをインストールする。
helm repo add elastic https://helm.elastic.co
helm repo update
helm install elastic-operator elastic/eck-operator -n elastic-system --create-namespace
このタイミングではあくまでもOperatorのみで、Elasticsearchなどのサービスは作成されない。
次にこの辺を参考にElasticsearchを作成する。
Elasticsearchを展開する。
cat <<EOF > ./es.yaml
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
name: quickstart
namespace: efk
spec:
version: 8.13.4
http:
tls:
selfSignedCertificate:
disabled: true
nodeSets:
- name: default
count: 1
config:
node.store.allow_mmap: false
EOF
kubectl apply -f ./es.yaml
こちらを参考にKibanaを展開する
cat <<EOF > ./kibana.yaml
apiVersion: kibana.k8s.elastic.co/v1
kind: Kibana
metadata:
name: quickstart
namespace: efk
spec:
version: 8.13.4
http:
tls:
selfSignedCertificate:
disabled: true
count: 1
elasticsearchRef:
name: quickstart
EOF
kubectl apply -f ./kibana.yaml
ここまででElasticsearchとKinabaの展開は完了となる。
次にそれぞれのサービスにドメインでアクセスするためにIngress
を作成する。
最初にElasticsearchのIngress
を作成する。
cat << EOF > ./ing-es.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: quickstart-es
namespace: efk
annotations:
konghq.com/protocols: "https"
spec:
ingressClassName: kong
rules:
- host: es.$MYDOMAIN
http:
paths:
- backend:
service:
name: quickstart-es-http
port:
number: 9200
path: /
pathType: Prefix
tls:
- hosts:
- es.$MYDOMAIN
secretName: efk-ca
EOF
kubectl apply -f ./ing-es.yaml
Ingress
でTLS終端するためにcert-managerで作ったTLSのSecret(es-tls
)を指定し、Ingress
のAnnotationでHTTPSのみ通すよう指定した(konghq.com/protocols: "https"
)
他のIngress Controllerを使う場合はそのControllerの書き方に従うこと。
同様にKibanaのIngress
も作成する。
cat << EOF > ./ing-kibana.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: quickstart-kibana
namespace: efk
annotations:
konghq.com/protocols: "https"
spec:
ingressClassName: kong
rules:
- host: kibana.$MYDOMAIN
http:
paths:
- backend:
service:
name: quickstart-kb-http
port:
number: 5601
path: /
pathType: Prefix
tls:
- hosts:
- kibana.$MYDOMAIN
secretName: efk-ca
EOF
kubectl apply -f ./ing-kibana.yaml
Ingressを展開したら設定したホスト名でアクセスできるようになっているため、早速アクセスする。
Elasticsearchのユーザelastic
の初期パスワードを取得する。
kubectl get secret -o yaml quickstart-es-elastic-user -o jsonpath={.data.elastic} -n efk | base64 -d
Kibanaにユーザ名:elastic
、パスワード:取得したパスワード
でログインするとログイン出来ることが確認できる。
Elasticsearchにも同様にブラウザでアクセスし、同じユーザ名、パスワードでログインすればログイン出来ることが確認できる。
fluent-bitの構築
fluent-bitのHelmのvalues.yamlを抜き出す。
helm repo add fluent https://fluent.github.io/helm-charts
helm show values fluent/fluent-bit > fb-values.yaml
デフォルトではOUTPUTプラグインの設定箇所にElasticsearchに転送する設定が入っている。
これを編集する。
[OUTPUT]
Name es
Match kube.*
Host quickstart-es-default
Logstash_Format On
Retry_Limit False
HTTP_User elastic
HTTP_Passwd ma8Av06F8nxxxxxxx
Suppress_Type_Name On
[OUTPUT]
Name es
Match host.*
Host quickstart-es-default
Logstash_Format On
Logstash_Prefix node
Retry_Limit False
HTTP_User elastic
HTTP_Passwd ma8Av06F8nxxxxxxx
Suppress_Type_Name On
変更箇所は以下となる。
-
Host
: Elasticsearchのアドレス(ここではService
経由でアクセスするよう設定) -
HTTP_User
: 先ほどログインに使用したユーザ -
HTTP_Passwd
: 先ほどログインに使用したパスワード -
Suppress_Type_Name
: ES8以降はOnにするよう説明があるのでOnにする
修正が終わったらvaluesを使ってfluent-bitをデプロイする。
helm upgrade -i fluent-bit fluent/fluent-bit -n efk -f ./fb-values.yaml
動作確認
テスト用のPodを起動する。
kubectl run nginx --image nginx -n default --port 80
出力を確認する。
$ kubectl logs -n default nginx
:(省略)
2024/05/22 06:23:51 [notice] 1#1: using the "epoll" event method
2024/05/22 06:23:51 [notice] 1#1: nginx/1.25.5
2024/05/22 06:23:51 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14)
2024/05/22 06:23:51 [notice] 1#1: OS: Linux 5.10.215-203.850.amzn2.x86_64
2024/05/22 06:23:51 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2024/05/22 06:23:51 [notice] 1#1: start worker processes
2024/05/22 06:23:51 [notice] 1#1: start worker process 29
2024/05/22 06:23:51 [notice] 1#1: start worker process 30
このログがfluent-bitが拾ってElasticsearchに転送し、Kibanaから見れるか確認する。
まず、Kibanaにログインし、Discover
->Create data view
から
データビューを適当に作成する。
作成後、先程起動したPodのログを検索してみる。
ログが取れているので、動作は問題なさそうだ。
ということで、問題なく構築できた。