docker-日志管理
docker 日志处理
- 日志管理:logging driver
- 日志驱动:json-file
- 通过 docker info 查看上面这俩个东西
docker默认自带日志功能
- 对于一个运行的容器,docker会将日志发送到容器标准的输入输出设备
[root@localhost ~]# ll /dev/stdout lrwxrwxrwx. 1 root root 15 12月 16 21:47 /dev/stdout -> /proc/self/fd/1 [root@localhost ~]# ll /dev/stderr lrwxrwxrwx. 1 root root 15 12月 16 21:47 /dev/stderr -> /proc/self/fd/2 # 上面的两个设备,容器会默认把日志输出到里面 [root@localhost ~]# ll /dev/zero crw-rw-rw-. 1 root root 1, 5 12月 16 21:47 /dev/zero [root@localhost ~]# ll /dev/null crw-rw-rw-. 1 root root 1, 3 12月 16 21:47 /dev/null
查看容器的日志
[root@localhost ~]# docker run -itd --name web1 httpd 1d66f6cb4689852c41d4160a0ce4c830dec8791a2ea0b661f15d81696ea29147 [root@localhost ~]# docker logs web1 AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message [Wed Dec 16 13:50:34.114666 2020] [mpm_event:notice] [pid 1:tid 139756802856064] AH00489: Apache/2.4.46 (Unix) configured -- resuming normal operations [Wed Dec 16 13:50:34.184415 2020] [core:notice] [pid 1:tid 139756802856064] AH00094: Command line: 'httpd -D FOREGROUND' # 可以看到容器的httpd日志 # 访问httpd服务 # 加 -t 查看访问数据 [root@localhost ~]# curl 172.17.0.2 <html><body><h1>It works!</h1></body></html> [root@localhost ~]# docker logs -f web1 AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message [Wed Dec 16 13:50:34.114666 2020] [mpm_event:notice] [pid 1:tid 139756802856064] AH00489: Apache/2.4.46 (Unix) configured -- resuming normal operations [Wed Dec 16 13:50:34.184415 2020] [core:notice] [pid 1:tid 139756802856064] AH00094: Command line: 'httpd -D FOREGROUND' 172.17.0.1 - - [16/Dec/2020:13:51:50 +0000] "GET / HTTP/1.1" 200 45
- 容器将日志发送到stdout、stderr是docker默认的日志行为
- 实际上docker提供了多种多样的日志机制帮助用户从运行容器到提取日志,此过程为logging driver
查看日志的存储地址
[root@localhost ~]# docker inspect web1 "LogPath": "/var/lib/docker/containers/1d66f6cb4689852c41d4160a0ce4c830dec8791a2ea0b661f15d81696ea29147/1d66f6cb4689852c41d4160a0ce4c830dec8791a2ea0b661f15d81696ea29147-json.log", # 进入到日志目录中 [root@localhost ~]# cd /var/lib/docker/containers/ [root@localhost containers]# ls 1d66f6cb4689852c41d4160a0ce4c830dec8791a2ea0b661f15d81696ea29147 [root@localhost containers]# cd 1d66f6cb4689852c41d4160a0ce4c830dec8791a2ea0b661f15d81696ea29147/ [root@localhost 1d66f6cb4689852c41d4160a0ce4c830dec8791a2ea0b661f15d81696ea29147]# ls 1d66f6cb4689852c41d4160a0ce4c830dec8791a2ea0b661f15d81696ea29147-json.log checkpoints config.v2.json hostconfig.json hostname hosts mounts resolv.conf resolv.conf.hash [root@localhost 1d66f6cb4689852c41d4160a0ce4c830dec8791a2ea0b661f15d81696ea29147]# cat 1d66f6cb4689852c41d4160a0ce4c830dec8791a2ea0b661f15d81696ea29147-json.log {"log":"AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message\r\n","stream":"stdout","time":"2020-12-16T13:50:34.090352695Z"} {"log":"AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message\r\n","stream":"stdout","time":"2020-12-16T13:50:34.133440171Z"} {"log":"[Wed Dec 16 13:50:34.114666 2020] [mpm_event:notice] [pid 1:tid 139756802856064] AH00489: Apache/2.4.46 (Unix) configured -- resuming normal operations\r\n","stream":"stdout","time":"2020-12-16T13:50:34.184523557Z"} {"log":"[Wed Dec 16 13:50:34.184415 2020] [core:notice] [pid 1:tid 139756802856064] AH00094: Command line: 'httpd -D FOREGROUND'\r\n","stream":"stdout","time":"2020-12-16T13:50:34.184542089Z"} {"log":"172.17.0.1 - - [16/Dec/2020:13:51:50 +0000] \"GET / HTTP/1.1\" 200 45\r\n","stream":"stdout","time":"2020-12-16T13:51:50.139992282Z"} # 可以看到httpd的日志数据
日志管理
- linux日志是开源的,每种linux的日志格式是不同的 需要elk日志分析工具
- 大多数日志存放路径在 /var/log内
/var/log内的日志文件 解释 boot.log 记录系统在引导过程中发生的事件(linux系统在开机自检中产生的信息) messages 记录linux操作系统中常见的系统和服务错误日志 cron 记录计算机当中计划任务产生的日志 dmesg 记录计算机引导过程中产生的日志 mailog 记录电子邮件的活动信息 lastlog 激素计算机用户最后一次登录的时间 ip等 secure 加密的 linux系统安全日志,记录用户的工作组变化情况,用户登录,认证,与用户相关的信息日志 syslog 警告日志 stmp 记录用户登录,注销,系统的启动信息
系统日志 syslogd服务
- 配置文件
/etc/rsyslog.conf
- 配置文件格式 语法
服务名.日志级别 动作 保存路径
时间 主机名 子系统名称/程序名 消息具体内容配置文件内的程序服务解释
服务名 | 解释 |
---|---|
auth | 认证相关:权限 |
authpriv | 权限授权相关 PAM模块 远程等 |
cron | 计划任务 |
daemon | 守护进程(后台运行的程序) |
kem | 内核相关 |
lpr | 打印机相关 : 打印池 |
邮件相关 本地邮件 | |
mark | 标记相关 防火墙网络标识 |
news | 新闻相关 |
security | 安全相关与auth类似:触发与更改 |
user | 用户和组 |
uucp | unix to unix cp相关 isp |
local0-7 | 用户自定义的 |
* | 表示所有的 |
日志级别
级别 | 信息 | 解释 |
---|---|---|
8 | none | 不记录任何日志 |
7 | debug | 记录程序/系统调试信息 |
6 | info | 记录一般信息 |
5 | notice | 记录不影响任何功能,但是需要注意的信息 |
4 | warnning | 记录可能影响功能,但是需要注意的信息 (例如apache的dns绑定) |
3 | err | 记录允许运行但是出现错误,到时无法继续运行的信息 |
2 | crit | 记录比较严重的错误,运行中出现的错误 |
1 | alert | 记录必须马上解决的问题,系统的问题 |
0 | emerg | 记录内核/硬件错误 |
配置文件内的日志级别书写定义
# user程序记录一般信息 输出到 /var/log/user文件下 user.info /var/log/user # mail程序记录一般信息 延迟输出到 /var/log/mail (延迟输入,一般是不需要立即查看日志的程序,可以降低服务器的压力) mail.info -/var/log/mail # auth程序记录和info级别相等的日志信息,将日志信息以udp的形式传输到 192.168.100.212 auth.=info @192.168.100.212 # user程序只记录user不包含error的日志 以tcp的形式传输给 192.168.100.212 user.!=error @@192.168.100.212 # user程序记录error级别以下的信息(-1) 发送给user用户 user.!error : user # user程序记录error级别以下的信息(-1) 将日志信息 转交给logrotate -f 命令来处理 user.!error | logrotate -f ## 等等 还有好多 # != 用户相关的,但不包括error的日志(只记录user不包含error的日志) # ! 记录与user的error相反的 # *.info 所有info级别都记录 # Mail.* mail邮件的所有级别 # Mail的所有级别,但是不包括info级别
日志采集
需要把日志从一台主机传递给另外一台主机上,需要做日志处理。
计算机本身有日志处理功能
也可以改变日志的存放路径
[root@localhost ~]# vim /etc/rsyslog.conf authpriv.* /usr/local/secure # 将 /var/log/secure日志文件 改变存储到 /usr/local/secure (57行) # 重启日志管理工具 [root@localhost ~]# systemctl restart rsyslog # 没有生成文件 [root@localhost local]# ls bin etc games include lib lib64 libexec sbin share src # 因为有selinux标签,需要关闭selinux才能生成 [root@localhost local]# setenforce 0 [root@localhost local]# systemctl restart rsyslog.service [root@localhost local]# ls bin etc games include lib lib64 libexec sbin secure share src # 生成日志信息 [root@localhost local]# su kml [kml@localhost local]$ exit exit [root@localhost local]# cat secure Dec 16 22:44:09 localhost polkitd[718]: Registered Authentication Agent for unix-process:67985:340794 (system bus name :1.92 [/usr/bin/pkttyagent --notify-fd 5 --fallback], object path /org/freedesktop/PolicyKit1/AuthenticationAgent, locale zh_CN.UTF-8) Dec 16 22:44:10 localhost polkitd[718]: Unregistered Authentication Agent for unix-process:67985:340794 (system bus name :1.92, object path /org/freedesktop/PolicyKit1/AuthenticationAgent, locale zh_CN.UTF-8) (disconnected from bus) Dec 16 22:44:47 localhost su: pam_unix(su:session): session opened for user kml by root(uid=0) Dec 16 22:44:48 localhost su: pam_unix(su:session): session closed for user kml [root@localhost local]# pwd /usr/local # 可以看到日志信息已经能写入到这里面了
日志的属性权限
- 也是一个隐藏权限
- 权限有 rwx 和 selinux标签 以及 属性权限
权限 解释 A time时间不能更改 S 数据同步写入到硬盘中 a 只能增加不能减少 c 自动将文档进行压缩 i 文件锁死不能做任何更改 s 完全移除硬盘(被删除不能恢复) u 被删除后一定能恢复 d dump备份 # 给 secure设置 a 权限 [root@localhost local]# chattr +a /usr/local/secure # 查看权限 有一个a权限 [root@localhost local]# lsattr /usr/local/secure -----a---------- /usr/local/secure
日志远程传输
主机 | 服务 |
---|---|
192.168.100.211 | rsyslog |
192.168.100.212 | rsyslog |
每台主机设置
# 关闭防火墙或者放行防火墙 514端口
# 关闭selinux沙盒
[root@localhost local]# vim /etc/rsyslog.conf
# 开启udp日志转发 14行
# Provides UDP syslog reception
$ModLoad imudp
$UDPServerRun 514
# 开启tcp日志转发 18行
# Provides TCP syslog reception
$ModLoad imtcp
$InputTCPServerRun 514
192.168.100.211主机
# 192.168.100.211 将日志信息传输到 192.168.100.212中
# 修改配置文件
[root@localhost local]# vim /etc/rsyslog.conf
# 在 下面这个标签之内添加
#### RULES ####
# 这个标签之内都是将服务的日志信息输出到特定的文件中
# 我是在74行添加的
*.* @192.168.100.212
# 意思是 将所有的程序的所有级别的日志都 以udp的形式传输到 192.168.100.212主机中
所有主机重启 服务
[root@localhost ~]# systemctl restart rsyslog.service
192.168.100.211主机 产生日志
# 产生日志
[root@localhost local]# logger hello_lmk
# 只有先产生日志 192.168.100.212 才能看到日志输出
192.168.100.212主机 查看日志信息输出
# 查看日志信息输出
[root@localhost ~]# tail -f /var/log/messages
# 注意 192.168.100.212出现日志时,发送过来这才会有
Dec 16 23:08:19 localhost root: hello_lmk
# 多出来一条
采集第三方日志(nginx日志)
主机 | 服务 |
---|---|
192.168.100.211 | rsyslog nginx |
192.168.100.212 | rsyslog |
每台主机设置
# 关闭防火墙或者放行防火墙 514端口
# 关闭selinux沙盒
[root@localhost local]# vim /etc/rsyslog.conf
# 开启udp日志转发 14行
# Provides UDP syslog reception
$ModLoad imudp
$UDPServerRun 514
# 开启tcp日志转发 18行
# Provides TCP syslog reception
$ModLoad imtcp
$InputTCPServerRun 514
192.168.100.211安装nginx
[root@localhost nginx-1.15.4]# yum -y install pcre-devel openssl-devel zlib-devel
[root@localhost nginx-1.15.4]# ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx && make && make install
[root@localhost nginx-1.15.4]# ln -s /usr/local/nginx/sbin/* /usr/sbin/
[root@localhost nginx-1.15.4]# useradd -M -s /sbin/nologin nginx
[root@localhost nginx-1.15.4]# nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[root@localhost nginx-1.15.4]# ls /usr/local/nginx/logs/
access.log error.log nginx.pid
[root@localhost nginx-1.15.4]# nginx
修改rsyslog配置文件
# 添加第三方日志采集的功能模块 (13行添加)
$Modload imfile
# 在#### RULES #### 标签后添加
# 我在76行添加的这些
$InputFilePollInterval 1 # 设置采集时间间隔 1s采集一次
$InputFileName /usr/local/nginx/logs/access.log # 设置要采集的日志目录文件
$InputFileTag nginx-info-access; # 标记日志名称 全局唯一 (可以随便写名字)
$InputFilestateFile state-nginx-info-accesslog # 标记日志上传进度 全局唯一 (可以随便写名字)
$InputRunFileMonitor # 开启监控 采集 上面文件的日志信息
$InputFileName /usr/local/nginx/logs/error.log # 设置要采集的日志目录文件
$InputFileTag nginx-info-error; # 标记日志名称 全局唯一 (可以随便写名字)
$InputFilestateFile state-nginx-info-errorlog # 标记日志上传进度 全局唯一 (可以随便写名字)
$inputRunFileMonitor # 开启监控 采集 上面文件的日志信息
$InputFilePollInterval 10 # 定义往对端主机传输日志信息的事件间隔
if Sprogramname == "nginx-info-accesslog" then @192.168.100.212 # 往 212网址的主机传输 nginx的access日志信息
if Sprogramname == "nginx-info-accesslog" then ~ # 这个 ~的意思是在本地也保留一份
if Sprogramname == "nginx-info-errorlog" then @192.168.100.212 # 往 212网址的主机传输 nginx的error日志信息
if Sprogramname == "nginx-info-errorlog" then ~ # 这个 ~的意思是在本地也保留一份
[root@localhost nginx-1.15.4]# systemctl restart rsyslog # 重启rsyslog服务
[root@localhost nginx-1.15.4]# curl 192.168.100.211 # 访问nginx
192.168.100.212查看日志输出
[root@localhost ~]# tail -f /var/log/messages
# 会出现日志信息
Dec 16 23:35:58 localhost nginx-info-access; 192.168.100.211 - - [16/Dec/2020:23:35:54 +0800] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0"
日志切割
即日志轮滚-日志轮替
在服务器架构当中,层级越多,所产生的日志就越多,将产生的日志发送到日志服务器上(logserver),对于日志,我们需要防止文件过大,
可以通过关闭本地syslog,在logserver上对其进行切割(1G进行切割)
查看默认可以切割的日志目录
[root@localhost ~]# cd /etc/logrotate.d/ [root@localhost logrotate.d]# ls bootlog cups iscsiuiolog libvirtd.qemu ppp samba syslog yum chrony glusterfs libvirtd numad psacct sssd wpa_supplicant # 这些是默认可以切割的日志信息 # 查看切割时使用的参数 [root@localhost logrotate.d]# grep -v ^# /etc/logrotate.conf | grep -v ^$ Weekly # 每周切割 rotate 4 # 保留4个切割结果,表示最高可以查询一个月以内的日志 Create # 日志切割以后,在本地创建另外一个空白的日志供日志来写 Dateext # 当前以日期的形式来标注切割文件的名称 include /etc/logrotate.d # 哪些文件遵循这个规则 /var/log/wtmp { # 这个文件按照括号内这个标注切割 Monthly # 每个月切割一次 create 0664 root utmp # 创建的新文件的具体权限是多少,属组属主是多少 minsize 1M # 当我们日志大小到达1M才切割 rotate 1 # 日志切割后最多保存多少份 } /var/log/btmp { Missingok # 丢失没关系 monthly # # 每个月切割一次 create 0600 root utmp # 创建的新文件的具体权限是多少,属组属主是多少 rotate 1 # 日志切割后最多保存多少份 }
切割日志的配置参数
参数 解释 Compress 切割之后要进行压缩 Nocompress 切割之后不需要进行压缩 Copytruncate 如果日志正在使用,先copy清空旧日志(可能会导致丢失) Nocopytruncate 备份文件中不截断 create 权限 属主 属组 轮滚之后生成新的文件,后面跟的权限和属组属主 Nocreate 切割文件后不生成文件 Delaycompress 和compress连用,转存的日志的下一次在进行压缩 Nodelaycompress 轮询之后马上压缩 Missingok 日志切割时丢失也没关系 errors address@123.com 把错误信息发送个某个电子邮件 Ifempty 即使文件为空也轮询 Noifempty 日志为空则不论滚 mail address@123.com 把切割后的文件发送给这个文件 Nomail 切割后的文件在本地存储 olddir /var/log/xxxx 切割之后的文件存储的位置 Noolddir 在本地切割文件和源文件在同一个目录下,则不需要执行切割 Sharedscripts 后面执行某个脚本 endscript 脚本执行结束 Prerotate 切割日志之前需要做什么… Postrotate 切割日志之后需要做什么… Daily 每天切割 Weekly 每周切割 Monthly 每月切割 rotate 数量 切割之后保存多少,保存几次 Dateext 存储之后的文件以计算机当中日期为名字 Size或者minisize 最小的切割大小满足该大小之后才进行切割(例:size = 5 size 5M)
切割 secure日志
[root@localhost ~]# vi secure /var/log/secure { missingok # 日志切割时丢失也没关系 notifempty # 日志为空则不切割 daily # 每天切割 create # 切割后生成新的日志文件 防止日志没法添加到原来的日志文件 rotate 4 # 保存4条切割后的文件 compress # 切割之后要进行压缩 }
手动进行切割(如果不手动就要等一天)
# 先查看一下日志 [root@localhost ~]# ls /var/log/ anaconda grubby_prune_debug secure vmware-vgauthsvc.log.0 audit lastlog speech-dispatcher vmware-vmsvc.log boot.log libvirt spooler vmware-vmusr.log btmp maillog sssd wpa_supplicant.log chrony messages swtpm wtmp cron ntpstats tallylog Xorg.0.log cups pluto tuned Xorg.0.log.old dmesg ppp vmware-network.1.log Xorg.9.log dmesg.old qemu-ga vmware-network.2.log yum.log firewalld rhsm vmware-network.3.log gdm sa vmware-network.4.log glusterfs samba vmware-network.log # 手动切割日志 [root@localhost ~]# logrotate -vf /root/secure reading config file /root/secure Allocating hash table for state file, size 15360 B Handling 1 logs ....................... # 在查看日志地址 [root@localhost ~]# ls /var/log/ anaconda grubby_prune_debug secure vmware-network.log audit lastlog secure.1.gz vmware-vgauthsvc.log.0 boot.log libvirt speech-dispatcher vmware-vmsvc.log btmp maillog spooler vmware-vmusr.log chrony messages sssd wpa_supplicant.log cron ntpstats swtpm wtmp cups pluto tallylog Xorg.0.log dmesg ppp tuned Xorg.0.log.old dmesg.old qemu-ga vmware-network.1.log Xorg.9.log firewalld rhsm vmware-network.2.log yum.log gdm sa vmware-network.3.log glusterfs samba vmware-network.4.log # 多了一个secure.1.gz
- 引发出的问题
# 但是这样会引发一个问题,用户在进行操作时,日志已经传输不到原来的secure日志文件中了 要重启服务才可以 [root@localhost ~]# cd /var/log [root@localhost log]# cat secure [root@localhost log]# su lmk [lmk@localhost log]$ exit exit [root@localhost log]# cat secure # 是没有写入数据的 # 重启服务 [root@localhost log]# systemctl restart rsyslog.service [root@localhost log]# su lmk [lmk@localhost log]$ exit exit [root@localhost log]# cat secure Dec 17 00:14:41 localhost polkitd[792]: Unregistered Authentication Agent for unix-process:98236:883928 (system bus name :1.111, object path /org/freedesktop/PolicyKit1/AuthenticationAgent, locale zh_CN.UTF-8) (disconnected from bus) Dec 17 00:14:49 localhost su: pam_unix(su:session): session opened for user lmk by root(uid=0) Dec 17 00:14:50 localhost su: pam_unix(su:session): session closed for user lmk # 重启服务才会写入数据,所以切割文件要优化一下
新切割文件
[root@localhost ~]# chattr +a /var/log/secure [root@localhost ~]# vi secure /var/log/secure { sharedscripts # 后面执行某个脚本 prerotate # 切割日志之前需要做什么... /usr/bin/chattr -a /var/log/secure # 将这个日志文件的a属性权限删掉 endscript # 脚本执行结束 missingok # 日志切割时文件丢失也没关系 notifempty # 日志内容为空则不切割 daily # 每天切割一次 create # 切割完成后创建原来的那个secure日志文件 rotate 4 # 切割后的文件最多保存4份 compress # 切割后要进行压缩 dateext # 切割后文件以计算机当中的日志为名字 sharedscripts # 后面执行某个脚本 postrotate # 切割日志之后需要做什么... /bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null # 重启syslogd程序 /usr/bin/chattr +a /var/log/secure # 再给secure文件加会a属性权限 endscript # 脚本执行结束 }
手动切割
[root@localhost ~]# logrotate -vf /root/secure reading config file /root/secure Allocating hash table for state file, size 15360 B Handling 1 logs rotating pattern: /var/log/secure forced from command line (4 rotations) empty log files are not rotated, old logs are removed considering log /var/log/secure ......... # 查看日志文件目录 [root@localhost ~]# ls /var/log/ anaconda grubby_prune_debug secure vmware-network.4.log audit lastlog secure.1.gz vmware-network.log boot.log libvirt secure-20201217.gz vmware-vgauthsvc.log.0 btmp maillog speech-dispatcher vmware-vmsvc.log chrony messages spooler vmware-vmusr.log cron ntpstats sssd wpa_supplicant.log cups pluto swtpm wtmp dmesg ppp tallylog Xorg.0.log dmesg.old qemu-ga tuned Xorg.0.log.old firewalld rhsm vmware-network.1.log Xorg.9.log gdm sa vmware-network.2.log yum.log glusterfs samba vmware-network.3.log # 多出来 secure-20201217.gz 文件 # 而且 目录中的 secure还可以正常写入日志
- 接下来用任务计划把命令定时执行就ok了
[root@localhost ~]# crontab -e * * * * 1 /usr/sbin/logrotate -vf /root/secure # 每周1切割一次
本博客所有文章是以学习为目的,如果有不对的地方可以一起交流沟通共同学习 邮箱:1248287831@qq.com!