Docker使用指南
本文最后更新于:2024年2月19日 晚上
码头工人,启动!
什么是Docker
Docker容器是与系统其他部分隔离开的一系列进程,运行这些进程所需的所有文件都由另一个镜像提供,从开发到测试再到生产的整个过程中,Linux 容器都具有可移植性和一致性。相对于依赖重复传统测试环境的开发渠道,容器的运行速度要快得多,并且支持在多种主流云平台(PaaS)和本地系统上部署。Docker容器很好地解决了“开发环境能正常跑,一上线就各种崩”的尴尬。
Docker容器的特点:
- 轻量
- 快速:容器的启动和创建无需启动GuestOS,可以实现秒级甚至毫秒级的启动。
- 可移植性:Docker容器技术是将应用及所依赖的库和运行时的环境技术改造包成容器镜像,可以在不同的平台运行。
- 自动化:容器生态中的容器编排工作(如:Kubernetes)可帮助我们实现容器的自动化管理。
使用表格对比如下:
特性 | 普通虚拟机 | Docker |
---|---|---|
跨平台 | 通常只能在桌面级系统运行,例如 Windows/Mac,无法在不带图形界面的服务器上运行 | 支持的系统非常多,各类 windows 和 Linux 都支持 |
性能 | 性能损耗大,内存占用高,因为是把整个完整系统都虚拟出来了 | 性能好,只虚拟软件所需运行环境,最大化减少没用的配置 |
自动化 | 需要手动安装所有东西 | 一个命令就可以自动部署好所需环境 |
稳定性 | 稳定性不高,不同系统差异大 | 稳定性好,不同系统都一样部署方式 |
打包、分发、部署
- 打包:就是把你软件运行所需的依赖、第三方库、软件打包到一起,变成一个安装包
- 分发:你可以把你打包好的“安装包”上传到一个镜像仓库,其他人可以非常方便的获取和安装
- 部署:拿着“安装包”就可以一个命令运行起来你的应用,自动模拟出一摸一样的运行环境,不管是在 Windows/Mac/Linux。
镜像、容器
- 镜像:可以理解为软件安装包,可以方便的进行传播和安装。
- 容器:软件安装后的状态,每个软件运行环境都是独立的、隔离的,称之为容器。
基本教程
怎么编写Dockerfile
Dockerfile是用来描述文件的构成的文本文档,其中包含了用户可以在使用行调用以组合Image的所有命令,用户还可以使用Docker build实现连续执行多个命令指今行的自动构建。
Dockerfile的语法非常简单,常用的只有11个:
命令 | 说明 |
---|---|
FROM | 基于哪个镜像来实现 |
MAINTAINER | 镜像的创建者 |
ENV | 声明环境变量 |
RUN | 执行的命令 |
ADD | 添加宿主机文件到容器里,有需要解压的文件会自动解压 |
COPY | 添加宿主机文件到容器里 |
WORKDIR | 工作目录 |
EXPOSE | 容器内应用可使用的端口 |
CMD | 容器启动后所执行的程序,如果执行docker run后面跟启动命令会被覆盖掉 |
ENTRYPOINT | 与CMD功能相同,但需docker run不会覆盖,如果需要覆盖可增加参数-entrypoint来覆盖 |
VOLUME | 将宿主机的目录挂载到容器里 |
一些命令的详细介绍
FROM:定制的镜像都是基于 FROM 的镜像,例如 :
FROM ros:humble
, 这个Docker镜像是从名为 ros 的镜像中的 humble 版本构建的。(ros 是ROS官方提供的Docker镜像,humble 是其版本或标签)。
后续的操作都是基于 ros。RUN:用于执行后面跟着的命令行命令。有以下俩种格式:
- shell 格式:
1
2RUN <命令行命令>
# <命令行命令> 等同于,在终端操作的 shell 命令。 - exec 格式:
1
2
3RUN ["可执行文件", "参数1", "参数2"]
# 例如:
# RUN ["./test.php", "dev", "offline"] 等价于 RUN ./test.php dev offline - 设置在容器内部执行命令时所使用的Shell类型,指定为bash的命令:
SHELL ["/bin/bash", "-c"]
- Dockerfile 的指令每执行一次都会在 docker 上新建一层。过多无意义的层,会造成镜像膨胀过大。以
&&
符号连接命令,这样执行后,只会创建 1 层镜像。
- shell 格式:
ENV: 设置环境变量,将在Docker容器启动时生效,并可供容器内的应用程序或脚本使用。
- 格式:
ENV <key> <value>
- 例如:
1
2ENV NVIDIA_VISIBLE_DEVICES all
ENV NVIDIA_DRIVER_CAPABILITIES compute,utility,graphics,video - NVIDIA_VISIBLE_DEVICES: 使用CUDA环境变量CUDA_VISIBLE_DEVICES来限定CUDA程序所能使用的GPU设备
- NVIDIA_DRIVER_CAPABILITIES: 设置容器中允许使用显卡的某些能力
- 格式:
NVIDIA_DRIVER_CAPABILITIES 变量的可能值是:
可能的值 | 描述 |
---|---|
compute,video 或 graphics,utility |
容器需要的驱动程序功能的逗号分隔列表。 |
all |
启用所有可用的驱动程序功能。 |
为空或未设置 | 使用默认驱动程序功能:utility ,compute 。 |
下面提供了支持的驱动程序功能:
驱动能力 | 描述 |
---|---|
compute |
CUDA 和 OpenCL 应用程序需要。 |
compat32 |
运行 32 位应用程序所必需的。 |
graphics |
运行 OpenGL 和 Vulkan 应用程序所必需的。 |
utility |
需要使用 nvidia-smi 和 NVML。 |
video |
需要使用视频编解码器 SDK。 |
display |
利用 X11 显示所需的。 |
all |
启用所有可用的驱动程序功能。 |
- CMD :
类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:- CMD 在docker run 时运行。
- RUN 是在 docker build。
作用:为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。
注意:如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效
。
COPY :复制指令,从上下文目录中复制文件或者目录到容器里指定路径。
1
2COPY [--chown=<user>:<group>] <源路径1>... <目标路径>
COPY [--chown=<user>:<group>] ["<源路径1>",... "<目标路径>"]- [–chown=
: ]:可选参数,用户改变复制到容器内文件的拥有者和属组。 - <源路径>:源文件或者源目录,这里可以是通配符表达式,其通配符规则要满足 Go 的 filepath.Match 规则。
例如:1
2COPY hom* /mydir/
COPY hom?.txt /mydir/ - <目标路径>:容器内的指定路径,该路径不用事先建好,路径不存在的话,会自动创建。
- [–chown=
EXPOSE : 仅仅只是声明端口。
- 作用:
帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射。
在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口。1
EXPOSE <端口1> [<端口2>...]
- 作用:
WORKDIR :
指定工作目录。
用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。以后各层的当前目录就被改为指定的目录,如该目录不存在,WORKDIR 会帮你建立目录。- docker build 构建镜像过程中的,每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创建的目录才会一直存在。
1
2
3
4
5
6
7
8
9
10
11
12
13FROM ubuntu
# 设置工作目录为 /app
WORKDIR /app
# 将当前目录下的所有文件复制到 /app 目录下
COPY . .
# 在 /app 目录下执行命令
RUN apt-get update && apt-get install -y python3
# 当容器启动时,默认进入 /app 目录
CMD ["python3", "app.py"]
- docker build 构建镜像过程中的,每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创建的目录才会一直存在。
Dockerfile的基本结构
1 |
|
Build 为镜像(安装包)和运行
在 Dockerfile 文件的存放目录下,执行构建动作:
step 1 : 编译
1 |
|
-t
设置镜像名字和版本号
命令参考
step 2 :运行
1 |
|
-p
映射容器内端口到宿主机
--name
容器名字
-d
后台运行
更多相关命令:
- docker ps 查看当前运行中的容器
- docker images 查看镜像列表
- docker rm container-id 删除指定 id 的容器
- docker stop/start container-id 停止/启动指定 id 的容器
- docker rmi image-id 删除指定 id 的镜像
- docker volume ls 查看 volume 列表
- docker network ls 查看网络列表