Logging with Fluentd

本文介绍如何配置Istio创建定制日志并将日志发送到Fluentd,再通过Fluentd转发到Elasticsearch存储,最后使用Kibana进行日志查看。通过部署示例栈和配置Istio,可以实现对Bookinfo应用的日志记录。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这个task展示如何配置Istio去创建定制日志记录并发送它们到Fluentd 后台进程。Fluentd 是一个开源日志收集器,支持多种数据输出类型( data outputs ),并有一个可插拔的架构。一个流行的日志后端是 Elasticsearch,,然后使用 Kibana 作为查看器。完成这个task后,一个新的日志流将会发送日志到 Fluentd / Elasticsearch / Kibana 栈中。

这个task中使用 Bookinfo 示例。

Before you begin

  • 在集群中安装Istio并部署一个应用。这个task假设Mixer以默认配置安装(--configDefaultNamespace=istio-system)。如果你使用不同的值,在这个task中更新配置和命令中对应值。

Setup Fluentd

在你的集群中,你可能已经有一个Fluentd 后台进程正在运行,像 here and here所描述的插件,或者你的集群提供的特定内容。这可以通过配置发送日志到Elasticsearch 系统或日志提供者。

你可能使用这些Fluentd 后台进程,或其他你建立的Fluentd 后台进程,只要它们监听转发日志,并且Mixer能够和它们建立连接。为了Mixer能够连接一个运行的Fluentd 后台进程,你可能需要添加一个Fluentd 的 service 。监听转发日志的 Fluentd 配置如下:

<source>
  type forward
</source>

将Mixer连接到所有可能的Fluentd配置的完整细节不在本task讨论范围内。

Example Fluentd,Elasticsearch,Kibana Stack

为了达到这个task的目的,你可能要部署提供的示例栈。这个栈包括 Fluentd, Elasticsearch, and Kibana ,它们都位于一个名为logging 的新命名空间,是一组不在生产环境中的 Services and Deployments

保存下面内容到 logging-stack.yaml.

# Logging Namespace. All below are a part of this namespace.
apiVersion: v1
kind: Namespace
metadata:
  name: logging
---
# Elasticsearch Service
apiVersion: v1
kind: Service
metadata:
  name: elasticsearch
  namespace: logging
  labels:
    app: elasticsearch
spec:
  ports:
  - port: 9200
    protocol: TCP
    targetPort: db
  selector:
    app: elasticsearch
---
# Elasticsearch Deployment
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: elasticsearch
  namespace: logging
  labels:
    app: elasticsearch
  annotations:
    sidecar.istio.io/inject: "false"
spec:
  template:
    metadata:
      labels:
        app: elasticsearch
    spec:
      containers:
      - image: docker.elastic.co/elasticsearch/elasticsearch-oss:6.1.1
        name: elasticsearch
        resources:
          # need more cpu upon initialization, therefore burstable class
          limits:
            cpu: 1000m
          requests:
            cpu: 100m
        env:
          - name: discovery.type
            value: single-node
        ports:
        - containerPort: 9200
          name: db
          protocol: TCP
        - containerPort: 9300
          name: transport
          protocol: TCP
        volumeMounts:
        - name: elasticsearch
          mountPath: /data
      volumes:
      - name: elasticsearch
        emptyDir: {}
---
# Fluentd Service
apiVersion: v1
kind: Service
metadata:
  name: fluentd-es
  namespace: logging
  labels:
    app: fluentd-es
spec:
  ports:
  - name: fluentd-tcp
    port: 24224
    protocol: TCP
    targetPort: 24224
  - name: fluentd-udp
    port: 24224
    protocol: UDP
    targetPort: 24224
  selector:
    app: fluentd-es
---
# Fluentd Deployment
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: fluentd-es
  namespace: logging
  labels:
    app: fluentd-es
  annotations:
    sidecar.istio.io/inject: "false"
spec:
  template:
    metadata:
      labels:
        app: fluentd-es
    spec:
      containers:
      - name: fluentd-es
        image: gcr.io/google-containers/fluentd-elasticsearch:v2.0.1
        env:
        - name: FLUENTD_ARGS
          value: --no-supervisor -q
        resources:
          limits:
            memory: 500Mi
          requests:
            cpu: 100m
            memory: 200Mi
        volumeMounts:
        - name: config-volume
          mountPath: /etc/fluent/config.d
      terminationGracePeriodSeconds: 30
      volumes:
      - name: config-volume
        configMap:
          name: fluentd-es-config
---
# Fluentd ConfigMap, contains config files.
kind: ConfigMap
apiVersion: v1
data:
  forward.input.conf: |-
    # Takes the messages sent over TCP
    <source>
      type forward
    </source>
  output.conf: |-
    <match **>
       type elasticsearch
       log_level info
       include_tag_key true
       host elasticsearch
       port 9200
       logstash_format true
       # Set the chunk limits.
       buffer_chunk_limit 2M
       buffer_queue_limit 8
       flush_interval 5s
       # Never wait longer than 5 minutes between retries.
       max_retry_wait 30
       # Disable the limit on the number of retries (retry forever).
       disable_retry_limit
       # Use multiple threads for processing.
       num_threads 2
    </match>
metadata:
  name: fluentd-es-config
  namespace: logging
---
# Kibana Service
apiVersion: v1
kind: Service
metadata:
  name: kibana
  namespace: logging
  labels:
    app: kibana
spec:
  ports:
  - port: 5601
    protocol: TCP
    targetPort: ui
  selector:
    app: kibana
---
# Kibana Deployment
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: kibana
  namespace: logging
  labels:
    app: kibana
  annotations:
    sidecar.istio.io/inject: "false"
spec:
  template:
    metadata:
      labels:
        app: kibana
    spec:
      containers:
      - name: kibana
        image: docker.elastic.co/kibana/kibana-oss:6.1.1
        resources:
          # need more cpu upon initialization, therefore burstable class
          limits:
            cpu: 1000m
          requests:
            cpu: 100m
        env:
          - name: ELASTICSEARCH_URL
            value: http://elasticsearch:9200
        ports:
        - containerPort: 5601
          name: ui
          protocol: TCP
---

新建资源:

kubectl apply -f logging-stack.yaml

你将看到如下内容:

namespace "logging" created
service "elasticsearch" created
deployment "elasticsearch" created
service "fluentd-es" created
deployment "fluentd-es" created
configmap "fluentd-es-config" created
service "kibana" created
deployment "kibana" created

Configure Istio

现在这有一个正在运行的Fluentd 后台进程,用一个新的日志类型来配置Istio,并发送这些日志到监听后台进程。新建一个YAML文件来保存Istio自动生成和收集日志流的配置:
保存如下内容到fluentd-istio.yaml:

# Configuration for logentry instances
apiVersion: "config.istio.io/v1alpha2"
kind: logentry
metadata:
  name: newlog
  namespace: istio-system
spec:
  severity: '"info"'
  timestamp: request.time
  variables:
    source: source.labels["app"] | source.service | "unknown"
    user: source.user | "unknown"
    destination: destination.labels["app"] | destination.service | "unknown"
    responseCode: response.code | 0
    responseSize: response.size | 0
    latency: response.duration | "0ms"
  monitored_resource_type: '"UNSPECIFIED"'
---
# Configuration for a fluentd handler
apiVersion: "config.istio.io/v1alpha2"
kind: fluentd
metadata:
  name: handler
  namespace: istio-system
spec:
  address: "fluentd-es.logging:24224"
---
# Rule to send logentry instances to the fluentd handler
apiVersion: "config.istio.io/v1alpha2"
kind: rule
metadata:
  name: newlogtofluentd
  namespace: istio-system
spec:
  match: "true" # match for all requests
  actions:
   - handler: handler.fluentd
     instances:
     - newlog.logentry
---

新建资源:

istioctl create -f fluentd-istio.yaml

预期输出类似:

Created config logentry/istio-system/newlog at revision 22374
Created config fluentd/istio-system/handler at revision 22375
Created config rule/istio-system/newlogtofluentd at revision 22376

注意 address: "fluentd-es.logging:24224" 行在处理器配置中指定了在示例栈中我们建立的Fluentd 后台进程。

View the new logs

1, 为示例应用发送流量。
对于 Bookinfo ,在你的浏览器中访问 http://$GATEWAY_URL/productpage 或执行如下命令:

curl http://$GATEWAY_URL/productpage

2.在k8s环境中,通过如下命令设置Kibana 的端口转发:

kubectl -n logging port-forward $(kubectl -n logging get pod -l app=kibana -o jsonpath='{.items[0].metadata.name}') 5601:5601

让这个命令运行,当能够访问 Kibana UI时,按 Ctrl-C 退出。

3.操作 Kibana UI 并点击右上角 “Set up index patterns”。

4.使用 * 作为索引模式,然后点击 “Next step.”。

5.选择 @timestamp 作为 Time Filter 列名,然后点击“Create index pattern.”。

6.现在在左菜单点击“Discover” ,然后开始发现生成的日志。

Cleanup

  • 移除新的遥测配置:
istioctl delete -f fluentd-istio.yaml
  • 移除示例 Fluentd, Elasticsearch, Kibana 栈:
kubectl delete -f logging-stack.yaml
  • 如果你不打算探索接下来地任何课题,参考 Bookinfo cleanup 指南来关闭应用。
<think>嗯,用户的问题是关于在Kubernetes中使用DaemonSet(ds)部署Fluentd时是否需要将宿主机的文件挂载到容器中的。首先,我需要确认用户对FluentdDaemonSet的理解程度。可能用户已经了解DaemonSet的基本概念,但可能在具体配置时遇到了问题,或者想确认自己的配置是否正确。 Fluentd作为日志收集工具,通常需要访问每个节点上的日志文件。DaemonSet确保每个节点运行一个Pod实例,适合这种场景。用户提到“挂载宿主机文件进容器”,这确实是常见的做法,因为Fluentd需要读取宿主机上的日志文件,比如/var/log目录下的内容。 接下来,我需要考虑用户可能遇到的问题。比如,他们是否在挂载路径时遇到了权限问题,或者配置错误导致Fluentd无法读取日志。此外,用户可能想知道如何正确配置volumeMountsvolumes部分,或者是否需要使用hostPath卷类型。 另外,用户可能对安全性最佳实践感兴趣,比如是否应该以特权模式运行Pod,或者如何设置适当的文件权限。可能用户还关心如何将收集的日志发送到后端存储,如Elasticsearch或S3,但这可能超出当前问题的范围。 需要解释为什么需要挂载宿主机目录:因为每个节点的日志存储在本地,Fluentd需要访问这些文件才能收集转发。同时,可能还需要提到其他相关配置,如容器内的日志路径映射、rbac权限(如果集群启用了RBAC),以及可能的持久化存储需求。 可能存在的误区是用户认为DaemonSet本身会自动处理文件挂载,但实际上需要显式配置。需要明确说明配置步骤,并给出示例YAML片段,突出关键部分,如volumeMountshostPath的使用。 还要考虑不同环境下的差异,比如不同的Kubernetes版本或不同的日志文件位置,是否需要调整挂载路径。此外,可能提到使用Sidecar模式或其他日志收集方案的对比,但用户明确询问的是DaemonSet,所以需要集中在这一点上。 总结,回答需要涵盖以下几点: 1. DaemonSet的作用Fluentd的使用场景。 2. 为何需要挂载宿主机目录。 3. 具体的Kubernetes配置示例,包括volumesvolumeMounts。 4. 可能的权限问题及解决方法。 5. 其他相关配置建议,如RBAC或资源限制。 6. 常见问题排查,如日志无法读取或权限错误。 同时,需要以结构化的方式呈现,分步骤解释,确保用户能够逐步理解应用配置。可能使用代码块展示YAML配置,并注释关键部分。此外,强调安全最佳实践,比如避免使用特权模式除非必要,或者设置只读挂载。</think>### 深入解析 Fluentd 以 DaemonSet 部署时的宿主机文件挂载机制 --- #### 一、核心需求与原理 **DaemonSet 的特殊性** $$\text{每个节点运行1个Pod实例} \Rightarrow \text{直接访问节点本地文件系统}$$ **Fluentd 日志采集模式**: ```mermaid graph LR 宿主机日志文件 -->|实时监控| Fluentd容器 --> 日志聚合存储(Elasticsearch/S3等) ``` **必须挂载的场景**: 1. 采集 `/var/log/containers/*.log`(K8s默认容器日志路径) 2. 读取 `/var/lib/docker/containers`(原始Docker日志,需配置log-driver) 3. 监控自定义应用日志(如 `/app/logs/*.log`) --- #### 二、完整配置示例(带深度注解) ```yaml apiVersion: apps/v1 kind: DaemonSet metadata: name: fluentd namespace: kube-system spec: selector: matchLabels: app: fluentd template: metadata: labels: app: fluentd spec: # 关键安全配置 automountServiceAccountToken: false hostNetwork: true # 可选,需采集主机网络日志时启用 tolerations: - key: node-role.kubernetes.io/master effect: NoSchedule containers: - name: fluentd image: fluent/fluentd-kubernetes-daemonset:v1.16-debian-elasticsearch8-1 env: - name: FLUENT_ELASTICSEARCH_HOST value: "elasticsearch-logging.kube-system.svc.cluster.local" # 关键挂载配置 volumeMounts: - name: varlog mountPath: /var/log readOnly: true # 安全最佳实践 - name: dockercontainers mountPath: /var/lib/docker/containers readOnly: true - name: fluentd-config mountPath: /fluentd/etc volumes: - name: varlog hostPath: path: /var/log type: Directory - name: dockercontainers hostPath: path: /var/lib/docker/containers type: Directory - name: fluentd-config configMap: name: fluentd-config ``` **关键配置解析**: 1. `hostPath` 卷类型实现宿主机目录映射 2. `readOnly: true` 防止容器意外修改宿主机文件 3. `hostNetwork: true` 的特殊场景需求 4. ConfigMap 挂载配置文件的标准化做法 --- #### 三、多维度挂载策略对比 | 挂载方式 | 适用场景 | 安全隐患 | 性能影响 | |----------------|---------------------------|-----------------------|---------| | 全量挂载`/var/log` | 需采集系统级多源日志 | 暴露敏感系统日志 | 中 | | 精准挂载容器日志目录 | 仅需K8s标准容器日志 | 路径依赖版本变化 | 低 | | 动态发现挂载 | 应对动态创建的日志文件 | 配置复杂度高 | 中 | | 符号链接解析 | 处理Docker日志轮转文件 | 需要特殊权限 | 低 | --- #### 四、进阶安全配置方案 1. **SELinux上下文配置** ```yaml securityContext: seLinuxOptions: type: "container_logreader_t" # 自定义SELinux策略 ``` 2. **AppArmor配置文件** ```bash # 在节点创建配置文件 /etc/apparmor.d/fluentd_logreader { /var/log/** r, } ``` 3. **Pod Security Policy(PSP)** ```yaml allowedHostPaths: - pathPrefix: "/var/log" readOnly: true ``` 4. **Open Policy Agent(OPA)策略** ```rego package kubernetes.validating.hostpath deny[msg] { input.request.kind.kind == "Pod" volume := input.request.object.spec.volumes[_].hostPath not startswith(volume.path, "/var/log") msg := sprintf("禁止挂载非日志目录: %v", [volume.path]) } ``` --- #### 五、性能优化实践 1. **inotify参数调优** ```bash # 在Fluentd配置中调整 <source> @type tail read_from_head true pos_file /var/log/fluentd-containers.log.pos refresh_interval 5 # 默认60秒,缩短可加快发现新文件 rotate_wait 10 # 处理日志轮转的等待时间 </source> ``` 2. **内核参数调整** ```bash # 调整节点内核参数 sysctl -w fs.inotify.max_user_watches=524288 sysctl -w fs.inotify.max_user_instances=1024 ``` 3. **资源限额配置** ```yaml resources: limits: memory: 500Mi cpu: 500m requests: memory: 200Mi cpu: 100m ``` --- #### 六、多集群统一日志架构方案 ```mermaid graph TB 子集群1[边缘集群] -->|Fluentd过滤| 区域聚合层 子集群2[核心集群
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值