docker日志监控

1,267 阅读4分钟

docker日志处理机制

当启动一个容器的时候,它其实是 docker daemon 的一个子进程, docker daemon 可以拿到你容器里面进程的标准输出,拿到标准输出后,它会通过自身的一个 LogDriver 模块来处理,LogDriver支持的方式很多,可以写到本地的文件(默认方式),可以发送到syslog等。

Docker 会默认收集应用程序的标准输出存储到一个 json.log 文件中,文件的格式类似下面这种:

{"log":"root@c835298de6dd:/# ls\r\n","stream":"stdout","time":"xxoo.155863426Z"}
{"log":"bin  boot  dev\u0009etc  home  lib\u0009lib64  media  mnt  opt\u0009proc  root  run  sbin  selinux\u0009srv  sys  tmp  usr  var\r\n"}

以一行一个作为一条 JSON 数据存储。 Docker 的这种日志存储方式是可以配置的,具体参数可以在执行 run 启动容器的时候通过 log-driver 进行配置,具体配置请参考 log-driver 。 docs.docker.com/config/cont…

Docker Logging Driver

Docker 默认使用了 json-file driver 作为 log driver,而 gelf 则是我们需要使用的 log driver。

为什么使用grayLog (gelf协议)

当容器多了,或者是采用类似 swarm 集群部署 Docker 的时候,各种日志分散存在各个 json.log 文件中,当查找问题或者进行相关统计的时候,分散的日志对我们来说是非常不友好的

优点: - Docker 原生支持 graylog 协议,直接将日志发送到 graylog(通过gelf协议) - graylog官方提供了将本身部署在Docker的支持

Graylog 部署

  1. 创建graylog目录作为部署的工作目录:
mkdir graylog
  1. 创建配置文件以及数据存储目录并赋权限
# graylog数据目录()
mkdir -p ./graylog/config
mkdir -p ./graylog/data/graylog_data
# 由于Graylog以ID 1100 定义了用户和用户组,导致Graylog在启动的时候可能会报config目录权限不足的错误,可以通过以下命令来解决
chown -R 1100:1100 ./graylog/config ./graylog/data/graylog_data
cd ./graylog/config
#直接下载官方推荐配置文件
wget https://raw.githubusercontent.com/Graylog2/graylog-docker/2.5/config/graylog.conf 
#日志配置文件
wget https://raw.githubusercontent.com/Graylog2/graylog-docker/2.5/config/log4j2.xml
# 修改graylog.conf时区
root_timezone = Asia/Shanghai
------------------------------------------
# 创建elasticeSearch目录
mkdir -p ./graylog/data/es_data
# 授权(如果数据目录挂载出来不授权限会报错)
chmod +777 ./graylog/data/es_data
------------------------------------------
# 创建mongodb数据目录
mkdir -p ./graylog/data/mongo_data
  1. docker-compose.yml脚本文件
version: '2'
services:
  # MongoDB: https://hub.docker.com/_/mongo/
  mongodb:
    image: mongo:3
    volumes:
      - /etc/localtime:/etc/localtime
      # - mongo_data:/data/db
      - ./data/mongo_data:/data/db
  # Elasticsearch: https://www.elastic.co/guide/en/elasticsearch/reference/6.x/docker.html
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:6.5.1
    volumes:
      - /etc/localtime:/etc/localtime
      # - es_data:/usr/share/elasticsearch/data
      - ./data/es_data:/usr/share/elasticsearch/data
    environment:
      - http.host=0.0.0.0
      - transport.host=localhost
      - network.host=0.0.0.0
      # Disable X-Pack security: https://www.elastic.co/guide/en/elasticsearch/reference/6.x/security-settings.html#general-security-settings
      - xpack.security.enabled=false
      - xpack.watcher.enabled=false
      - xpack.monitoring.enabled=false
      - xpack.security.audit.enabled=false
      - xpack.ml.enabled=false
      - xpack.graph.enabled=false
      - "ES_JAVA_OPTS=-Xms256m -Xmx256m"
    ulimits:
      memlock:
        soft: -1
        hard: -1
    mem_limit: 256M
  # Graylog: https://hub.docker.com/r/graylog/graylog/
  graylog:
    image: graylog/graylog:2.5
    volumes:
      - /etc/localtime:/etc/localtime
      # - graylog_journal:/usr/share/graylog/data/journal
      - ./data/graylog_data:/usr/share/graylog/data/journal
      # - ./graylog/config:/usr/share/graylog/data/config
      - ./config:/usr/share/graylog/data/config
    environment:
      # CHANGE ME!
      - GRAYLOG_PASSWORD_SECRET=somepasswordpepper
      # Password: admin
      - GRAYLOG_ROOT_PASSWORD_SHA2=8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918
      # 这个地址需要配置成你要访问的地址,比如你的容器部署在192.168.1.2,你需要配置成http://192.168.1.2:9000/api,否则访问会报错
      - GRAYLOG_WEB_ENDPOINT_URI=http://192.168.5.106:9000/api
    links:
      - mongodb:mongo
      - elasticsearch
    depends_on:
      - mongodb
      - elasticsearch
    ports:
      # Graylog web interface and REST API
      # web界面端口
      - 9000:9000
      # gelf收集日志的端口,如果需要添加graylog收集器,可以新增暴露出来的端口
      # Syslog TCP
      - 514:514
      # Syslog UDP
      - 514:514/udp
      # GELF TCP
      - 12201:12201
      # GELF UDP
      - 12201:12201/udp
# Volumes for persisting data, see https://docs.docker.com/engine/admin/volumes/volumes/
# 数据卷使用卷标的方式
# volumes:
  # mongo_data:
    # driver: local
  # es_data:
    # driver: local
  # graylog_journal:
    # driver: local

Graylog 系统配置

  1. graylog的日志收集通过定义input对象来完成,在graylogweb管理界面按照如下图片进入input对象配置,选择GELF UDP协议来新建一个输入器(input):

  1. 填好相关属性,新建、保存后,就可以开始收集日志了

docker 配置

  1. 如果docker通过命令行启动,可以在run命令中加上如下参数:
 docker run --log-driver=gelf --log-opt gelf-address=udp://{graylog服务器地址}:12201 
 --log-opt tag=<当前容器服务标签,用来供graylog查询的时候进行分类>  <IMAGE> <运行命令>
  1. 如果通过docker-compose命令,则可以在docker-compose.yml中加入相关配置,以下用 nginx容器举例
version: '2'
services:
  nginx:
    image: nginx:latest
    ports:
        - "80:80"
    logging:
      driver: "gelf"
      options:
        gelf-address: "udp://192.168.100.249:12201"
        tag: front-nginx

  1. 容器启动的时候可能会有下面这个提示:
nginx_1_4bd0934b4b62 | WARNING: no logs are available with the 'gelf' log driver

可以无视这个警告,日志还是会继续发送过去的。
到这里为止我们可以在 graylog 的 web 后台中看到 nginx 所产生的日志了
  1. 测试
docker run -d \
--log-driver=gelf \
--log-opt gelf-address=udp://localhost:12201 \
--log-opt tag="{{.ImageName}}/{{.Name}}/{{.ID}}" \
busybox sh -c 'while true; do echo "Graylog test message"; sleep 10; done;'