Docker 容器日志分析
查看容器日志
先使用 dockerrun-it--rm-d-p80:80nginx:1.15.8-alpine命令启动一个nginx容器。如果没有异常,会得到容器ID如 d2408a7931c95a3a83ffeca2fba887763cf925a67890ef3be4d9ff838aa25b00 的长串。再使用 curl-ihttp://127.0.0.1 访问服务,确认nginx容器正常启动运行。最后使用 dockerlogs-fd24 查看容器的日志输出,大概如下:
172.17.0.1--[24/Mar/2019:03:51:21+0000]"GET/HTTP/1.1"200612"-""curl/7.29.0""-"
一般来说使用容器ID的前3位即可
以上就是我们查看容器日志的日常方法了,非常简单实用。
容器日志文件存储
容器的日志会以json文件方式存储在本地磁盘,可以使用下面方式查看文件路径 dockerinspectd42|grepLog可以找到:
"LogPath":"/var/lib/docker/containers/d2408a7931c95a3a83ffeca2fba887763cf925a67890ef3be4d9ff838aa25b00/d2408a7931c95a3a83ffeca2fba887763cf925a67890ef3be4d9ff838aa25b00-json.log",
注意1:mac上没有/var/lib/docker目录,因为dockerformac的运作方式不一样,最好使用linux系统练习。
注意2: 如果LogPath内容为空,大概是因为dockerengine版本,升级docker版本能到docker-ce18.09.3
查看d2408a7931c95a3a83ffeca2fba887763cf925a67890ef3be4d9ff838aa25b00-json.log文件,可以看到:
{"log":"172.17.0.1--[24/Mar/2019:03:51:21+0000]\"GET/HTTP/1.1\"200612\"-\"\"curl/7.29.0\"\"-\"\r\n","stream":"stdout","time":"2019-03-24T03:51:21.982476951Z"}
这条信息的log字段内容和之前通过 dockerlogs 命令查看的内容一致。
容器日志会跟随容器生命周期,容器销毁后日志也会销毁。使用 dockerstop24 关停测试的nginx服务。因为容器启动使用时候用了 --rm 参数,关停后会自动清理删除,所以会发现/var/lib/docker/containers/d2408a7931c95a3a83ffeca2fba887763cf925a67890ef3be4d9ff838aa25b00 目录不存在了,相应的日志文件也就删除了。
容器日志文件滚动策略
docker容器日志默认写入json文件,在线上运行时候会有磁盘写满的风险。可以调整策略,让其进行滚动。修改/etc/docker/daemon.json(如果没有就手工创建一个),增加下面内容:
{ "log-opts":{ "max-size":"1m", "max-file":"3" } }
修改完成后重启docker服务:
systemctldaemon-reload systemctlrestartdocker.service
测试一下新的日志策略,使用下面的命令创建一个容器:
dockerrun-d--rmalpine:3.6sh-c"whiletrue;doechohelloworld;usleep10;done"
这个alpine容器就是每隔10微秒输出helloworld,保持高频度输出,快速生产日志文件。
注:shell中的时间控制
1、sleep:默认为秒。
sleep1s表示延迟一秒
sleep1m表示延迟一分钟
sleep1h表示延迟一小时
sleep1d表示延迟一天
2、usleep:默认以微秒。
1s=1000ms=1000000us
按照前文中查看日志文件的方法
#pwd /var/lib/docker/containers/aa3307f5b42770319129e126122be123cfd8e0ebe1c412371ad27e62faa007e3 #ls-lah total2.6M drwx------4rootroot4.0KMar2416:22. drwx------3rootroot4.0KMar2416:21.. -rw-r-----1rootroot647KMar2416:22aa3307f5b42770319129e126122be123cfd8e0ebe1c412371ad27e62faa007e3-json.log -rw-r-----1rootroot977KMar2416:22aa3307f5b42770319129e126122be123cfd8e0ebe1c412371ad27e62faa007e3-json.log.1 -rw-r-----1rootroot977KMar2416:21aa3307f5b42770319129e126122be123cfd8e0ebe1c412371ad27e62faa007e3-json.log.2
很容易发现,日志文件的策略就是维持3个1m大小文件存在,和我们设置保持一致。
测试完成后,记得使用dockerstopaa3清理测试现场,max-size也可以按照真实需求调整大小。
nginx容器日志
了解docker容器的日志策略后,再看看常用的容器是如何处理的。先看看nginx容器。
首先 dockerrun-it--rm-d-p80:80nginx:1.15.8-alpine 创建一个nginx容器,然后 dockerexec-itb6dsh 进入容器,查看/etc/nginx/nginx.conf可以看到下面内容:
error_log/var/log/nginx/error.logwarn; access_log/var/log/nginx/access.logmain;
也就是nginx会将错误日志和访问日志写入对应的日志文件。继续查看/var/log/nginx目录:
/var/log/nginx#ls-lah total0 drwxr-xr-x2rootroot39Mar407:54. drwxr-xr-x3rootroot18Mar407:54.. lrwxrwxrwx1rootroot11Jan3123:32access.log->/dev/stdout lrwxrwxrwx1rootroot11Jan3123:32error.log->/dev/stderr
这就发现奥秘了,access.log文件会通过软链接重定向到标准输出,而错误日志error.log则会重定向标准错误。这样使用dockerlog命令就可以看到nginx的访问日志了。
为了进一步验证,查看nginxdockerfile文件,其中有:
#forwardrequestanderrorlogstodockerlogcollector &&ln-sf/dev/stdout/var/log/nginx/access.log\ &&ln-sf/dev/stderr/var/log/nginx/error.log
可见nginx镜像创建时候就定义好了日志文件的输出。
同样使用dockerstop524清理现场,以后就不再介绍清理这一步骤了。
mysql容器日志
启动一个mysql容器
dockerrun--rm-eMYSQL_ROOT_PASSWORD=123456mysql:5.7
不难看到mysql容器日志输出,截取其中片段如下:
Initializingdatabase
2019-03-24T08:48:19.102726Z0[Warning]TIMESTAMPwithimplicitDEFAULTvalueisdeprecated.Pleaseuse--explicit_defaults_for_timestampserveroption(seedocumentationformoredetails).
2019-03-24T08:48:20.241459Z0[Warning]InnoDB:Newlogfilescreated,LSN=45790
2019-03-24T08:48:20.414933Z0[Warning]InnoDB:Creatingforeignkeyconstraintsystemtables.
2019-03-24T08:48:20.509897Z0[Warning]NoexistingUUIDhasbeenfound,soweassumethatthisisthefirsttimethatthisserverhasbeenstarted.GeneratinganewUUID:935a6ee7-4e11-11e9-b135-0242ac110002.
2019-03-24T08:48:20.519148Z0[Warning]Gtidtableisnotreadytobeused.Table'mysql.gtid_executed'cannotbeopened.
2019-03-24T08:48:20.519843Z1[Warning]root@localhostiscreatedwithanemptypassword!Pleaseconsiderswitchingoffthe--initialize-insecureoption.
2019-03-24T08:48:24.066683Z1[Warning]'user'entry'root@localhost'ignoredin--skip-name-resolvemode.
2019-03-24T08:48:24.066730Z1[Warning]'user'entry'mysql.session@localhost'ignoredin--skip-name-resolvemode.
2019-03-24T08:48:24.066740Z1[Warning]'user'entry'mysql.sys@localhost'ignoredin--skip-name-resolvemode.
2019-03-24T08:48:24.066756Z1[Warning]'db'entry'performance_schemamysql.session@localhost'ignoredin--skip-name-resolvemode.
2019-03-24T08:48:24.066761Z1[Warning]'db'entry'sysmysql.sys@localhost'ignoredin--skip-name-resolvemode.
2019-03-24T08:48:24.066772Z1[Warning]'proxies_priv'entry'@root@localhost'ignoredin--skip-name-resolvemode.
2019-03-24T08:48:24.066814Z1[Warning]'tables_priv'entry'usermysql.session@localhost'ignoredin--skip-name-resolvemode.
2019-03-24T08:48:24.066822Z1[Warning]'tables_priv'entry'sys_configmysql.sys@localhost'ignoredin--skip-name-resolvemode.
Databaseinitialized
Initializingcertificates
GeneratingaRSAprivatekey
查看mysqlDockerfile 文件,可以知道mysql镜像启动入口在entrypoint.sh,从脚本中发现:
echo'Initializingdatabase' "$@"--initialize-insecure echo'Databaseinitialized'
这样就是mysql容器启动时候的输出对应起来了。entrypoint.sh比较复杂,主要功能就是启动mysqld,并将日志输出,因为不是本文重点,就不详细介绍了。
总结
- docker容器默认输出到本地json文件,并且可以对其进行大小和数量控制。
- 应用容器日志可以先生成日志文件,然后将应用日志文件软连接到标准输出,比如nginx;也可以在启动时候直接将日志打印到标准输出,比如mysql。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。