<p style="margin-bottom: 3px;font-size: 18px;font-weight: bold">本文目录一览:</p><ul><li style='margin-bottom: 3px;list-style: none'>
讯享网
1、如何通过vs2017的Dockerfile来生成镜像
如何通过dockerhistory命令来对docker镜像进行反向工程推测它们的Dockerfile,从而在对不同的Docker镜像反向工程获取Dockerfile之后合并成一个。常言道,“不要重复发明轮子!”在使用docker时,最好在构建你自己的镜像前上DockerHub寻找一些直接可以用的。把你的软件架构分布到一系列容器中,每一个容器只做一件事情是非常有用的。构建分布式应用的最好的基石是使用来自DockerHub的官方镜像,因为你可以信任它们的质量。在某些情况下,你可能想让一个容器做两件不同的事情。在另一些情况下,你可能想让一个Docker镜像包含来自两个不同镜像的依赖。如果你有每个镜像的Dockerfile,这是非常简单的。将它们组织到一个Dockerfile里然后build即可。但是,如果大多数时间你都在使用DockerHub上准备好的镜像,你将没有它们的源Dockerfile。我花了一些时间来找这样一个工具,它可以合并(或flatten)两个不同的我没有它们的Dockerfile的Docker镜像。即我在找一个能做下面这件事的东西:image1—–merged_image_12/image2–尽管这个问题在之前的两个进程中被关闭了(1,2),当你想这么做时,这个问题仍然会产生。
[img]在第4节讲解了tomcat镜像的制作与优化,在实际操作过程中其实碰到了不少的问题,结合工作中碰到的问题,讲讲自己在遇到这些问题过程中的调试方法,如果有更好的方法也请各位留言补充。
tomcat的启动命令有很多种,在镜像的启动过程中,我最早使用了catalina.sh start 命令,这个命令在linux机器上是可以正常启动的,那为何在镜像中定义entrypoint的时候就不行呢,原来这个命令是以后台的方式运行的,docker就会变成Exit(0) 状态,就自动退出了。docker镜像需要一个前台的进程一直运行才能保证镜像不会退出,那么这时候就需要运行catalina.sh run了,它会让tomcat镜像一直在前台运行。(打个比方,如果你用虚拟机运行,运行这个命令后,命令行无法输入其他命令,只能ctrl+c终止tomcat的运行)
这一招是我目前用来调试最好用的一招,如有更好的招式烦请留言。tomcat启动一开始遇到各种千奇百怪的问题,前面那个启动的问题还好很多人碰到,搜索下就能解决。比如碰到permission deny,文件不存在这种日志提示问题,有什么好的办法排查呢。最直观的方法就是进入镜像里面去看看文件的权限、文件的路径是否存在。
Docker提供了这样的命令,如下
这里-it 和 /bin/bash 就是以终端命令的方式运行镜像,这样跟SSH到远程Linux机器上效果一样,可以查看文件的权限和文件的路径了。这里增加了–rm,这个参数的作用是退出这个镜像后,容器也会自动删除,方便临时运行镜像。
这里由于我制作的tomcat镜像包含最后的entrypoint命令(由于这个命令最早是有问题的),直接运行上面的命令会报错,导致无法进入容器内部。因此这里建议 调试的时候把entrypoint,cmd这里命令先注释掉重新生成镜像,使用上面的命令进入容器内部调试完成之后再开启entrypoint,cmd 。
首先在项目根目录下添加Dockerfile文件(这里我选用的是简单地nestjs作为例子)
在项目根目录下添加docker-compose.yml
在项目根目录下添加nodemon-docker-debug.json
在package.json中加入docker运行命定及nodejs debug命定
1.首先运行yarn docker(npm run docker)来构建及运行docker 容器
1.项目根目录下新建.vscode文件夹,在.vscode文件夹下添加launch.json
*注意这里的port一定要与你docker-compose.yml设置的debug port保持一致
运行vscode调试工具,如果能够成功连接到docker中的程序,可以在container logs 中看到连接成功的log
接下来尝试断点调试
原文链接
在docker的容器中,不能使用gdb调试程序。经过调查发现是原因是 ptrace: Operation not permitted. 。
上网查找发现是ubuntu的安全设置问题,运行如下命令可以解决:
但仍然提示 ptrace: Operation not permitted.
再次查找 docker ptrace: Operation not permitted. ,发现了docker的一个issues,原因是apparmor的docker profile中限制了ptrace。
通过改变docker profile的状态,可以让gdb正常运行了。
因为Docker技术的火热,因此在工作中我们经常会以容器的方式来运行一个应用。每当容器无法成功运行或者想要对容器中的应用参数、应用配置以及应用启动进行深入研究时,当然希望能够像在宿主机上调试程序一样在容器中调试应用。容器的本质包括应用与应用运行所依赖的环境, 因此首先需要创建一个空壳容器(没有运行应用的应用容器),然后进入容器中调试应用。此处的空壳容器提供了应用运行所需的环境,进而可方便的在其中调试应用。实践环境:Centos7.2+Docker1.12.6。
比较规范的镜像的Dockerfile中通常会有ENTRYPOINT与CMD的定义(Docker官方推荐这样做)。因此容器的启动命令则为ENTRYPOINT所对应的脚本或可执行程序加上CMD中定义的内容。比如elasticsearch的Dockerfile定义的ENTRYPOINT与CMD分别为:ENTRYPOINT [“/docker-entrypoint.sh”] CMD [“elasticsearch”],则创建的容器的启动命令为: /docker-entrypoint.sh elasticsearch ;mysql的Dockerfile:ENTRYPOINT [“docker-entrypoint.sh”] CMD [“mysqld”],则创建的容器的启动命令为: /docker-entrypoint.sh mysqld 。所以想要知道一个容器的启动命令需要首先了解其镜像的Dockerfile中ENTRYPOINT与CMD的定义。如何查看一个镜像的ENTRYPONT与CMD的值呢?一般采用如下两种方式:
上述第一种方式适用于比较规范的镜像,这类镜像通常会提供清晰、具体的Dockerfile。第二种方式适用于各种镜像,尽管是不规范的镜像。通过history、inspect两个命令的任一个均可快速、方便的查看镜像的ENTRYPOINT与CMD的值。
若要调试容器中的应用程序,则需额外的设置实现。docker run命令提供的–entrypoint参数能够覆盖Dockerfile中默认定义的ENTRYPOINT;docker run [OPTIONS] IMAGE [COMMAND] [ARG…]的COMMAND能够替换Dockerfile中定义的CMD。通过上面的示例可以发现,有的镜像的Dockerfile中ENTRYPOINT值为:/docker-entrypoint.sh,CMD为应用的可执行程序;有的镜像的Dockerfile中ENTRYPOINT值为应用的可执行程序,CMD为可执行程序的参数。因此针对不同的镜像想要创建空壳容器其方式是不同的。
容器其实是应用与应用运行所依赖的环境,创建空壳容器即提供了应用所需要的环境,进入此环境中可以调试应用,可以验证应用的各个参数,同样更可以像在宿主机中运行程序一样在此环境中运行应用,区别仅是容器与宿主机的两个环境。上面是对如何在容器中调试应用程序做的一些记录,希望与大家一起讨论、交流,一起学习。
前几天一个小伙伴发邮件问我,他在docker内部使用gdb调试时刻遇到了gdb如下报错信息
ptrace:Operation not permitted
当时我的答复是在docker create或者docker run时刻开启 万精油–privileged参数 。小伙伴的问题就此解决了。
但是事实并非如此简单
Docker借用了linux对进程设置capabilities,而其子进程继承父进程capabilites特性来完成对容器capacities的控制。Docker create和docker run参数中有下面两个参数可以对容器默认的capabilites进行修改:
–cap-add //添加某个capabilites属性 –cap-del //剔除某个默认的capabilites属性
cap-add和cap-del可以设置的参数可以通过下面链接查询到:
但是这并不是问题的全部,对于上述测试程序,如果执行下面命令gdb又有告警出来
虽然依然可以调试,但是我们还是需要搞清楚上述告警的意思。地址随机化是linux一项安全特性,它允许内核进程启动每次加载库的时候都在随机化的分布在进程虚拟内存地址空间上(早期固定的库要加载到固定地方,如果固定地方被占用才加载到别地方。会造成多次加载程序,其库地址都不变。如此有安全隐患)。在gdb调试中gdb默认需要关闭linux的地址随机化功能,可以通过gdb 命令set disable-randomization off关闭。 如果在地址随机化下调试同一段程序,多次run时候可以看到它的运行地址和函数地址不一致,这没有什么太大的问题。问题可以结束一半了
关于gdb 设置地址随机化开关详情见下面链接:
当然上述告警其实也可以不通过gdb设置来完成,可以通过下面介绍的Docker参数可以达成。
Docker默认情况下为每个容器都设置了一个默认的seccom profile。一般情况下无需修改。但是docker依然支持
docker create或者docker run时候通过–security-opt seccomp=xxx参数来设置docker容器的seccomp策略。
xxx可以是一个json格式文件,里面定义了docker容器每个具体的seccomp规则。也可以是字符unconfined表示关闭默认的docker seccomp 规则。
可以通过下面命令彻底关闭docker默认seccomp引入的任何限制
docker run -it –security-opt seccomp=unconfined centos:lastes
在运行上述gdb 调试命令run一个进程,告警信息终于彻底消失了。
Docker设置的seccomp 默认profile规则可以通过如下链接查询到:
本文就不再做详细展开了。
从Linux 2.6.23开始支持这种特性对进程能够使用的系统调用进行控制,如此可以进行一些安全性策略。sandbox就是依赖于此技术。docker梳理了Linux的系统调用,从300+个系统调用中屏蔽掉了44个系统调用,但是又最大程度的不影响正常的应用使用系统。
从Linux 2.1开始支持的特性,将超级用户的权限划分为多个组,每个进程都有一个capabilities属性,子进程从自己的父进程中基础capacities。这个特性和sudo不一样,因为sudo控制粒度太粗;而capabilities控制粒度很精细。linux有一系列的调用可以设置、查看,清除和比较进程的capabilities。可以通过:
man cap_set_flag
来查看这一系列的系统调用。而具体进程的capacities可以通过/proc/$pid/status中:
Capxxx字段看到,本文就不再展开。感兴趣的朋友可以参考

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/159408.html