docker 日志方案

docker logs默认会显示命令的标准输出(STDOUT)和标准错误(STDERR)。下面使用echo.sh和Dockerfile创建一个名为echo.v1的镜像,echo.sh会一直输出”hello“
[root@ docker]# cat echo.sh
#!/bin/sh
while true;do echo hello;sleep 2;done
[root@ docker]# cat Dockerfile FROM busybox:latest WORKDIR
/home COPY echo.sh /home CMD [ "sh",-c/home/echo.sh" ]
# chmod 777 echo.sh 
# docker build -t echo:v1 .

运行上述镜像,在对于的容器进程目录下可以看到该进程打开个4个文件,其中fd为10的即是运行的shell 脚本,

# ps -ef|grep echo
root      11198  11181  0 09:04 pts/0    00:01 /bin/sh /home/echo.sh
root      24346  21490  12:30 pts/5    00 grep --color=auto echo
[root@ docker]# cd /proc/11198/fd
[root@ fd]# ll
lrwx------. 1 root root 64 Jan 28 30 0 -> /dev/pts/01 -> /dev/pts/
lr-x------. 10 -> /home/echo.sh
lrwx------. 2 -> /dev/pts/0

执行docker logs -f CONTAINER_ID 跟踪容器输出,fd为1的文件为docker logs记录的输出,可以直接导入一个自定义的字符串,如echo ”你好“ > 1,可以在docker log日志中看到如下输出

hello
hello
你好
hello

docker支持多种插件,可以在docker启动时通过命令行传递log driver,也可以通过配置docker的daemon.json文件来设置dockerd的log driver。docker默认使用json-file的log driver,使用如下命令查看当前系统的log driver

# docker info --format '{{.LoggingDriver}}'
json-file

下面使用journald来作为log driver

#  docker run -itd --log-driver=journald echo:v1
8a8c828fa673c0bea8005d3f53e50b2112b4c8682d7e04100affeba25ebd588c
# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8a8c828fa673 echo:v1
sh -c /home/echo.sh" 2 minutes ago Up minutes vibrant_curie
# journalctl CONTAINER_NAME
=vibrant_curie --all

在journalctl中可以看到有如下log日志,8a8c828fa673就是上述容器的ID 

-- Logs begin at Fri 2019-01-25 10:15:42 CST,end at Mon 13:55 CST. --
Jan 08:47 . 8a8c828fa673[9709]: hello
Jan 49 . 8a8c828fa673[]: hello
...

 同时使用docker inspect查看该容器配置,可以看到log driver变为了journald,

LogConfig": {
     Type": journald,Config: {}
},

 

生产中一般使用日志收集工具来对服务日志进行收集和解析,下面介绍使用fluentd来采集日志,fluentd支持多种插件,支持多种日志的输入输出方式,插件使用方式可以参考官网。下载官方镜像

docker pull fluent/fluentd

首先创建一个fluentd的配置文件,该配置文件用于接收远端日志,并打印到标准输出

# cat fluentd.conf
 <source>
   @type forward
 </source>

 <match *>
   @type stdout
 </match>

创建2个docker images,echo:v1和echo:v2,内容如下

# cat echo.sh ---echo:v1
#!/bin/do
    echo docker1 -> 11111docker1,this is docker1
    sleep 
done
# cat echo.sh ----echo:v2
#!/bin/docker2 -> 11111docker2,1)">
done

首先启动fluentd,然后启动echo:v1,fluentd使用本地配置文件/home/fluentd/fluentd.conf替换默认配置文件,fluentd-address用于指定fluentd的地址,更多选项参见fluentd logging driver

# docker run -it --rm -p 24224:24224 -v /home/fluentd/fluentd.conf:/fluentd/etc/fluentd.conf -e FLUENTD_CONF=fluentd.conf fluent/fluentd:latest
# docker run --rm --name=docker1 --log-driver=fluentd --log-opt tag={{.Name}}" --log-opt fluentd-address=192.168.80.189:24224 echo:v1

fluentd默认绑定地址为0.0.0.0,即接收本机所有接口IP的数据,绑定端口为指定的端口24224,fluentd启动时有如下输出

[info]: #0 listening port port=24224 bind=0.0.0.0"

在fluentd界面上可以看到echo:v1重定向过来的输出,下面加粗的docker1为容器启动时设置的tag值,docker支持tag模板,可以参考Customize log driver output

29 07:46:24.000000000 +0000 docker1: {container_name":/docker1sourcestdoutlogcontainer_id74c0af9defd10d33db0e197f0dd3af382a5c06a858f06bdd2f0f49e43bf0a25e}
}

上述场景中,如果fluentd没有启动,echo:v1也会启动失败,可以在容器启动时使用fluentd-async-connect来避免因fluentd退出或未启动而导致容器异常,如下图,当fluentd未启动也不会导致容器启动失败

docker run --rm --name=docker1 --log-driver=fluentd --log-opt tag=docker1.{{.Name}}" --log-opt fluentd-async-connect=true --log-opt fluentd-address=24224 echo:v1

上述场景输出直接重定向到标准输出,也可以使用插件重定向到文件,fluentd使用如下配置文件,日志文件会重定向到/home/fluent目录下,match用于匹配echo:v1的输出(tag="docker1.{{.Name}}"),这样就可以过滤掉echo:v2的输出


   @type forward
 </source>

 <match docker1.*>
   @type file
    path /home/fluent/
 </match>

使用如下方式启动fluentd

# docker run -it --rm -p 24224 -v /home/fluentd/fluentd.conf:/fluentd/etc/fluentd.conf -v /home/fluent:/home/fluent -e FLUENTD_CONF=fluentd.conf fluent/fluentd:latest

在/home/fluent下面可以看到有生成的日志文件

# ll
total 8
-rw-r--r--. 1 charlie charlie 2404 Jan 17:14 buffer.b58095399160f67b3b56a8f76791e3f1a.log
-rw-r--r--. 1 charlie charlie   68 Jan 14 buffer.b58095399160f67b3b56a8f76791e3f1a.log.meta

 

上述展示了使用fluentd的标准输出来显示docker logs以及使用file来持久化日志。生产中一般使用elasticsearch作为日志的存储和搜索引擎,使用kibana为log日志提供显示界面。可以在这里获取各个版本的elasticsearch和kibana镜像以及使用文档,本次使用6.5版本的elasticsearch和kibana。注:启动elasticsearch时需要设置sysctl -w vm.max_map_count=262144

 fluentd使用elasticsearch时需要在镜像中安装elasticsearch的plugin,也可以直接下载包含elasticsearch plugin的docker镜像,如果没有k8s.gcr.io/fluentd-elasticsearch的访问权限,可以pull这里的镜像。

使用docker-compose来启动elasticsearch,kibana和fluentd,文件结构如下

# ll
-rw-r--r--. 1287 Jan 31 16:51 docker-compose.yml
-rw-r--r--. 1 root root  196 Jan 11:56 elasticsearch.yml
-rw-r--r--. 332 Jan 48 fluentd.conf
-rw-r--r--. 1408 Jan 07 kibana.yml

centos上docker-compose的安装可以参见这里。docker-compose.yml以及各组件的配置如下。它们共同部署在同一个bridge esnet上,同时注意kibana.yml和fluentd.yml中使用elasticsearch的service名字作为host。kibana的所有配置可以参见kibana.yml

# cat docker-compose.yml
version: '2'
services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:6.5.4
    container_name: elasticsearch
    environment:
      - http.host=0.0.0.0
      - transport.host=0.0
      - ES_JAVA_OPTS=-Xms1g -Xmx1g
    volumes:
      - esdata:/usr/share/elasticsearch/data
      - ./elasticsearch.yml:/usr/share/elasticsearch/config/elasticsearch.yml
    ports:
      - 9200:9200
      - 9300:9300
    networks:
      - esnet
    ulimits:
      memlock:
        soft: -1
        hard: -
      nofile:
        soft: 65536
        hard: 
    mem_limit: 2g
    cap_add:
      - IPC_LOCK

  kibana:
    image: docker.elastic.co/kibana/kibana:
    depends_on:
      - elasticsearch
    container_name: kibana
    environment:
      - SERVER_HOST=0.0
    volumes:
      - ./kibana.yml:/usr/share/kibana/config/kibana.yml
    ports:
      - 5601:5601 esnet

  flunted:
    image: fluentd-elasticsearch:v2.4.0 elasticsearch
    container_name: flunted
    environment:
      - FLUENTD_CONF=fluentd.conf
    volumes:
      - ./fluentd.conf:/etc/fluent/fluent.conf
    ports:
      - 24224 esnet

volumes:
  esdata:
    driver: local
networks:
  esnet:
# cat elasticsearch.yml
cluster.name: chimeo-docker-cluster
node.name: chimeo-docker-single-node
network.host: 0.0
# cat kibana.yml
#kibana is served by a back end server. This setting specifies the port to use.
server.port: 

# Specifies the address to which the Kibana server will bind. IP addresses and host names are both valid values.
# The default is localhostfrom remote users,set this parameter to a non-loopback address.
server.host: 

# The Kibana servers name.  This is used for display purposes.
server.name: charlie

# The URLs of the Elasticsearch instances to use for all your queries.
elasticsearch.url: http://elasticsearch:9200

# Kibana uses an index in Elasticsearch to store saved searches,visualizations and
# dashboards. Kibana creates a new index if the index doesnt already exist.
kibana.index: .kibana

# Time in milliseconds to wait  Elasticsearch to respond to pings. Defaults to the value of
# the elasticsearch.requestTimeout setting.
elasticsearch.pingTimeout: 5000for responses from the back end or Elasticsearch. This value
# must be a positive integer.
elasticsearch.requestTimeout: 30000 Elasticsearch at Kibana startup before retrying.
elasticsearch.startupTimeout: 10000

# Set the interval  milliseconds to sample system and process performance
# metrics. Minimum is 100ms. Defaults to .
ops.interval: 5000

    @type forward
 </source>

 <match **>
    @type elasticsearch
    log_level info
    include_tag_key true
    host elasticsearch
    port 9200
    logstash_format 
    chunk_limit_size 10M
    flush_interval 5s
    max_retry_wait 30
    disable_retry_limit
    num_threads 8
  </match>

使用如下命令启动即可

# docker-compose up

启动一个使用fluentd的容器。注:测试过程中可以不加fluentd-async-connect=true,可以判定该容器是否能连接到fluentd

docker run -it --rm --name=docker1 --log-driver=fluentd --log-opt tag=fluent.{{.Name}}" --log-opt fluentd-true --log-opt fluentd-address=127.0.0.1:24224 echo:v1

打开本地浏览器,输入kibana的默认url:http://localhost:5601,创建index后就可以看到echo:v1容器的打印日志

在使用到kubernetes时,fluentd一般以DaemonSet方式部署到每个node节点,采集node节点的log日志。也可以以sidecar的方式采集同pod的容器服务的日志。更多参见Logging Architecture

TIPS:

  •  fluentd给elasticsearch推送数据是以chunk为单位的,如果chunk过大可能导致elasticsearch因为payload过大而无法接收,需要设置chunk_limit_size大小,参考Fluentd-ElasticSearch配置
  • 生产中fluentd直接发送日志到elasticsearch,可能会因为es没能及时读取日志而导致fluentd中缓存的日志爆满,建议在fluentd和es之间使用kafka进行日志缓存

 参考:

https://stackoverflow.com/questions/44002643/how-to-use-the-official-docker-elasticsearch-container

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


最近一直在开发Apworks框架的案例代码,同时也在一起修复Apworks框架中的Bug和一些设计上的不足。遇到的一个普遍问题是,代码的调试过程需要依赖很多外部系统,比如MongoDB、PostgreSQL、RabbitMQ等。当然可以在本机逐一安装这些服务,然后对服务进行配置,使其满足自己开发调试
最近每天都在空闲时间努力编写Apworks框架的案例代码WeText。在文本发布和处理微服务中,我打算使用微软的SQL Server for Linux来做演示,于是也就在自己的docker-compose中加入了MS SQL Server的服务。其实在Docker中运行SQL Server是非常容
在《Kubernetes中分布式存储Rook-Ceph部署快速演练》文章中,我快速介绍了Kubernetes中分布式存储Rook-Ceph的部署过程,这里介绍如何在部署于Kubernetes的ASP.NET Core MVC的应用程序中使用Rook-Ceph所创建的存储对象。 构建ASP.NET C
最近在项目中有涉及到Kubernetes的分布式存储部分的内容,也抽空多了解了一些。项目主要基于Rook-Ceph运行,考虑到Rook-Ceph部署也不那么简单,官方文档的步骤起点也不算低,因此,在整合官方文档的某些步骤的基础上,写篇文章简单总结一下。 Rook-Ceph是Kubernetes中分布
CentOS下Docker与.netcore(一) 之 安装 CentOS下Docker与.netcore(二) 之 Dockerfile CentOS下Docker与.netcore(三)之 三剑客之一Docker-Compose CentOS下Docker与.netcore(四)之 三剑客之一D
CentOS下Docker与.netcore(一) 之 安装 CentOS下Docker与.netcore(二) 之 Dockerfile CentOS下Docker与.netcore(三)之 三剑客之一Docker-Compose CentOS下Docker与.netcore(四)之 三剑客之一D
构建镜像最具挑战性的一点是使镜像大小尽可能的小。Dockerfile中的每条指令都为图像添加了一个图层,您需要记住在移动到下一层之前清理任何不需要的工件。对于多阶段构建,您可以在Dockerfile中使用多个FROM语句。每个FROM指令可以使用不同的基础,并且每个指令都开始一个新的构建。您可以选择
本文介绍compose配置文件参数的使用,熟练编写compose文件 [root@docker lnmp]# cat lnmp.yaml version: &#39;3&#39; services: nginx: build: /root/docker_demo/nginx/ ports: - &q
环境 docker-machine主机:192.168.1.9 docker主机:192.168.1.10 步骤: 安装docker-machine 创建ssh密钥对,实现两主机无密登录 创建docker主机,命名host1 变更docker环境变量 运行容器查看两端是否同步 镜像容器同步测试成功
CentOS下Docker与.netcore(一) 之 安装 CentOS下Docker与.netcore(二) 之 Dockerfile CentOS下Docker与.netcore(三)之 三剑客之一Docker-Compose CentOS下Docker与.netcore(四)之 三剑客之一D
https://blog.csdn.net/wanglei_storage/article/details/77508620 实践中会发现,生产环境中使用单个 Docker 节点是远远不够的,搭建 Docker 集群势在必行。然而,面对 Kubernetes, Mesos 以及 Swarm 等众多容
1.引言 紧接上篇.NET Core容器化@Docker,这一节我们先来介绍如何使用Nginx来完成.NET Core应用的反向代理,然后再介绍多容器应用的部署问题。 2. Why Need Nginx .NET Core中默认的Web Server为Kestrel。 Kestrel is grea
docker rm `docker ps -a | grep Exited | awk &#39;{print $1}&#39;` 删除异常停止的docker容器 docker rmi -f `docker images | grep &#39;&lt;none&gt;&#39; | awk &#3
什么是Docker Compose 在微服务盛行的今天,我们通常是这么定义Compose的:对容器的统一启动和关闭的编排工具。 但是我以前还是有个疑惑,谁会用Compose在一台服务器上部署多个服务呢?干脆直接用单体服务就行了!直到我遇到了以下的一个需求,让我明白了在一台服务器上不得不用多个服务的时
CentOS下Docker与.netcore(一) 之 安装 CentOS下Docker与.netcore(二) 之 Dockerfile CentOS下Docker与.netcore(三)之 三剑客之一Docker-Compose CentOS下Docker与.netcore(四)之 三剑客之一D
很多时候,我们在本地开发过程中程序运行很正常,但是发布到线上之后由于环境的原因,可能会有一些异常。通常我们会通过日志来分析问题,除了日志还有一种常用的调试手段就是:附加进程。 VS中的附加进程非常强大,目前提供了9种常用的附加方式。 在当前.Net Core支持跨平台的大背景下,其中Linux环境和
https://www.cnblogs.com/bigberg/p/8867326.html 一、简介 Docker有个编排工具docker-compose,可以将组成某个应该的多个docker容器编排在一起,同时管理。同样在Swarm集群中,可以使用docker stack 将一组相关联的服务进行
.Net6中想实现对某个网址截屏,可通过Selenium模拟访问网址并实现截图。 实现 安装Nuget包 &lt;PackageReference Include=&quot;Selenium.Chrome.WebDriver&quot; Version=&quot;85.0.0&quot; /&g
原文&#160;https://www.cnblogs.com/gispathfinder/p/5871043.html 我们在使用docker run创建Docker容器时,可以用--net选项指定容器的网络模式,Docker有以下4种网络模式: host模式,使用--net=host指定。 co