Elasticsearch + Filebeat + Kibana = EFK F: it’s not Fluentd
Fluentd需要学习配置语法, Filebeat相对熟悉
https://github.com/elastic/helm-charts
Requirements
Helm >=2.8.0 and <3.0.0
Kubernetes >=1.8
3 Work-node
1GB of RAM for the JVM heap
Helm Charts 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 helm repo add elastic https://helm.elastic.co helm repo updatecd ~/k8s/helm/charts helm search elasticsearch --version 7.6.2 helm search filebeat --version 7.6.2 helm search kibana --version 7.6.2 helm fetch elastic/elasticsearch --version 7.6.2 helm fetch elastic/filebeat --version 7.6.2 helm fetch elastic/kibana --version 7.6.2 tar -zxf elasticsearch-7.6.2.tgz tar -zxf filebeat-7.6.2.tgz tar -zxf kibana-7.6.2.tgz helm install --name elasticsearch -f values.yaml . --namespace logging helm install --name filebeat -f values.yaml . --namespace logging helm install --name kibana -f values.yaml . --namespace logging helm upgrade -f values.yaml elasticsearch . --namespace logging helm upgrade -f values.yaml filebeat . --namespace logging helm upgrade -f values.yaml kibana . --namespace logging helm delete --purge elasticsearch helm delete --purge filebeat helm delete --purge kibana kubectl -n logging delete pvc -l app=elasticsearch-logging
Elasticsearch 创建CA证书 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 curl -LO https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.6.2-linux-x86_64.tar.gz tar -zxf elasticsearch-7.6.2-linux-x86_64.tar.gzcd elasticsearch-7.6.2 bin/elasticsearch-certutil ca --days 36500 bin/elasticsearch-certutil cert --ca elastic-stack-ca.p12 --days 36500 openssl pkcs12 -in elastic-certificates.p12 -out elastic-certificates.pem -nodes openssl x509 -in elastic-certificates.pem -noout -dates kubectl -n logging create secret generic elastic-certificates --from-file=elastic-certificates.p12 secretMounts: - name: elastic-certificates secretName: elastic-certificates path: /usr/share/elasticsearch/config/certs xpack.security.enabled: true xpack.security.transport.ssl.enabled: true xpack.security.transport.ssl.verification_mode: certificate xpack.security.transport.ssl.keystore.path: certs/elastic-certificates.p12 xpack.security.transport.ssl.truststore.path: certs/elastic-certificates.p12
Elasticsearch Helm Values配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 clusterName: "elasticsearch" nodeGroup: "logging" masterService: "elasticsearch-logging" esConfig: elasticsearch.yml: | xpack.security.enabled: true # 开启xpack.security, 所以需要下面ssl证书, 所以需要下面extraEnvs xpack.security.transport.ssl.enabled: true xpack.security.transport.ssl.verification_mode: certificate xpack.security.transport.ssl.keystore.path: certs/elastic-certificates.p12 xpack.security.transport.ssl.truststore.path: certs/elastic-certificates.p12 xpack.monitoring.enabled: true # 开启xpack.monitoring监控 xpack.monitoring.collection.enabled: true xpack.monitoring.exporters.my_local: # 监控数据export当前集群。用自己监控自己, not最佳实践 type: local use_ingest: false extraEnvs: - name: ELASTIC_USERNAME value: "elastic" - name: ELASTIC_PASSWORD value: "123456" secretMounts: - name: elastic-certificates secretName: elastic-certificates path: /usr/share/elasticsearch/config/certs esJavaOpts: "-Xmx1g -Xms1g" resources: requests: cpu: "1000m" memory: "2Gi" limits: cpu: "1000m" memory: "2Gi" volumeClaimTemplate: accessModes: [ "ReadWriteOnce" ] storageClassName: "openebs-hostpath" resources: requests: storage: 200Gi clusterHealthCheckParams: "wait_for_status=green&timeout=3s" ingress: enabled: true annotations: kubernetes.io/ingress.class: nginx path: / hosts: - elasticsearch.boer.xyz
Filebeat Filebeat Helm Values配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 --- filebeatConfig: filebeat.yml: | filebeat.inputs: - type: docker containers.ids: - '*' processors: - add_kubernetes_metadata: ~ - drop_fields: # drop掉不需要的字段 fields: ["ecs", "log", "input", "agent"] # 缩进很重要 ignore_missing: false setup.template.name: "kube-logging-template" setup.template.pattern: "kube-logging*" setup.ilm.enabled: false output.elasticsearch: host: '${NODE_NAME}' hosts: '${ELASTICSEARCH_HOSTS:elasticsearch-logging:9200}' index: "kube-logging" username: "elastic" password: "123456"
Kibana Kibana Helm Values配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 elasticsearchHosts: "http://elasticsearch-logging:9200" extraEnvs: - name: "NODE_OPTIONS" value: "--max-old-space-size=1800" - name: ELASTICSEARCH_USERNAME value: "elastic" - name: ELASTICSEARCH_PASSWORD value: "123456" healthCheckPath: "/app/kibana" kibanaConfig: kibana.yml: | elasticsearch: i18n.locale: "zh-CN" hosts: [ "http://elasticsearch-logging:9200" ] username: "elastic" password: "123456" ingress: enabled: true annotations: kubernetes.io/ingress.class: nginx path: / hosts: - logging.boer.xyz tls: []
Kibana Pod readinessProbe 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 http () { local path="${1} " set -- -XGET -s --fail if [ -n "${ELASTICSEARCH_USERNAME} " ] && [ -n "${ELASTICSEARCH_PASSWORD} " ]; then set -- "$@ " -u "${ELASTICSEARCH_USERNAME} :${ELASTICSEARCH_PASSWORD} " fi STATUS=$(curl --output /dev/null --write-out "%{http_code}" -k "$@ " "http://localhost:5601${path} " ) if [[ "${STATUS} " -eq 200 ]]; then exit 0 fi echo "Error: Got HTTP code ${STATUS} but expected a 200" exit 1 } curl -XGET -s --fail --output /dev/null --write-out "%{http_code}" -k -u elastic:123456 http://localhost:5601/app/kibana
iLM管理索引生命周期 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 GET _cluster/health GET _cat/indices PUT _ilm/policy/kube-logging-policy { "policy" : { "phases" : { "hot" : { "actions" : { "rollover" : { "max_size" : "50gb" , "max_age" : "1d" } } }, "warm" : { "min_age" : "2d" , "actions" : { "forcemerge" : { "max_num_segments" : 1 } } }, "cold" : { "min_age" : "5d" , "actions" : { "freeze" : {} } }, "delete" : { "min_age" : "10d" , "actions" : { "delete" : {} } } } } } PUT _template/kube-logging-template { "index_patterns" : ["kube-logging*" ], "settings" : { "number_of_shards" : 3, "number_of_replicas" : 1, "index.lifecycle.name" : "kube-logging-policy" , "index.lifecycle.rollover_alias" : "kube-logging" , "index.refresh_interval" : "30s" , "index.translog.durability" : "async" , "index.translog.sync_interval" :"30s" } } PUT %3Ckube-logging-%7Bnow%2Fd%7D-000001%3E { "aliases" : { "kube-logging" : {} } } GET kube-logging-2020.07.09-000001/_search PUT _cluster/settings { "persistent" : { "indices.lifecycle.poll_interval" : "30s" } } GET _ilm/status POST _ilm/start
ES进阶配置 1 2 3 4 5 6 cluster.routing.allocation.same_shard.host: true cluster.routing.allocation.awareness.attributes: box_type index.routing.allocation.require.box_type: hot index.routing.allocation.total_shards_per_node: 1
Filebeat配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 filebeat.inputs: - type: log paths: - /home/apps/Logs/*.boer.xyz/*.log fields: {ip: ipv4address , log_type: apps } fields_under_root: true multiline.match: after multiline.negate: true multiline.pattern: ^[0-9]{4}-[0-9]{2}-[0-9]{2} tail_files: true symlinks: true - type: log paths: [/home/apps/Logs/nginx/*.log ] fields: {ip: ipv4address , log_type: elb } fields_under_root: true tail_files: true symlinks: true - type: log paths: [/var/log/messages , /var/log/secure , /var/log/cron , /var/log/spooler , /var/log/audit/audit.log ] fields: {ip: ipv4address , log_type: syslog } fields_under_root: true tail_files: true symlinks: true - type: log paths: [/home/apps/Logs/*.boer.xyz/monitor/*.log ] fields: {ip: ipv4address , log_type: monitor } fields_under_root: true tail_files: true symlinks: true - type: log paths: - "/home/apps/Logs/*.boer.xyz/audit/*.log" fields: {ip: ipv4address , log_type: audit } fields_under_root: true tail_files: true symlinks: true processors: - rename: fields: - from: "log.file.path" to: "source" ignore_missing: false fail_on_error: true - drop_fields: fields: ["log" ,"ecs" ,"host" ,"agent" ] - drop_fields: when: equals: log_type: monitor fields: ["input_type" ,"source" ] output.kafka: hosts: ["node1.kafka.boer.lo:9092" , "node2.kafka.boer.lo:9092" , "node3.kafka.boer.lo:9092" , "node4.kafka.boer.lo:9092" ] topic: "%{[log_type]} " partition.round_robin: reachable_only: false required_acks: 1 compression: lz4 max_message_bytes: 1000000
Logstash配置 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 elasticsearch: host: elasticsearch-logging port: 9200 config: xpack.monitoring.enabled: true xpack.monitoring.elasticsearch.hosts: ["http://elasticsearch-logging:9200" ] xpack.monitoring.elasticsearch.username: "logstash_system" xpack.monitoring.elasticsearch.password: "t6XK9kDvistPyuSvVwK3" config.reload.automatic: true config.reload.interval: 120 path.config: /usr/share/logstash/pipeline path.data: /usr/share/logstash/data pipeline.workers: 12 pipeline.batch.size: 16000 pipeline.batch.delay: 10 queue.type: memory queue.max_bytes: 5gb inputs: main: |- input { kafka { bootstrap_servers => "10.10.62.38:9092,10.10.62.39:9092,10.10.62.40:9092" topics => ["app"] client_id => "app-logs" group_id => ["app-logs"] max_poll_records => "8000" consumer_threads => 4 codec => "json" } } filters: main: |- filter { grok { break_on_match => false pattern_definitions => { "TXID_PRE" => "TxId\s*\:\s*" "SDOT_SUF" => "\s+\," } match => { "source" => "/home/boer/Logs/%{GREEDYDATA:app_name}.(boer|boermall).(lo|com|xyz)/%{GREEDYDATA:app_logfile}.log" "message" => "%{TIMESTAMP_ISO8601:log_timestamp}%{SPACE}%{WORD:log_level}%{DATA}%{TXID_PRE}%{DATA:log_txid}%{SDOT_SUF}%{GREEDYDATA}" } remove_field => [ "offset", "input_type", "input.type", "type", "tag", "source" ] } } outputs: main: |- output { elasticsearch { hosts => ["http://elasticsearch-logging:9200"] index => "app-logs" user => "elastic" password => "rAQc9m19NdWcFIfLgNVQ" } }