基于ECK的下一代日志收集框架
十八岁
k8s日志收集-基于ECK的下一代日志收集框架
1.哪些日志需要收集
做日志收集首先需要明确有哪些日志需要收集:

- 操作系统日志 /var/log/messages
- k8s组件日志(如果有分类的话按照分类的路径找到日志文件,笔记中的集群没有分类组件日志,也在/var/log/messages中)
- 业务应用程序的日志 :包含云原生日志-输出到控制台(/var/log/containers);非云原生日志-输出到本地文件(容器内日志文件)
2.收集日志常用的技术栈
ELK技术栈:Elasticsearch、Logstash、Kibana(传统架构)
EFK技术栈:Elasticsearch、Fluentd、Kibana(Fluentd在针对亿级流量有缺陷,此时可以替换为Filebeat或者Fluent-bit)(kubernetes架构推荐使用Elasticsearch+Filebeat+Kibana组合)
3.日志收集工具对比

4.云原生应用日志收集框架

5.非云原生应用日志框架

6.操作系统及k8s组件日志收集框架

7.云原生日志框架—ECK
ECK 全称是 Elastic Cloud on Kubernetes。记住最关键的一句话:
ECK 不是一种新的日志采集框架,也不是 ELK/EFK 的替代品;ECK 是 Elastic 官方提供的 Kubernetes Operator,用来在 Kubernetes 中部署和管理 Elasticsearch、Kibana 等 Elastic Stack 组件。
也就是说,ELK/EFK 解决的是“日志怎么采、怎么存、怎么看”,而 ECK 主要解决的是:
这些 Elastic 组件在 Kubernetes 里怎么部署、扩容、升级、维护。

8.ECK核心资源Elasticsearch资源定义
Elasticsearch主要作用:分布式、RESTful 风格的搜索和分析引擎。负责存储、索引、搜索和分析海量数据
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
| apiVersion: elasticsearch.k8s.elastic.co/v1 kind: Elasticsearch metadata: name: es-cluster namespace: logging spec: version: 9.5.2 image: registry.cn-beijing.aliyuncs.com/k8s-liujunwei/elasticsearch:9.5.2 nodeSets: - name: default count: 3 volumeClaimTemplates: - metadata: name: elasticsearch-data spec: accessModes: - ReadWriteOnce resources: requests: storage: 20Gi storageClassName: cfs-sc podTemplate: spec: volumes: - name: elasticsearch-data emptyDir: {} initContainers: - name: sysctl securityContext: privileged: true runAsUser: 0 command: - sh - -c - sysctl -w vm.max_map_count=1048576
|
9.ECK核心资源Kibana资源定义
Kibana主要作用:Elastic Stack 的官方 Web 用户界面,可视化的查询日志。
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
| apiVersion: kibana.k8s.elastic.co/v1 kind: Kibana metadata: name: kibana namespace: logging spec: version: 9.5.2 image: registry.cn-beijing.aliyuncs.com/k8s-liujunwei/kibana:9.5.2
count: 2
elasticsearchRef: name: es-cluster
config: server.publicBaseUrl: "https://kibana.jiugen.cn" secureSettings: - secretName: kibana-encryption-keys
http: service: spec: type: ClusterIP
podTemplate: spec: containers: - name: kibana env: - name: NODE_OPTIONS value: "--max-old-space-size=2048" resources: requests: memory: 2Gi cpu: "1" limits: memory: 2Gi cpu: "2" affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100 podAffinityTerm: labelSelector: matchLabels: common.k8s.elastic.co/type: elasticsearch topologyKey: kubernetes.io/hostname
|
10.ECK核心资源Logstash资源定义
主要作用:服务器端的数据处理管道。负责从多种来源采集、转换(过滤/解析)、丰富数据,然后将其发送到指定的输出端(通常是 Elasticsearch)。
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 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139
| apiVersion: logstash.k8s.elastic.co/v1alpha1 kind: Logstash metadata: name: logstash namespace: logging spec: version: 9.5.2 image: registry.cn-beijing.aliyuncs.com/k8s-liujunwei/logstash:9.5.2
count: 3
elasticsearchRefs: - name: es-cluster clusterName: es-cluster namespace: logging pipelines: - pipeline.id: main config.string: | input { kafka { # Kafka 集群初始连接地址(host:port)。客户端通过它发现整个集群的 broker 列表。 # 生产环境优先使用 K8s 内部 DNS(如 kafka.logging.svc.cluster.local:9092)。 bootstrap_servers => "kafka.logging.svc.cluster.local:9092" # 要消费的 Kafka 主题列表。支持多个主题,用数组表示。 # 按业务拆分主题可提升隔离性与扩展性。 topics => ["k8spodlogs"] # 指定消费的 Kafka topic group_id => "logstash-logging-prod" # 消费者组名,用于分摊分区,自定义一个名字即可 codec => json #消息解码方式
consumer_threads => 1 enable_auto_commit => true auto_commit_interval_ms => "1000" auto_offset_reset => "earliest"
security_protocol => "SASL_PLAINTEXT" sasl_mechanism => "SCRAM-SHA-256" sasl_jaas_config => 'org.apache.kafka.common.security.scram.ScramLoginModule required username="${KAFKA_USERNAME}" password="${KAFKA_PASSWORD}";' } }
output { elasticsearch { hosts => ["https://es-cluster-es-http:9200"] index => "k8spodlogs-%{+YYYY.MM.dd}" user => "${ELASTICSEARCH_USERNAME}" password => "${ELASTICSEARCH_PASSWORD}" ssl_enabled => true ssl_certificate_authorities => "${ES_CLUSTER_ES_SSL_CERTIFICATE_AUTHORITY}" } } podTemplate: spec: containers: - name: logstash resources: requests: cpu: "500m" memory: "1Gi" limits: cpu: "1" memory: "2Gi" env: - name: KAFKA_USERNAME valueFrom: secretKeyRef: name: logstash-credentials key: kafka-username - name: KAFKA_PASSWORD valueFrom: secretKeyRef: name: logstash-credentials key: kafka-password - name: ELASTICSEARCH_USERNAME value: "elastic" - name: ELASTICSEARCH_PASSWORD valueFrom: secretKeyRef: name: es-cluster-es-elastic-user key: elastic
volumeClaimTemplates: - metadata: name: logstash-data spec: accessModes: - ReadWriteOnce storageClassName: cfs-sc resources: requests: storage: 20Gi
|
11.ECK核心资源Beat资源定义
主要作用:安装在数据源(主机、容器、网络设备)上的轻量级代理,负责单向发送数据。
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 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240
| apiVersion: beat.k8s.elastic.co/v1beta1 kind: Beat metadata: name: filebeat namespace: logging labels: app: filebeat spec: type: filebeat version: "9.5.2" image: registry.cn-beijing.aliyuncs.com/k8s-liujunwei/filebeat:9.5.2
config: name: "filebeat-${NODE_NAME}" logging.level: info logging.to_stderr: true logging.metrics.enabled: false
filebeat.autodiscover: providers: - type: kubernetes node: ${NODE_NAME} hints.enabled: true hints.default_config: type: filestream id: "kubernetes-container-${data.kubernetes.container.id}" paths: - /var/log/containers/*${data.kubernetes.container.id}.log
prospector.scanner: fingerprint.enabled: true symlinks: true file_identity.fingerprint: {} close.on_state_change.removed: false ignore_older: 72h close.on_state_change.inactive: 5m clean_inactive: 96h fields: log_topic: k8spodlogs cluster: production fields_under_root: false
processors:
- add_host_metadata: when.not.contains.tags: forwarded netinfo.enabled: true - drop_event: when: equals: kubernetes.container.name: "filebeat" - drop_event: when: not: or: - equals: kubernetes.namespace: "monitoring" - equals: kubernetes.namespace: "kube-system"
output.kafka: hosts: - "kafka.logging.svc.cluster.local:9092" topic: "k8spodlogs"
required_acks: 1 compression: gzip max_message_bytes: 1000000
username: "user1" password: "${KAFKA_PASSWORD}" sasl.mechanism: "SCRAM-SHA-256" queue.mem: events: 4096 flush.min_events: 512 flush.timeout: 5s
http.enabled: true http.host: localhost http.port: 5066
daemonSet: updateStrategy: type: RollingUpdate rollingUpdate: maxUnavailable: 1 podTemplate: metadata: labels: app: filebeat k8s-app: filebeat annotations: co.elastic.logs/enabled: "false" spec: serviceAccountName: filebeat automountServiceAccountToken: true
hostNetwork: true dnsPolicy: ClusterFirstWithHostNet
securityContext: runAsUser: 0
terminationGracePeriodSeconds: 30
containers: - name: filebeat
env: - name: NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName - name: KAFKA_PASSWORD valueFrom: secretKeyRef: name: kafka-user-passwords key: client-passwords
volumeMounts: - name: varlogcontainers mountPath: /var/log/containers
- name: varlogpods mountPath: /var/log/pods
- name: varlibdockercontainers mountPath: /var/lib/docker/containers
- name: data mountPath: /usr/share/filebeat/data
volumes: - name: varlogcontainers hostPath: path: /var/log/containers - name: varlogpods hostPath: path: /var/log/pods - name: varlibdockercontainers hostPath: path: /var/lib/docker/containers
- name: data hostPath: path: /var/lib/filebeat-data type: DirectoryOrCreate
|
11.1Filebeat Autodiscover自动发现解析
详细解读参考案例中的配置

详细解读参考案例中的配置
