graylog是一个小型的开源日志收集、分析、展示框架。

    主要graylog运行需要mongo、elasticsearch,所以他们就组成了一个小的整体。一般在虚拟机上搭建,可以分开安装部署,但是既然是一个日志服务,而且想尽量整理的简单一些,所以考虑直接使用docker容器的方式,而直接一个一个docker run,还是显得很复杂,主要是他们需要做一些配置,而且三个容器之间,graylog依赖于mongo、elasticsearch,还不能先启动graylog。索性就整理一个docker-compose.yml文件,把他们三个一起部署,然后每次要修改配置或者重启就方便很多。

    如下是根据一些资料整理的一个简洁的docker-compose.yml配置:

version: '2'
services: 
  mongodb:
    container_name: mongodb
    image: mongo:3
    restart: always
    volumes:
      - /data/graylog/mongo_data:/data/db


  es:
    image: docker.elastic.co/elasticsearch/elasticsearch-oss:6.8.5
    container_name: es
    restart: always
    volumes:
      - /data/graylog/es_data:/usr/share/elasticsearch/data
    ports:
      - 9200:9200
      - 9300:9300
    environment:
      - TZ=Aisa/Shanghai
      - http.host=0.0.0.0
      - transport.host=localhost
      - network.host=0.0.0.0
      - http.cors.allow-origin=*
      - http.cors.enabled=true
      - discovery.type=single-node
      - 'ES_JAVA_OPTS=-Xms1024m -Xmx1024m'


  graylog:
    image: graylog/graylog:4.0.2
    container_name: graylog
    restart: always
    volumes:
      - /data/graylog/graylog_journal:/usr/share/graylog/data/journal
      - /data/graylog/config:/usr/share/graylog/config
    ports:
      - 9000:9000
      - 12201:12201/udp
    environment:
      - GRAYLOG_HTTP_EXTERNAL_URI=http://192.168.17.100:9000/
    depends_on:
      - mongodb
      - es
    links:
      - mongodb:mongo
      - es:elasticsearch

    需要说明的是:

    1、mongo的配置很简单,就是为了持久化,做了一个存储的映射。

    2、elasticsearch的配置,这里做了端口映射,其实也是没有必要的,因为graylog访问它是根据容器名称来访问的。 环境变量中discovery.type=single-node是必须的,默认就是zen的模式。最重要的一个配置就是jvm参数ES_JAVA_OPTS,这里必须设置至少512m,否则es可能因为启动时内存不足,导致启动失败,然后容器一直处于restarting状态,后续的graylog就连接不上,同样也会启动异常并报错。

    3、graylog这里采用了本地配置映射,用到了/data/graylog/config目录下的graylog.conf,里面配置了很多参数,其实这些参数可以通过环境变量environment的方式添加并覆盖,这里想用自定义的配置文件。但是配置了http_external_uri,访问的时候,页面上的资源文件全部还是请求的容器ip里面的,所以报错,如下图所示,后来通过environment的方式修改了这个变量,所以这里的配置显得很繁琐。

dockercompose images 指定版本 docker-compose logs_mongodb

    4、graylog需要依赖其他两个容器,而且访问的时候,直接使用的容器名称做的主机,所以links这里配置需要注意,我们在定义mongodb、elasticsearch services名称的时候可以随便定义,这里叫的是mongodb和es,但是graylog默认使用的是mongo和elasticsearch,所以我们需要在links里面做这样的映射:

links:
      - mongodb:mongo
      - es:elasticsearch

    如果你的service定义的名字就是mongo和elasticsearch,就不需要映射,直接:

links:
      - mongo
      - elasticsearch

   5、graylog采用了映射配置文件与环境变量共存的办法,这里配置文件是从github下载,文件名称是graylog.conf,配置项主要是用户登录秘钥和密码sha2的加密串、时区等等。在这个配置文件里面可以很清楚的看到,graylog连接mongo与elasticsearch所使用的url,分别是:

    mongodb_uri = mongodb://mongo/graylog

    elasticsearch_hosts = http://elasticsearch:9200

    所以说前面,我们配置links的为什么要指定一个映射。

    其他的配置:

    password_secret = somepasswordpepper      #对应环境变量就是GRAYLOG_PASSWORD_SECRET=somepasswordpepper

    root_password_sha2 = 8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918 #对应环境变量就是#GRAYLOG_ROOT_PASSWORD_SHA2=8c6976e5b5410415bde908bd4dee15dfb167a9c873fc4bb8a81f6f2ab448a918

    root_timezone = PRC  #对应环境变量是 TZ=Asia/Shanghai

   6、前面配置es,graylog,mongodb都做了存储本地映射,尤其是es,mongodb,文件夹的权限必须是777,如下所示:

    

dockercompose images 指定版本 docker-compose logs_docker-compose_02

    这个也是在实际中采坑得出的结论,容器启动正常,但是报错,permission denied。

    7、这里在graylog里面不仅配置了links,还配置了depends_on,主要是graylog依赖于mongodb,es,它必须在他们两个服务启动之后,才能启动,相当于做了一个约束,这个很好理解。

    以上这些都做好了,就可以进行启动docker容器了。

    容器启动,es会做初始化,graylog等待连接es,mongodb,这个过程会比较耗时,当我们看到graylog出现server up and running的时候,才可以通过浏览器访问graylog可视化webui。

2021-02-02 16:40:42,493 INFO : org.graylog2.bootstrap.ServerBootstrap - Graylog server up and running.

    访问http://192.168.17.100:9000,用户名密码都是admin,其中192.168.17.100是虚拟机的ip,docker安装在虚拟机中。

dockercompose images 指定版本 docker-compose logs_mongodb_03

     登录,进入首页:

dockercompose images 指定版本 docker-compose logs_graylog_04

    首页菜单栏的位置会出现两个警告,我们可以点开,一个是es磁盘空间问题,一个是graylog本身刚创建,还没有设置日志收集的输入规则。

dockercompose images 指定版本 docker-compose logs_graylog_05

    根据提示,我们尝试创建日志收集规则,在launch页面,我们选择gelf udp,然后点击Launch new input按钮。

dockercompose images 指定版本 docker-compose logs_graylog_06

     在弹出框中,设置title就可以了。采用的是udp的方式,端口使用的是我们在docker-compose.yml中定义的12201/udp。

dockercompose images 指定版本 docker-compose logs_graylog_07

   点击Save保存按钮,这个input马上就会运行起来,警告也随之消失,变成一个。

dockercompose images 指定版本 docker-compose logs_elasticsearch_08

     前面这些操作,我们只是搭建了graylog运行环境,以及设置了日志收集输入配置,下面就等待客户端日志发送到服务器了,我们可以通过java编程,也可以通过一个简单的测试,下面通过一个简单的模拟,定时发送消息到graylog中。这里也会启动一个docker,他是一个很小的容器busybox。

dockercompose images 指定版本 docker-compose logs_elasticsearch_09

    运行的命令:

docker run -d \
           --log-driver=gelf \
           --log-opt gelf-address=udp://localhost:12201 \
           --log-opt tag="log-test-container-B" \
           busybox sh -c 'while true; do echo "This is a log message from container B"; sleep 10; done;'

    运行之后,就会不断的发送日志,我们在graylog的可视化界面中就可以看到日志内容了:

dockercompose images 指定版本 docker-compose logs_mongo_10

     graylog最新的版本是4.0.2,如果不用最新的版本镜像,进入首页,还有个警告是你使用了一个过时的graylog...

     graylog日志收集方式,默认提供了很多种协议,http,tcp,udp,作为一个日志收集系统,其实大量的日志,并不需要保证每一条都需要保存下来,它不比数据库系统那么高要求,所以使用udp协议,保证收发的效率,牺牲传输可靠性,是一个理想的办法。因为丢失一条日志,并不会影响系统的正常运行。