k8s容器日志收集方案

背景
由于以下容器本身特性和现有日志采集工具的缺陷,开发者在收集Kubernetes分布式集群日志时常常遇到困扰:

容器本身特性:
    采集目标多:容器本身的特性导致采集目标多,需要采集容器内日志、容器stdout。对于容器内部的文件日志采集,现在并没有一个很好的工具能够动态发现采集。针对每种数据源都有对应的采集软件,但缺乏一站式的工具。
    弹性伸缩难:Kubernetes是分布式的集群,服务、环境的弹性伸缩对于日志采集带来了很大的困难,无法像传统虚拟机环境下那样,事先配置好日志的采集路径等信息,采集的动态性以及数据完整性是非常大的挑战。
现有日志工具的一些缺陷:
    缺乏动态配置的能力。目前的采集工具都需要事先手动配置好日志采集方式和路径等信息,因为它无法自动感知到容器的生命周期变化或者动态漂移,所以它无法动态地去配置。
    日志采集重复或丢失的问题。因为现在的一些采集工具通过tail的方式进行日志采集,这样可能导致日志丢失,比如采集工具在重启的过程中,而应用依然在写日志,那么就有可能导致这个窗口期的日志丢失。对于这种情况一般保守的做法默认往前多采集1 M日志或2 M的日志,那么这就又会可能引起日志采集重复的问题。
    未明确标记日志源。因为一个应用可能有很多个容器,输出的应用日志也是一样的,那么当将所有应用日志收集到统一日志存储后端时,在搜索日志的时候,您无法明确这条日志具体是哪一个节点上的哪一个应用容器产生的。

Log-pilot介绍
   Log-pilot是一个智能容器日志采集工具,它不仅能够高效便捷地将容器日志采集输出到多种存储日志后端,同时还能够动态地发现和采集容器内部的日志文件。
   针对前面提出的日志采集难题,Log-pilot通过声明式配置实现强大的容器事件管理,可同时获取容器标准输出和内部文件日志,解决了动态伸缩问题,此外,Log-pilot具有自动发现机制、CheckPoint及句柄保持的机制、自动日志数据打标、有效应对动态配置、日志重复和丢失以及日志源标记等问题。
基于阿里云的开源日志搜集方案,并且使用daemonset的方式部署到node节点上用来自定义搜集控制台或者固定目录下的日志文件
本次的yaml是自定义输出到后端到kafka然后由logstash过滤以后发送到es中,kibana直接读es的索引
注:在阿里云上开通阿里云sls日志收集与arms应用链路监控,
    会导致自定义安装的log-polit日志收集无法收集到日志,
    默认的阿里云自定义前缀是aliyun_logs,
    会导致冲突,需要自定义 - name: PILOT_LOG_PREFIX 日志收集格式的前缀可以解决。

架构图

 k8s容器日志收集方案_第1张图片

log-pilot安装

#在k8s集群內以daemonset的方式来进行部署
#注:在阿里云上开通阿里云sls日志收集与arms应用链路监控,
	会导致自定义安装的log-polit日志收集无法收集到日志,
	默认的阿里云自定义前缀是aliyun_logs,
	会导致冲突,需要自定义 - name: PILOT_LOG_PREFIX 日志收集格式的前缀可以解决。


apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: log-pilot
  labels:
    k8s-app: log-pilot
  namespace: kube-system
spec:
  updateStrategy:
    type: RollingUpdate
  template:
    metadata:
      labels:
        k8s-app: log-pilot
    spec:
      tolerations:
      - key: node-role.kubernetes.io/master
        effect: NoSchedule
      containers:
      - name: log-pilot
        image: registry.cn-hangzhou.aliyuncs.com/acs/log-pilot:0.9.7-filebeat
        env:
          - name: "LOGGING_OUTPUT"
            value: "kafka"
          - name: PILOT_LOG_PREFIX
            value: ailieyun
          - name: "KAFKA_BROKERS"
            value: "192.168.200.100:9092,192.168.200.101:9092,192.168.200.102:9092"
          - name: "NODE_NAME"
            valueFrom:
              fieldRef:
                fieldPath: spec.nodeName
        volumeMounts:
        - name: sock
          mountPath: /var/run/docker.sock
        - name: logs
          mountPath: /var/log/filebeat
        - name: state
          mountPath: /var/lib/filebeat
        - name: root
          mountPath: /host
          readOnly: true
        - name: localtime
          mountPath: /etc/localtime
        securityContext:
          capabilities:
            add:
            - SYS_ADMIN
      terminationGracePeriodSeconds: 30
      volumes:
      - name: sock
        hostPath:
          path: /var/run/docker.sock
      - name: logs
        hostPath:
          path: /var/log/filebeat
      - name: state
        hostPath:
          path: /var/lib/filebeat
      - name: root
        hostPath:
          path: /
      - name: localtime
        hostPath:
          path: /etc/localtime

 安装zookeeper和kafka集群 

#zookeeper集群
#以其中一台机器为例
tar -zxvf zookeeper-3.4.14.tar.gz -C /data/service/
cd /data/service/zookeeper-3.4.14/ && cp conf/zoo_sample.cfg conf/zoo.cfg
查看配置:
cat /data/service/zookeeper-3.4.14/conf/zoo.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/data/data/zookeeper
clientPort=2181
server.1=192.168.1.7:2888:3888
server.2=192.168.1.6:2888:3888
server.3=192.168.1.5:2888:3888
添加:
echo 1 > /data/data/zookeeper/myid
其他机器:
echo 2 > /data/data/zookeeper/myid
echo 3 > /data/data/zookeeper/myid
 
启动: /data/service/zookeeper-3.4.14/bin/zkServer.sh start
查看状态: /data/service/zookeeper-3.4.14/bin/zkServer.sh status
 
#kafka集群
tar -zxvf kafka_2.12-2.0.1.tgz -C /data/service/
#修改zookeeper链接地址:
/data/service/kafka_2.12-2.0.1/config/server.properties
zookeeper.connect=192.168.1.7:2181,192.168.1.6:2181,192.168.1.5:2181

安装logstash  

#logstash集群
tar -zxvf logstash-7.7.1.tar.gz -C /data/service/
cd /data/service/logstash-7.7.1
cat log-polit.conf
input {
  kafka {
    bootstrap_servers=>"192.168.2.137:9092,192.168.2.138:9092,192.168.2.139:9092"
    topics_pattern => "logs.*"
    client_id => "kafka_client_one"
    group_id => "logstash"
    codec => "json"
  }
}
 
filter {
  mutate {
   remove_field => ["input","beat","prospector","@version","offset"]
  }
}
 
output {
  if "nginx-access" in [tags] {
    elasticsearch {
      hosts => ["192.168.1.5:9200","192.168.1.6:9200","192.168.1.7:9200"]
      index => "%{[domain]}-%{+YYYY-MM-dd}"
    }
  } else {
    elasticsearch {
      hosts => ["192.168.1.5:9200","192.168.1.6:9200","192.168.1.7:9200"]
      index => "%{[topic]}-%{+YYYY-MM-dd}"
    }
  }
}
#cd /data/app/logstash-7.7.1 && nohup ./bin/logstash -f log-polit.conf &

es集群安装 

#es集群
tar -zxvf elasticsearch-7.7.1-linux-x86_64.tar.gz -C /data/service/
cd /data/service/elasticsearch-7.7.1
#cat elasticsearch.yml
cluster.name: kkb-logs
node.name: kkb-sys-esmaster-001
path.data: /data/data/elasticsearch/data
path.logs: /data/data/elasticsearch/logs
bootstrap.memory_lock: true
network.host: 192.168.23.30
action.auto_create_index: true
http.port: 9200
discovery.seed_hosts: ["192.168.1.18", "192.168.1.19"]
cluster.initial_master_nodes: ["192.168.1.18", "192.168.1.19"]
node.master: true
node.data: false
#设置堆内存大小
# cat jvm.options|grep "Xm"
# Xms represents the initial size of total heap space
# Xmx represents the maximum size of total heap space
-Xms6g
-Xmx6g
 
#cd /data/app/elasticsearch && ./bin/elasticsearch -d

kibana集群 

此处应该为3台机器,由于是test,所以只上了一台
rpm -ivh kibana-7.7.1-x86_64.rpm
cat /etc/kibana/kibana.yml |grep -Ev "^#|^$"
server.port: 5601
xpack.reporting.csv.maxSizeBytes: 2097152000
server.host: "192.168.1.21"
server.name: "192.168.1.21"
elasticsearch.hosts: ["http://192.168.1.18:9200","http://192.168.1.19:9200"]
elasticsearch.requestTimeout: 300000

 k8s集群日志接入

#nginx deployment
#- name: ailieyun_logs_logs-plat-file-console
#  value: "stdout"
#- name: ailieyun_logs_logs-plat-file-console_ttl
#  value: "3"
#这两行会自动在kafka集群中创建topic
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    run: ng-demo-1
  name: ng-demo-1
spec:
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  replicas: 5
  selector:
    matchLabels:
      run: java-demo-1
  template:
    metadata:
      labels:
        run: ng-demo-1
    spec:
      containers:
      - image:  nginx:latest
        name: ng-demo-1
        ports:
        - containerPort: 80
        resources:
          requests:
            cpu: "500m"
            memory: "512Mi"
          limits:
            cpu: "500m"
            memory: "512Mi"
        env:
          - name: ailieyun_logs_logs-java-demo
            value: "stdout"
          - name: ailieyun_logs_logs-java-demo_ttl
            value: "3"

#创建好deploy以后进到容器里while true;do curl 127.0.0.1;sleep 1 ;done
#然后手动执行数据消费
./kafka-console-consumer.sh --bootstrap-server 192.168.1.5:9092,192.168.1.6:9092,192.168.1.7:9092   --topic logs-java-demo
#然后看到下面到图即视为任务收集成功

你可能感兴趣的:(kubernetes,容器,云原生)