docker
Docker简介
Docker 就像一个盒子,里面可以装很多物件,如果需要某些物件,可以直接将该盒子拿走,而不需要从该盒子中一件一件的取。
Docker 包括三个基本概念:
镜像(Image)
Docker的镜像概念类似于虚拟机里的镜像(比如.ISO文件),是一个只读的模板,一个独立的文件系统,包括运行容器所需的数据,可以用来创建新的容器。
例如:一个镜像可以包含一个完整的 ubuntu 操作系统环境,里面仅安装了MySQL或用户需要的其它应用程序。
这里的镜像就如下方虚拟机创建时候使用的镜像类似。这个镜像便于移动,并且这个镜像我们可以交给任何人使用,其他人使用的时候也很方便,只需要将其实例化即可。
容器(Container)
Docker容器是由Docker镜像创建的运行实例,类似VM虚拟机,支持启动,停止,删除等。
每个容器间是相互隔离的,容器中会运行特定的应用,包含特定应用的代码及所需的依赖文件。
容器就类似与虚拟机中我们创建好的虚拟机系统,之后我们所有的操作都是在容器中进行的,我们的程序也是运行在容器中。
仓库(Repository)
镜像便于传播,而仓库就是专门用来传播这些镜像的地方,他有点类似与Github,或者你可以把他看成一个存放各种镜像的镜像商店
Docker官方的仓库: 他的服务器处于国外,所以下载速度较慢,不过我们可以通过换源解决。
daocloud国内仓库: 国内也有一些优秀的商店,他和Docker官方的仓库的区别类似与Github和Gitee的区别。
网易云镜像中心
sdn.net/qq_39611230/article/details/108641842
Dockerfile 是什么?如何使用它?
Dockerfile 是一个文本文件,包含了一系列用于构建 Docker 镜像的指令。通过编写 Dockerfile,您可以定义镜像的构建过程,包括基础镜像选择、环境变量设置、文件复制、命令执行等。通过运行
# 写一个dockerfile 是的,你可以在容器中开放多个端口,并且将这些端口一一映射到宿主机上的不同端口FROM ubuntu:20.04EXPOSE 22 # SSHEXPOSE 80 # HTTPEXPOSE 443 # HTTPS# 可以开放多个# docker run -d -p 2222:22 -p 8080:80 -p 8443:443 my_image 多端口映射
清理垃圾:
清理 Docker 中不再使用的容器、镜像和其他资源可以帮助释放磁盘空间并保持系统整洁。以下是一些命令可以用来清理 Docker 垃圾:
- 清理停止的容器:
docker container prune
- 清理无效的镜像:
docker image prune
- 清理未被使用的数据卷:
docker volume prune
- 清理网络:
docker network prune
- 清理所有不再使用的资源(容器、镜像、数据卷和网络):
docker system prune
快速安装docker
陈橘墨 2024-03-20 21:14:25大陆环境下没办法直接curl,部分的地区被屏蔽了陈橘墨 2024-03-20 21:14:44访问https://get.docker.com/,内容保存为install-docker.sh陈橘墨 2024-03-20 21:14:47chmod +x install-docker.sh陈橘墨 2024-03-20 21:14:57./install-docker.sh --mirror Aliyun陈橘墨 2024-03-20 21:15:13就能获得丝滑顺畅的安装体验了
安装docker-compose
docker-compose up -d # 创建并启动所有服务(常用)docker-compose build # 容器镜像创建(没启动)docker-compose stop # 关闭所有服务Docker-compose 是一个用来把 docker 自动化的东西。有了 docker-compose 你可以把所有繁杂重复的 docker 操作全都一条命令,自动化的完成。Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,你可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。文件名:docker-compose.ymlYML
# 指定该文件版本version:'3'# 把每个子目录视为一个镜像,开始构建services: web1: # 此处仅允许 image, build, ports,禁止其他字段出现,如果有 volume,cmd 等设置需求,请在 Dockerfile 里进行文件拷贝或者申明。 image:ctf/test1#镜像名字 build:./web/#build的位置,docker会去web1中的dockerfile开始搭建 # restart: always ports: -"5555:80"#设置映射的断口 environment: -FLAG=flag{
this_is_test_flag}
# 这里定义了flag,但是不会覆盖sh里的$FLAG # - FLAG=flag{
$(cat /proc/sys/kernel/random/uuid)} # 获取容器的uuid作为flag 会报错 - version
说明了 yml 文件指明的版本号,一般我们使用 2,3 这两个版本。- services
yml 文件的主体,定义了服务了配置。里面的 web 标签是我们自己定义的。
build 表明了以 dockerfile 类型启动一个容器,后面跟的是 dockerfile 的路径,支持相对路径和绝对路径,在这个 yml 文件里面,表明 dockerfile 与 yml 处在同个目录下。
容器的启动可以根据已有的镜像,如果定义了 image 这个标签,就会从本地搜寻相关镜像构建容器,如果本地找不到相关的镜像,就会从网上数据库搜寻相关的镜像。
但大家可能会产生疑问了,这里我们定义了 build 还有 image 两个不同的标签来构建镜像,那么容器到底要用 build 还是 image 来构建呢,这种情况下将按照 dockerfile 的方式来构建镜像,并且把镜像的名称定义为 image 标签里面的名称。
- environment
构建了相关的环境变量,在这里我们是定义了一个 FLAG 环境变量,并且值为 flag{this_is_test_flag}
定义之前要删除 shell文件中的定义变量,否则会报错 - ports
定义了映射的端口,5555:80 表示映射到本机的 5555 端口,后面的 80 端口则要与 Dockerfile 文件中 EXPOSE 的端口保持一致。
Docker 使用
文件名:Dockerfile
FROMubuntu:16.04LABEL Author="Ztop"LABEL Blog="https://www.zeker.top"ENVREFRESHED_AT 2022-03-01ENVLANG C.UTF-8# 先写 修改源/更新 【如果必须的话】# 替换源(这里可用sed或者直接COPY一个完整的sources.list来替换)RUN sed -i s@/deb.debian.org/@/mirrors.aliyun.com/
@g /etc/apt/sources.list && \ sed -i s@/security.debian.org/@/mirrors.aliyun.com/
@g /etc/apt/sources.list && \ apt-get update -y#防止Apache安装过程中地区的设置出错ENVDEBIAN_FRONTEND noninteractive#安装apache2RUN apt-get install apache2 -y#安装phpRUN apt-get install php -yRUN apt-get install libapache2-mod-php -y --fix-missingRUN apt-get install php7.0-mysql -y# #安装mysql# RUN apt-get install mysql-server -y# RUN apt-get install mysql-client -y# 然后才是复制文件,不推荐挂载卷# ADD会自动解压压缩包,而COPY不会# ADD html.tgz /var/www#将题目源码放进去RUN rm -rf /var/www/html/index.htmlCOPY ./src/ /var/www/html/ WORKDIR /var/www/html/#启动脚本COPY ./run.sh /root/run.shRUN chmod +x /root/run.shENTRYPOINT ["/root/run.sh"]#设置环境变量#ENV FLAG=flag{
test_flag}
#暴露端口EXPOSE 80
构建运行
docker build -t ctf:v1 . # dockerfile目录下输入构建命令,用来构建基于ubuntu:16.04的自定义镜像。 docker run -d -p 5555:80 -e FLAG=flag{
$(cat /proc/sys/kernel/random/uuid)} 镜像id # 添加系统docker run -d --name <容器名称> <镜像名称>:<标签>uuid作为动态flag字段docker ps # 查看是否运行docker exec -it 容器id /bin/bash # 进入容器exit # 在容器内退出
拉取查看篇
1
2
3
4
5
6
7
8
docker pull ubuntu:16.04 # 拉取对应镜像
docker images # 查看当前系统中存在镜像
docker ps # 查看运行中的容器
docker ps -a # 查看所有容器(包括已结束运行的)
docker cp 主机文件名 容器id:容器指定目录 # 将主机文件复制到指定位置,反之则交换位置
停止删除篇
docker stop 容器id #停止指定容器docker stop $(docker ps -a -q) #停止所有已经运行的容器startdocker rm 容器id #删除指定容器,删除前先停止docker rm $(docker ps -a -q) #删除所有已经停止的指令docker rmi 镜像id # 删除指定镜像docker rmi -f $(docker images-q) 删除全部 -f 强制
进入退出容器篇
1
2
3
# docker exec -it 容器id /bin/bash # 进入容器的bash界面
docker attach 容器id # 进入容器内部
exit # 进入docker内部后退出容器
之前的 docker exec -it ID /bin/bash 其实并没有进入这个容器,而是弹了一个 bash 出来让我们能在容器里操作,而 attach 才算进入了容器内部。
查看相关配置
1
2
3
4
docker port 容器id # 查看容器映射端口
netstat -tlnp # 查看主机开放端口
systemctl status firewalld # 查看防火墙状态
systemctl stop firewalld # 暂时关闭防火墙
导出导入篇
1
2
3
4
docker export 容器id > ctf.tar # 导出为tar文件
docker save 镜像name > ./ctf.tar # 将→指定镜像名←保存成 tar 归档文件
cat ctf.tar | docker import - ctf # 可以这样导入
docker load<ctf.tar # 载入镜像包
小 Tip:
- docker save 保存的是镜像(image),docker export 保存的是容器(container);- docker load 用来载入镜像包,docker
import 用来载入容器包,但两者都会恢复为镜像;- docker load 不能对载入的镜像重命名,而 docker
import 可以为镜像指定新名称。 若导入时出现这个问题 open /var/lib/docker/tmp/docker-import-970689518/bin/json: no such file or directory,说明这个 tar 包缺少 docker 所需要的一些 json 文件,不能直接导入。Docker network ls 查看网络Docker network rm 删除网络
docker 网络模式
Docker 提供了几种不同的网络模式,每种模式有不同的用途和适用场景。以下是 Docker 支持的主要网络模式:
bridge(桥接模式):
- 默认的网络模式。
- 每个容器会连接到一个虚拟的网络桥接设备(
docker0),并分配一个私有 IP 地址。 - 容器之间可以通过私有 IP 地址相互通信,但对外部网络是隔离的,通常通过端口映射暴露服务。
host(主机模式):
- 容器直接使用宿主机的网络堆栈。
- 容器没有自己的虚拟网络接口,而是共享宿主机的网络接口。这意味着容器与宿主机之间没有隔离,它将使用宿主机的 IP 地址和端口。
- 适合高性能、低延迟需求的场景,但没有网络隔离。
none(无网络模式):
- 容器不会连接到任何网络。
- 容器无法访问网络,除非手动配置网络接口。通常用于特殊用途,例如完全隔离的容器或不需要网络的应用。
container:(容器模式):
- 让一个容器共享另一个容器的网络堆栈。
- 共享容器的网络配置,包括 IP 地址、端口等。容器间通信就像是在同一网络中一样,不需要额外的网络配置。
- 适合那些需要直接与另一个容器进行通信的场景。
overlay(覆盖网络模式):
- 用于多主机 Docker 集群,通常配合 Docker Swarm 或 Kubernetes 等工具使用。
- 容器可以跨多个 Docker 主机通信,Docker 会自动在主机之间创建一个虚拟的网络覆盖层,容器之间能够像在同一网络中一样通信。
- 需要 Docker 的集群管理工具(如 Swarm 或 Kubernetes)支持。
macvlan(MACVLAN 模式):
- 为容器分配一个独立的 MAC 地址,并将其视为物理网络上的独立设备。
- 适用于需要容器直接与宿主机网络进行通信的场景。容器通过 MAC 地址与其他设备进行通信,容器之间的隔离性较低。
- 可以用于需要与外部网络直接交互,或需要将容器暴露到宿主网络中的情况。
ipvlan(IPvlan 模式):
- 是一种基于 IP 地址的网络模式,与 macvlan 相似,但提供更细粒度的 IP 管理。
- 比 macvlan 更加灵活且高效,适合需要通过多个子网进行容器通信的场景。
- 容器和宿主机共享网络堆栈,但容器通过虚拟的网络接口进行通信。