关闭→
当前位置:科普经验站>综合知识>docker容器日志存储多久

docker容器日志存储多久

科普经验站 人气:6.62K

docker容器日志存储多久

docker容器运行后容器日志会一直存储,时间久后会出现日志文件过大,从而导致查询日志困难,容器日志一般会在docker持久化目录containers下对应不同镜像名称以*-json.log形式展现。Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用,以及依赖包到一个可移植的镜像中,然后发布到任何流行的Linux或Windows操作系统的机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。

小编还为您整理了以下内容,可能对您也有帮助:

对docker容器产生的日志做轮转

logrotate是Linux系统的日志轮转程序,能够对系统产生的日志自动管理

logrotate配置文件在/etc/logrotate.d下,创建对docker容器日志轮转的配置文件

第一行添加要轮转的日志的位置

daily 表示按天轮转 还有 hourly, weekly,monthly ,yearly

weekly 指定转储周期为每周

monthly 指定转储周期为每月

rotate 转储次数,超过将会删除最老的那一个

copytruncate 这个参数如果不添加的话,logrotate程序会将日志

missingok 忽略错误,如“日志文件无法找到”的错误提示

dateext 切换后的日志文件会附加上一个短横线和YYYYMMDD格式的日期

compress 通过gzip 压缩转储旧的日志

delaycompress 当前转储的日志文件到下一次转储时才压缩

notifempty 如果日志文件为空,不执行切割

sharedscripts 只为整个日志组运行一次的脚本

prerotate/endscript 在转储以前需要执行的命令可以放入这个对,这两个关键字必须单独成行

postrotate/endscript 在转储以后需要执行的命令可以放入这个对,这两个关键字必须单独成行

size  size当日志文件到达指定的大小时才转储,Size 可以指定 bytes (缺省)以及KB (sizek)或者MB (sizem).

对zabbix-agent日志进行配置,创建zabbix-agent文件即可

logrotate可以在任何时候从命令行手动调用

Docker 容器的日志大家都是怎么处理的

Docker时代的日志,步子并未跨得太大,毕竟安全第一。然而,不可否认发展的时代总有让你意想不到的亮点。

如果你是容器中的应用,哪怕你是始乱终弃,抑或是洒脱不羁,Docker容器都会记录下你的点点滴滴,只要你对着标准输出标准错误说一句action。(Docker容器所有的标准输出标准错误都会被Docker Daemon接管)

如果你是个阅尽人间无数,拳打南山,脚踢北海,四海流窜的Docker容器,你在北京的One Night,兴许第二天在上海的你早已酒醒如初;第三天出差杭州的你,更是不记得昨天在上海住的是几星级宾馆。(Docker容器本身理应尽量无状态,容器内应用持久化的日志则有状态,频繁迁移不宜容器日志管理)。

如果你有一部肾机,如果你继续支持大表姐。Docker容器中的你,很容易将容器走南闯北的经历传至云端,以便他日传看。(Docker容器的应用日志,如果自己发往集中的日志处理中心,则为上上策,易统一;问题是成本高,得有钱买肾机,还需统一化的标准)

Docker(5)——数据管理

docker 容器的文件系统在宿主机上存在的方式很复杂,这会带来下面几个问题:

为了能够 保存(持久化) 数据以及 共享 容器间的数据,docker 引入了数据卷(volume) 机制。数据卷是存在于一个或多个容器中的特定文件或文件夹,它可以绕过默认的联合文件系统,以正常的文件或者目录的形式存在于宿主机上。

其生存周期于容器的生存周期。

容器中主要有 两种 管理数据方式: 数据卷(Data Volumes) , 数据卷容器(Data Volume Containers) 。

数据卷是一个可供容器使用的特殊目录,它绕过文件系统,可以提供很多有用的特性:

数据卷的使用类似 linux 下对目录或文件进行 mount 操作,目前Docker提供了 三种 不同的方式将数据从宿主机挂载到容器中,分别是

其中 volume 、 bind mount 比较常用, tmpfs mount 基本不会用.

volumes作为Docker管理宿主机文件系统的一部分 ,默认位于 /var/lib/docker/volumes 目录中,不是宿主机已有数据,而是新建的。

docker 专门提供了 volume 子命令来操作数据卷:

先创建一个名称为 hello 的数据卷并通过 ls 命令进行查看:

然后可以使用 inspect 命令看看数据卷hello的详细信息

该数据卷使用的 Driver 为默认的 local ,表示数据卷使用宿主机的本地存储;

Mountpoint 是 volumes 的挂载点,默认是本机 /var/lib/docker/volumes 下的一个目录。

所有Container的数据都保存在了这个目录下边,由于没有在创建时指定卷,所以Docker帮我们默认创建许多匿名卷。

使用 -v 选项也可以指定挂载一个本地的已有目录到容器中去作为数据卷:

docker run -it –-name robot1 -v /var/data:/opt/mydata ros/kinetic /bin/bash

上面的命令挂载主机的 /var/data 目录到容器的 /opt/mydata 目录。

这个功能在测试的时候特别方便,比如用户可以放置一些程序或数据到本地目录中,然后在容器中使用。另外,本地目录的路径必须是绝对路径,如果目录不存在,Docker 会自动创建。

Docker 挂载数据卷的默认权限是可读写 rw ,用户也可以通过 ro 标记指定为只读:

docker run -it –-name robot1 -v /var/data:/opt/mydata:ro ros/kinetic /bin/bash

加了 :ro 之后,容器内挂载的数据卷内的数据就变成只读的了。

除了把数据卷中的数据存储在宿主机,docker 还允许我们通过指定 volume driver 的方式把数据卷中的数据存储在其它的地方,比如 Azrue Storge 或 AWS 。

通过 vieux/sshfs 驱动把数据卷的存储在云主机上,docker 默认是不安装 vieux/sshfs 插件的,我们可以通过下面的命令进行安装:

docker plugin install --grant-all-permissions vieux/sshfs

然后通过 vieux/sshfs 驱动创建数据卷,并指定远程主机的登录用户名、密码和数据存放目录:

注意:确保指定的远程主机上的挂载点 /home/nick/sshvolume 目录是存在的,否则在启动容器时会报错。

最后在启动容器时指定挂载这个数据卷:

在容器中 /world 目录下操作的文件都存储在远程主机的 /home/nick/sshvolume 目录中。进入容器 testcon 然后在 /world 目录中创建一个文件,然后打开远程主机的 /home/nick/sshvolume 目录进行查看,新建的文件会出现在那里。

当使用 bind mounts 将主机上的目录挂载到容器中时,目录由其在主机上的完整或相对路径引用。

bind mount 和 volume 其实都是利用宿主机的文件系统,不同之处在于volume是docker自身管理的目录中的子目录,所以不存在权限引发的挂载的问题,并且目录路径是docker自身管理的,所以也不需要在不同的服务器上指定不同的路径,不需要关心路径

bind mounts 可以挂载在宿主机系统的任意位置 ,但 bind mount 在不同的宿主机系统是不可移植的,比如Windows和Linux的目录结构是不一样的, bind mount 所指向的 host 目录也不能一样。这也是为什么 bind mount 不能出现在Dockerfile中的原因,因为这样Dockerfile就不可移植了。

如果使用 Bind mounts 挂载 宿主机目录 到 容器内非空目录 ,那么 此容器中的非空目录中的文件会被隐藏 ,容器访问这个目录时能够访问到的文件均来自于宿主机目录。这也是Bind mounts模式和Volumes模式最大的行为上的不同。

挂载存储在宿主机系统的内存中,而不会写入宿主机的文件系统;

这张图说明 bind mount 和 volume 其实都是利用宿主机的文件系统, Bind mounts 模式是将宿主机上的任意文件或文件夹挂载到容器,而 Volumes 本质上是将Docker服务管理的一块区域(默认是 /var/lib/docker/volumes 下的文件夹)挂载到容器。所以 volume 不存在权限引发的挂载的问题,并且目录路径是docker自身管理的,所以也不需要在不同的服务器上指定不同的路径,不需要关心路径。

相对于 bind mount , volume 是Docker Engine在自己的“地盘”分配了一个路径作为挂载点,自己地盘的权限肯定是安排的明明白白。所以,以上挂载宿主机路径的问题都解决了。

在使用 volume 作为数据卷挂载到容器时,直接用 volume 名称代替宿主机路径名就行:

docker run -d -v test_vol:/var/data some_image

这样就将数据卷 test_vol 挂载到了容器内的 /var/data 目录下。

命名的容器挂载数据卷,其它容器通过挂载这个(父容器)实现数据共享,挂载数据卷的容器,称之为数据卷容器

可以利用数据卷容器对其中的数据卷进行备份、恢复,以实现数据的迁移。

备份

使用下面的命令来备份 mydata 数据卷容器内的数据卷:

sudo docker run --volumes-from mydata -v $(pwd):/backup –-name worker ubuntu tar cvf /backup/backup.tar /data

这个命令首先利用 Ubuntu 镜像创建了一个容器 worker。又使用 --volumes-from mydata 参数来让 worker 容器挂载 mydata 容器的数据卷。接下来使用 -v $(pwd):/backup 参数来挂载本地的当前目录到 worker 容器的 /backup 目录。

在 worker 容器启动后,使用了 tar cvf /backup/backup.tar /data 命令来将 /data 下内容备份为容器内的 /backup/backup.tar,即宿主主机的当前目录下的backup.tar。

恢复

如果要恢复数据到一个容器,可以按照下面的操作。首先创建一个带有数据卷的容器 mydata2:

sudo docker run -v /data –-name mydata2 ubuntu /bin/bash

然后创建另一个新的容器,挂载 mydata2 的数据卷,并使用 tar 解压缩备份文件到所挂载的容器卷中:

sudo docker run --volumes-from mydata2 -v $(pwd):/backup busybox tar xvf /backup/backup.tar

如果用户需要在容器之间共享一些持续更新的数据,最简单的方式是使用数据卷容器。数据卷容器其实就是一个普通的容器,专门用它提供数据卷供其他容器挂载。下面简单介绍其使用方法。

首先要创建一个数据卷容器 mydata,并在其中创建一个数据卷挂载到 /data 目录。

sudo docker run -it -v /data –-name mydata ubuntu

然后在其他容器中使用 --volumes-from 来挂载 mydata 容器中的数据卷。例如创建两个容器 mycon1 和 mycon2,并从 mydata 容器挂载数据卷:

sudo docker run -it --volumes-from mydata –-name mycon1 ubuntu

sudo docker run -it --volumes-from mydata –-name mycon2 ubuntu

(注意,命令中没有指定数据卷的信息,也就是说新容器中挂载数据卷的目录和源容器中是一样的。)

此时容器 mycon1 和 mycon2 都挂载同一个数据卷到相同的目录 /data。三个容器任何一个在该目录下写入数据其他容器都能看到。

可以多次使用 --volumes-from 参数来从多个容器挂载多个数据卷。还可以从其他已经挂载了容器的容器来挂载数据卷。并且使用 --volumes-from 参数所挂载数据卷的容器自身并不需要保持在运行状态。

但删除挂载了数据卷的容器时,数据卷并不会被自动删除。如果要删除一个数据卷,必须在删除最后一个还挂载着它的容器时显式的使用 docker rm -v 命令来指定同时删除关联的容器。

如何对已经运行的容器挂载目录?

https://blog.51cto.com/hjun169/2440799

手动修改mount挂载的json文件,狂神的那个视频里面也有写。

深刻理解Docker镜像大小

https://blog.csdn.net/2ab509379d867c/38af113f849d6e/3db811378e9d78/6dea5661d2c1.9

理解docker的分层镜像实现 base 镜像共享(DockerFile)

https://blog.csdn.net/35a83a67d6c03b/38af113f849d6e/3db811378e9d78/68ed5363d4c23f.0

docker查看日志命令

   

如何查看docker日志,让我们一起了解一下?

通过docker logs可以查看容器的日志命令。高效的监控和日志管理对保持生产系统持续稳定的运行以及排查问题至关重要。在微服务架构中,由于容器的数量众多以及快速变化的特性使得记录日志和监控变得越来越重要。

docker查看日志的几个方式:

1、docker logs --tail=1000 容器名称 (查看容器前多少行的日志)(推荐)

2、docker 容器启动后,可以进入以下位置查看日志(/var/lib/docker/containers/容器ID/容器ID-json.log)(进入容器内部查看日志)

3、#查看compose所有容器的运行日志

docker-compose -f docker-compose-app.yml logs -f

4、#查看compose下某个容器的运行日志

docker-compose -f docker-compose-app. yml logs -f服务名>

5、# 也可以把compose的容器日志输出到日志文件里去,然后用tail -f随时查看

docker-compose -f docker-compose-app. yml logs -f >> myDockerCompose.log &

具体操作如下:

docker attach [options] 容器会连接到正在运行的容器,然后将容器的标准输入、输出和错误流信息附在本地打印出来。命令中options的取值有三种:--detach-keys,--no-stdin,--sig-proxy。

该命令只是进入容器终端,不会启动新的进程。所以当你同时使用多个窗口进入该容器,所有的窗口都会同步显示。如果一个窗口阻塞,那么其他窗口也就无法再进行操作。

使用ctrl+c可以直接断开连接,但是这样会导致容器退出,而且还stop了。如果想在脱离容器终端时,容器依然运行。就需要使用--sig-proxy这个参数。例如:

$ docker attach --sig-proxy=false mytest

注意: 当使用docker attach连接到容器的标准输入输出时,docker使用大约1MB的内存缓冲区来最大化应用程序的吞吐量。如果此缓冲区填满,那么输出或写入的速度将会受到影响。因此查看应用日志,可以使用docker logs命令。

docker日志存储位置,设置docker容器日志大小

在Linux系统中docker启动后日志存储在 /var/lib/docker/containers/容器ID/ 目录中,启动一个容器后,容器ID目录中会生成如下文件:

每个容器的日志默认都会以 json-file 的格式存储于 /var/lib/docker/containers/<容器id>/<容器id>-json.log 下,不过并不建议去这里直接读取内容,因为容器的日志则可以通过 docker logs 命令来访问,而且可以像 tail -f 一样,使用 docker logs -f 来实时查看。如果使用 Docker Compose,则可以通过 docker-compose logs <服务名> 来查看。

从上面可以知道docker容器日志存储在文件中,容器销毁后 /var/lib/docker/containers/<容器id>/ 目录会被自动删除,所以容器日志也被一并删除。如果容器一直运行并且一直产生日志,容器日志会导致磁盘空间爆满,如何解决这个问题?

新建 /etc/docker/daemon.json ,若有就不用新建了。添加log-dirver和log-opts参数,如下:

设置完成之后,需要删除容器,并重新启动容器,我们可以看到 /var/lib/docker/containers/<容器id>/hostconfig.json 文件的变化如下:

设置 log-opts 之前:

设置 log-opts 之后:

在k8s集群中docker容器日志 /var/lib/docker/containers/容器ID/ 目录的文件如下:

与docker容器目录相比少了一些文件:hostname、hosts、resolv.conf、resolv.conf.hash

k8s通过 sandbox(pause容器,关于pause容器的介绍可以查阅资料) 关联了这些文件,通过查看 cat config.v2.json 可以发现如下配置:

使用命令 cat /var/lib/docker/containers/<容器id>/hostconfig.json 查看 hostconfig.json 的内容,发现有如下设置:

查看 /etc/docker/daemon.json 发现有如下配置:

下面列出了一个容器的日志文件达到设置值的情况:

参考文档:

Docker 日志都在哪里?怎么收集?

Docker容器日志查看与清理

Docker日志收集

Docker的应用为我们带来便利的同时,日志集中化问题就越来越有必要性了。

在收集之前,我们先来简单了解下docker日志处理的机制。当启动一个容器的时候,它其实是docker daemon的一个子进程,docker daemon可以拿到你容器里面进程的标准输出,拿到标准输出后,它会通过自身的一个LogDriver模块来处理,LogDriver支持的方式很多,可以写到本地的文件(默认方式),可以发送到syslog等,见下图:

目前,常见的收集方式有下面几种:

在日志收集的过程中,需要特别考虑性能的问题。试想一下,当容器的流量比较大的时候,势必日志也会随着大量地产生,这时就会有个问题,日志收集agent必然会跟容器抢占宿主机的资源,为了避免这个问题,在收集选型的时候就需要注意:

综上所属,最佳实践就是采用 旁路模式 来收集,并且使用容器方式来运行并限定使用的资源;最终采用了 logspout+Fluentd 的方案(架构图见下),采用的理由如下:

logspout通过docker.sock监听本地容器的启动,通过docker API获取到这个新容器的日志流,并将这个日志流通过udp的协议发送给fluentd处理,fluentd处理完成后发送给后续的日志系统。

最后,受阿里云fluentd-pilot的影响,我将官方的logspout进行一些小的修改, 请见 :

下面个出个docker-compose.yml, 通过docker-compose up就可以运行了;

fluent的简单配置:

最后,可以通过查看fluent的log来查看格式化的容器日志;

微服务基础服务之docker篇

什么是docker

Docker 最初是 dotCloud 公司创始人 Solomon Hykes 在法国期间发起的一个公司内部项目,它是基于 dotCloud 公司多年云服务技术的一次革新,并于 2013 年 3 月以 Apache 2.0 授权协议开源,主要项目代码在 GitHub 上进行维护。Docker 项目后来还加入了 Linux 基金会,并成立推动 开放容器联盟(OCI)。

Docker 使用 Google 公司推出的 Go 语言 进行开发实现,基于 Linux 内核的 cgroup,namespace,以及 AUFS 类的 Union FS 等技术,对进程进行封装隔离,属于 操作系统层面的虚拟化技术。由于隔离的进程于宿主和其它的隔离的进程,因此也称其为容器。最初实现是基于 LXC,从 0.7 版本以后开始去除 LXC,转而使用自行开发的 libcontainer,从 1.11 开始,则进一步演进为使用 runC 和 containerd。

Docker 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等等,极大的简化了容器的创建和维护。使得 Docker 技术比虚拟机技术更为轻便、快捷。

下面的图片比较了 Docker 和传统虚拟化方式的不同之处。传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。

传统虚拟化

Docker

为什么要用docker

对开发和运维(DevOps)人员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。

使用 Docker 可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过 Dockerfile 来进行镜像构建,并结合 持续集成(Continuous Integration) 系统进行集成测试,而运维人员则可以直接在生产环境中快速部署该镜像,甚至结合 持续部署(Continuous Delivery/Deployment) 系统进行自动部署。

而且使用 Dockerfile 使镜像构建透明化,不仅仅开发团队可以理解应用运行环境,也方便运维团队理解应用运行所需条件,帮助更好的生产环境中部署该镜像。

特性容器虚拟机 启动秒级分钟级 硬盘使用一般为MB一般为GB 性能接近原生弱于 系统支持量单机支持上千个容器一般几十个

基本概念

我们都知道,操作系统分为内核和用户空间。对于 Linux 而言,内核启动后,会挂载 root 文件系统为其提供用户空间支持。而 Docker 镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:18.04 就包含了完整的一套 Ubuntu 18.04 最小系统的 root 文件系统。

Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。

镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的 类 和 实例 一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。

前面讲过镜像使用的是分层存储,容器也是如此。每一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,我们可以称这个为容器运行时读写而准备的存储层为容器存储层。

按照 Docker 最佳实践的要求,容器不应该向其存储层内写入任何数据,容器存储层要保持无状态化。所有的文件写入操作,都应该使用 数据卷(Volume)、或者绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。

数据卷的生存周期于容器,容器消亡,数据卷不会消亡。因此,使用数据卷后,容器删除或者重新运行之后,数据却不会丢失。

镜像构建完成后,可以很容易的在当前宿主机上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry 就是这样的服务。

一个 Docker Registry 中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。

通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。

Centos安装docker18

常用的docker命令

常用的docker镜像

redis

mysql

细说kubernetes - 为什么是pod?

k8s作为现在最火的容器编排调度平台,好用我也就不必多说了。当我们初识k8s的时候一个新的概念就到了我们眼前,那就是pod。我们在使用了之后也就渐渐的接受了pod这个东西,但是你有没有想过,为什么是pod?k8s为什么会有这样的设计?今天我们就来细细说说这个pod

首先我们来回忆看看k8s的架构图是什么样子的

从架构图中我们可以看到,整个k8s的设计架构有以下几个要点:

当然其他组件都非常重要,这个我们以后再说,我们今天就来看看主角“pod”

一开始用的时候我就好奇为什么k8s要弄出一个pod,因为我们一开始使用的是docker,操作的是docker容器,构建的也是docker镜像,为什么不直接调度docker容器就好了,这样粒度不是更加细致,调度也会更加方便吗?

我们在使用k8s之前也使用过docker-compose,从另一个角度说,这也是一种容器的管理,看起来也挺好的。

下面我们就来说说pod

从上面的图你大概可以感受到pod在k8s中其实是一个什么样的角色。

我们如果使用虚拟机,那么上面就会有一系列的服务这些服务可能会有一些依赖,而这样的依赖就好像在服务器中运行的一个个进程组,往往其中也有着相关的依赖,而pod中的容器也是一样的道理,其中也会有类似这样的依赖,为了更好的描述和管理这样的依赖,于是就有了pod。

其实这样的理念往往可以类比出很多这样的设计。

一定会有这样的关系吗?我的感觉是,在现代技术服务的开发的过程中,这样的关系是不可避免的。我下面来举几个例子。

我们知道 java 的 web 应用往往需要部署在tomcat这样的容器之中,在 springboot 还没有出现以前,需要自己启动一个 tomcat 容器,然后将需要部署的应用打包部署到容器中去。

在以前你可能会想着,将 javaweb 打包一个war,然后编写一个 dockerfile 将 war 包cp到 tomcat 中的 webapp 目录中。但是这样带来的就是每次更新发布的时候,镜像会很大,因为每次构建都会有一个基础的tomcat镜像。

而在k8s使用的时候,会有的设计的是,将tomcat作为一个不变的镜像(它也不应该改变)而把 war 包作为另外一个容器,而这样个容器同时挂载同一个目录,将 webapp 挂载的目录与 war包挂载的目录相同来达到目的,然后将他们放到同一个 pod 中。

类似的操作还有: https://kubernetes.io/23b5/3db20625/2dbc163d94/38be06339482.application-cluster/communicate-containers-same-pod-shared-volume/ 里面说的就是前端静态页面和 nginx 的关系。

下面引用官网设计理念中的一句话:“ 比如你运行一个操作系统发行版的软件仓库,一个Nginx容器用来发布软件,另一个容器专门用来从源仓库做同步,这两个容器的镜像不太可能是一个团队开发的,但是他们一块儿工作才能提供一个微服务;这种情况下,不同的团队各自开发构建自己的容器镜像,在部署的时候组合成一个微服务对外提供服务。 ”

在使用 docker 部署项目的时候会遇到一个问题就是日志持久化的问题,因为 docker 容器如果被删除的话,其中的文件也会被删除,那么我们的日志文件同时也会被删除,也就是说我们必须要将日志持久化。

最常见的方式是,将日志存储的目录挂载到宿主机上,这样容器被删除的时候日志不会被删除。

而在k8s中常见的日志处理架构是怎么样的呢?

https://kubernetes.io/23b5/3db20625/3ab20b3582817f04/3ab11025939479.administration/logging/

使用的是 sidecar,这个是什么呢?其实就是一个辅助性质的容器,同时与主容器放在同一个 pod 中,读取主容器挂载出来的日志目录。其实后续还可以做更多的操作,比如日志发送es等等。

总之我们可以看到,在一个pod中的容器关系是非常密切的,他们可以拥有同一个目录,甚至可以拥有同一个网络,可以拥有相互的服务,这样的关系我听过的名词叫做“超亲密关系”。就类似一对夫妻之间的关系了。

因为在现在的多说应用中,已经几乎做不到一个人顶天立地了,总是会有各种各样的依赖,依赖一些组件,依赖一些工具,依赖一些网络服务等等,一个进程组有很多的进程互相帮助来最终实现功能一样。

这样的关系太过常见,于是k8s就将它设计为了pod。

如果你已经对docker的实现比较熟悉,其实pod的实现并不复杂。(如果对docker实现不熟悉可以翻看之前的博客)

其实pod是一个逻辑上的概念,其实pod做的事情很简单:

其实k8s做的就是初始化一个infra的容器(这是一个很小的容器),利用这个容器去抢先占用需要使用的 Namespace ,然后在将用户指定的容器加载进来,同时使用的就是相同的 Namespace 了。(如果有 InitContainer 会优先按顺序初始化它,图上就不做说明了)

这样共享网络应该是没有问题了,那么要共享Volume也很简单。pod 只需要将 Volume 目录挂载到宿主机,让内部的容器挂载这个目录就可以了。

再来说说pod还有哪些功能,这些功能也是k8s为什么设计pod的原因之一

通过Probe:LivenessProbe或者ReadinessProbe,可以探测应用是否处于健康状态,如果不健康做出相关的反应。

这就好比k8s可以定期的帮你监控、维持一整个应用的健康。

其实在我们看来,很多时候服务挂了,需要重启,需要做高可用,那么nginx呢?tomcat呢?也是一样的。所以pod的健康能保证整个服务的全部健康使用。

我们可以通过给Pod增加kubernetes.io/ingress-bandwidth和kubernetes.io/egress-bandwidth这两个annotation来Pod的网络带宽。

为什么我提到了这个功能呢?因为在实际的业务开发过程中经常会使用一些网络插件,这些网络插件在流量的控制上非常有用,有的时候我们会根据网络流量来做一系列的操作,用户的突然增长导致的流量剧增是否要扩容等等...而这样的监控和对于pod来说无疑会更加方便,而不需要管pod内部的容器的流量。

重启的策略,这个也算是一个功能吧

官网:一个Pod(就像一群鲸鱼,或者一个豌豆夹)。

我觉得 Pod 更证明了一种设计模式“组合”,在有的时候会,组合的合理,就会方便很多东西,比如设计了一堆组件,组合在一起;ps画图的时候方块更圆组合在一起,就可以一起多复制几个组合。

当然我们在认识到为什么要这样设计 Pod 的同时需要意识到,我们应该将什么样的容器组合放置在同一个 Pod 之中才比较合适。遵循一定的“容器设计模式”进行编排,调度的时候才会更加得心应手。

docker | 定时清理docker容器日志

使用linux的crontab命令每天晚上2点定期执行脚本清空容器日志

0 0 2 * * ? /opt/docker-sh/clean_docker_log.sh

将日志输出到Docker容器外

我们可以利用 docker logs 命令查看 Docker 容器内部应用程序运行时所产生的日志,可以免除首先进入 Docker 容器,再打开应用程序的日志文件的过程。docker logs 会监控容器中操作系统的标准输出设备(STDOUT),一旦 STDOUT 有数据产生,就会将这些数据传输到另一个“设备”中,该 Docker 的被称为“日志驱动(Logging Driver)”

例如,我们有一个容器实例 ID 为 “da6743d61e1a” ,随后我们使用 docker logs 命令,查看 da6743d61e1a 容器的日志

此时,Docker 日志也在同步输出,输出的日志类似下面这样。

Docker 是怎样做到的呢?或者说,所谓的 Docker 日志驱动,到底做了些什么事情?

我们使用 docker info 命令,可以看到 Docker 容器的相关信息,其中有一项 Logging Driver 的字段。

通过输入以上命令,将得到Docker 当前所设置的日志驱动类型:journald

其实,Docker 已为我们提供了大量的日志驱动类型。

通过 --log-opt 参数为 json-file 日志驱动添加了两个选项,max-size=10m 表示 JSON 文件最大为 10MB(超过 10MB 就会自动生成新文件),max-file=3 表示 JSON 文件最多为3个(超过3个就会自动删除多余的旧文件)

除了在启动 Docker 容器时,可指定日志驱动以外,还可以通过修改 Docker 配置文件来指定日志驱动。

打开配置文件 /etc/sysconfig/docker ,找到以下配置片段:

可以看出,默认的日志驱动为 journald,把它修改为 syslog

然后重启 docker

以上众多日志驱动类型中,较为常用 的是 Syslog,因为 Syslog 是 Linux 的日志系统,很多日志分析工具都可以从 Syslog 中获取日志,比如流行的 ELK(Elasticsearch、Logstash、Kibana)日志中心。Logstash 用于收集日志,Syslog 中写入的日志可转发到 Logstash 中,随后将日志存入 Elasticsearch 中,最后可通过 Kibana 来查询日志。

接下来咱们的目标是将 Docker 容器中输出的日志写入 Syslog,那么后面需要做的就是将 Syslog 接入 ELK 了。

默认,Linux 操作系统已经安装了 Syslog 软件包,但它叫 Rsyslog。实际上,Rsyslog 是 Syslog 标准的一种实现,还有一种叫 Syslog-ng 的第三方实现。虽然 Syslog-ng 的功能较为强大,但我们还是选择使用 Rsyslog,因为操作系统已经预装了,我们无须单独安装,可以通过以下命令查看 Rsyslog 是否已安装。

如果要开启 Rsyslog 服务,我们必须对 Rsyslog 进行配置,打开文件 vi /etc/rsyslog.conf

在 rsyslog.conf 文件中有一段配置,我们需要手工去开启

重启 Rsyslog 服务,否则配置无法生效

此时,我们可以查看本地是否对外开启了 514 端口

TAG标签:#日志 #存储 #容器 #docker #