Docker可以视为一种轻量级的虚拟机, 可以将应用程序和其依赖环境进行打包, 从而在新平台上直接部署. 由于Docker将程序的依赖全部打包到一起, 因此极大的简化了部署操作, 提高了软件部署的效率.
此外, 由于Docker本身具有的隔离性, 将其作为开发环境使用也非常方便, 可以随意尝试各种指令. 如果出现问题只需要重新运行镜像就可以恢复到最初的状态.
在适合Docker的场景下, 使用Docker可以减少工作量, 在其他场景下, 使用脚本可能是一个更适合的方案. 本文介绍Docker的基本概念, 配置方法, 和基本使用.
Docker安装与配置
对于Linux系统, 可以直接执行apt进行安装, 指令如下
1 | sudo apt install docker.io |
注意: 如果已经安装了docker, 需要先卸载相关组件在进行安装
其他的安装方式, 可以参考如下内容
(已失效)配置国内加速器
25.09更新: 由于相关监管需求, 目前已经没有国内加速器可以使用, DockerHub也主动屏蔽了很多IP. 只能使用特定网站的镜像服务来获取
可考虑使用毫秒镜像直接下载镜像. 更多可查看列表GitHub - dongyubin/DockerHub
在 /etc/docker/daemon.json 中写入如下内容(如果文件不存在请新建该文件)
1 | { |
然后重启服务
1 | sudo systemctl daemon-reload |
如果需要拉取的进行镜像在国内的加速器中没有, 则还可以考虑对docker配置代理, 使用代理服务器加速. 具体的配置可以参考Docker代理配置
Docker替代品
除了Linux平台下使用包管理器可以较为简单地安装Docker服务, 对于Windows和Mac平台, 都需要借助于虚拟机才能启动. 而Docker官方早就是一脸死相, 无法正常访问官网. 因此可以考虑使用替代产品.
可使用Podman Installation | Podman替换Docker. 对于本文提到的绝大部分docker指令, 直接替换为podman即可.
在安装了Desktop的情况下, 许多指令也可以通过GUI页面点击完成, 操作更简单.
Docker操作镜像
Docker的镜像操作都是以docker image开始的指令, 常见指令如下表所示
| 操作 | 指令 | 操作 | 指令 |
|---|---|---|---|
| 显示本地镜像 | ls |
删除本地镜像 | rm <imageName> |
| 拉取远程镜像 | pull <imageName> |
清理无效的镜像 | prune |
例如, 想要拉取官方的测试镜像, 可以执行
1 | docker image pull library/hello-world |
由于官方的镜像都位于library/下, 因此library/是默认路径, 也可以省略不写. 此外, 每个镜像还可以具有不同的标签, 例如UBUNTU:18.04表示具有18.04标签的的UBUNTU镜像. 如果不指定标签, 则默认下载LATEST标签
查询镜像列表
可使用第三方网站毫秒镜像或者轩辕镜像查询镜像和版本. 官方提供的Docker Hub主动屏蔽IP, 导致即使使用代理也难以访问.
Docker操作容器
镜像文件相当于存储在磁盘上的程序, 仅表示其中打包的程序的一个状态, 相当于程序的一个快照。而在运行镜像文件后, Docker还会生成对应的容器文件, 容器文件中保存了程序执行过程中的数据。关闭容器后, 其中的程序停止运行, 但容器文件本身并不会被删除. 容器操作的指令都是以docker container开头的指令, 常见的指令如下表所示
| 操作 | 指令 | 操作 | 指令 |
|---|---|---|---|
| 查看运行中容器 | ls |
查看所有容器 | ls --all |
| 启动镜像 | run <imageName> |
启动容器 | start <containerId> |
| 删除容器 | rm <containerID> |
停止容器 | stop <containerId> |
因为start指令需要指定容器ID, 因此这个指令实际上可以理解为再次启动已经关闭的容器. 默认情况下容器将会在后台启动并执行, 只有手动设置为交互使用时, 才会将当前终端链接到镜像.
执行ls指令后, 会输入类似如下格式的内容
1 | CONTAINER ID IMAGE COMMAND CREATED STATUS |
运行镜像
启动镜像时, 可以指定如下的一些参数来控制容器的行为, 具体如下表所示:
| 参数 | 效果 | 参数 | 效果 |
|---|---|---|---|
-i |
交互使用 | -t |
连接镜像的终端 |
--rm |
容器关闭后删除容器文件 | --name |
指定容器的名称 |
例如, 以下指令表示启动ubuntu 18.04的镜像文件, 以交互模式连接该系统的终端, 并且在容器关闭后删除容器文件.
1 | docker container run -it --rm ubuntu:18.04 bash |
通常情况下, 是不会删除容器文件的, 但出于测试的目的, 可以在使用完毕后删除容器文件, 从而节省硬盘空间.
但实际上只有修改的文件才会产生空间消耗, 所以容器本身并没有那么消耗空间
进入容器
在镜像运行以后, 还可以通过命令行进入容器内, 从而查看或者执行需要的指令. 可以使用如下的指令进入容器并启动一个shell
1 | sudo docker exec -it <containerID> /bin/bash |
例如可以进入一个mysql容器中, 并查看IP地址信息, 从而从外部连接到数据库.
查看日志
当容器运行情况不符合预期时, 可能需要查看容器内输出的日志, 此时可以执行如下指令持续的输出容器内的日志
1 | docker logs -f {{container_name}} |
使用
tldr docker-logs可以查看更多常见用法
重命名容器
可以使用docker rename指令对容器重命名, 使其具有一个可读性更好的名称
1 | docker rename <ContainerId> <newName> |
不能使用容器名替代容器ID, 容器名仅作为提高可读性的手段
Docker维护
映射
通常情况下, 可以直接运行相关的镜像, 如果容器需要存储空间, 会自动映射数据卷. 但也可以通过手动指定的方式, 明确数据卷的存储位置.
1 | $ docker run -d -v nextcloud:/var/www/html -p 8080:80 nextcloud |
以上述指令为例, 通过-v参数将宿主机的相对路径目录nextcloud映射到了容器中的/var/www/html. 当宿主机使用相对路径时, 其相对的根目录是数据卷的根目录/var/lib/docker/volumes/.
通过-p参数, 将宿主机的8080端口与容器的80端口关联, 从而访问宿主机8080端口就等价于访问容器的80端口.
查看空间占用情况
Docker的容器在运行过程中可能需要存储数据, 进而在磁盘上创建数据卷, 可以使用docker system df -v查看docker所有相关组件的空间占用情况
1 | root@iZ:~# docker system df -v |
其中VOLUME为容器的数据卷, 其生命周期独立于容器, 如果需要清理无用的数据卷, 可以执行docker volume prune
查看资源使用情况
Docker的容器运行过程中需要消耗CPU和内存, 可以使用docker stats查看所有正在运行的容器当前消耗的资源数量。
限制资源使用量
默认情况下容器使用的CPU和内存是不受限制的, 为了避免容器消耗了太多资源导致其他服务不可用, 可以对CPU和内存使用量进行限制。 使用以下参数对CPU使用进行限制
| 参数 | 含义 |
|---|---|
| –cpus | 指定CPU的使用量, 可以包含小数 |
| –cpuset-cpus | 指定具体使用那个CPU |
| –cpu-shares | 指定获得CPU的权重 |
--cpus=2可以理解为使用2个CPU --cpus=0.9则可以理解为使用0.9个CPU。具体执行的时候, 并不一定是真的使用2个或者0.9个CPU, 而是保证在使用时间上等价于使用2个或者0.9个CPU。
--cpuset-cpus="1,3"表示容器只在1号和3号CPU行运行。 --cpu-shares=512表示获取CPU时间的权重为512(默认值为1024)
使用以下参数对内存进行限制
| 参数 | 含义 |
|---|---|
| -m | 指定最大内存使用量 |
| –memory-swap | 指定包括swap在内的可用内存总量, -1表示无限制使用swap |
-m 300M --memory-swap -1表示最大可用内存为300M, 但是可以无限制使用swap空间, -m 300M --memory-swap 500M表示最大可用内存为300M, 还可以额外使用200M的swap空间。
参考文献
以下的几篇文章讨论了限制容器的资源使用情况的指令.
Docker原理简介
Docker虽然有时候被叫做轻量级虚拟机, 但Docker的技术通常视为一种容器化技术. Docker主要利用Linux内核提供的如下几种能力实现
Namespaces
操作系统对硬件进行了抽象, 提供了内存, 文件系统, CPU等资源. Linux内核的Namespaces技术可以对这些资源进行隔离, 让其中的程序觉得自己独占所有资源. 具体来说, Docker涉及了如下的几种隔离
- PID 命名空间:进程隔离,每个容器有独立的进程树
- Network 命名空间:网络隔离,每个容器有自己的网络接口、IP、路由表
- Mount 命名空间:文件系统挂载点隔离
- UTS 命名空间:主机名和域名隔离
- IPC 命名空间:进程间通信隔离
- User 命名空间:用户和用户组隔离(可选,用于增强安全性)
在进行如上的隔离后, 在Docker容器内就会感觉只有自己的进程, 而无法感知到其他容器或者宿主机的进程. 但由于这仅仅是操作系统内核制造的假象, 因此相较于虚拟机的方式性能更高.
Control Groups
使用控制组能力可以限制容器使用的CPU, 内存, 磁盘IO等资源, 从而限制容器的资源使用量, 防止单个容器耗尽系统资源.
UnionFS
联合文件系统(UnionFS)或层(Layer)技术允许将多个文件系统层叠在一起, 形成一个统一的视图. 每个镜像和容器都由一组层组成这些层可以共享和重用.
由于Docker高度依赖Linux内核的能力, 因此在非Linux平台, 无法直接运行Docker. 在Windows平台, 通常的解决方案是运行Windows的Linux子系统, 在子系统中启动Docker. 在Mac平台, 解决方案是先安装虚拟机, 在虚拟机中运行Linux系统, 最后在Linux系统中启动Docker(双层套娃结构). 由于Docker本质上是一种隔离, 因此无法直接在Docker中直接运行Windows或者Mac镜像.
docker-compose安装
当前docker-compose项目已经在Github上开源, 可在对应的release页面中找到需要的二进制文件, 以Linux系统下X86指令集为例, 可下载
1 | wget https://github.com/docker/compose/releases/download/v2.29.2/docker-compose-linux-x86_64 |
由于docker-compose项目使用GO语言实现, 因此选择正确的版本后, 直接赋予可执行权限即可运行, 无需其他任何依赖项目. 如果需要在任意位置执行, 可将文件复制到$PATH变量包含的路径中.
这大概就是GO语言静态编译的余裕吧
docker-compose.yml文件详解
在启动Docker镜像时, 如果镜像的配置比较复杂, 则命令行中需要附带大量的参数才可以启动. docker-compose.yml文件可将相关的配置固化到文件之中, 从而可以一键启动镜像. 此外, 基于yml文件还可以配置多个镜像的依赖关系, 使得我们能够便捷的将一组镜像按照一定规则启动, 组合成我们需要的应用.
一个基本的docker-compose.yml文件通常具有如下的一些属性
1 | version: '3.0' |
文件中的各个配置与命令行中的数据基本一一对应, 此处不再赘述
参考文献
第一篇文章对Docker进行了简要的介绍, 第二篇文章是一个系列教程, 对Docker进行了比较深入的介绍.
最后更新: 2026年04月16日 12:22
版权声明:本文为原创文章,转载请注明出处
原始链接: https://lizec.top/2020/06/19/Docker%E7%AC%94%E8%AE%B0%E4%B9%8B%E5%9F%BA%E7%A1%80%E4%BD%BF%E7%94%A8/