docker基本使用
Docker从17.03版本之后分为CE和EE两个版本。
(Community Edition,社区版),EE(Enterprise Edition,企业版),一般使用社区版。
首先,需要了解docker的几个概念:
-
镜像(Image):Docker 镜像(Image),就相当于是一个root文件系统。比如官方镜像ubuntu:16.04就包含了完整的一套Ubuntu16.04最小系统的root文件系统。
-
容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
-
仓库(Repository):仓库可看成一个代码控制中心,用来保存镜像。
简单来说,Docker镜像是用于创建Docker容器的模板,容器是独立运行的一个或一组应用,是镜像运行时的实例。如果不理解的话,可以类比虚拟机。镜像就好像是虚拟机快照文件,通过同一个快照文件,可以复制成很多个不同的虚拟机(容器)。
- [1] Docker官网
镜像使用
关于镜像的常用命令有4个:
docker search:搜索镜像;docker build:从Dockerfile或者「上下文(PATH或URL)」中构建镜像;docker images:查看已经构建的镜像列表;docker pull:从docker存储库中拉取镜像到本地;docker rmi:删除已经构建好的镜像;
1.1 搜索镜像 (docker search)
当不确定需要pull的镜像的全称时,可以先使用docker search来查询镜像列表,然后再选取想要的镜像来pull。
docker search [options] <某个XXX镜像名字> # 搜索镜像,一般在dockerhub网站中搜索
docker pull <某个XXX镜像名字> # 下载镜像
运行命令可以参考:
docker run -itd -p 8080:80 --name my-nginx nginx
# -d,--detach:以后台模式运行容器,并返回容器ID;
# -t,--tty:为容器分配一个伪终端;
# -i,--interactive,以交互模式运行容器,并保持终端激活;
## 一般创建的docker容器都需要使用 -d ,除非你想创建一个前台运行的容器,操作完成后就想让它停止;
## 如果在 docker run -it 不使用 -d 那么启动容器后如果你使用 ctrl+c 或 exit 退出交互模式,docker容器会停止运行
## -it 一般会同时使用。
# -p 选项用于将容器的80端口映射到宿主机的8080端口;
# --name 选项用于指定容器的名称为my-nginx;
# 最后的 nginx 是要运行的镜像的名称。
示例:
以下面的pikachu靶场为例:
docker run -itd -p 8888:80 --name pikachu area39/pikachu
此时再执行docker ps -a,这时会新开一个pikachu容器,PORT为3306/tcp, 0.0.0.0:8888->80/tcp, :::8888->80/tcp。在物理主机访问http://虚拟机IP:8080,成功访问靶场。
1.2 构建镜像 (docker build)
该命令从Dockerfile和「上下文」构建Docker镜像。
构建的上下文是位于指定PATH或URL。构建过程可以引用上下文中的任何文件。例如,您的构建可以使用COPY指令来引用上下文中的文件。
docker build [OPTIONS] PATH|URL|-
[OPTIONS]:
#1. --tag/-t:名称和可选的“名称:标签”格式的标签
URL:
#1. 引用Git存储库
#2. 引用预打包的tarball上下文
#3. 引用纯文本文件
示例:
docker build -t folive .
# 此示例指定当前目录"."为PATH,
# 因此本地目录中的所有文件都发送到 Docker 守护进程。
1.3 查看镜像列表 (docker images)
docker images [OPTIONS] [REPOSITORY[:TAG]]
[OPTIONS]:
#1. --all/-a: 显示所有图像(默认隐藏中间图像)
#2. --filter/-f: 根据提供的条件过滤输出
1.4 拉取镜像 (docker pull)
docker pull [OPTIONS] NAME[:TAG|@DIGEST]
[OPTIONS]:
# 1. --all-tags/-a:下载存储库中的所有标记图像
1.5 删除镜像 (docker rmi)
docker rmi [OPTIONS] IMAGE [IMAGE...]
[OPTIONS]:
#1. --force/-f: 强制删除图像
# 如果使用该 -f 标志并指定图像的短ID或长ID,
# 则此命令将取消tag并删除与指定ID匹配的所有镜像。
可以使用镜像的短ID或长ID、tag或摘要来删除镜像。如果图像有一个或多个引用它的tag,必须在删除图像之前删除所有这些tag。当镜像被tag删除时,摘要引用会自动删除。
容器使用
关于镜像的常用命令有4个:
docker run:初始化一个容器,将镜像放到容器中;docker ps:查看容器列表(类比ls);docker start/restart:启动/重启一个容器;docker stop:停止一个正在运行的容器;docker rm:删除一个容器;docker exec/attach:临时进入一个容器(命令行);docker logs:查看某个容器的日志;docker inspect:查看Docker底层日志;
初始化容器
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
IMAGE # 指定要运行的镜像
[OPTIONS]:
#_1. --detach/-d:让容器在后台运行。
#_2. --publish-all/-P: 将所有暴露的端口发布到随机端口。
#_3. --publish/-p:是容器内部端口绑定到指定的主机端口,
# 如 docker run -d -p [主机端口]:[容器端口] [IMAGE]
#_4. --hostname/-h: 容器主机名,访问域名或ip
#_5. --name: 自定义容器名字,需唯一
#_6. --restart: 容器退出时应用的重启策略,默认值为 no
#_7. --volume/-v:绑定挂载卷,即目录映射:[主机目录]:[容器内目录],
# 把容器的数据保存到主机,防止容器突然停止或被删除数据丢失
#_8. --rm: 容器退出时自动移除
#_9. --interactive/-i: 交互式操作,即使没有连接,也保持 STDIN 打开。
#10. --tty/-t: 终端,分配一个伪 TTY。
示例1
docker run -it ubuntu /bin/bash
# ubuntu: ubuntu 镜像。
# /bin/bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 /bin/bash。
若是docker中的服务与服务器本地服务段端口发生冲突(例如本地和docker同时开启了mysql服务),则可修改docker服务的端口映射
查看容器
docker ps [OPTIONS]
[OPTIONS]:
#1. --all/-a:显示所有容器(默认显示刚刚运行)
#2. --filter/-f "conditions": 根据提供的条件过滤输出,可通过容器名称or容器端口号等条件过滤
#3. --quiet/-q:仅显示容器 ID
#4. --size/-s: 显示总文件大小,每个容器显示两个不同的磁盘大小,
# size(virtual size),size是用于每个容器的可写层的数据量(在磁盘上),
# virtual size: 容器使用的只读镜像数据加上容器的可写层所使用的数据量size,
# 两个容器间的镜像数据可能是共享的。
示例1:--filter
# 匹配名称中包含该`name=nostalgic`字符串的所有容器
docker ps --filter "name=nostalgic"
# 匹配所有发布端口为 80 的容器
docker ps --filter publish=80
# 输出条件介绍:
# CONTAINER ID: 容器ID。
# IMAGE: 使用的镜像。
# COMMAND: 启动容器时运行的命令。
# CREATED: 容器的创建时间。
# STATUS: 容器状态。状态有7种:
# 1. created(已创建)
# 2. restarting(重启中)
# 3. running(运行中)
# 4. removing(迁移中)
# 5. paused(暂停)
# 6. exited(停止)
# 7. dead(死亡)
# PORTS: 容器的端口信息和使用的连接类型 (tcp\udp)
# NAMES: 自动分配/自定义的容器名称。
容器的启停、删除
2.3.1 启动已停止运行的容器 (docker start)
docker start CONTAINER_ID/CONTAINER_NAME
docker restart CONTAINER_ID/CONTAINER_NAME
2.3.2 停止运行的容器 (docker start)
docker stop CONTAINER_ID/CONTAINER_NAME
2.3.1 删除容器 (docker rm)
docker rm [OPTIONS] CONTAINER_ID/CONTAINER_NAME
[OPTIONS]:
#1. --force/-f: 强制删除正在运行的容器 (使用SIGKILL)
进入容器
在使用-d参数时,容器启动后会进入后台。此时想要进入容器,可以通过以下指令进入:
exec(推荐):推荐大家使用docker exec命令,用此命令退出容器终端,不会导致容器的停止。attach:如果从这个容器退出,会导致容器的停止。
2.4.1 attach
docker attach [OPTIONS] CONTAINER
2.4.2 exec
docker exec [OPTIONS] [CONTAINER_ID/CONTAINER_NAME] COMMAND [ARG...]
[OPTIONS]:
#1. --detach/-d:分离模式:后台运行命令
#2. --interactive/-i:交互式操作,即使没有连接,也保持STDIN打开
#3. --tty/-t:终端,分配一个伪TTY
示例:
docker exec -it [容器ID] /bin/bash
查看日志
2.5.1 查看容器日志 (docker logs)
docker logs [OPTIONS] CONTAINER
[OPTIONS]:
#1. --follow/-f:跟踪日志输出
#2. --since:显示某个开始时间的所有日志
#3. --time/-t:显示时间戳
#4. --tail:仅列出最新N条容器日志
示例:logs
跟踪查看容器mynginx的日志输出。
runoob@runoob:~$ docker logs -f mynginx
192.168.239.1 - - [10/Jul/2016:16:53:33 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.93 Safari/537.36" "-"
2016/07/10 16:53:33 [error] 5#5: *1 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 192.168.239.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "192.168.239.130", referrer: "http://192.168.239.130/"
192.168.239.1 - - [10/Jul/2016:16:53:33 +0000] "GET /favicon.ico HTTP/1.1" 404 571 "http://192.168.239.130/" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.93 Safari/537.36" "-"
192.168.239.1 - - [10/Jul/2016:16:53:59 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.93 Safari/537.36" "-"
...
查看容器mynginx从2016年7月1日后的最新10条日志。
docker logs --since="2016-07-01" --tail=10 mynginx
获取docker容器交互式命令行
2.5.2 检查WEB应用程序 (docker inspect)
查看Docker的底层信息, 它会返回一个JSON文件记录着Docker容器的配置和状态信息,如ip地址,mac地址,镜像名称,日志路径,端口映射等。
docker inspect [OPTIONS] CONTAINER_ID/CONTAINER_NAME
[OPTIONS]:
# --format/-f: 使用给定的Go模板格式化输出
示例:inspect
# 获取IP地址
docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $INSTANCE_ID
# 获取mac地址
docker inspect --format='{{range .NetworkSettings.Networks}}{{.MacAddress}}{{end}}' $INSTANCE_ID
# 获取日志路径
docker inspect --format='{{.LogPath}}' $INSTANCE_ID
# 获取镜像名称
docker inspect --format='{{.Config.Image}}' $INSTANCE_ID
# 获取所有端口映射
docker inspect --format='{{range $p, $conf := .NetworkSettings.Ports}} {{$p}} -> {{(index $conf 0).HostPort}} {{end}}' $INSTANCE_ID
宿主机与容器交互
文件操作
3.1.1 文件复制 (cp)
docker cp /path/to/host/file.txt <container_name_or_id>:/path/to/container/file.txt
3.1.2 文件挂载
容器操作(容器移动)
在Docker中,移动容器通常指的是将容器从一个主机迁移到另一个主机。以下是一些常见的方法:
使用Docker的导出和导入功能
导出容器:可以使用docker export命令将运行中的容器导出为一个tar包。
docker export -o container.tar <container_id>
导入容器:将导出的tar包传输到目标主机后,使用docker import命令将其导入为一个新的镜像。
docker import container.tar <image_name>:<tag>
运行容器:导入后,使用docker run命令启动容器。
docker run -d --name <new_container_name> <image_name>:<tag>
- 优点:简单易用,不需要额外工具。
- 缺点:不保留容器的运行状态(如内存状态、网络配置等),只保存文件系统。
使用Docker镜像
基于容器创建镜像:可以使用docker commit命令将运行中的容器创建为一个新的镜像。
docker commit <container_id> <new_image_name>:<tag>
推送镜像到仓库:将创建的镜像推送到Docker Hub或其他私有镜像仓库。
docker push <new_image_name>:<tag>
在目标主机拉取镜像:在目标主机上从仓库拉取镜像。
docker pull <new_image_name>:<tag>
运行容器:使用docker run命令启动容器。
docker run -d --name <new_container_name> <new_image_name>:<tag>
- 优点:可以保留容器的文件系统和部分配置。
- 缺点:不保留容器的运行状态(如内存、网络等)。
使用CRIU(Checkpoint/Restore in Userspace)
略
常见操作场景
删除镜像步骤
在容器是启动的情况下,我是先把容器停掉,删除容器,最后再是删除镜像。
停掉启动容器->删除容器->删除镜像
- 停掉启动容器:
docker stop <容器id> - 删除容器:
docker rm <容器id> - 删除镜像:
docker rmi <镜像id>
若通过docker rm <容器id>命令删除报错,可尝试使用docker rmi -f强制删除镜像
通过yml配置文件拉取docker镜像
以vulhub fastjson/1.2.24-rce靶场为例:
cd fastjson/1.2.24-rce
docker-compose build
docker-compose up -d # -d 为“以后台的方式运行容器”
失陷容器应急处理
确认容器失陷后,一般我们可以采取暂停容器、隔离容器甚至杀死容器的方式来做紧急处理。
-
使用
docker pause,暂停容器中所有的进程。 -
使用
docker commit,用于将被入侵的容器来构建镜像,从而保留现场痕迹,以便溯源。 -
将正在运行的Docker容器禁用网络。
# 将运行中的容器与用户定义的网桥断开连接 [root@localhost ~]#docker network disconnect bridge <container-name> _ # 禁用veth [root@localhost ~]#docker exec -it <container-name> cat /sys/class/net/eth0/iflink 29 [root@localhost ~]#ip link show |grep 29 29: vethbf5239e@if28: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue masteefault [root@localhost ~]# ip link set vethbf5239e down -
使用
docker kill杀掉运行中的容器(谨慎操作!!!)docker kill -s KILL <container-name>
没有vi/vim/nano,如何操作文档
# 删除最后一行
sed -i '$d' [FILEPATH]
# 往文件中写一行
echo "Hello, world!" >> [FILEPATH]
实战案例
搭建一个python环境,
方法一:直接pull镜像
Docker Hub上提供了官方的Python镜像,你可以根据需要选择合适的版本。
-
拉取最新版本的 Python 镜像:
# 拉取 Python 镜像 docker pull python:latest # 如果你需要特定版本的 Python(例如 Python 3.9),可以指定版本号: docker pull python:3.9 -
启动Python容器:你可以通过以下命令启动一个 Python 容器,并进入交互模式:
docker run -it python:latest /bin/bash # -it 参数表示以交互模式运行容器。 # /bin/bash 是容器启动后执行的命令,用于进入Bash终端。
方法二:基于Dockerfile创建
如果你需要一个更定制化的 Python 环境(例如安装特定的库),可以创建一个Dockerfile。以下是一个简单的示例:
# Dockerfile1
# 基于官方 Python 镜像
FROM python:3.11.4-slim-bullseye
# 复制自定义的 hosts 文件
COPY hosts /etc/hosts
# 设置工作目录
WORKDIR /opt/app
# 设置环境参数
# 略
# 复制当前目录下的文件到工作目录
COPY . /opt/app/
# 安装 python 依赖
RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
# 设置默认命令
ENTRYPOINT ["/bin/sh", "-c", "python main.py"]
/csmpProbeCheck文件树如下:
csmpProbeCheck
+-- log/
+-- conf.py
+-- flowProbeCheck.py
+-- keepAlive.py
+-- main.py
+-- requirements.txt
+-- TOKEN.txt
\-- toolkits.py
requirements.txt
pandas==2.1.4
requests==2.31.0
构建和运行Docker容器:
在包含Dockerfile的目录下,运行以下命令构建镜像:
docker build -t <image-name> <context-path>
docker build -t csmp-probe-check .
# -t 参数用于指定镜像的名称(例如 csmp-probe-check )。
其他注意事项
-
数据持久化:如果需要持久化数据(例如代码文件或数据库),可以使用
Docker卷:docker run -v $(pwd)/var/csmpProbeCheck:/var/csmpProbeCheck -it python:latest /bin/bash这会将当前目录下的
/csmpProbeCheck文件夹挂载到容器的/var/csmpProbeCheck目录。 -
如何查看docker配置文件(daemon.json)的默认路径?
dockerd --help在输出中,你会看到
--config-file参数,它指定了Docker配置文件的路径。默认情况下,Docker 使用/etc/docker/daemon.json文件。Daemon configuration file (default "")
方法三:Dockerfile+挂载宿主机文件
编写Dockerfile
# 基于官方 Python 镜像
FROM python:3.11.4-slim-bullseye
# 创建一个目录,用于挂载宿主机的文件夹
RUN mkdir -p /opt/app
# 设置工作目录
WORKDIR /opt/app
# 复制当前目录下的 requirements.txt 文件到工作目录
COPY ./requirements.txt /opt/app/
# 安装 python 依赖
RUN pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
# 设置默认命令
ENTRYPOINT ["/bin/sh", "-c", "python main.py"]
# 或者使用一个占位命令,确保容器启动后不会立即退出
# CMD ["tail", "-f", "/dev/null"]
生成docker镜像
根据Dockerfile,通过docker build生成镜像:
docker build -t csmp-app .
docker容器初始化
通过docker run将镜像投放到容器中(初始化):
Docker 的守护模式(Daemon Mode)和交互模式(Interactive Mode)是运行容器的两种不同方式,它们的主要区别在于容器的运行方式和用户与容器的交互方式。
- 守护模式(Daemon Mode)的容器在后台运行,不会占用当前终端。适合运行长期运行的服务(如Web服务器、数据库等)。容器的标准输入(stdin)被关闭,用户无法直接与容器交互。容器的标准输出(stdout)和标准错误(stderr)通常被重定向到日志文件或 Docker 的日志系统中。
- 交互模式(Interactive Mode)的容器在前台运行,会占用当前终端。适合需要用户交互的场景(如开发环境、调试工具等)。容器的标准输入(stdin)保持打开状态,用户可以通过终端直接与容器交互。容器的标准输出(stdout)和标准错误(stderr)直接显示在终端上。
-
守护模式(Daemon Mod)初始化:
docker run -d -p 8000:8000 --name my-container \ -v /path/to/host/folder:/app \ my-app # --detach/-d:以守护模式运行容器; # --port/-p 8000:8000:将容器的8000端口映射到宿主机的8000端口; # --name my-container:为容器指定一个名称; # -v /path/to/host/folder:/app:将宿主机的"/path/to/host/folder"挂载到容器的"/app"目录中; # my-app:使用之前构建的镜像。 ## 示例: docker run -d -p 8000:8000 --name csmp-app \ -v /var/csmpProbeCheck:/opt/app \ csmp-app文件挂载注意事项:
- 权限问题:确保宿主机的文件夹路径/path/to/host/folder对Docker守护进程是可访问的,并且具有适当的权限。
- 用户和组ID:如果宿主机和容器内的用户和组ID不一致,可能会导致权限问题。可以通过在 Dockerfile中设置用户和组来解决。
- 挂载路径:挂载路径在宿主机和容器中必须一致,且容器内的路径必须在镜像中已经存在。通过这种方式,你可以将宿主机的文件夹挂载到容器中,方便在容器中访问和操作宿主机的文件。
-
交互模式(Interactive Mode)初始化:
docker run -it --name my-container my-image # -i:表示交互式,保持标准输入(stdin)打开 # -t:分配一个伪终端 ## 示例: docker run -it --name csmp-app csmp-app
进入已经启动的容器
docker exec -it [CONTAINER_ID] /bin/bash
# 如果没有启动,可以使用 docker start [CONTAINER_ID/CONTAINER_NAME] 来启动容器
# 进行一些手动操作,例如向 hosts 中写入一行
echo "172.16.10.20 csmp.qaxc-inc.cn" >> /etc/hosts
*[可选]手动挂载宿主机文件夹
docker run --mount type=bind, source=[/path/to/host/folder],destination=[/app] \
[OPTIONS] IMAGES_NAME
docker run -d --name csmp-probe-check \
--mount type=bind,source=/var/csmpProbeCheck,destination=/opt/app \
csmp-app
docker run -d --name csmp-probe-check \
--mount type=bind,source=/var/csmpProbeCheck,destination=/opt/csmpProbeCheck \
csmp-app
退出docker容器
- 在交互模式下,可以通过输入
exit或按Ctrl+D退出容器,容器将停止运行。 - 如果你只是想暂时离开容器而不退出,可以按
Ctrl+P然后立刻按下Ctrl+Q组合键。容器将继续在后台运行,终端将返回到宿主机。
容器、镜像的铲除
- 使用
docker ps查看正在运行的容器,并使用docker stop [CONTAINER_ID]停止相关容器; - 使用
docker ps -a全面检查相关容器,然后使用docker rm [CONTAINER_ID]删除相关容器; - 使用
docker images查看本地镜像列表,然后使用docker rmi [IMAGES_ID]删除相关镜像;
报错排障
报错docker-compose API版本过低
[centos@CentOS]../fastjson/1.2.47-rce❯ docker-compose up -d
ERROR: client version 1.22 is too old. Minimum supported API version is 1.24, please upgrade your client to a newer version
可以试试下面的办法:
如果你使用Docker 1.13以上版本,需要将
docker-compose.yml中的version:'2'修改为version: '2.1'也就是这里的version。然后再docker-compose up -d试试。
报错,连接超时
$ docker pull python:latest
Error response from daemon: Get "https://registry-1.docker.io/v2/ ": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
编辑配置文件daemon.json文件,配置镜像加速地址,文件内容如下:
{
"registry-mirrors": [
"https://docker.m.daocloud.io",
"https://hub-mirror.c.163.com"
]
}
重启 Docker 服务:
sudo systemctl daemon-reload
sudo systemctl restart docker

浙公网安备 33010602011771号