【k8s】【ELK】【三】Sidecar容器运行日志Agent

news/2024/7/7 20:23:41

1、日志收集场景分析与说明

对于那些能够将日志输出到本地文件的Pod,我们可以使用Sidecar模式方式运行一个日志采集Agent,对其进行单独收集日志

在这里插入图片描述

1、首先需要将Pod中的业务容器日志输出至本地文件,而后运行一个Filebeat边车容器,采集本地路径下的日志;
2、Filebeat容器需要传递如下变量;环境:了解Pod属于隶属于哪个环境;项目名称:为了后期能在单个索引中区分出不同的项目;
podip:为了让用户清楚该Pod属于哪个IP;
3、Logstash根据不同的环境,拉取不同的topic数据,然后将数据存储至ES对应的索引中;
4、Kibana添加不同环境的 index pattern,而后选择对应环境 不同的项目 进行日志探索与展示;

Sidecar部署思路

1、制作一个业务镜像,要求镜像输出日志至本地;
2、制作Filebeat镜像,配置Input、output等信息;
3、采用边车模式运行不同环境的Pod,确保日志信息能输出至Kafka集群;
4、准备不同环境下Logstash配置文件,而后读取数据写入ES集群;
5、使用kibana添加索引,进行日志探索与展示;

2、制作Tomcat业务镜像

下载tomcat包

wget https://dlcdn.apache.org/tomcat/tomcat-10/v10.0.27/bin/apache-tomcat-10.0.27.tar.gz --no-check-certificate
#wget https://dlcdn.apache.org/tomcat/tomcat-10/v10.1.8/bin/apache-tomcat-10.1.8.tar.gz --no-check-certificate

[root@master01 tomcatImage]# ls
apache-tomcat-10.0.27.tar.gz

编写Dockerfile

FROM openjdk:8-jre

RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
    echo 'Asia/Shanghai' > /etc/timezone

ENV VERSION=10.1.8
ADD ./apache-tomcat-${VERSION}.tar.gz /app
RUN mv /app/apache-tomcat-${VERSION} /app/tomcat && \
    rm -f /app/apache-tomcat-${VERSION}.tar.gz 
    
ADD ./entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

EXPOSE 8080
CMD ["/bin/bash","-c","/entrypoint.sh"]

编写entrypoint.sh

# entrypoint.sh
# 启动tomcat方法,并且将日志打到对应的文件中
# 异常是多行的;  这里测试将tomcat jvm调整到20m  不断访问 就会抛出异常  OOM;
OPTS="-Xms${JVM_XMS:-25m} -Xmx${JVM_XMX:-25m} -XX:+UseConcMarkSweepGC"
sed -i "2a JAVA_OPTS=\"${OPTS}\"" /app/tomcat/bin/catalina.sh

cd /app/tomcat/bin && \
./catalina.sh  run &>>/app/tomcat/logs/stdout.log

编写entrypoint.sh

# 启动tomcat方法,并且将日志打到对应的文件中
# 异常是多行的;  这里测试将tomcat jvm调整到20m  不断访问 就会抛出异常  OOM;
OPTS="-Xms${JVM_XMS:-25m} -Xmx${JVM_XMX:-25m} -XX:+UseConcMarkSweepGC"
sed -i "2a JAVA_OPTS=\"${OPTS}\"" /app/tomcat/bin/catalina.sh

cd /app/tomcat/bin && \
./catalina.sh  run &>>/app/tomcat/logs/stdout.log

构建镜像并推送仓库

[root@master01 tomcatImage]# ls
apache-tomcat-10.1.8.tar.gz  Dockerfile  entrypoint.sh

docker build -t harbor.oldxu.net/base/tomcat:10.1.8_with_log .
docker push harbor.oldxu.net/base/tomcat:10.1.8_with_log

3.制作Filebeat镜像

curl -L -O https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.17.6-x86_64.rpm

Dockerfile

FROM centos:7
RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
    echo 'Asia/Shanghai' > /etc/timezone
    
#拷贝filebeat 和 拷贝filebeat配置文件(核心)
ENV VERSION=7.17.6
ADD ./filebeat-${VERSION}-x86_64.rpm /
RUN rpm -ivh /filebeat-${VERSION}-x86_64.rpm && \
    rm -f /filebeat-${VERSION}-x86_64.rpm

ADD ./filebeat.yml /etc/filebeat/filebeat.yml

ADD ./entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh

CMD ["/bin/bash","-c","/entrypoint.sh"]  

编写filebeat配置

{ENV} :用于定义环境的变量;
{PROJECT_NAME} :用于定义项目名称的变量;
{MULTILINE} :用于定义多行合并的正则变量;
{KAFKA_HOSTS} :用于定义KAFKA集群地址的变量;
{PodIP} :用于获取该Pod地址的变量;
{Node} :用于获取该Pod所处的节点;

filebeat.yml

filebeat.inputs:
- type: log
  enabled: true
  paths:
    - /logu/*.log
    - /logu/*/*.log
  tags: ["logu"]
  fields:
    topic: {PROJECT_NAME}
    podip: {PodIP}
    node: {Node}
  fields_under_root: true               # 增加的所有字段都为顶级字段


- type: log
  enabled: true
  paths:
    - /logm/*.log
    - /logm/*/*.log
  tags: ["logm"]
  fields:
    topic: {PROJECT_NAME}
    podip: {PodIP}
    node: {Node}
  fields_under_root: true               # 增加的所有字段都为顶级字段
  multiline.pattern: '{MULTILINE}'      
  multiline.negate: true
  multiline.match: after
  multiline.max_lines: 10000    #默认最大合并行为500,可根据实际情况调整。

output.kafka:
  hosts: [{KAFKA_HOSTS}]
  topic: app-{ENV}-%{[topic]}
  required_acks: 1              # 保证消息可靠,0不保证,1等待写入主分区(默认),-1等待写入副本分区
  compression: gzip             # 压缩
  max_message_bytes: 1000000    # 每条消息最大的长度,多余的被删除

entrypoint.sh

#1、替换filbeat配置文件中的内容
Beat_Conf=/etc/filebeat/filebeat.yml
sed -i s@{ENV}@${ENV:-test}@g ${Beat_Conf}
sed -i s@{PodIP}@${PodIP:-"no-ip"}@g ${Beat_Conf}
sed -i s@{Node}@${Node:-"none"}@g ${Beat_Conf}

sed -i s@{PROJECT_NAME}@${PROJECT_NAME:-"no-define"}@g ${Beat_Conf}
sed -i s@{MULTILINE}@${MULTILINE:-"^\\\d{2}"}@g ${Beat_Conf}  # \\用来转义
sed -i s@{KAFKA_HOSTS}@${KAFKA_HOSTS}@g ${Beat_Conf}

# 运行filebeat
filebeat -e -c /etc/filebeat/filebeat.yml

制作镜像&推送

[root@master01 filebeatImage]# ls
Dockerfile  entrypoint.sh  filebeat-7.17.6-x86_64.rpm  filebeat.yml
docker build -t harbor.oldxu.net/base/filebeat_sidecar:7.17.6 .
docker push harbor.oldxu.net/base/filebeat_sidecar:7.17.6

排错:漏写冒号

[root@master01 tomcat-test]# kubectl logs -n test demo-auth-f89d7ccb6-x4ftp -c filebeat 
Exiting: error loading config file: yaml: line 2: mapping values are not allowed in this context

在这里插入图片描述

4.以边车模式运行Pod

4.1 运行测试环境Pod

4.1.1 创建namespace 和 Secrets

kubectl create namespace test

kubectl create secret docker-registry harbor-admin \
--docker-username=admin \
--docker-password=Harbor12345
--docker-server=harbor.oldxu.net -n test

4.1.2 创建tomcat deployment

demo-auth-test.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-auth
  namespace: test
spec:
  replicas: 2
  selector:
    matchLabels:
      app: auth
  template:
    metadata:
      labels:
        app: auth
    spec:
      imagePullSecrets:
      - name: harbor-admin

      volumes:
      - name: log
        emptyDir: {}

      containers:
      - name: auth
        image: harbor.oldxu.net/base/tomcat:10.0.27_with_log
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
        volumeMounts:
        - name: log
          mountPath: /app/tomcat/logs
        livenessProbe:                  # 存活探针
          httpGet:
            path: '/index.jsp'
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 10
        readinessProbe:                 # 就绪探针
          httpGet:
            path: '/index.jsp'
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 10

      - name: filebeat
        image: harbor.oldxu.net/base/filebeat_sidecar:7.17.6 
        imagePullPolicy: Always
        volumeMounts:
        - name: log
          mountPath: /logm
        env:
        - name: ENV
          value: "test"                         # 也可以使用metadata.namespace 具体看业务如何规划
        - name: PodIP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        - name: Node
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        - name: PROJECT_NAME
          value: "demo-auth"
        - name: KAFKA_HOSTS
          value: '"kafka-0.kafka-svc.logging:9092","kafka-1.kafka-svc.logging:9092","kafka-2.kafka-svc.logging:9092"'

4.1.3 创建tomcat svc

apiVersion: v1
kind: Service
metadata:
  name: tomcat-svc
  namespace: test
spec:
  selector:
    #app: tomcat
    app: auth
  ports:
  - port: 8080
    targetPort: 8080

在这里插入图片描述

特别说明

这里一个pod运行两个容器,名称分别为: auth和filebeat 。
kubectl logs xxxPodName -n test -c auth 
此时是一点日志都没有的。auth的日志在/app/tomcat/logs/stdout.log .

所以要换成看filebeat的logs
kubectl logs xxxPodName -n test -c filebeat

如果启动的pod,状态出现1/2 CrashLoopBackOff  ,则去到filebeat容器里面 /logm/查看日志 排查。
#可进入filebeat容器,查看内容是否替换成功。
cat /etc/filebeat/filebeat.yml

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

4.1.4 进行压力测试

 ab -n 10000 -c 500 10.102.112.251:8080/index.jsp

在这里插入图片描述

4.1.5 检查KafkaTopic

在这里插入图片描述
点击“preview” ,查看最近的日志
在这里插入图片描述

4.1.6 demo-system-test-dp.yaml

在namespace test,创个新的 demo-system ,看看efak 有没有创建对应的topics

apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-system
  namespace: test
spec:
  replicas: 2
  selector:
    matchLabels:
      app: system
  template:
    metadata:
      labels:
        app: system
    spec:
      imagePullSecrets:
      - name: harbor-admin

      volumes:
      - name: log
        emptyDir: {}

      containers:
      - name: system
        image: harbor.oldxu.net/base/tomcat:10.0.27_with_log
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
        volumeMounts:
        - name: log
          mountPath: /app/tomcat/logs
        livenessProbe:                  # 存活探针
          httpGet:
            path: '/index.jsp'
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 10
        readinessProbe:                 # 就绪探针
          httpGet:
            path: '/index.jsp'
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 10

      - name: filebeat
        image: harbor.oldxu.net/base/filebeat_sidecar:7.17.6 
        imagePullPolicy: Always
        volumeMounts:
        - name: log
          mountPath: /logm
        env:
        - name: ENV
          value: "test"                         # 也可以使用metadata.namespace 具体看业务如何规划
        - name: PodIP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        - name: Node
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        - name: PROJECT_NAME
          value: "demo-system"
        - name: KAFKA_HOSTS
          value: '"kafka-0.kafka-svc.logging:9092","kafka-1.kafka-svc.logging:9092","kafka-2.kafka-svc.logging:9092"'

在这里插入图片描述
在这里插入图片描述

压测这个demo-system

在这里插入图片描述

分割线

4.2 运行生产环境Pod (prod)

4.2.1 创建namespace和 Secrets

kubectl create namespace prod

kubectl create secret docker-registry harbor-admin --docker-username=admin --docker-password=Harbor12345 --docker-server=harbor.oldxu.net -n prod

4.2.2 创建tomcat deployment (prod)

apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-auth
  namespace: prod
spec:
  replicas: 1
  selector:
    matchLabels:
      app: auth
  template:
    metadata:
      labels:
        app: auth
    spec:  
      imagePullSecrets:
      - name: harbor-admin
      
      volumes:
      - name: log
        emptyDir: {}
      
      containers:
      - name: auth
        image: harbor.oldxu.net/base/tomcat:10.0.27_with_log
        imagePullPolicy: Always 
        ports:
        - containerPort: 8080
        volumeMounts:
        - name: log
          mountPath: /app/tomcat/logs
        livenessProbe:
          httpGet:
            path: '/index.jsp'
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 10
        readinessProbe:
          httpGet:
            path: '/index.jsp'
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 10            
        
      - name: filebeat
        image: harbor.oldxu.net/base/filebeat_sidecar:7.17.6 
        imagePullPolicy: Always
        volumeMounts:
        - name: log
          mountPath: /logm
          
        env:
        - name: ENV
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: PodIP
          valueFrom:
             fieldRef:
               fieldPath: status.podIP
        - name: Node
          valueFrom:
             fieldRef:
               fieldPath: spec.nodeName
        - name: PROJECT_NAME
          value: "demo-auth"
        - name: KAFKA_HOSTS
          value: '"kafka-0.kafka-svc.logging:9092","kafka-1.kafka-svc.logging:9092","kafka-2.kafka-svc.logging:9092"' 

在这里插入图片描述

4.2.3 创建service (prod)

apiVersion: v1
kind: Service
metadata:
  name: tomcat-svc
  namespace: prod
spec:
  selector:
    app: auth
  ports:
  - port: 8080
    targetPort: 8080

4.2.4 进行压力测试 (prod)


不懂跟不跟压测tomcat有关,压测完后efak也寄了 ,出现nginx 502

4.2.5 检查KafkaTopic (prod)

在这里插入图片描述

5.交付测试环境Logstash

5.1 测试环境Logstash配置

1、编写logstash配置

input{
    kafka{
        bootstrap_servers => "kafka-0.kafka-svc:9092,kafka-1.kafka-svc:9092,kafka-2:kafka-svc:9092"
        group_id => "logstash-test" #消费者组名称
        consumer_threads => "3"
        topics_pattern => "app-test-.*" #通过正则表达式匹配要订阅的主题
    }
}

filter {
    json {
        source => "message"
    }
}

output {
    stdout{
        codec => rubydebug
    }
    elasticsearch{
        hosts => ["es-data-0.es-svc:9200","es-data-1.es-svc:9200"]
        index => "app-test-%{+YYYY.MM.dd}"  #输出的显示
        template_overwrite => true
    }
}

5.2 创建测试环境configmap

mkdir conf
kubectl create configmap logstash-test-conf \
--from-file=logstash.conf=conf/logstash-test.conf -n logging

5.3 运行测试环境Logstash (03-logstash-test-sts.yaml)

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: logstash-test
  namespace: logging
spec:
  serviceName: "logstash-svc"
  replicas: 1
  selector: 
    matchLabels:
      app: logstash
      env: test
  template:
    metadata:
      labels:
        app: logstash
        env: test
    spec:
      imagePullSecrets:
      - name: harbor-admin
      containers:
      - name: logstash
        image: harbor.oldxu.net/base/logstash-oss:7.17.6
        args: ["-f","config/logstash.conf"]
        resources:
          limits:
            memory: 512Mi
        env:
        - name: PIPELINE_WORKERS
          value: "2"
        - name: PIPELINE_BATCH_SIZE
          value: "10000"
        lifecycle:
          postStart:
            exec:
              command:
              - "/bin/bash"
              - "-c"
              - "sed -i -e '/^-Xms/c-Xms512m' -e '/^-Xmx/c-Xmx512m' /usr/share/logstash/config/jvm.options"
        volumeMounts:
        - name: data
          mountPath: /usr/share/logstash/data
        - name: conf
          mountPath: /usr/share/logstash/config/logstash.conf
          subPath: logstash.conf
      volumes:
      - name: conf
        configMap:
          name: logstash-test-conf
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: ["ReadWriteMany"]
      storageClassName: "nfs"
      resources:
        requests:
          storage: 20Gi          

5.4 检查ES测试环境索引

在这里插入图片描述

6.交付生产环境Logstash

6.1 生产环境Logstash配置

2、准备 logstash 读取kafka生成环境配置

input {
    kafka {
        bootstrap_servers => "kafka-0.kafka-svc:9092,kafka-1.kafka-svc:9092,kafka-2.kafka-svc:9092"
        group_id => "logstash-prod"      # 消费者组名称
        consumer_threads => "3"          # 理想情况下,配置与分区数一样多的线程,实现均衡
        topics_pattern => "app-prod-.*"  # 通过正则表达式匹配要订阅的主题
    }
}

filter {
	json {
		source => "message"
	}
}

output {
    stdout {
        codec => rubydebug
    }
    elasticsearch {
        hosts => ["es-data-0.es-svc:9200","es-data-1.es-svc:9200"]
        index => "app-prod-%{+YYYY.MM.dd}"
        template_overwrite => true
    }
}

6.2 创建生产环境configmap

kubectl create
configmap logstash-prod-conf \
--from-file=logstash.conf=conf/logstash-prod.conf -n logging

6.3 运行生产环境Logstash ((03-logstash-prod-sts.yaml))

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: logstash-prod
  namespace: logging
spec:
  serviceName: "logstash-svc"           # 使用此前创建的svc,则无需重复创建
  replicas: 2
  selector:
    matchLabels:
      app: logstash
      env: prod
  template:
    metadata:
      labels:
        app: logstash
        env: prod
    spec:
      imagePullSecrets:
      - name: harbor-admin
      containers:
      - name: logstash
        image: harbor.oldxu.net/base/logstash-oss:7.17.6
        args: ["-f","config/logstash.conf"]                     # 启动时指定加载的配置文件
        resources:
          limits:
            memory: 512Mi
        env:
        - name: PIPELINE_WORKERS
          value: "2"
        - name: PIPELINE_BATCH_SIZE
          value: "10000"
        lifecycle:
          postStart:                                            # 设定JVM
            exec:
              command:
              - "/bin/bash"
              - "-c"
              - "sed -i -e '/^-Xms/c-Xms512m' -e '/^-Xmx/c-Xmx512m' /usr/share/logstash/config/jvm.options"
        volumeMounts:
        - name: data                                            # 持久化数据目录
          mountPath: /usr/share/logstash/data
        - name: conf
          mountPath: /usr/share/logstash/config/logstash.conf
          subPath: logstash.conf

      volumes:
      - name: conf
        configMap:
          name: logstash-prod-conf
          
  volumeClaimTemplates:
  - metadata:
      name: data
    spec:
      accessModes: ["ReadWriteMany"]
      storageClassName: "nfs"
      resources:
        requests:
          storage: 22Gi

6.4 检查ES测试环境索引

推荐使用ab压测 namespace prod的podIP 。  使用手动curl几十次后,这个podIP ,竟然kibana没数据!?

在这里插入图片描述

7.Kibana数据展示

7.1 添加索引

1、添加测试环境索引
在这里插入图片描述

2、添加生产环境索引
在这里插入图片描述

7.2 查看测试环境数据

1、点击测试环境索引
2、选择需要查看的字段
3、进行filter筛选项目
4、选择对应时间段
在这里插入图片描述

7.3 查看生产环境数据

1、点击测试环境索引
2、选择需要查看的字段
3、进行filter筛选项目
4、选择对应时间段
在这里插入图片描述

2023年5月18日11:27:56
END


http://lihuaxi.xjx100.cn/news/1151357.html

相关文章

nginx浅看

nginx start on macos sudo nginx # sudo nginx -s [stop or reload or quit]where the conf file at # at /usr/local/etc/nginx/nginx.conf 这是配置文件 # at /usr/local/Cellar/nginx/<version> 这是nginx安装目录&#xff0c;在这里读取html文件nginx 最出色的能…

chatgpt赋能Python-python3怎么降到2

Python3如何降级到Python2 Python3是Python语言的最新版本&#xff0c;但是一些旧的项目或者库可能只支持Python2&#xff0c;这就需要将Python3降级到Python2。本文将介绍如何在MacOS和Windows系统上进行Python3到Python2的降级&#xff0c;并提供详细的步骤和注意事项。 Ma…

PySide6/PyQT多线程之 线程池的基础概念和最佳实践

前言 在PySide6/PyQT 多线程编程中&#xff0c;线程池也是重要的一项知识点&#xff0c;线程池是一种高效管理和调度多个线程执行任务的方式。 通过结合线程池&#xff08;QThreadPool&#xff09;和任务类&#xff08;QRunnable&#xff09;&#xff0c;可以轻松地实现并发执行…

【已解决】grub引导项修复:Minimal BASH-like line editing is supported.

目录 1 问题背景2 问题探索3 问题解决4 告别Bug 1 问题背景 环境&#xff1a; Win10Ubuntu20.04 现象&#xff1a;双系统电脑向移动硬盘安装Ubuntu系统后&#xff0c;重启黑屏并显示Minimal BASH-like line editing is supported. For the first word, TAB lists possible comm…

一、通过命令行体验长安链

一、通过命令行体验长安链 1 、概述2、环境依赖2.1、硬件依赖2.2、软件依赖2.3、git安装2.4、golang安装2.5、gcc 3、环境搭建3.1、源码下载3.2、 源码编译3.3、编译及安装包制作3.4、启动节点集群3.5、查看节点启动使用正常 4、使用CMC命令行工具部署、调用合约4.1、编译&…

【MYSQL】事务的4大属性,对隔离级别的详细讲解

目录 1.原子性和持久性 1.1.手动提交事务 1.2.自动提交事务 1.3.事务的原理&#xff1a; 2.隔离性 1.读未提交&#xff08;Read Uncommitted&#xff09; 2.读提交&#xff08;Read Committed&#xff09; 3.可重复读 4.串行化 3.一致性 4.理解读提交和可重复读的实现…

hadoop各种配置文件的含义及作用

文件描述core-default.xml该文件包含了对于 Hadoop 核心部分的默认配置&#xff0c;例如 I/O 设置、网络设置、副本设置等hdfs-default.xml该文件包含了对于 Hadoop 分布式文件系统&#xff08;HDFS&#xff09;的默认配置&#xff0c;例如 NameNode 和 DataNode 的地址、端口、…

〖Python网络爬虫实战㉖〗- Selenium库和ChromeDriver驱动的安装

订阅&#xff1a;新手可以订阅我的其他专栏。免费阶段订阅量1000 python项目实战 Python编程基础教程系列&#xff08;零基础小白搬砖逆袭) 说明&#xff1a;本专栏持续更新中&#xff0c;目前专栏免费订阅&#xff0c;在转为付费专栏前订阅本专栏的&#xff0c;可以免费订阅付…