容器非常适合封装软件,但是有时一味地改造容器镜像以使其尽可能小时,您可能走得太远。我们需要在“简洁”的镜像和无法调试的镜像之间找到很好的平衡。看到人们调试正在运行的容器的正常方法是
docker exec -it
$ CONTAINER sh
并根据需要在容器中安装调试工具。但是,如果您的容器没有/ bin / sh怎么办?如果没有包管理器怎么办?您可以使用docker cp将实用程序复制到容器中,然后将exec复制到正在运行的容器中,但这也很麻烦。
因此,一个朋友最近没有询问如何从容器中进行调试,而是询问如何从其他容器中进行调试。我没有那么聪明,所以我在网上问了很多聪明的人,并得到了很好的答复。
我们创建一个只有caddy的精简容器。
首先下载/提取caddy二进制文件
$: curl https://getcaddy.com | bash -s personal && mv /usr/local/bin/caddy .
然后创建一个Dockerfile将二进制文件复制到临时容器中。
FROM scratch
ADD caddy /
构建容器并运行caddy
$: docker build -t caddy .
<output trimmed>
现在运行这个容器
$: docker run -d --name caddy -p 2015:2015 caddy /caddy
现在caddy正在运行发布端口2015(目前提供404页面,因为没有内容,但没有关系)。您如何调试容器?caddy并没有bug,这不是您所需要的。 :)但出于假设的原因。
许多人建议使用--link,但这只会将容器放在同一网络上。不是相同的名称空间,而是在同一虚拟网络上彼此连接。
$: docker run -it --rm --link caddy:caddy alpine sh
/ # ping caddy -c 1
PING caddy (172.30.238.2): 56 data bytes
64 bytes from 172.30.238.2: seq=0 ttl=64 time=0.075 ms
/ # ps aux
PID USER TIME COMMAND
1 root 0:00 sh
8 root 0:00 ps aux
其他人建议使用--volumes-from,但这不能使您将工具安装到现有的运行容器中,除非该运行容器正在导出卷并且该卷已经在$ PATH中。
相反,我们将使用所需的所有工具(在本例中为strace)构建一个单独的容器,并在与原始容器相同的pid和网络名称空间中运行它。
首先使用strace创建一个调试容器
FROM alpine
RUN apk update && apk add strace
CMD ["strace", "-p", "1"]
构建容器
$: docker build -t strace .
<output trimmed>
现在,在相同的pid和网络名称空间中运行strace容器。
$: docker run -t --pid=container:caddy \
--net=container:caddy \
--cap-add sys_admin \
--cap-add sys_ptrace \
strace
strace: Process 1 attached
futex(0xd72e90, FUTEX_WAIT, 0, NULL
附加的strace到caddy进程,并在执行时跟随它。
很好,但我们也可以使用远程容器的根文件系统(不是很多)。这次,我们将使用alpine 镜像并再次在相同的pid和网络名称空间中启动一个shell。
$: docker run -it --pid=container:caddy \
--net=container:caddy \
--cap-add sys_admin \
alpine sh
我们现在可以看到caddy 运行如下:
/ # ps aux
PID USER TIME COMMAND
1 root 0:00 /caddy
13 root 0:00 strace -p 1
34 root 0:00 sh
40 root 0:00 ps aux
caddy容器文件系统位于/ proc / 1 / root中
/ # ls -l /proc/1/root/caddy
-rwxr-xr-x 1 root root 16099400 Jan 24 15:30 /proc/1/root/caddy
将此容器附加到原始容器后,我们可以进行更多调试。您仍然可以调试网络,但请确保使用localhost,因为新的sh进程正在同一网络名称空间中运行
/ # apk update && apk add curl lsof
/ # curl localhost:2015
404 Not Found
/ # lsof -i TCP
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
caddy 1 root 4u IPv6 330044347 0t0 TCP *:2015 (LISTEN)
您所有的标准调试工具都应在第二个容器中运行,而不会污染原始容器。如果遇到错误,请确保检查内核权限(注意strace需要如何--cap-add sys_ptrace但sh容器仅需要sys_admin)
这显然对于go容器或您只需要在不更改容器本身的情况下将一些额外的调试工具引入的任何其他容器很有用。
原文:https://medium.com/@rothgar/how-to-debug-a-running-docker-container-from-a-separate-container-983f11740dc6
编写Dockerfile:在项目根目录新建名为Dockerfile的文件, 并添加以下代码:编写好Dockerfile后, 则可通过docker命令创建一个docker镜像, 以下为参考指令:
Docker中部署tomcat相信大家也都知道,不知道的可以google 或者bing 一下。这里主要是为了记录在我们启动容器之后,tomcat需要直接定位到网站信息,而不是打开域名之后,还得加个blog后缀才能访问到我们的网站首页。
当你最后投入容器的怀抱,发现它能解决很多问题,而且还具有众多的优点:第一:它是不可变的 – 操作系统,库版本,配置,文件夹和应用都是一样的。
随着开发过程中自动 UI 测试的兴起,无头浏览器已变得非常流行。网站爬虫和基于 HTML 的内容分析也有无数的用例。在 99% 的场合下,你实际上不需要浏览器 GUI,因为它是完全自动化的
在容器安全方面,有很多使用开源工具阻止安全灾难的故事,例如前不久发生的特斯拉 Kubernetes 集群入侵事件。容器的安全性一直是一件很棘手的事情,因此如何巧妙使用开源工具就成为一件重要的事情。
当我们使用 traefik 反向代理和自动服务发现后,我们对集群内部的服务分为两类:公有服务。如我的博客,网站,以及为它们提供服务的 API。我们可以通过公有的域名去映射服务使得外网能够访问
Docker 变得越来越流行,它可以轻便灵活地隔离环境,进行扩容,运维管理。对于业务开发者而言,随着持续集成的发展,对代码质量及快速迭代的要求也越来越高。对于前端而言,在 CI 环境中使用也更容易集成开发,测试与部署。
所以我们可以通过修改docker compose的配置文件来完成我们的需求。熟悉Docker的都应该知道容器运行时其内部会有一个端口以映射到我们外部的端口,我们需要固定的就是这个外部端口。
虚拟化和容器化是项目云化不可避免的两个问题。虚拟化由于是纯平台操作,一个运行于linux操作系统的项目几乎不需要做任何改造就可以支持虚拟化。而项目如果要支持容器化则需要做许多细致的改造工作。
本篇内容非常简单,讲述了如何快速在 Docker 上部署一个 Jenkins 实例,避免多采坑,浪费不必要的练习时间。
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!