对docker学习进行的小总结
因为打CTF pwn题的时候,经常遇见本地程序的libc与远程服务器那边程序所依赖的libc不匹配的情况,尽管可以用patchelf和glibc-all-in-one来给程序patch一个libc。但是patchelf似乎有点小bug,为了防止比赛的时候在这个地方掉链子,因此可以采用在docker里跑不同版本的ubuntu。
本文是对我学习docker做了一个简单的小总结。
什么是docker?
docker是一种容器技术,它提供了一种便利的打包机制,这种机制直接打包了应用运行所需要的整个操作系统,从而能够保证本地环境(开发环境)和生产环境(运行环境)的高度一致。
镜像和容器
镜像与容器的关系有点像类与对象的关系,镜像是一个静态概念,容器是一个运行时概念,容器是镜像的实例。通俗的讲,镜像就是放在硬盘上的,而容器是基于镜像跑起来后的东西
我感觉上述内容写的很好,因此上述内容转自 https://www.cnblogs.com/haoliuhust/p/15255577.html
docker安装
一条命令安装docker:
sudo curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun
如果没有安装curl的话,先安装curl:
sudo apt-get install curl
ubuntu不同版本对应默认libc:
需要什么版本libc,接下来下载对应的版本镜像即可
22.04---->2.35-0ubuntu3
21.04---->2.33-0ubuntu5
20.04---->2.31-0ubuntu9.7
21.10---->2.34-0ubuntu3.2
18.04---->2.27-3ubuntu1.5
下载镜像
roderick师傅编译了很多版本的镜像,在下面这个链接下载(使用roderick师傅的镜像,运行起来的容器里面要用gdb.attach的话,需要指定终端tmux,roderick师傅把一些快捷键给改了,具体请在容器里输入cat ~/.tmux.conf 来查看)
https://hub.docker.com/r/roderickchan/debug_pwn_env/tags
点这个,然后直接粘到虚拟机上就开始下载了(注意权限问题)。
我简单说一下这个docker是咋用的
刚刚下载下来的镜像,要实例化成容器(也就是让容器运行起来)。当容器运行起来之后,我们就相当于有了"另一个版本的ubuntu"。如果你想退出它可以用exit,此时它依然是运行状态,如果你停止了一个容器,那么此时它处于停止状态,不过不管是你exit还是stop还是关机,容器依然存在(里面你新下载的文件也存在),可以使用start开启停止状态的容器,如果删除了容器,则里面你新下载的文件会消失(容器原本的文件不会消失)
查看镜像或者容器
查看所有容器
sudo docker ps -a
查看正在运行的容器
sudo docker ps
查看已有镜像:
sudo docker images
启动容器
这意味着是在把一个镜像给实例化(除非删除,不然启动的容器不会消失(即使主机重启,或者输入stop,或者exit)
sudo docker run -it IMAGE ID /bin/bash
启动已停止的容器(启动被stop暂停的容器)
sudo docker start CONTAINER ID
进入容器&&退出容器
进入容器的前提是容器必须启动(也就是用docker ps可以看到容器),如果容器处于了停止状态,需要用docker start将其启动,然后再进入容器.
下面两个命令都可以进入容器,二者区别在于前者使用之后执行exit会顺便把容器停止,而后者执行exit,容器依然在运行。
sudo docker attach CONTAINER ID
sudo docker exec -it CONTAINER ID /bin/bash
如果要以root权限进入容器的话,命令如下
sudo docker exec -it -u root CONTAINER ID /bin/bash
退出容器执行exit
即可,只要容器被启动,则输入上述命令就能再次进入。
删除镜像或者容器
删除指定的容器
sudo docker rm -f CONTAINER ID
下面的命令可以清理掉所有处于终止状态的容器。
sudo docker container prune
删除所有镜像(如果被实例化的镜像是不能删除的)
sudo docker system prune -a
停止容器
请注意停止容器和删除容器的区别:停止容器,仅仅是用docker ps查看不到了(因为他不再运行了,但它依然存在,只不过属于停止状态,用docker ps -a可以查看到)
停止容器
sudo docker stop CONTAINER ID
将文件从主机复制到docker
sudo docker cp file CONTAINER ID:Destination_directory
挂载命令
可以通过挂载的方式来让宿主机和Docker直接来共享文件。(下面这个方法只适用于创建新的容器时同时创建共享目录,不适于后期添加共享目录)
创建容器时执行Docker Volume
docker run -itd --volume /tmp/source:/tmp/destination --name test ubuntu/nginx bash
示例:
sudo docker run -it --volume /home/hacker/Desktop/ROPgadget:/home/roderick/ROPgadget --name test roderickchan/debug_pwn_env:22.04
解释:将本机上的ROPgadget文件复制到容器里面,命名为test。
本人也只是刚开始接触docker的使用,如果上述理解又什么问题,欢迎各位师傅斧正,如果以后用到了docker的其他用法,我会更新这篇文章。
下面为后来的更新部分:
NAMES有些地方可以代替CONTAINER ID
上面的命令我一直以为 CONTAINER ID要输入下面这个东西才行
刚才我试了一下发现也可以输入NAMES来代替,也就是下面这个东西。
以启动这个glibc2.33的容器举例,重新启动docker的时候,输入 sudo docker start glibc2.33即可。
容器的重命名
如果最开始创建容器的时候没有进行命名,那么就会随机给这个容器分配一个名字,之后可以通过下面这个命令给容器重命名(docker1为容器原本的名字,docker2为容器的新名字)
sudo docker rename docker1 docker2
PS:我个人觉得如果往容器里下载了一些文件,平常不用了就stop就ok了,只要不把这个容器删了,下回使用容器,直接start比较方便(不用重新实例化镜像)