镜像与容器
要学习docker就必须先理解这两个概念,镜像与容器
1.镜像:可以认为是超轻量级的虚拟机快照
2.容器:可认为是超轻量级的虚拟机,是镜像运行起来所处的可读写的状态;容器里面可安装,运行程序,还可以把安装好的程序存储起来打包成新的镜像;一个容器通常只运行一个程序
docker相关命令
安装:
sudo apt install docker.io
查看docker的信息:
sudo docker info
启动:
sudo systemctl start docker
重启:
sudo systemctl restart docker
停止:
sudo systemctl stop docker
查看运行状态:
sudo systemctl status docker
docker镜像相关命令
查看所以后下载的镜像:
sudo docker images
搜索镜像
sudo docker search 镜像名称
获取镜像
sudo docker pull 镜像名称
运行镜像
sudo docker run -d --name 容器名称 -p 80:80 镜像名称
- -d:后台运行
- –name:容器名称(自己命名)
- -p指定docker运行此镜像所使用的端口,第一个是宿主机的端口,第二个是容器端口
- -privileged:使用该参数,容器内的root拥有真正的root权限
- -i:以交互模式运行容器
- -t:为容器重新分配一个伪输入终端
- -link 其他容器:将该容器与其他容器进行连接
删除镜像
sudo docker rmi IMAGE-ID/name
其中,IMAGE-ID可在镜像列表中查看;只需使用前四位id即可;也可以使用镜像的名字
更换下载源
docker默认源为国外官方的,下载速度较慢;更新源:修改或新增/etc/docker/daemon.json:
vi /etc/docker/daemon.json
写入:
{
“registry-mirrors”:[“http://hub.mirror.c.163.com"]
}
再重启即可
docker容器相关命令
查看容器列表
sudo docker ps -a
停止容器
sudo docker stop CONTAINER-ID/name
其中,CONTAINER ID可在容器列表中查看;只需使用CONTAINER ID前四位即可;也可以使用运行镜像时所命名的容器名字
运行容器
sudo docker start CONTAINER-ID/name
当自定义名字的容器正在运行
,不能用重复的名字
删除容器
sudo docker rm CONTAINER-ID/name
进入容器
sudo docker exec -it CONTAINER-ID/name /bin/bash
退出:
exit 或者 Crtl+D
添加docker权限给当前用户
上述命令都需要sudo,有些麻烦,直接使用下面这条命令:
sudo usermod -aG docker 当前用户名
自定义镜像
将容器提交成一个镜像:
docker commit CONTAINER-ID/name 镜像名称
使用dockerfile
dockerfile相当于镜像的配置文件;可以通过写一个dockerfile,之后编译这个文件来创建一个自定义镜像,编译命令:
docker build -t 镜像名称.
dockerfile中的一些指令:
- FROM:from debian:stretch表示以debian:stretch作为基础镜像进行构建
- RUN:RUN后面跟着执行的shell命令
- ARG:可以进行一些宏定义,比如ENV JAVA_HOME=/opt/jdk,之后RUN后面的shell命令中的${JAVA_HOME}都会被/opt/jdk代替
- ENV:在shell中设置一些环境变量
- FROM…AS…:给这个阶段的镜像起个别名:FROM…(基础镜像)AS…(别名),在后面引用这个阶段的镜像直接史依弘别名就可以了
- COPY:复制文件,COPY ./root/workspace/agent表示将当前文件夹的所以后文件拷贝到容器的/root/workspace/agent文件夹中。通过–from参数也可以从前面阶段的镜像中拷贝文件过来,比如–from=builder表示文件来源不是本地文件系统,而是之前的别名为builder的容器
- WORKDIR:在执行RUN后面的shell命令前会先cd进WORKDIR后面的目录
- ENTRYPOINT:这个参数表示镜像的“入口”,镜像打包完成之后,使用docker run命令运行这个镜像时,其实就是执行这个ENTRYPOINT后面的可执行文件(一般是一个shell脚本文件),也可以通过[“可执行文件”,“参数1”,“参数2”]这种方式来赋予可执行文件的执行参数,这个“入后”执行的工作目录
使用dockerfile部署题目
以De1CTF的SSRF Me这道题的dockerfile为例:(https://github.com/De1ta-team/De1CTF2019/blob/master/writeup/web/SSRF%20Me/docker.zip)
1.将dockerr.zip下载下来,解压打开,里面有一个dockerfile文件和一些源码文件 2.查看dockerfile文件:
FROM tiangolo/uwsgi-nginx-flask:python2.7
WORKDIR /app
COPY ./ssrf_me /app
RUN mv /app/sources.list /etc/apt/sources.list
RUN apt-get update && apt-get install -y sudo
RUN python2 -m pip install flask
RUN sudo uwsgi -d /app/uwsgi.ini
根据第三步COPY ./ssrf_me /app,可以得出dockerfile需要在ssrf_me目录外执行,那么先新建一个文件夹ssrf,将dockerfile文件和ssrf_me文件夹移动到里面,结构如下:
┌─(~/桌面/ssrf)──────────────────────────────────(gtfly@ubuntu:pts/0)─┐
└─(10:09:12)──> tree ──(四,8月08)─┘
.
├── dockerfile
└── ssrf_me
├── app.py
├── code.txt
├── flag.txt
├── requirements.txt
├── sources.list
└── uwsgi.ini
1 directory, 7 files
之后在dockerfile目录下执行:
docker build -t ssrf .
执行成功后即可找到这个ssrf镜像:
docker images
运行这个镜像:
docker run -d -name ssrfme -p 100:80 ssrf
之后在本地浏览器访问127.0.0.1:100即可
docker-compose的安装与使用
dockerfile记录单个镜像的构建过程,docker-compose.yml记录一个项目(多个镜像)的构建过程
安装:
sudo apt install docker-compose
运行yml(在docker-compose.yml目录执行):
docker-compose up -d
列出所有运行容器:
docker-compose ps
查看服务日志:
docker-compose logs
启动指定服务已存在的容器(不加名称的话则启动所有容器,下同):
docker-compose start 容器名称
停止已运行的服务的容器:
docker-compose stop 容器名称
删除指定的服务的容器:
docker-compose rm 容器名称
使用docker-compose.yml部署题目
以De1CTF ShellShellShell这道题的docker-compose.yml为例:https://github.com/De1ta-team/De1CTF2019/tree/master/writeup/web/ShellShellShell/dockerfile
下载解压后,在docker-compose.yml目录下执行:
docker-compose up -d
之后,查看容器:
└─(11:10:08)──> docker-compose ps ──(四,8月08)─┘
Name Command State Ports
dockerfile_getshell_1 /bin/bash Up 80/tcp
dockerfile_jaivyweb1_1 bash /run.sh Up 0.0.0.0:11027->80/tcp, 8080/tcp
那么在本地浏览器访问127.0.0.1:11027即可
有时候docker-compose的版本不符合docker-compose.yml里的version,搭建的时候会报错,这时候就要更新docker-compose的版本了,可以使用pip安装并指定版本:
pip install docker-compose==1.23.2
(测试发现version=’2.4’适用,其他不清楚)
参考链接:
https://blog.csdn.net/qq_33256688/article/details/80319673