docker exec 与容器日志

翻看 Docker 的历史,您会发现 Docker 一直在强调 “Application” 一词,Docker 也希望能为分布式应用提供容器化的解决方案。

从 Docker 化应用软件的生命周期来看,开发工作似乎位于 Docker 的构建之前,而后容器化的测试、部署与运维都与Docker容器息息相关。不得不说,Docker 思维下的应用软件,管理流程与传统场景有着很大的区别。

最大的区别当属:Docker 容器运行环境的封闭性。单一应用的运行,使得容器内部缺少功能丰富的服务。虽然用户可以通过 Docker 的层面,获取部分容器的信息,但是依然无法直接获悉应用内部的状态信息(虽然 Docker 倡导容器运行无状态的应用),比如:应用容器内部持久化的日志文件,应用容器内部的临时存储等等。而这些信息在传统模式下,都可以较为轻易的获取。

为了缓解容器运行环境封闭性带来的使用障碍,Docker 提供了docker exec 命令,方便用户在容器之外让容器执行指定的命令,以实现用户的需求。

今天你 docker exec 了吗?如果还没有的话,灵活穿越容器的感觉你值得拥有;如果有的话,那下面这些内容你不得不看。

1. 容器进程树与 docker exec



随着 Docker 的普及,相信越来越多的 Docker 爱好者已经意识到:

(1)Docker 容器其实就是若干进程构成;

(2)而 “一般情况下” 这些进程呈现出 “树状” 关系;

(3)容器内 pid为1的进程为容器主进程;

(4)一旦容器主进程退出,容器内所有进程退出。

其实,在 Docker 1.3 之前还不支持 docker exec 的时候,以上观点鲜有不妥,但是现在的情况却已然不同,且看下图:

2. docker exec 原理与容器日志



简述上图中 docker exec 的原理可以理解为以下两个步骤:

  • Docker Daemon 创建一个用户指定的进程 /bin/bash,因此 /bin/bash 的父进程为 Docker Daemon
  • Docker Daemon 为进程 P5 设定限制,如:加入容器主进程 P1 所在的隔离环境(namespaces),与其他进程一样受到资源限制(cgroup)等

观察上图,分析原理,不难发现,容器内部的进程关系已然不是树。然而,为什么总是强调 “树状” 关系呢?

答案是:树状的继承关系,有利于容器管理。以上文《docker logs实现剖析》中卖的关子 “docker exec 的标准输出不会作为容器日志” 为例,Docker Daemon 创建容器主进程时,负责接管主进程的标准输出,从而保证容器主进程下所有进程的标准输出被接管,然而 Docker Daemon 在新创建 docker exec 所需执行的进程时,后者的标准输出并未与容器主进程作关联,也并未被 Docker Daemon 特殊处理,故 docker exec 所执行进程的标准输出不会进入容器的日志文件中。

虽然 docker exec 所执行的进程也是容器的一部分,但是更准确的理解 Docker 容器的日志,可以是这样子的:Docker 容器的日志只负责应用本身的标准输出,不包括 docker exec衍生进程的标准输出。

虽然本文标题与日志相关,但是几乎都在谈论 docker exec,既然说到,不妨在这个屡试不爽的命令上提个醒:

  • docker exec 完成容器内外的交互,但希望完成大量标准输出时需谨慎
  • 每次 docker exec,Docker Daemon 均会记录一次 execID,切忌过于频繁

从描述 docker exec 的原理到引入容器日志的一些小 trick,再加上前文的 docker logs 分析,相信很多人都会觉得对 Docker 容器的日志有了一个较为完整的认识。

然而,笔者却有不同的看法。应用 Docker 化之后,日志依然是一件非常棘手的事。笔者认为:容器内部日志文件 app.log 与 docker logs 依然无法满足传统模式下对日志的需求。

欢迎关注Docker源码分析公众号

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-13 16:08:50

docker exec 与容器日志的相关文章

docker exec重启容器内部服务遇到的问题

起因:因为更改ldap域名,老的ldap服务器还是不断有请求发过来,经过排查发现是虚拟机的nslcd发过来的请求,但是nslcd服务配置中配置的是域名而不是ldap的ip地址,试了一下,重启服务才能去连接新的ldap服务,但是由于虚拟机众多,一个一个执行时灰常傻X的,所以打算用docker exec来循环执行,但是执行遇到了问题,如下 [[email protected] ~]# for i in tianpei.wang_172.16.162.105; do docker exec -i $i

Docker 镜像与容器管理(2)

title: Docker 镜像与容器管理(2) date: 2018-12-14 17:04:05 tags: Docker categories: Docker copyright: true --- Docker是基于Go语言实现的开源容器项目,Docker让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化.容器是完全使用沙箱机制,相互之间不会有任何接口,Docker诞生于2013年年初,最初发起者是dotCloud公司.D

docker第二天:管理docker镜像与容器(下)

本次介绍常用的镜像与容器的相关管理命令 一.常用的与镜像相关的命令: 1.了解镜像的制作过程 [[email protected] ~]# docker history centos 2.了解镜底层信息 [[email protected] ~]# docker inspect centos 查看某一具体项信息 [[email protected] ~]# docker inspect -f {{.RootFS}} centos 3.删除本地镜像 [[email protected] ~]# d

docker的镜像 容器 仓库

docker镜像与容器 ##docker 下载镜像 docker pull centos ##查看docker里有哪些镜像 docker image ##创建容器 docker run -p 8080:8080 -d centos [-d :后台运行 ]不加-d 会一直显示 只能另开终端stop掉[ -p :绑定本机端口和容器端] ##查看docker正在运行的容器 docker ps ##查看docker的运行日志 docker logs -f 容器id[-f :动态显示容器运行日志]不加-f

Docker 容器日志的那些事儿

如果时光可以倒流,现实世界的每一步都可以分解到最小,记录下来,就是日志,万物即日志. 面对历史,审视日志,可以选择忘却,也可以选择铭记:经历过的,可以选择珍藏,同样也可以让它尘封. Docker容器又何尝不是?日志就像一根时间轴,你在或者不在,他都在那.有人对其善意,有人却对其随意.如若不信,可以回忆,自己是否善待Docker容器的日志. 1.传统应用的日志 如若不是被过去伤得太深,踏入一个新的世界,应该还是会怀念过往的吧.新世界的"诱惑"与崭新的节奏,相信依旧无法掩盖旧世界的铅印.数

【docker】docker部署spring boot服务,但是docker logs查看容器输出控制台日志,没有日志打印,日志未打印,docker logs不打印容器日志

如题: docker部署spring boot服务,但是docker logs查看容器输出控制台日志,没有日志打印,日志未打印,docker logs不打印容器日志 场景再现: docker部署并启动了  springboot服务,容器启动正常,docker exec 也可以正常进入容器内部,但是docker logs 控制台并没有日志打印出来. 同样的,/var/lib/docker/containers目录下的对应容器目录中,也没有对应的 *-json.log日志文件生成. 原因: dock

【Docker常见问题2】如何设置容器日志大小和保留个数

举例:当tomcat容器的运行,容器占用空间越来越大,约1个月就会超过2G,如何解决? 步骤1:查看容器日志大小:假设容器目录为/var/lib/docker/containers,那么执行如下命令 cd /var/lib/docker/containers  #进入默认容器空间目录 du -sh *            #统计文件大小2.4G  de92a5643f7ffb106f8abba21fc0f93996842917a52879153adc95a73312934a-json.log

日志系统之基于flume收集docker容器日志

最近我在日志收集的功能中加入了对docker容器日志的支持.这篇文章简单谈谈策略选择和处理方式. 关于docker的容器日志 docker 我就不多说了,这两年火得发烫.最近我也正在把日志系统的一些组件往docker里部署.很显然,组件跑在容器里之后很多东西都会受到容器的制约,比如日志文件就是其中之一. 当一个组件部署到docker中时,你可以通过如下命令在标准输出流(命令行)中查看这个组件的日志: docker logs ${containerName} 日志形如: 但这种方式并不能让你实时获

Docker容器日志清理

前言 最近发现公司Gitlab服务器磁盘满了,经排查发现是docker容器日志占用了几十个G容量,那么这些日志怎么去查看和清理呢? 本节主要讲到的知识点如下: (1)Docker容器日志路径 (2)如何清理Docker容器日志 (3)如何从根本上解决Docker容器日志占用空间问题 Docker容器日志路径 在linux上,容器日志一般存放在/var/lib/docker/containers/container_id/下面,以json.log结尾的文件(业务日志).如下: 如何清理Docker