MENU

Kubernetes进阶:集群日志收集

2019 年 07 月 01 日 • 应用服务器

emmmm,准备开始收集集群内的日志了,先来大概了解一下具体要收集哪些日志,大概是两个方面,一个是pod的日志,还有一个就是系统日志,比较主流的方案还是filebeat+ELK,具体容器中的日志要怎么去收集,下面来了解一下撒。

日志收集三种方案

目前官方给我出了三种方案,下面分别来看一哈。

Node上部署一个日志收集程序

说白了就是用DaemonSet在每个node上部署一个日志收集程序,也就是filebeat,其实docker会有一个专用的目录来存放容器的日志,也就是这个位置,

[root@node-1 ~]# ls /var/lib/docker/containers/

有很多目录,一个目录对应一个容器,每个目录下都会有一个xxx-json.log的文件,这个文件就是存储容器控制台输出的log,随便看一个,

当然这是json格式的,应该是coredns的日志,这个日志k8s也会在帮你保存一份,存储位置如下,

[root@node-1 ~]# ls -l /var/log/containers/    

在这里找一下上面coredns所对应的日志文件看一哈,看后面的ID就知道是哪个了,

内容一致,所以filebeat只需要收集这个目录下的日志就可以了,当然系统日志最好也不要放过,因为容器和宿主机的资源都是隔离的,所以你需要将日志目录挂载到filebeat容器的某个目录,使filebeat可以正常读取日志内容即可,这是一个方案,来看看他的优缺点

这种方式每个Node只需要部署一个日志收集程序就可以了,相对来说资源消耗比较少,对应用没有入侵,缺点就是应用程序日志需要写到标准输出和标准错误输出,也就是需要将日志输出到控制台,如果是将日志输出到了某个文件,这种方式你是无法收集到日志的,说白了就是想用这种方式收集日志,你的日志必须能通过docker logs能看到,如果看不到你是收集不到的,这是其一。

其二是不支持多行日志,多行日志举个栗子,java抛错日志从开始到结束其实就是一行,我在测试服务器随便找了一段抛错日志,测试用的也是swarm,用 docker service logs看到的。

一共是11行,其实这11行输出就是一行,看一下这个容器的json文件里是怎么写的,

json文件里面被拆成了十一行,因为filebeat在读这个文件,所以他被filebeat推到es之后显示的也是11行,正常的话应该是这样的,这是我在生产elk截取到的一个抛错日志。

虽然抛错不一样,下面的这张图就是一个完成的抛错,这种日志对我们来说还是很重要的,所以下文不会用这种方式来收集pod日志,而是来收集系统日志,看看第二种方式。

Pod中附加专用日志收集器

这种方式是在你Pod中再去运行一个收集日志的容器,提过一个Pod是由一个或多个容器组成,通过emptyDir来共享日志目录,这样filebeat的容器就可以收集到你应用容器中的日志了,下文会用这种方式去收集pod日志,看看他的优缺点。

好处就是低耦合,低耦合指的就是对象之间的依赖要松散,不要牵一发动全身,缺点就是每个pod都会启动一个filebeat,会增加资源消耗和维护成本,再看看第三种方式。

应用程序直接推送日志

目前我们这里用的就是这种方式,log4j直接推送日志到kafkalogstash监听kafka消息,logstash收到kafka的消息后处理日志,日志处理完之后logstash会直接推送到elasticsearch里,所以这样的话就不需要filebeat去收集日志了,我只需搭建一个kafka集群就可以了,这个超出了k8s的范围。

第三种好处是无需额外收集工具,缺点就是侵入应用,增加应用的复杂度,说白了就是这个需要在应用程序中去实现了,跟运维没啥子关系了,你只需要搭建他们所需要的东西就够了,具体怎么收集日志我们这里就不用管了,我们这里是log4j推到了kafka里面,其实log4j也可以推到redis甚至是es里面,这个确实是增加了很大的应用复杂度,最开始用这个测试的时候发现如果kafka崩了这个项目就崩掉了,无法正常提供服务了,到最后开发这里怎么改的我不太清楚,总之这个问题解决了,就算kafka崩了也不会影响到项目的正常运行,好像是什么同步改到异步什么什么的,目前我们这里使用filebeat的地方也就是收集nginx的日志了,扯的有点远了,上面提到了是用filebeat+elk来收集,filebeat暂时不用管,先把es集群、kibana&logstash搞出来吧,我这里也琢磨了一段时间,可以在k8s中将es集群部署出来了,开撸。

在K8S中部署es-kibana-logstash

我这里上周又加了三个node节点进来,所以现在有6node节点了,之前三个node节点明显有点不够用了,大概这样

集群插件需要有coredns&NFS动态供给的支持,开始部署es集群吧。

部署elasticsearch 集群

elasticsearch就是一个典型的有状态服务了,他需要一个固定的网络标识和存储,所以用StatefulSet去部署集群,存储还是用NFS,我打算把es的全部组件扔到一个名为elasticsearch命名空间下,看一下我的YAML文件内容吧。

创建命名空间和secret

刚提到了我把全部组件扔到了一个名为elasticsearch的命名空间下,还有就是我拉取的是私有仓库的镜像,所以还需要创建一个secret,就这样,YAML文件内容如下,直接创建了。

[root@master-1 ~/es-cluster]# cat secret-namespace.yaml 
apiVersion: v1
kind: Namespace
metadata:
   name: elasticsearch
   labels:
     name: elasticsearch
---
apiVersion: v1
kind: Secret
metadata:
  namespace: elasticsearch
  name: registry-secret
data:
  .dockerconfigjson: cat ~/.docker/config.json | base64 -w 0的结果
type: kubernetes.io/dockerconfigjson
[root@master-1 ~/es-cluster]# kubectl apply -f secret-namespace.yaml 
namespace/elasticsearch created
secret/registry-secret created

这样命名空间和secret就创建好了,然后就可以创建es集群了,YAML文件如下。

创建ES集群

使用StatefulSet方式去部署,启动三个副本,也用到了初始化容器,先看一下YAML文件吧,下面es部署最开始的时候用的是6.5.4的,最近换成了7.2.0版本,下面只是把YAML文件更新了一下,图片没变,镜像这里的话你可以直接拉官方的,下文我所使用的镜像都是根据官方的进行了微调,就这样,

[root@master-1 ~/es-cluster]# cat es-statefulset.yaml 
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: es-cluster
  namespace: elasticsearch
spec:
  serviceName: elasticsearch-headless
  replicas: 3
  selector:
    matchLabels:
      app: elasticsearch
  template:
    metadata:
      labels:
        app: elasticsearch
    spec:
      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            - labelSelector:
                matchExpressions:
                  - key: "app"
                    operator: In
                    values:
                    - elasticsearch
              topologyKey: "kubernetes.io/hostname"
      imagePullSecrets:
      - name: registry-secret
      containers:
      - name: elasticsearch
        image: registry.cn-beijing.aliyuncs.com/rj-bai/elasticsearch:7.2.0 
        imagePullPolicy: IfNotPresent
        livenessProbe:
          tcpSocket:
            port: 9200
          initialDelaySeconds: 60
          timeoutSeconds: 5
          failureThreshold: 12
        readinessProbe:
          tcpSocket:
            port: 9200
          initialDelaySeconds: 60
          timeoutSeconds: 5
          failureThreshold: 12
        resources:
            limits:
              cpu: "1000m"
              memory: "1500Mi"
            requests:
              cpu: "500m"
              memory: "512Mi"
        ports:
        - containerPort: 9200
          name: es-http
          protocol: TCP
        - containerPort: 9300
          name: cluster-port
          protocol: TCP
        volumeMounts:
          - mountPath: /usr/share/elasticsearch/data
            name: data-elasticsearch
        env:
          - name: REQUESTS_MEMORY
            valueFrom:
              resourceFieldRef:
                resource: requests.memory
                divisor: 1Mi
          - name: node.name
            valueFrom:
              fieldRef:
                fieldPath: metadata.name
          - name: cluster.name
            value: es-cluster
          - name: http.cors.enabled
            value: "true"
          - name: http.cors.allow-origin
            value: "*"
          - name: ES_JAVA_OPTS
            value: "-Xms$(REQUESTS_MEMORY)m -Xmx$(REQUESTS_MEMORY)m"
          - name: cluster.initial_master_nodes
            value: "es-cluster-0,es-cluster-1,es-cluster-2"
          - name: discovery.seed_hosts
            value: "es-cluster-0.elasticsearch-headless,es-cluster-1.elasticsearch-headless,es-cluster-2.elasticsearch-headless"
      initContainers:
      - name: vm-max-map
        image: busybox
        imagePullPolicy: IfNotPresent
        command: ["sysctl", "-w", "vm.max_map_count=262144"]
        securityContext:
          privileged: true
      - name: fd-ulimit
        image: busybox
        imagePullPolicy: IfNotPresent
        command: ["sh", "-c", "ulimit -n 65535"]
        securityContext:
          privileged: true
  volumeClaimTemplates:
  - metadata:
      name: data-elasticsearch
    spec:
      accessModes: [ "ReadWriteOnce" ]
      resources:
        requests:
          storage: 5Gi

---
kind: Service
apiVersion: v1
metadata:
  name: elasticsearch
  namespace: elasticsearch
  labels:
    app: elasticsearch
spec:
  type: NodePort
  selector:
    app: elasticsearch
  ports:
    - port: 9200
      name: es-http
      nodePort: 39200

--- 

apiVersion: v1
kind: Service
metadata:
  name: elasticsearch-headless
  namespace: elasticsearch
  labels:
    app: elasticsearch
spec:
  ports:
  - name: elasticsearch
    port: 9200
  selector:
    app: elasticsearch
  clusterIP: None

有些配置我也是第一次使用,譬如这里

      affinity:
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            - labelSelector:
                matchExpressions:
                  - key: "app"
                    operator: In
                    values:
                    - elasticsearch
              topologyKey: "kubernetes.io/hostname"

这一段是告诉Scheduler控制器,把appelasticsearchpod部署到不同的node上,说白了就是一个同一个节点不要运行多个appelasticsearchpod,所以创建后这三个pod会分布到不同的节点,更详细的说明看这里吧。

还运行了两个initContainer,也就是初始化容器,很久之前提过,但是没用过,这次用上了,是以特权模式运行的两个容器,这两个容器做了两件事情,调整了最大虚拟内存和最大打开文件的值,如果这两个不调整elasticsearch是无法启动的,之前用swarm的时候是在节点执行的脚本,现在不用了,直接用初始容器解决就可以了。

健康检查那里去检查9200端口通不通就够了,如果你不了解es集群在各种状态下访问9200端口返回的状态码是什么,建议你先去了解一下,如果使用httpGet去检查9200状态码可能会给你造成不必要的麻烦,毕竟有些问题不是重启就能解决的,这里就不多解释了,别的貌似就没啥了,我这里开始创建了,

[root@master-1 ~/es-cluster]# kubectl apply -f es-statefulset.yaml 
statefulset.apps/es-cluster created
service/elasticsearch created
service/elasticsearch-headless created

等着吧,StatefulSet是有序进行,所以会很慢,这样就是创建完了撒

直接看集群状态就完了,

[root@master-1 ~]# kubectl get service -n elasticsearch 
[root@master-1 ~]# curl 10.0.0.25:9200/_cluster/health?

绿色,莫得问题,下面把kibana弄一下撒。

部署kibana

这个就比较简单了,用一个deployment就可以了,YAML文件如下。

[root@master-1 ~/es-cluster]# cat kibana-deployment.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: elasticsearch
  name: kibana
  labels:
    app: kibana
spec:
  replicas: 1
  selector:
    matchLabels:
      app: kibana
  template:
    metadata:
      labels:
        app: kibana
    spec:
      imagePullSecrets:
      - name: registry-secret
      containers:
      - name: kibana
        image: registry.cn-beijing.aliyuncs.com/rj-bai/kibana:7.2.0 
        livenessProbe:
          httpGet:
            path: /app/kibana
            port: 5601
            scheme: HTTP
          initialDelaySeconds: 120
          timeoutSeconds: 10
          failureThreshold: 10
        readinessProbe:
          httpGet:
            path: /app/kibana
            port: 5601
            scheme: HTTP
          initialDelaySeconds: 240
          timeoutSeconds: 10
          failureThreshold: 12
        resources:
            limits:
              cpu: "1000m"
              memory: "500Mi"
            requests:
              cpu: "100m"
              memory: "300Mi"
        securityContext:
          runAsUser: 1000
          runAsGroup: 1000
        env:
          - name: ELASTICSEARCH_HOSTS
            value: http://elasticsearch.elasticsearch:9200
        ports:
        - containerPort: 5601
          name: kibana
          protocol: TCP

---

apiVersion: v1
kind: Service
metadata:
  namespace: elasticsearch
  name: kibana
  labels:
    app: kibana
spec:
  type: NodePort
  ports:
  - port: 5601
    name: kibana
    nodePort: 35601
  selector:
    app: kibana

创建吧,

[root@master-1 ~/es-cluster]# kubectl apply -f kibana-deployment.yaml 
deployment.apps/kibana created
service/kibana created

正常启动了,可以访问了

[root@master-1 ~]# kubectl get pod,services -n elasticsearch 

现在是什么数据都没有,直接看这里就完了,

莫得问题,下面部署一个logstash出来吧。

部署logstash

logstash还是部署到k8s集群中,我之前做的只需要监听kafka就可以了,现在是filebeatlogstash推,logstash默认端口5044,所以还是要写一个配置文件,这个配置文件我以configmap形式存到集群中了,所以我先创建configmap了,YAML文件内容如下。

创建Configmap

配置文件算是随便写了一个,自行酌情更改吧。

[root@master-1 ~/es-cluster]# cat logstash-configmap.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
  name: logstash-config
  namespace: elasticsearch
  
data:
  logstash.conf: |-
    input {
      beats {
         port => 5044
      }
    }
    
    filter {
    
        grok {
    
            match => ["message", "%{TIMESTAMP_ISO8601:logdate}"]
    
        }
    
        date {
    
            match => ["logdate", "yyyy-MM-dd HH:mm:ss,SSS"]
    
            target => "@timestamp"
    
        }
        
        mutate {
    
            remove_tag => ["logdate"]
    
        }
    }
    
    output {
         elasticsearch {
            hosts => ["elasticsearch.elasticsearch:9200"]
            index => "k8s-log-%{+YYYY.MM.dd}"
        }
        stdout {
        codec => rubydebug {}
        }
    }
[root@master-1 ~/es-cluster]# kubectl apply -f logstash-configmap.yaml 
configmap/logstash-config created

配置文件有了,还得创建一个logstash

创建logstash

就用deployment去创建了,所以YAML文件如下。

[root@master-1 ~/es-cluster]# cat logstash-deployment.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: elasticsearch
  name: logstash
  labels:
    app: logstash
spec:
  replicas: 1
  selector:
    matchLabels:
      app: logstash
  template:
    metadata:
      labels:
        app: logstash
    spec:
      imagePullSecrets:
      - name: registry-secret
      containers:
      - name: logstash
        image: registry.cn-beijing.aliyuncs.com/rj-bai/logstash:7.2.0
        imagePullPolicy: Always
        livenessProbe:
          tcpSocket:
            port: 9600
          initialDelaySeconds: 60
          timeoutSeconds: 10
          failureThreshold: 10
        readinessProbe:
          tcpSocket:
            port: 9600
          initialDelaySeconds: 60
          timeoutSeconds: 10
          failureThreshold: 10
        resources:
            limits:
              cpu: "2000m"
              memory: "2Gi"
            requests:
              cpu: "500m"
              memory: "1Gi"
        env:
          - name: REQUESTS_MEMORY
            valueFrom:
              resourceFieldRef:
                resource: requests.memory
                divisor: 1Mi
          - name: LS_JAVA_OPTS
            value: "-Xms$(REQUESTS_MEMORY)m -Xmx$(REQUESTS_MEMORY)m"
        ports:
        - containerPort: 5044
          name: filebeat
          protocol: TCP
        - containerPort: 9600
          name: logstash
          protocol: TCP
        volumeMounts: 
          - mountPath: /usr/share/logstash/pipeline
            name: logstash-config
      volumes: 
        - name: logstash-config
          configMap: 
            name: logstash-config

---
apiVersion: v1
kind: Service
metadata:
  namespace: elasticsearch
  name: logstash
  labels:
    app: logstash
spec:
  type: NodePort
  ports:
  - port: 5044
    nodePort: 35044
    name: filebeat
  - port: 9600
    nodePort: 39600
    name: logstash
  selector:
    app: logstash

当前版本logstash启动时默认读的就是/usr/share/logstash/pipeline/logstash.conf,所以我直接把Configmap挂载到了这里,你也可以启动多个副本,我这里资源紧张我暂时就启动一个了,可以创建了撒。

[root@master-1 ~/es-cluster]# kubectl apply -f logstash-deployment.yaml 
deployment.apps/logstash created
service/logstash created

等启动后还是看kibana监控页面,如果一切正常显示如下,

现在elk已经搭建完毕了,下面可以启动filebeat去收集日志了。

收集系统日志

也就是收集/var/log/message的日志,这个就是使用上面提到的第一种方式,在所有node上部署一个filebeat,也就是用daemonsets去部署,挂载宿主机的messages文件到容器,编写配置文件去读message文件就可以了撒,所以YAML文件如下,Configmapdaemonset写到一起了撒。

apiVersion: v1
kind: ConfigMap
metadata:
  name: filebeat-systemlog-config
  namespace: elasticsearch
  
data:
  filebeat.yml: |-
    filebeat.inputs: 
      - type: log
        paths:
          - /messages
        fields:
          name: system-log
          type: module 
        fields_under_root: true

    output.logstash:
      hosts: ['logstash.elasticsearch:5044']

---

apiVersion: apps/v1
kind: DaemonSet 
metadata:
  name: system-logs
  namespace: elasticsearch
spec:
  selector:
    matchLabels:
      project: k8s 
      app: filebeat
  template:
    metadata:
      labels:
        project: k8s
        app: filebeat
    spec:
      containers:
      - name: filebeat
        image: docker.elastic.co/beats/filebeat:7.2.0
        args: [
          "-c", "/etc/filebeat.yml",
          "-e",
        ]
        resources:
          requests:
            cpu: 100m
            memory: 100Mi
          limits:
            cpu: 500m
            memory: 500Mi
        securityContext:
          runAsUser: 0
        volumeMounts:
        - name: filebeat-config
          mountPath: /etc/filebeat.yml
          subPath: filebeat.yml
        - name: system-log
          mountPath: /messages
      volumes:
      - name: system-log
        hostPath: 
          path: /var/log/messages
          type: File
      - name: filebeat-config
        configMap:
          name: filebeat-systemlog-config

镜像是直接在官方拉的,运行进程用户UID0,就是这样子撒,创建吧。

[root@master-1 ~/es-cluster]# kubectl apply -f filebeat-daemonsets.yaml 
configmap/filebeat-systemlog-config created
daemonset.apps/system-logs created

正常启动了撒,随便看一个filebeat的日志。

[root@master-1 ~/es-cluster]# kubectl get pod -n elasticsearch 
[root@master-1 ~/es-cluster]# kubectl logs -n elasticsearch system-logs-5kmdx | tail

kibana看一眼,没意外的话会有一个名为k8s-log的索引,这个名字实在logstash中指定哇,也就是这个,

加进去看一眼推送过来的日志,

是系统日志没错了,但是这特么系统日志刷的有点快,二十分钟刷了2W多条,目前只有6node

当然你可以收集其他的,在filebeat中多写几个,然后把日志文件也挂载进来就阔以了撒,思路给你了,下面开始收集pod日志,我特么先停掉了,一会把我硬盘跑满了,一小时没管将近10W条了。

收集pod日志

也是使用上面第二种方式,来收集dimplebloglog吧,这是我之前做CI/CD时候用的示例java项目,关于这个项目我是怎么部署的你可以去看一哈这里,我改了一哈这个项目日志的位置,他现在的路径是/home/dimple/logs,我改成了/www/logs,日志配置文件是这个撒,

项目启动后会有两个日志文件,分别是system-{info,error}.log,这个名字我就不动了,一会配置filebeat直接去读取这个文件就可以了撒,所以先定义filebeatconfigmap吧,我直接写到资源文件里面了撒。

[root@master-1 ~/DimpleBlog]# cat deploy-dimpleblog.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
  name: filebeat-dimpleblog-config
  
data:
  filebeat.yml: |-
    filebeat.inputs: 
      - type: log
        paths:
          - /www/logs/system-info.log
        fields:
          name: dimpleblog
          type: dimpleblog-info
        fields_under_root: true

      - type: log
        paths:
          - /www/logs/system-error.log
        fields:
          name: dimpleblog
          type: dimpleblog-error
        fields_under_root: true
        multiline:
          pattern: '^\s+'
          negate: false
          match: after

    output.logstash:
      hosts: ['logstash.elasticsearch:5044']
---

指定了两个日志文件的位置,错误日志这里配置了一下支持多行,下面去改deployment吧,得加一个filebeat容器和挂载目录的配置,emmm,所以,最终的资源文件如下。

[root@master-1 ~/DimpleBlog]# cat deploy-dimpleblog.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
  name: filebeat-dimpleblog-config
  
data:
  filebeat.yml: |-
    filebeat.inputs: 
      - type: log
        paths:
          - /www/logs/system-info.log
        fields:
          name: dimpleblog
          type: dimpleblog-info
        fields_under_root: true

      - type: log
        paths:
          - /www/logs/system-error.log
        fields:
          name: dimpleblog
          type: dimpleblog-error
        fields_under_root: true
        multiline:
          pattern: '^\s+'
          negate: false
          match: after

    output.logstash:
      hosts: ['logstash.elasticsearch:5044']
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-dimpleblog
spec:
  replicas: 1 
  selector:
    matchLabels:
      app: dimpleblog
  template:
    metadata:
      labels:
        app: dimpleblog 
    spec:
      imagePullSecrets:
      - name: $SECRET_NAME 
      containers:
      - name: dimpleblog 
        image: $IMAGE_NAME 
        ports:
        - name: web-dimpleblog
          containerPort: 80
        livenessProbe:
          httpGet:
            path: /login
            port: 80
          initialDelaySeconds: 60
          timeoutSeconds: 10
          failureThreshold: 12
        readinessProbe:
          httpGet:
            path: /login
            port: 80
          initialDelaySeconds: 60
          timeoutSeconds: 10
          failureThreshold: 12
        resources:
          limits:
            cpu: 1
            memory: 1Gi
          requests:
            cpu: 0.5
            memory: 512Mi
        volumeMounts:
        - name: dimpleblog-logs
          mountPath: /www/logs

      - name: filebeat
        image: docker.elastic.co/beats/filebeat:7.2.0
        args: [
          "-c", "/etc/filebeat.yml",
          "-e",
        ]
        resources:
          limits:
            cpu: 100m
            memory: 300Mi
          requests:
            cpu: 100m
            memory: 100Mi
        securityContext:
          runAsUser: 0
        volumeMounts:
        - name: filebeat-config
          mountPath: /etc/filebeat.yml
          subPath: filebeat.yml
        - name: dimpleblog-logs
          mountPath: /www/logs

      volumes:
      - name: dimpleblog-logs
        emptyDir: {}
      - name: filebeat-config
        configMap:
          name: filebeat-dimpleblog-config

---
apiVersion: v1
kind: Service
metadata:
  name: web-dimpleblog
spec:
  type: NodePort
  selector:
    app: dimpleblog 
  ports:
    - name: web-dimpleblog 
      protocol: TCP
      port: 80
      targetPort: 80
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: web-dimpleblog 
spec:
  rules:
  - host: dimpleblog.rj-bai.com
    http:
      paths:
      - path: /
        backend:
          serviceName: web-dimpleblog 
          servicePort: 80

至于我没改之前的配置文件是啥样可以看一下这里,其实就是就是加了一个挂载目录和一个filebeat容器,挂载目录类型为emptyDir,如果你的日志打算在宿主机留一份,两个都用hostPath也可以,就这样,还有logstash的配置文件也要修改一下撒,如果现在部署这个博客系统,它的日志索引也是在k8s-log中,现在把它分出来,改一下logstashConfigmap吧,如下。

[root@master-1 ~/es-cluster]# cat logstash-configmap.yaml 
apiVersion: v1
kind: ConfigMap
metadata:
  name: logstash-config
  namespace: elasticsearch
  
data:
  logstash.conf: |-
    input {
      beats {
         port => 5044
      }
    }
    
    filter {
    
        grok {
    
            match => ["message", "%{TIMESTAMP_ISO8601:logdate}"]
    
        }
    
        date {
    
            match => ["logdate", "yyyy-MM-dd HH:mm:ss,SSS"]
    
            target => "@timestamp"
    
        }
    
        mutate {
    
            remove_tag => ["logdate"]
    
        }
    }
    
    output {
        if [name] == "dimpleblog" {
            if [type] == "dimpleblog-info" {
               elasticsearch {
                  hosts => ["http://elasticsearch.elasticsearch:9200"]
                  index => "dimpleblog-info-%{+YYYY.MM.dd}"
               }
            }
            else if [type] == "dimpleblog-error" {
               elasticsearch {
                  hosts => ["http://elasticsearch.elasticsearch:9200"]
                  index => "dimpleblog-error-%{+YYYY.MM.dd}"
               }
            }
        } else if [name] == "system-log" {
            if [type] == "module" {
               elasticsearch {
                  hosts => ["http://elasticsearch.elasticsearch:9200"]
                  index => "system-log-%{+YYYY.MM.dd}"
               }
            }
         }
        stdout { codec => rubydebug }
    }

就是对名字和类型做了个判断,这个名字是在filebeat中指定的撒,不同的名字类型推送到不同的索引,更新一下这个Configmap,配置文件是更新了,但是logstashpod并不会自动重启,没办法,帮助他一下吧,直接删了这个pod就会再启一个了,哈哈

[root@master-1 ~/es-cluster]# kubectl delete pod -n elasticsearch logstash-58fd5685f5-dgfp8

然后再把收集系统log的那个filebeat启动了,会有一个新的索引,名为system-log,也就是这个,

所以一会启动dimpleblog之后又会多两个索引,也就是dimpleblog-{info,error},提交代码,

[root@master-1 ~/DimpleBlog]# git add .
[root@master-1 ~/DimpleBlog]# git commit -m 'log'
[root@master-1 ~/DimpleBlog]# git push origin master

jenkins中使用pipeline部署到k8s集群中,抽根烟去,回来也就差不多了,

跑完了,

kibana看一眼

也有了,暂时还没有错误日志,所以也就没有error的索引,现在让他抛个错,停一下数据库应该就有抛错了,直接把mysqlpod删掉,

[root@master-1 ~/DimpleBlog]# kubectl delete pod mysql-0 

嗯,有了,

添加到索引,看一下错误日志是不是多行的,

莫得问题,就是这种效果,info的如下。

这是健康检查的探针,就是这种效果哇,莫得问题。

无论你想收集什么日志,道理都是一样的,挂载日志目录到filebeat容器,写好filebeat配置文件去读取日志文件推送到logstash就可以了,思路就是这样,暂时就这样吧。

最后编辑于: 2019 年 08 月 05 日
返回文章列表 文章二维码 打赏
本页链接的二维码
打赏二维码