K8S环境 使用ELK+Filebeat 收集容器日志的方案和安装部署

前言

看到这篇文章的同学相信对K8S已经有一定的了解了,现在很多公司都使用K8S来部署自己的应用,使用K8S来发布应用确实很好,但是日志查看方面还是有诸多的不便,比如主机权限不能随便开放,并且公司层面的K8S 集群内应用数和副本数都比较多,问题定位时不知道从那个副本的日志开始查看,还有一个是容器的重启后想查看重启之前的日志等等问题,造成了在K8S集群查看日志的诸多不便。
所以引申出下面的方案设计

方案说明

此方案 使用 ELK +Filebeat 的架构。
本来 ELK 就能实现日志采集,查询和展示,由于 logstash资源占用比较大(800M+内存),官方使用 GO语言重写了一个Filebeat实现了部分 logstash的功能,资源占用( 30M+) 指数级的资源占用下降,但是日志解析方面还做得不到位,所以我们使用 filebeat采集日志, logstash来进行解析的设计。
Filebeat 使用DaemonSet 部署负责收集每个节点的所有应用日志数据上报 Logstash ,Logstash 对数据进行一次处理,推送到 ES ,最后使用 Kibana进行展示 。

架构图

在这里插入图片描述
画了一个简易架构图来说明:
K8S的应用,默认会把标准输出日志,生成一个文件,通过软链接的方式挂载到节点主机的 /var/log/containers 目录,我们在每个节点部署一个Filebeat去采集这个目录下的内容就OK了

安装部署

相关的chart已经上传 github.com 点击此处 ELK+Filbeat 下载原码
或者 码云下载

我们这里使用 helm来安装,helm安装特别简单,没啥说的,主要是chart编写,详情这里就不说了,点击之处了解 ,安装命令在最后,现把主要的编排内容摘抄如下:

ES编排文件

kind: StatefulSet
metadata:
  name: enervated-puma-elasticsearch
  labels:
    heritage: "Tiller"
    release: "enervated-puma"
    chart: "elasticsearch"
    app: "enervated-puma-elasticsearch"
  annotations:
    esMajorVersion: "7"
spec:
  serviceName: enervated-puma-elasticsearch-headless
  selector:
    matchLabels:
      app: "enervated-puma-elasticsearch"
  replicas: 1
  podManagementPolicy: Parallel
  updateStrategy:
    type: RollingUpdate
  template:
    metadata:
      name: "enervated-puma-elasticsearch"
      labels:
        heritage: "Tiller"
        release: "enervated-puma"
        chart: "elasticsearch"
        app: "enervated-puma-elasticsearch"
      annotations:

    spec:
      securityContext:
        fsGroup: 1000
        runAsUser: 1000

      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - "enervated-puma-elasticsearch"
            topologyKey: kubernetes.io/hostname
      terminationGracePeriodSeconds: 120
      volumes:
      initContainers:
      - name: configure-sysctl
        securityContext:
          runAsUser: 0
          privileged: true
        image: "docker.elastic.co/elasticsearch/elasticsearch:7.5.0"
        imagePullPolicy: "Always"
        command: ["sysctl", "-w", "vm.max_map_count=262144"]
        resources:
          {}


      containers:
      - name: "elasticsearch"
        securityContext:
          capabilities:
            drop:
            - ALL
          runAsNonRoot: true
          runAsUser: 1000

        image: "docker.elastic.co/elasticsearch/elasticsearch:7.5.0"
        imagePullPolicy: "Always"
        readinessProbe:
          failureThreshold: 3
          initialDelaySeconds: 10
          periodSeconds: 10
          successThreshold: 3
          timeoutSeconds: 5

          exec:
            command:
              - sh
              - -c
              - |
                #!/usr/bin/env bash -e
                # If the node is starting up wait for the cluster to be ready (request params: 'wait_for_status=green&timeout=1s' )
                # Once it has started only check that the node itself is responding
                START_FILE=/tmp/.es_start_file

                http () {
                    local path="${1}"
                    if [ -n "${ELASTIC_USERNAME}" ] && [ -n "${ELASTIC_PASSWORD}" ]; then
                      BASIC_AUTH="-u ${ELASTIC_USERN
<think>好的,用户想在Kubernetes中部署ELK堆栈来收集日志。首先,我需要回忆一下ELK的各个组件以及它们在K8s中的部署方式。ELK包括Elasticsearch、LogstashKibana,但现在通常会用Filebeat代替Logstash,因为Filebeat更轻量,适合日志采集。不过用户提到的是ELK,可能还是需要Logstash?或者可能混淆了EFK(Elasticsearch、Fluentd、Kibana)ELK。根据用户提供的引用,他们之前提到过EFKFilebeat,所以可能需要确认用户的意图,但根据问题描述,用户明确说ELK,所以可能需要调整。 接下来,查看用户提供的引用内容。引用12提到了EFKELK,引用3提到了使用SideCar模式部署Filebeat。但用户现在问的是ELK,所以可能需要结合这些信息。ELK中的Logstash通常用于日志处理,而Filebeat用于收集。不过,在K8s中常见的做法是使用Filebeat或Fluentd作为日志收集器,然后发送到Elasticsearch。所以可能需要确定用户的ELK具体指哪个架构,是包含Logstash还是用Filebeat代替。 用户的问题是在K8s部署ELK堆栈用于日志采集。根据引用2,ELK部署过程包括集中式日志管理、实时分析监控报警。引用3提到两种部署方式:DaemonSetSideCar模式。可能需要在回答中涵盖这两种方法,并给出具体的部署步骤。 首先,需要部署Elasticsearch,作为存储搜索引擎。在K8s中,通常使用StatefulSet来部署有状态应用,并配置持久化存储。需要创建Service来暴露Elasticsearch的端口。 然后,部署Logstash(如果用户确实需要的话),或者使用Filebeat作为日志收集器。根据引用3,Filebeat可以作为SideCar或者DaemonSet部署。如果使用DaemonSet,每个节点运行一个Filebeat实例,收集节点上的日志;如果是SideCar模式,每个Pod中运行一个Filebeat容器收集该Pod的日志。需要根据用户的需求选择合适的方式,并配置Filebeat日志发送到Elasticsearch。 接下来是部署Kibana,用于可视化。需要创建DeploymentService,并配置连接到Elasticsearch的URL。 另外,用户引用1提到EFK的部署,其中可能包括Filebeat。可能需要比较ELKEFK的区别,但用户的问题明确是ELK,所以可能需要调整步骤。 此外,用户引用1还提到Kibana的认证问题,可以通过Nginx配置密码。这可能是一个后续的安全建议,可以在回答中提及。 现在需要整理步骤:部署Elasticsearch -> 部署Logstash(如果需要) -> 部署Filebeat(DaemonSet或SideCar) -> 部署Kibana。同时,根据引用2中的ELK日志收集过程,可能需要Filebeat直接发送到Elasticsearch,或者通过Logstash处理。但根据常见架构,可能用户需要的是使用Filebeat收集日志,发送到Elasticsearch,然后通过Kibana展示,即EFK。但用户明确要求ELK,可能需要包括Logstash。不过这可能增加复杂性,所以需要确认。 或者,可能用户将ELKEFK混用,实际需要的是EFK。但根据问题描述,必须按ELK来处理。因此,可能需要包括Logstash的部署步骤。但根据引用2中的描述,ELK使用Filebeat实时发送到Elasticsearch,可能Logstash不在其中。这里可能存在混淆,需要理清。 可能正确的步骤是: 1. 部署Elasticsearch:使用StatefulSet,持久化存储,Headless Service。 2. 部署Filebeat:作为DaemonSet或SideCar收集日志,发送到Elasticsearch。 3. 部署Kibana:通过DeploymentService,连接到Elasticsearch。 此时,如果用户要求ELK,可能需要将Logstash包含进去,但根据引用2中的描述,ELK可能指的是Elasticsearch、Logstash、Kibana,而Filebeat作为收集器。这种情况下,Filebeat收集日志后发送到Logstash进行处理,再由Logstash发送到Elasticsearch。但这样会增加Logstash的部署步骤。 需要明确ELK的标准架构,但在K8s环境中,可能更常见的是EFK(Elasticsearch、Fluentd/Fluent Bit、Kibana)或者使用Filebeat直接发送到Elasticsearch。因此,用户的问题可能存在术语混淆,可能需要根据引用中的信息调整回答。 根据用户提供的引用,引用2提到的是ELK日志收集,其中使用Filebeat发送到Elasticsearch,所以可能ELK在这里指的是Elasticsearch、Logstash、Kibana,但实际流程中Filebeat替代了Logstash的角色。或者可能Logstash不在此架构中,而由Filebeat直接发送到Elasticsearch,构成EFK。这可能造成混乱,但用户明确询问ELK,所以可能需要按照包含Logstash的情况来回答。 不过,根据引用2中的描述,“通过 Filebeat日志数据实时发送到 Elasticsearch”,所以可能ELK在这里是笔误,应为EFK。但用户的问题明确为ELK,所以需要处理这种不一致。可能需要指出这一点,或者在回答中说明ELK的不同部署方式,包括使用Filebeat的情况。 考虑到用户的引用中提到了Filebeat作为日志收集器,可能用户实际上需要的是EFK,但问题写成了ELK。可能需要指出这一点,并给出两种可能的方案使用Logstash的ELK,或使用Filebeat的EFK,并询问用户是否需要调整。但根据问题,用户可能希望得到ELK部署步骤,所以需要包含Logstash。 因此,步骤可能如下: 1. 部署Elasticsearch:StatefulSet,持久化卷。 2. 部署Logstash:处理日志,可能需要配置管道,从Filebeat接收日志,然后输出到Elasticsearch。 3. 部署Filebeat:作为DaemonSet或SideCar收集日志,发送到Logstash。 4. 部署Kibana:用于可视化。 但这样会增加复杂性,可能用户更倾向于使用Filebeat直接发送到Elasticsearch,无需Logstash。因此,可能需要给出两种方案,或者根据引用中的信息,推荐使用Filebeat直接到Elasticsearch的方式,即EFK,并说明ELKEFK的区别。 但用户的问题明确是ELK,所以可能需要按照包含Logstash的方式来回答。这可能不太符合引用中的内容,因为引用2中的ELK流程使用Filebeat到Elasticsearch。因此,可能存在术语混淆,需要明确。 在这种情况下,可能最佳做法是按照用户的问题回答,即使可能存在术语差异,并在回答中说明可能的架构选择,例如使用Filebeat代替Logstash的情况,或者包括Logstash作为处理层。 现在,整理具体步骤: 首先部署Elasticsearch: - 创建命名空间,如logging。 - 使用StatefulSet部署Elasticsearch,配置持久化存储(PVC),设置discovery.type为single-node(如果是测试环境)或配置集群。 然后部署Logstash(如果使用): - 创建ConfigMap存储Logstash的配置文件,配置输入(如beats接收)、过滤器输出到Elasticsearch。 - 部署Logstash的DeploymentService,暴露5044端口接收Filebeat的数据。 部署Filebeat: - 作为DaemonSet部署,配置收集宿主机的日志路径(如/var/log/containers/*.log),然后输出到Logstash或直接到Elasticsearch。 或者使用SideCar模式,每个应用Pod中添加Filebeat容器收集特定日志。 最后部署Kibana: - 创建DeploymentService,配置Elasticsearch的地址,并暴露服务,可能需要Ingress或NodePort访问。 此外,安全方面,如引用1提到的Kibana的认证,可以通过Nginx反向代理添加基本身份验证。 需要提供具体的YAML示例,例如Elasticsearch的StatefulSet,Filebeat的DaemonSet配置,Kibana的Deployment等。 另外,用户引用3提到SideCar模式部署Filebeat,这可能更适合收集特定Pod的日志,而DaemonSet适合收集节点级别的日志。需要解释这两种方式的优缺点。 总结步骤: 1. 创建命名空间。 2. 部署Elasticsearch集群(StatefulSet)。 3. 部署Logstash(如果需要处理日志)。 4. 部署Filebeat(DaemonSet或SideCar)。 5. 部署Kibana。 6. 配置Kibana索引模式,可视化日志。 同时,需要提及持久化存储的重要性,特别是对于Elasticsearch的数据。此外,调整资源请求限制,确保Pod有足够资源运行。 最后,生成相关问题,例如性能优化、安全配置、不同收集模式的比较等。</think>### 在 Kubernetes 中部署 ELK 堆栈的步骤 #### 1. 创建命名空间 为日志系统创建独立的命名空间,隔离资源: ```yaml apiVersion: v1 kind: Namespace metadata: name: logging ``` #### 2. 部署 Elasticsearch Elasticsearch 是核心存储检索组件,需使用 `StatefulSet` 保障数据持久性: ```yaml # elasticsearch-statefulset.yaml apiVersion: apps/v1 kind: StatefulSet metadata: name: elasticsearch namespace: logging spec: serviceName: elasticsearch replicas: 1 # 生产环境建议至少3节点 selector: matchLabels: app: elasticsearch template: metadata: labels: app: elasticsearch spec: containers: - name: elasticsearch image: docker.elastic.co/elasticsearch/elasticsearch:7.14.0 ports: - containerPort: 9200 volumeMounts: - name: data mountPath: /usr/share/elasticsearch/data env: - name: discovery.type value: single-node # 单节点模式,集群需调整 volumes: - name: data persistentVolumeClaim: claimName: elasticsearch-pvc # 创建持久化存储声明(PVC) apiVersion: v1 kind: PersistentVolumeClaim metadata: name: elasticsearch-pvc namespace: logging spec: accessModes: - ReadWriteOnce resources: requests: storage: 10Gi # 创建服务暴露端口 apiVersion: v1 kind: Service metadata: name: elasticsearch namespace: logging spec: ports: - port: 9200 name: http clusterIP: None # Headless Service selector: app: elasticsearch ``` #### 3. 部署 Filebeat日志收集器) ##### 方案一:DaemonSet 模式(节点级日志收集) ```yaml # filebeat-daemonset.yaml apiVersion: apps/v1 kind: DaemonSet metadata: name: filebeat namespace: logging spec: selector: matchLabels: app: filebeat template: metadata: labels: app: filebeat spec: containers: - name: filebeat image: docker.elastic.co/beats/filebeat:7.14.0 volumeMounts: - name: varlog mountPath: /var/log/containers readOnly: true - name: config mountPath: /usr/share/filebeat/filebeat.yml subPath: filebeat.yml volumes: - name: varlog hostPath: path: /var/log/containers - name: config configMap: name: filebeat-config # 配置文件映射 apiVersion: v1 kind: ConfigMap metadata: name: filebeat-config namespace: logging data: filebeat.yml: | filebeat.inputs: - type: log paths: - /var/log/containers/*.log processors: - add_kubernetes_metadata: # 自动添加K8s元数据 host: ${NODE_NAME} output.elasticsearch: hosts: ["elasticsearch.logging.svc.cluster.local:9200"] ``` ##### 方案二:Sidecar 模式(Pod 级别日志收集) 在业务 Pod 中添加 Filebeat 容器: ```yaml apiVersion: v1 kind: Pod metadata: name: myapp namespace: default spec: containers: - name: app image: myapp:latest volumeMounts: - name: app-logs mountPath: /var/log/app - name: filebeat # Sidecar容器 image: docker.elastic.co/beats/filebeat:7.14.0 volumeMounts: - name: app-logs mountPath: /var/log/app - name: config mountPath: /usr/share/filebeat/filebeat.yml subPath: filebeat.yml volumes: - name: app-logs emptyDir: {} - name: config configMap: name: filebeat-sidecar-config ``` #### 4. 部署 Kibana(可视化) ```yaml # kibana-deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: kibana namespace: logging spec: replicas: 1 selector: matchLabels: app: kibana template: metadata: labels: app: kibana spec: containers: - name: kibana image: docker.elastic.co/kibana/kibana:7.14.0 env: - name: ELASTICSEARCH_HOSTS value: "http://elasticsearch.logging.svc.cluster.local:9200" ports: - containerPort: 5601 --- apiVersion: v1 kind: Service metadata: name: kibana namespace: logging spec: type: NodePort # 或使用Ingress ports: - port: 5601 targetPort: 5601 nodePort: 30601 selector: app: kibana ``` #### 5. 配置安全认证(可选) 通过 Nginx 反向代理为 Kibana 添加基础认证[^1]: ```nginx server { listen 80; server_name kibana.example.com; auth_basic "Restricted Access"; auth_basic_user_file /etc/nginx/.htpasswd; location / { proxy_pass http://kibana.logging.svc.cluster.local:5601; } } ``` ### 验证部署 1. 检查 Elasticsearch 健康状态: ```bash curl http://elasticsearch.logging.svc.cluster.local:9200/_cluster/health ``` 2. 在 Kibana 界面(通过 `http://<NodeIP>:30601`)创建索引模式 `filebeat-*`,即可查询日志。 ### 关键优化点 - **性能调优**:Elasticsearch 需根据数据量调整 JVM 堆大小分片数。 - **高可用**:Elasticsearch 应部署为多节点集群[^2]。 - **日志过滤**:通过 Filebeat 的 `processors` 字段添加日志过滤规则。
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值