• day07 k8s+ELK


    1.前情回顾

    k8s从kube-metrics-server获取到里面cpu的依据,进行自动扩容
    kubectl top node 可以看节点状态,和prometheus对比
    prometheus带着参数去请求blackbox-exporter,black-exporter才知道去检测哪些是否存活,tcp存活,http存活
    能用http的就用http,不能的话再用tcp

    PromQl,不管grafana出图还是alertManager报警都是依赖这个PromQl查询语句

    2.日志

    业务容器扩容,缩容
    业务日志,2份变4份
    日志集中收集
    中国互联网公司,落磁盘为主,日志比较好的收集起来

    需求:
    日志收集,分析的系统

    • 收集--能够采集多种来源的日志数据(流式日志收集器)logstash
    • 传输--能够稳定的把日志数据传输到中央系统(消息队列)
    • 存储--可以将日志以结构化数据的形式存储起来(搜索引擎),日志转成json,存储起来
    • 分析--支持方便的分析,检索方法,最好有gui管理系统(前端)
    • 警告--能够提供错误报告,监控机制(监控工具)(es里面插件有告警)

    3.ELK Stack

    火了7,8年了
    E:ElasticSearch(mysql是b+数的索引)
    L:logstash
    K:kibana

    es倒排索引,关键字做分词,可以关键字做索引.

    3.1 传统elk框架

    • logstash使用ruby开发,吃资源,消耗高
    • 业务程序与logstash耦合松,不利于业务迁移
    • 日志收集与ES耦合过紧,易打爆,丢数据(容易把es打爆)
    • 容器云环境,传统ELK模型难以完成工作

    3.2 改进后的架构

    • 业务容器pod部分:logstash耗资源,使用filebeat(golang)替换,流式日志收集,消耗资源更小.并且pod和filebeat用了边车模式绑定到了一起运行,耦合度变紧了.一个pod里面运行了2个container,一个是业务container,一个是filebeat,共享了ipc,user,uts.隔离了net,fs,pid(共享了3个名称空间,隔离了3个名称空间)
    • kafka:做了一层解耦,消息队列,支持发布订阅模型,filebeat是用topic的形式,去kafka上publish(kafka吞吐量比较大的消息队列),不同的业务是用kafka上不同的topic来区分的,一个应用一个topic
    • logstash:订阅了kafka上的topic(异步的过程),实时kinbana看日志的时候有一定延迟
    • ElasticSearch:里面用了index-pattern去给日志环境做区分,生产环境,还是测试环境

    4.改造dubbo-demo-web项目

    改为使用tomcat类型的项目,底包,放war包这种
    使用tomcat8.5.50.tar.gz二进制包

    [root@jdss7-200]# cd /opt/src
    [root@jdss7-200]# wget http://xxxx/apache-tomcat8.5.50.tar.gz
    [root@jdss7-200]# mkdir -p /data/dockerfile/tomcat/
    [root@jdss7-200]# tar zxf apache-tomcat8.5.50.tar.gz -C /data/dockerfile/tomcat/
    [root@jdss7-200]# cd /data/dockerfile/tomcat/\
    

    4.1 优化tomcat,移除AJP协议

    [root@jdss7-200]# vim server.xml
    # 关闭AJP端口,8009,这个端口ajp协议是和apache一起用的
    <!--<Connector port="8009" portocol="JP/1.3" redirectPort="8443" /> -->
    

    4.2 配置日志,移除不需要的日志handler

    vim conf/logging.properties
    删除3manager,4host-manager的handlers

    上面标注的要删掉

    上面的要注释掉

    4.3 修改日志级别INFO


    5.制作Tomcat的Dockerfile

    Dockerfile

    FROM harbor.od.com/public/jre:8u112
    RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' > /etc/timezone
    ENV CATALINA_HOME /opt/tomcat
    ENV LANG zh_CN.UTF-8
    ADD apache-tomcat-8.5.50 /top/tomcat
    ADD config.yml /opt/prom/config.yml # 这个是prometheus基于file sd,手动发现的相关配置,
    ADD jmx_javaagent-0.3.1.jar /opt/prom/jmx_javaagent-0.3.1.jar
    WORKDIR /opt/tomcat
    ADD entrypoint.sh /entrypoint.sh
    CMD ["/entrypoint.sh"]
    

    config.yml

    ---
    rules:
      - pattern: '.*'
    

    entrypoint.sh(chmod +x entrypoint.sh)

    #!/bin/bash
    M_OPTS="-Duser.timezone=Asia/Shanghai -javaagent:/opt/prom/jmx_javaagent-0.3.1.jar=$(hostname -i):${M_PORT:-"123456"}:/opt/prom/config.yml"
    C_OPTS=${C_OPTS} # apollo的连接串,env是啥,apollo的config地址是啥
    MIN_HEAP=${MIN_HEAP:-"128m"}
    MAX_HEAP=${MAX_HEAP:-"128m"}
    JAVA_OPTS=${JAVA_OPTS:-"-Xmn384m -Xss256k -Duser.timezone=GMT+08 -XX:+DisableExplicitGC -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=0 -XX:+CMSClassUnloadingEnabled -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=80 -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+PrintClassHistogram -Dfile.encoding=UTF8 -Dsun.jnu.encoding=UTF8"}
    CATALINA_OPTS="${CATALINA_OPTS}"
    JAVA_OPTS="${M_OPTS} ${C_OPTS} -Xms${MIN_HEAP} -Xmx{MAX_HEAP} ${JAVA_OPTS}"
    sed -i -e "1a\JAVA_OPTS=\"$JAVA_OPTS\"" -e "1a\CATALINA_OPTS=\"$CATALINA_OPTS\"" /opt/tomcat/bin/catalina.sh
    
    cd /opt/tomcat && /opt/tomcat/bin/catalina.sh run 2> &1 >> /opt/tomcat/logs/stdout.log
    # catalina.sh run 进程前台运行了
    

    6.构建tomcat基础镜像

    docker build . -t harbor.od.com/base/tomcat:v8.5.50
    docker push harbor.od.com/base/tomcat:v8.5.50
    

    7.改造项目,dubbo-demo-web

    tomcat分支,pom.xml改packing的类型为war包

    多建一条流水线,针对tomcat类型的,普通类型的流水线无法正常运行

    8.二进制安装elasticsearch

    使用版本是6.8.6,elasticsearch的7版本以后的jdk要11版本了.

    7.12部署一台es来实验

    [root@jdss7-12]# cd /opt/src
    [root@jdss7-12]# wget http://xxx/elasticsearch-6.8.6.tar.gz
    [root@jdss7-12]# tar xfv elasticsearch-6.8.6.tar.gz -C /opt
    [root@jdss7-12]# ln -s /opt/elasticsearch-6.8.6 /opt/elasticsearch
    [root@jdss7-12]# mkdir -p /data/elasticsearch/{data,logs}
    

    8.1 编辑配置文件elasticsearch.yml

    [root@jdss7-12]# vim config/elasticsearch.yml
    cluster.name: es.od.com
    node.name: jdss7-12.host.com
    path.data: /data/elasticsearch/data
    path.logs: /data/elasticsearch/logs
    bootstrap.memory_lock: true
    network.host: 10.4.7.12
    http.port: 9200
    

    8.2 优化jvm.options

    es1个节点占内存官方推荐32G,太大的话会触发full gc,实验环境就整512MB

    [root@jdss7-12]# vim config/jvm.options
    -Xms512m
    -Xmx512m
    

    8.3 创建普通用户,root用户起不来es

    [root@jdss7-12]# useradd -s /bin/bash -M es
    -M 代表没有家目录
    [root@jdss7-12]# chown -R es.es /opt/elasticsearch-6.8.6
    [root@jdss7-12]# chown -R es.es /data/elasticsearch/
    
    

    8.4 调整文件描述符,及内核参数

    /etc/security/limits.d/es.conf
    es hard nofile  6553
    es soft fsize unlimited
    es hard memlock unlimited
    es soft memlock unlimited
    
    sysctl -w vm.max_map_count=262144
    echo "vm.max_map_count=262144" >> /etc/sysctl.conf
    sysctl -p
    

    8.5 启动es

    方法1
    su - es
    /opt/elasticsearch/bin/elasticsearch -d
    方法2:使用es用户去执行命令
    su - es -c "/opt/elasticsearch/bin/elasticsearch -d"
    方法3:
    sudo -ues "/opt/elasticsearch/bin/elasticsearch -d"
    netstat -tulnp | grep 9200
    

    8.6 调整es的日志模板

    template 去匹配模板

    number_of_shards: 5, 调整分片
    number_of_replicas: 0 调整副本级,因为单机就写成0了,生产一般是3副本,原数据一份,2份副本
    curl -H "Content-Type:application/json" -XPUT http://10.4.7.12:9200/_template/k8s -d '{
      "template":"k8s",
      "index_patterns":["k8s"],
      "settings":{
         "number_of_shards":5,
         "number_of_replicas":0
       }
    }'
    

    8.7 说明

    elasticsearch6.8.6本班依赖jdk是1.8版本

    9.kafka搭建

    jdss7-11机器上装kafka
    使用版本2.2.0,不要超过2.2.0版本,kafka-manager这个工具最多支持到kafka到2.2.0版本

    9.1 下载二进制包

    [root@jdss7-11]# cd /opt/src/
    
    [root@jdss7-11]# wget kafka_2.12-2.2.0.tgz 
    [root@jdss7-11]# ln -s /opt/kafka-2.12-2.2.0 /opt/kafka
    
    

    9.2 配置kafka

    [root@jdss7-11]# mkdir -pv /data/kafka/logs
    [root@jdss7-11]# vim config/server.properties
    log.dir=/data/kafka/logs
    zookeeper.connect=localhost:2181
    log.flush.interval.messages=10000
    log.flush.interval.ms=1000
    delete.topic.enable=true
    host.name=jdss7-11.host.com
    

    9.3 启动kafka

    bin/kafka-server-start.sh -daemon config/server.properties
    ps aux | grep kafka 
    netstat -tulnp # 发现用的是9092端口
    

    9.4 安装kafka-manager的东西

    yahoo开源的

    1. 可以使用dockerfile方式来安装
    [root@jdss7-200]# mkdir -p /data/dockerfile/kafka-manager
    [root@jdss7-200]# cd /data/dockerfile/kafka-manager;vim Dockerfile 
    FROM haseeberget/scala-sbt
    
    ENV ZK_HOSTS=10.4.7.11:2181 \
        KM_VERSION=2.0.0.2
    
    RUN mkdir -p /tmp/ && \
        cd /tmp/ &7 \
        wget https://github.com/yahoo/kafka-manager/archive/${KM_VERSION}.tar.gz && \
        tar xf ${KM_VERSION}.tar.gz && \
        cd /tmp/kafka-manager-${KM_VERSION} && \
        sbt clean dist && \
        unzip -d / ./target/universal/kafka-manager-${KM_VERSION}.zip && \
        rm -fr /tmp/${KM_VERSION} /tmp/kafka-manager-${KM_VERSION}
    
    WORKDIR /kafka-manager-${KM_VERSION}
    EXPOSE 9000
    ENTRYPOINT ["./bin/kafka-manager","-Dconfig.file=conf/application.conf"]
    

    带web界面的东西,github上也有8.4k的star,

    1. 下载docker镜像(但是对kafka版本有要求)
      sheepkiller/kafka-manager

    9.5 准备kafka-manager的资源配置清单,交付到k8s集群的infra命名空间里

    kubectl scale deployment grafana --reeplicas=0 -n infra # 关掉grafana

    dp.yaml

    kind: Deployment
    apiVersion: extensions/v1beta1
    metadata:
      name: kafka-manager
      namespace: infra
      labels:
        name: kafka-manager
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: kafka-manager     
      strategy:
        type: RollingUpdate
        rollingUpdate:
          maxUnavailable: 1
          maxSurge: 1    
      revisionHistoryLimit: 7
      progressDeadlineSeconds: 600  
      template:
        metadata:
          labels:
            app: kafka-manager
        spec:
          containers:
          - name: kafka-manager
            image: harbor.od.com/infra/kafka-manager:v2.0.0.2
            imagePullPolicy: Always
            ports:
            - containerPort: 9000
              protocol: TCP
            env:
            - name: ZK_HOSTS
              value: zk1.od.com:2181
            - name: APPLICATION_SECRET
              value: letmein        
          imagePullSecrets:
          - name: harbor
          terminationGracePeriodSeconds: 30
          securityContext:
            runAsUser: 0
    

    svc.yaml

    kind: Service
    apiVersion: v1
    metadata:
      name: kafka-manager
      namespace: infra
    spec:
      selector:
        app: kafka-manager
      ports:
        - port: 9000
          targetPort: 9000
          protocol: TCP
    

    ingress.yaml

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: kafka-manager
      namespace: infra
    spec:
      rules:
      - host: km.od.com
        http:
          paths:
          - path: /
            backend:
              serviceName: kafka-manager
              servicePort: 9000
    

    9.6 应用资源配置清单

    kubeclt apply -f http://k8s-yaml.od.com/kafka-manager/dp.yaml
    kubeclt apply -f http://k8s-yaml.od.com/kafka-manager/svc.yaml
    kubeclt apply -f http://k8s-yaml.od.com/kafka-manager/ingress.yaml
    

    9.7 验证


    add Cluster

    consumer_offsets

    10.linux的top,load分析扩展

    load average: 1min,5min,15min

    4核核的cpu,load average中1分钟的,不超过8都是ok的,每个逻辑cpu上等待的任务不超过1个

    11.制作filebeat底包并接入dubbo服务消费者


    使用filebeat版本和elasticsearch版本建议一样,此处使用filebeat7.4.0
    filebeat使用9200的http端口与kafka去通信

    [root@jdss7-200]# cd /opt/src
    
    

    11.1 编写Dockerfile

    FROM debian:jessie
    ENV FILEBEAT_VERSION=7.5.1 
    ADD filebeat-7.5.1 /opt/filebeat-7.5.1
    RUN set -x && \
        cd /opt && \
        cd filebeat-* && \
        cp filebeat /bin && \
        cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
        apt-get update && \
        apt-get install vim lsof -y
    ADD docker-entrypoint.sh /docker-entrypoint.sh
    ENTRYPOINT ["/docker-entrypoint.sh"]
    

    entrypoint.sh

    #!/bin/bash
    ENV=${ENV:-"test"}
    # 项目名,可能用到了kafka的topic上或者es的索引上
    PROJ_NAME=${PROJ_NAME:-"no-define"}
    # 多行匹配,java异常一大片,算1条,传递正则匹配的规则,以2位数字开头的就匹配上
    MULTILINE=${MULTILINE:-"^\d(2)"}
    
    cat > /etc/filebeat.yaml << EOF
    filebeat.inputs:
    - type: log
      fields_under_root: true
      fields:
        topic: logm-${PROJ_NAME}
      paths: # 多行匹配,用的比较多,一般都是这个
        - /logm/*.log
        - /logm/*/*.log
        - /logm/*/*/*.log
        - /logm/*/*/*/*.log
        - /logm/*/*/*/*/*.log
      scan_frequency: 120s
      max_bytes: 10485760
      multiline.pattern: $MULTILINE
      multiline.negate: true
      multiline.match: after
      multiline.max_lines: 100
    - type: log
      fields_under_root: true
      fields:
        topic: logu-${PROJ_NAME}
      paths: # 单行匹配
        - /logu/*.log
        - /logu/*/*.log
        - /logu/*/*/*.log
        - /logu/*/*/*/*.log
        - /logu/*/*/*/*/*.log
        - /logu/*/*/*/*/*/*.log
    logging.level: info
    output.kafka:
      hosts: ["10.4.7.11:9092"]
      topic: k8s-fb-$ENV-%{[topic]} # fb是filebeat的意思
      version: 2.0.0 # kafka是2.2.0也要写2.0.0,只要是2版本以上就写2.0.0
      required_acks: 0
      max_message_bytes: 10485760
    EOF
    
    set -xe
    
    if [[ "$1" == "" ]];then
      exec filebeat -c /etc/filebeat.yaml
    else
      exec "$@"
    fi
    

    11.2 制作镜像

    docker build . -t harbor.od.com/infra/filebeat:v7.5.1
    

    12.让dubbo-demo-service的资源配置清单接入filebeat,变成边车模式运行

    cd /data/k8s-yaml/dubbo-demo-consumer/
    dp.yaml
    关键配置

    volumes:
    - emptyDir: {} # 空目录的卷,宿主机上开辟一块空间,容器里挂载用,如果容器被销毁了,这个目录页没了
      name: logm
    
    # 挂载
    volumeMounts:
    - mountPath: /opt/tomcat/logs
      name: logm
    


    共享uts,net,user
    不共享fs,ipc

    重新应用资源配置清单

    然后进filebeat的容器的/logm目录就可以看到consumer容器的日志,这两个container共享了日志目录;临时共享的一个池子,pod消失了,empty就没了.跟随pod的生命周期
    共享了uts,所以hostname是一样的
    隔离ipc,不能filebeat的容器里杀掉consumer的进程
    隔离了fs,pid

    kafka日志就有了

    或者daemonSet一个node跑一个filebeat,一个计算节点上所有日志都靠它

    12.部署logstash

    logstash从kafka中拉取数据出来,然后写到es中去
    版本对应关系

    准备6.8.6版本的logstash

    [root@jdss7-200]# docker pull logstash:6.8.6
    [root@jdss7-200]# docker images | grep logstash
    [root@jdss7-200]# docker tag xxxxxxx harbor.od.com/infra/logstash:v6.8.6
    [root@jdss7-200]# docker push harbor.od.com/infra/logstash:v6.8.6
    

    测试环境起一个logstash,生产环境起一个

    12.1 logstash的配置

    input {
      kafka {
        bootstrap_servers => "10.4.7.11:9092"
        client_id => "10.4.7.200"
        consumer_threads => 4
        group_id => "k8s_test"
        topic_pattern => "k8s-fb-test-.*"
      }
    }
    
    filter {
      json {
        source => "message"
      }
    }
    
    output {
      elasticsearch {
        host => ["10.4.7.12:9200"]
        index => "k8s-test-$(+YYYY.MM.DD)"
      }
    }
    

    12.2 创建配置文件,然后docker挂载进去

    mkdir -p /etc/logstash
    vim /etc/logstash/logstash-test.conf
    input {
      kafka {
        bootstrap_servers => "10.4.7.11:9092"
        client_id => "10.4.7.200"
        consumer_threads => 4
        group_id => "k8s_test"
        topics_pattern => "k8s-fb-test-.*"
      }
    }
    
    filter {
      json {
        source => "message"
      }
    }
    
    output {
      elasticsearch {
        hosts => ["10.4.7.12:9200"]
        index => "k8s-test-%{+YYYY.MM.DD}"
      }
    }
    vim /etc/logstash/logstash-prod.conf
    input {
      kafka {
        bootstrap_servers => "10.4.7.11:9092"
        client_id => "10.4.7.200"
        consumer_threads => 4
        group_id => "prod"
        topics_pattern => "k8s-fb-prod-.*"
      }
    }
    
    filter {
      json {
        source => "message"
      }
    }
    
    output {
      elasticsearch {
        hosts => ["10.4.7.12:9200"]
        index => "k8s-prod-%{+YYYY.MM.DD}"
      }
    }
    

    裸docker启动logstash

    docker run -d --name logstash-test -v /etc/logstash(宿主机):/etc/logstash(容器里) harbor.od.com/infra/logstash:v6.8.6 -f /etc/logstash/logstash-test.conf
    # -f 是指定配置文件
    

    12.3 去es里看有数据没有

    13.部署kibana

    nodejs写的纯前端项目

    13.1 准备镜像

    [root@jdss7-200]# docker pull kibana:6.8.6
    [root@jdss7-200]# docker tag xxxx harbor.od.com/infra/kibana:v6.8.6
    [root@jdss7-200]# docker push harbor.od.com/infra/kibana:v6.8.6
    

    13.2 准备资源配置清单

    dp.yaml

    kind: Deployment
    apiVersion: extensions/v1beta1
    metadata:
      name: kibana
      namespace: infra
      labels:
        name: kibana
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: kibana
      strategy:
        type: RollingUpdate
        rollingUpdate:
          maxUnavailable: 1
          maxSurge: 1    
      revisionHistoryLimit: 7
      progressDeadlineSeconds: 600  
      template:
        metadata:
          labels:
            app: kibana
        spec:
          containers:
          - name: kafka-manager
            image: harbor.od.com/infra/kibana:v6.8.6
            imagePullPolicy: Always
            ports:
            - containerPort: 5601
              protocol: TCP
            env:
            - name: ELASTICSEARCH_URL
              value: http://10.4.7.12:9200        
          imagePullSecrets:
          - name: harbor
          securityContext:
            runAsUser: 0
    

    svc.yaml

    kind: Service
    apiVersdion: v1
    metadata:
      name: kibana
      namespace: infra
    spec:
      selector:
        app: kibana
      ports:
        - port: 5601
          targetPort: 5601
          protocol: TCP
    

    ingress.yaml

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: kibana
      namespace: infra
    spec:
      rules:
      - host: kibana.od.com
        http:
          paths:
          - path: /
            backend:
              serviceName: kibana
              servicePort: 5601
    

    13.3 可以看到Monitoring

    13.4 manager,看index-patterns


    next

    create index pattern
    然后Discover就能看到日志了

    配置index(Managements -> index patterns -> create index pattern)

    14.扩展知识

    kafka里面可以分partion,分了partion后可以起多个logstash
    可以让logstash1去消费k8s-prod-message的1,2,3分区
    可以让logstash2去消费k8s-prod-message的4,5,6分区
    可以起多个logstash去消费topic

    15.Kibana的用法

    给测试和开发使的
    kibana有4个选择器

    1. 时间选择器

    2. 环境选择器

    3. 项目选择器


      topic is 指定的是filebeat里指定的环境变量

    4. 关键字选择器

    message,log.file.path,host.name
    搜索实验,应用的是lucene的查询预发

    16.扩展

    直接k8s起来的应用程序,控制台输出的日志如何filebeat收集,走elk


    重新docker build . -t harbor.od.com/base/jre8:8u112_with_logs
    做一个底包带日志文件的,然后改jenkins中的build parameters

    17.作业

    spinniker了解
    提供的软件包,10个镜像都load进harbor仓库里

  • 相关阅读:
    日常小算法
    美化type="file"控件
    流文件_从网络中获取文件
    Kibana配置安装
    JDK安装
    Node.js安装windows环境
    RabbitMQ高可用
    RabbitMQ实例C#
    RabbitMQ基础命令rabbitmqctl
    RabbitMQ配置
  • 原文地址:https://www.cnblogs.com/PythonOrg/p/16171278.html
Copyright © 2020-2023  润新知