利用kurise做日志采集使用promtail做sidecar采集日志

avatar 2026年1月14日18:44:25 评论 7 次浏览

利用OpenKurise中的kruise做日志采集,原来我使用的是filebeat作为sidecar采集日志的,虽然采集没有什么问题,但是通过es进才看日志就比较繁琐了,这次实验promtail作为sidecar采集日志loki存储,grafana展示日志内容,看看会怎么样,以前部署的时候采集的是swarm的日志,在使用上比较便捷,这次看看k8s里是否不一样.

在没有做这个实验之前,需要理解通过filebeat默认是可以读取到kubernetes的API,这个是OpenKruise自己在安装的时候已经创建了RBAC,所以我们在创建``promtail的时候也需要创建RBAC才可以获取到pod的标签,下面看一下我部署的方式,因为我原来的使用的是filebeat,现在改成promtail,所以我已经删除了filebeat了.

配置sidecar

采集日志需要两个配置内容,分别是sidecar和配置的yaml文件,下面是我的配置内容

 cat promtail-config.yaml
 apiVersion: v1
 kind: ConfigMap
 metadata:
   name: promtail-config
 data:
   promtail.yaml: |
     server:
       http_listen_port: 9080
       grpc_listen_port: 0
 
     positions:
       filename: /run/promtail/positions.yaml
 
     clients:
       - url: http://192.168.6.210:3100/loki/api/v1/push
 
     scrape_configs:
       - job_name: kubernetes-pods
         static_configs:
           - targets:
               - localhost
             labels:
               __path__: /var/log/*
               app: myapp
 cat promtail-sidecarset.yml
 apiVersion: apps.kruise.io/v1alpha1
 kind: SidecarSet
 metadata:
   name: promtail-sidecar
 spec:
   selector:
     matchLabels:
       kruise.io/inject-promtail: "true"
   updateStrategy:
     type: RollingUpdate
   containers:
     - name: promtail
       image: harbor.efreight.cn/ops/promtail:2.9.2
       args:
         - -config.file=/etc/promtail/promtail.yaml
       volumeMounts:
         - name: log
           mountPath: /var/log
         - name: promtail-config
           mountPath: /etc/promtail
         - name: promtail-position
           mountPath: /run/promtail
       resources:
         requests:
           cpu: 50m
           memory: 64Mi
         limits:
           cpu: 200m
           memory: 256Mi
 
   volumes:
     - name: log
       emptyDir: {}
     - name: promtail-config
       configMap:
         name: promtail-config
     - name: promtail-position
       emptyDir: {}

这个是一个简单的采集日志,但是我发现通过grafana展示时日志标签只能使用上面配置的固定标签app: myapp这个是我不能接受的,我需要根据我的服务名,如果多个namespace下有相同名字的服务还需要通过namespace进行区分,这时就需要用到RBAC,我们需要创建一个用户并且有权限获取namespace下的标签权限,然后拼接一下可以通过namespce加服务名的方式进行区分.

通过获取标签采集不同服务日志

因为默认是没有权限的,所以需要创建一个RBAC,然后把用户赋予给sidecar这样采集日志时就可以获取pod的标签和namespace了,下面先看看我创建的RBAC.

 cat promtail-rbac.yaml
 # promtail-rbac.yaml
 # 注意:这个需要在每个命名空间都创建,或者创建一个全局的
 apiVersion: v1
 kind: ServiceAccount
 metadata:
   name: promtail-sidecar
   namespace: qa-demo-ai  # 根据实际命名空间修改
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRole
 metadata:
   name: promtail-sidecar-role
 rules:
 - apiGroups: [""]
   resources:
   - nodes
   - services
   - endpoints
   - pods
   verbs:
   - get
   - list
   - watch
 ---
 apiVersion: rbac.authorization.k8s.io/v1
 kind: ClusterRoleBinding
 metadata:
   name: promtail-sidecar-role-binding
 roleRef:
   apiGroup: rbac.authorization.k8s.io
   kind: ClusterRole
   name: promtail-sidecar-role
 subjects:
 # 可以为每个命名空间创建一个 binding,或者使用这个全局的
 - kind: Group
   name: system:serviceaccounts
   apiGroup: rbac.authorization.k8s.io

这里创建了一个promtail-sidecar的用户,并且获取pod,变量,server等权限,根据自己的需求创建到不同的namespace里.并且把创建的promtail-sidecar绑定了整个集群里,也包括命名空间下的默认default ServiceAccount,所以我只需要创建一个RBAC,所有namespace都可使用.下面看看我的配置

 cat promtail-config.yaml
 # promtail-config.yaml
 apiVersion: v1
 kind: ConfigMap
 metadata:
   name: promtail-config
   namespace: qa-demo-ai  # 或您的命名空间
 data:
   promtail.yaml: |
     server:
       http_listen_port: 9080
       grpc_listen_port: 0
 
     positions:
       filename: /run/promtail/positions.yaml
 
     clients:
       - url: http://192.168.6.210:3100/loki/api/v1/push
 
     scrape_configs:
       - job_name: kubernetes-pods
         kubernetes_sd_configs:
         - role: pod
 
         # 关键:自动获取 Pod 的元数据作为标签
         relabel_configs:
         # 1. 首先获取命名空间(最重要)
         - source_labels: [__meta_kubernetes_namespace]
           target_label: namespace
 
         # 2. 获取服务名(从 app 标签)
         - source_labels: [__meta_kubernetes_pod_label_app]
           target_label: service
 
         # 3. 如果 app 标签不存在,使用 name 标签
         - source_labels: [__meta_kubernetes_pod_label_name]
           target_label: service
           regex: "(.+)"
 
         # 4. 如果都没有,使用 Pod 名称前部分作为服务名
         - source_labels: [__meta_kubernetes_pod_name]
           target_label: service
           regex: "(.+?)-"
           replacement: "$1"
 
         # 5. 创建组合标签:namespace_service(用于唯一标识)
         - source_labels: [namespace, service]
           separator: "_"
           target_label: namespace_service
 
         # 6. 自动映射其他所有 Pod 标签
         - action: labelmap
           regex: __meta_kubernetes_pod_label_(.+)
 
         # 7. 添加 Pod 和容器信息
         - source_labels: [__meta_kubernetes_pod_name]
           target_label: pod
         - source_labels: [__meta_kubernetes_pod_container_name]
           target_label: container
         - source_labels: [__meta_kubernetes_pod_node_name]
           target_label: node
 
         # 8. 设置日志路径
         - source_labels: [__meta_kubernetes_pod_uid, __meta_kubernetes_pod_container_name]
           action: replace
           regex: (.+);(.+)
           replacement: /var/log/*.log
           target_label: __path__
 
         # 9. 可选:只处理带有特定标签的 Pod
         - source_labels: [__meta_kubernetes_pod_label_kruise_io_inject_promtail]
           action: keep
           regex: "true"

我这里定义了多种动态获取变量和标签的方式,在grafana里可以根据自己的标签选择不同的服务的日志内容.

 cat promtail-sidecarset.yml
 # promtail-sidecarset.yml(保持原样,只加必要的环境变量)
 apiVersion: apps.kruise.io/v1alpha1
 kind: SidecarSet
 metadata:
   name: promtail-sidecar
 spec:
   selector:
     matchLabels:
       kruise.io/inject-promtail: "true"
   updateStrategy:
     type: RollingUpdate
   containers:
     - name: promtail
       image: harbor.efreight.cn/ops/promtail:2.9.2
       args:
         - -config.file=/etc/promtail/promtail.yaml
       # 只需添加环境变量,不需要其他复杂挂载
       podInjectPolicy: AfterAppContainer
       env:
         - name: HOSTNAME
           valueFrom:
             fieldRef:
               fieldPath: spec.nodeName
         - name: POD_NAME
           valueFrom:
             fieldRef:
               fieldPath: metadata.name
         - name: POD_NAMESPACE
           valueFrom:
             fieldRef:
               fieldPath: metadata.namespace
       volumeMounts:
         - name: log
           mountPath: /var/log
         - name: promtail-config
           mountPath: /etc/promtail
         - name: promtail-position
           mountPath: /run/promtail
       resources:
         requests:
           cpu: 50m
           memory: 64Mi
         limits:
           cpu: 200m
           memory: 256Mi
   volumes:
     - name: log
       emptyDir: {}
     - name: promtail-config
       configMap:
         name: promtail-config
     - name: promtail-position
       emptyDir: {}

这样就可以根据自己的需求获取不同的日志内容了,下面看一下我的日志查询的内容.

查看日志

安装好lokigrafan之后,直接根据标签查看,这里有在配置文件里定义的标签字段,可以动态获取所有日志内容,这样就可以满足不同的namespace下的服务日志查看了.

日志收集正常,环境搭建完整,至于loki和grafana就更简单了,直接使用docker运行即可,这里就不过多的叙述了.

avatar

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: