Docker从0到1
0x00 写在前面
安装docker
安装docker-compose
docker简介
0x01 Docker常用命令
以下命令均在root下
启动docker
1 | service docker start |
查看当前镜像列表
1 | docker images |
导入镜像
1 | docker import [options] file|URL|- [REPOSITORY[:TAG]] |
导出镜像
1 | docker export [OPTIONS] CONTAINER |
进入镜像的终端
1 | docker run -t -i music:centos /bin/bash |
网络端口映射
1 | docker run -d -p 1001:80 music:centos /run.sh |
删除容器进程
1 | docker rm -f ID |
查看所有容器
1 | docker ps -a |
查看正在运行的容器
1 | docker ps |
docker停止一个容器
1 | docker stop 容器ID |
开启以关闭容器
1 | docker start 容器ID |
删除镜像
1 | docker rmi 镜像ID |
使用dockerfile
1 | docker build . -t test-mysql |
进入一个以开启的容器
1 | docker exec -it 容器ID /bin/bash |
从宿主机复制文件到容器
1 | docker cp 本地文件 容器ID:路径 |
1 | docker search [keywords] 搜寻与keywords相关的镜像 |
0x02 实例
下面以一道ctf为例
搜索环境镜像
1 | docker search lamp |
拉取环境需要的镜像
1 | docker pull tutum/lamp |
用镜像创建容器
1 | root@test:~# docker run -d -p 8888:80 tutum/lamp |
上传本地文件到容器
1 | docker cp /home/test/2019JNUCTF/Web/easyupload/ cb0bc63b1ebbec1258c9eb:/var/www/html |
访问 ip:8888/easyupload
成功。
0x03 Dockerfile
我们可以把构建一道题目的过程分为以下具体三步。
- 指定具体要使用的镜像
- 启动镜像,构建一个容器
- 移入相关的源码,构建容器里面的环境配置
在上面的实例中,我们第三步里面需要进行的操作只有把源码移入/var/www/html文件夹里面而已,但如果环境配置较为复杂,比如需要构建数据库,安装各种插件等,第三步需要的时间就太长了。如果我们改变下上面的步骤。变成: - 指定使用的镜像
- 配置相关的环境,移入相关的代码
- 根据第二步的内容,把这些操作以类似于代码,程序的模式写入一个模板,让Docker根据这个模板来生成新的镜像
- 根据这个新的镜像来生成新的容器
如果是这么操作的话,带来的好处就是可以方便的构造出一个针对性的镜像。配置题目的时候,我们只需要根据这个我们创作的模板生成特制的镜像,直接按照这个镜像就可以直接生成环境了。这个需要的模板就是Dockerfile
。Dockerfile
是一个包含用于组合映像的命令的文本文档。可以使用在命令行中调用任何命令。 Docker通过读取Dockerfile
中的指令自动生成映像。docker build
命令用于从Dockerfile构建映像。可以在docker build
命令中使用-f标志指向文件系统中任何位置的Dockerfile
。Dockerfile
一般分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令,#
为 Dockerfile 中的注释。
Docker以从上到下的顺序运行Dockerfile
的指令。为了指定基本映像,第一条指令必须是FROM
。一个声明以#字符开头则被视为注释。可以在Docker文件中使用RUN
,CMD
,FROM
,EXPOSE
,ENV
等指令。
常用指令
FROM: 指定基础镜像,必须为第一个命令
1 | FROM <image> |
MAINTAINER: 维护者信息
1 | MAINTAINER <name> |
RUN: 构建镜像时执行的命令
1 | RUN用于在镜像容器中执行命令,其有以下两种命令执行方式: |
ADD: 将本地文件添加到容器中,tar类型文件会自动解压(网络压缩资源不会被解压),可以访问网络资源,类似wget
1 | ADD <src> ... <dest> |
COPY: 功能类似ADD,但是不会自动解压文件,也不能访问网络资源
CMD: 构建容器后调用,也就是在容器启动时才进行调用
1 | CMD ["executable","param1","param2"] # 执行可执行文件,优先 |
ENTRYPOINT: 配置容器,使其可执行化。配合CMD可省去 application,只使用参数
1 | ENTRYPOINT ["executable","param1","param2"] # 可执行文件,优先 |
LABEL: 用于为镜像添加元数据
1 | LABEL <key>=<value> <key>=<value> ... |
ENV: 设置环境变量
1 | ENV <key> <value> # <key>之后的所有内容均会被视为其<value>的组成部分,因此一次只能设置一个变量 |
EXPOSE: 指定外界交互的端口
1 | EXPOSE <port> [<port>...] |
VOLUME: 用于指定持久化目录
1 | VOLUME ["/path/to/dir"] |
USER: 指定运行容器时的用户名或UID,后续的RUN也会使用指定用户。使用USER指定用户时,可以使用用户名、UID或GID,或者是两者组合。当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户
1 | USER user |
ARG: 用于指定传递给构建运行时的变量
1 | ARG <name> |
ONBUILD: 用于设置镜像触发器
1 | ONBUILD [INSTRUCTION] |