超详细的 Docker 基本概念及常用命令

1,087 阅读8分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第2天,点击查看活动详情

Docker 介绍

官网:链接

Docker 是一个可以简化开发、部署和运行应用程序的开源平台,是用 Go 语言开发的。Docker 可以帮助开发者做好基础设施层的工作,让开发者更多地关注业务的实现,加快从开发到上线的迭代速度

Docker 架构模式

Docker 使用了 client / server 的架构模式,如下图所示

Docker daemon 是后台总管,对外提供了REST API,当收到 Docker Client 发送的请求时,执行诸如镜像、容器、网络、存储等一系列操作,Registry 是存放 Docker镜像 的仓库

Docker 基本概念

仓库 / Registry

Docker Hub 是 Docker 的官方仓库,阿里云也提供了镜像加速器,此外,还可以配置私有仓库

执行以下命令时,Docker daemon 会和已配置的镜像仓库交互(如未配置,使用Docker Hub)

docker pull
docker run 
docker push

镜像 / Image

镜像是用于创建容器的只读模板,包含一系列指令。镜像模板的定义文件叫做 Dockerfile,一般而言,该文件中的每一条指令会创建一个镜像层(Layer)

以 Redis 镜像为例

在创建自定义镜像时,如果修改了 Dockerfile 中的部分指令,重新编译时,只有变化的指令对应的镜像层会重新构建,这也是 Docker镜像 轻量级、小巧、高速的一个原因

容器 / Container

容器是镜像的可运行实例,一个镜像可以创建出多个容器(这和面向对象语言中的类和对象类似,一个类可以创建多个对象实例)

Docker 底层使用了 namespace 技术,这使得不同容器可以运行在互相隔离的命名空间下

基于定制后的容器,还可以反向生成镜像

网络 / Network

Docker 容器和服务之间通过 Docker Network 互相连接,此外,该网络还可以连接非Docker负载

Docker 的网络子系统是插件式的网络驱动,Docker 提供了如下几种驱动

  • bridge - 默认驱动
  • host
  • overlay
  • ipvlan
  • macvlan
  • none

由于驱动是插件式的,还可以使用第三方或者自研的网络驱动

存储 / Storage

默认情况下,Docker 容器内生成的文件被保存在一个可写的容器层中,容器销毁后,这些文件也跟着销毁了

Docker 提供了 2 种方式持久化容器内的文件。无论是哪种方式,在容器内看起来是一样的,在容器的文件系统中,要么是一个文件夹,要么是一个独立的文件

1. Volume

这是 Docker 官方推荐的最佳方式,在 Linux 系统中,Volume 存储在 /var/lib/docker/volumes/ 目录下

Docker 不会主动删除 Volume,但是对于不再使用的 Volume,可以用如下命令手动清理

docker volume prune

挂载 Volume 时,推荐为其命名。当然也可以不命名,这种情况下,Docker 会随机分配一个当前宿主机下唯一的名字

2. bind mount

相比于 Volume, bind mount在功能上有一些限制,且不能通过 Docker 命令行工具直接操作。宿主机上的文件夹或文件以全路径的方式被挂载到容器中

此外,还有一种基于宿主机内存的存储方式:tmpfs mount,这种方式通常用于在容器的生命周期内,保存一些非持久化的状态或敏感信息

这3种方式的区别如下图所示

Docker常用命令

通用操作 / Common Operation

查看 Docker 版本

# Docker版本号
docker -v
# Docker版本详细信息
docker version

镜像操作 / Image Operation

查看镜像列表

# 查看最新创建的镜像,以下两个命令等价
docker images
docker image ls
# 查看所有镜像
docker images --all
docker iamges -a
# 查看与Redis相关的镜像
docker images redis
# 只显示镜像ID,可以与docker rmi命令结合使用
docker images -q

搜索当前配置的远程仓库中的可用镜像

docker search redis

从镜像仓库拉取镜像

# 拉取最新版,相当于docker pull redis:latest
docker pull redis
# 拉取指定版本
docker pull redis:7.0.5

使用 Dockerfile 构建镜像

# 语法:docker build [OPTIONS] PATH | URL | -

###### 第一种方式,根据Dockerfile生成镜像 ######
# 切换到Dockerfile所在目录
cd dockerfile-path
# -t 等价于 --tag,指定镜像的标签
docker build -t image-from-path .
# 语法:docker build [OPTIONS] PATH | URL | -

###### 第二种方式,根据URL生成镜像 ######
# URL可以是Git远程仓库(包含Dockerfile文件)
# URL也可以是预先打包好的tarball上下文链接
# URL也可以是普通文本文件(内容和Dockerfile相同)
docker build -t image-from-url github.com/creack/docker-firefox

删除镜像(一个或多个)

# 删除指定镜像
docker rmi redis:7.0.5
# 删除所有符合过滤条件的镜像
docker rmi $(docker images -f "dangling=true" -aq)
# 删除所有Redis镜像
docker rmi $(docker images redis -aq)

为镜像打标签

# 语法 docker image tag sourceImage:version targetImage:version
# 简写 docker tag sourceImage:version targetImage:version
docker tag redis my-local-redis:v1.0

容器操作 / Container Operation

查看容器列表

docker ps
# 查看所有容器,包含已停止的
docker ps -a
# 查看容器ID, -q 等价于 --quiet
docker ps -q

根据某个镜像创建容器但不启动

# 语法:docker create [OPTIONS] IMAGE [COMMAND] [ARG...]
docker create -d --name redis-demo -p 6379:6379 redis:7.0.5

根据某个镜像创建容器并启动

# -d 让容器在后台运行,其实就是一个进程
# --name 指定容器名称
# -p 将容器的端口映射到宿主机的端口
# --cpus CPU核心数
# -m 等价于 --memory 指定最大内存
# -e 等价于 --env,设置环境变量
docker run -d \
    --name redis-demo -p 6379:6379 \
    --cpus 1 -m 100m \
    -e REDIS_NAME=my-redis-demo \
    redis:7.0.5

以交互式的方式进入容器

# docker exec -it containerId /bin/bash
docker exec -it redis-demo /bin/bash

启动/停止/暂停/重启容器 

# 启动容器,语法:docker start containerId / containerName
docker start redis-demo

# 停止容器,语法:docker stop containerId / containerName
docker stop redis-demo

# 暂停容器,语法:docker pause CONTAINER [CONTAINER...]
docker pause redis-demo

# 运行状态下重启容器,语法:docker restart containerId / containerName
docker restart redis-demo

删除容器(一个或多个)

# 语法 docker rm [OPTIONS] CONTAINER [CONTAINER...]

# 删除redis-demo,前提是redis-demo已停止
docker rm redis-demo
# 删除redis-demo及其匿名Volume
docker rm -v redis-demo
# 删除所有已停止的容器
docker rm $(docker ps -f status=exited -q)

根据容器的当前变更反向生成镜像

# 语法 docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
# -m 等价于 --comment,备注
docker commit -m 'Image from Container' redis-demo local-redis-image:1.0.0
# 查看新建镜像的提交信息
docker image inspect local-redis-image:1.0.0 | grep Comment
# 或者
docker inspect local-redis-image:1.0.0 | grep Comment

查看容器详细信息

# 语法 docker inspect [OPTIONS] NAME|ID [NAME|ID...]
docker inspect redis-demo

 查看容器资源使用情况

# 语法:docker stats [OPTIONS] [CONTAINER...]

# 以流式的方式展示所有运行中的容器资源使用数据
docker stats
# 所有容器资源使用数据
docker stats -a
# 指定容器(redis-demo)资源使用数据
docker stats redis-demo
# 资源使用快照
docker stats --no-stream redis-demo

查看容器日志

# 语法:docker logs [OPTIONS] CONTAINER
docker logs redis-demo
# 实时日志, -f 等价于 --follow,-n 等价于 --tail,显示倒数多少行日志
docker logs -f -n 12 redis-demo

存储操作 / Storage Operation

列举 Volume

docker volume ls

创建 Volume

# 语法:docker volume create [OPTIONS] [VOLUME]
# 创建数据卷时,指定名称:v-redis
docker volume create v-redis
# 创建数据卷时,不指定名称,Docker会创建64位的随机名称
docker volume create

查看 Volume 详情

# 语法:docker volume inspect [OPTIONS] VOLUME [VOLUME...]
docker volume inspect v-redis

删除 Volume

# 语法:docker volume rm [OPTIONS] VOLUME [VOLUME...]
docker volume rm v-redis

清理未使用的Volume 

docker volume prune

 创建容器时挂载 Volume

# 将数据卷v-redis挂载到容器内的/usr/local/redis目录
docker run -d --name redis-demo -p 6379:6379 \
    -v v-redis:/usr/local/redis \
    redis:7.0.5

网络操作 / Network Operation

查看网络列表

# 语法:docker network ls [OPTIONS]
docker network ls

创建 Docker 网络

# 语法:docker network create [OPTIONS] NETWORK
# -d 等价于 --driver
docker network create -d bridge nw-redis-b

创建容器时指定 Network 

docker run -d --name redis-demo-nw -p 6378:6379 \
    --network nw-redis-b \
    redis:7.0.5

运行中的容器连接 Docker 网络

# 语法:docker network connect [OPTIONS] NETWORK CONTAINER
docker network connect nw-redis-b redis-demo

运行中的容器断开Docker网络

# 语法:docker network disconnect [OPTIONS] NETWORK CONTAINER
docker network disconnect nw-redis-b redis-demo

删除Docker网络

# 语法:docker network rm NETWORK [NETWORK...]
docker network rm nw-redis-b

清理未使用的 Docker 网络

# 语法:docker network prune [OPTIONS]
docker network prune

Docker 命令使用技巧

如果要查看完整的 Docker 命令,可以参考官方文档:链接

下面分享一些使用技巧

Docker 帮助手册

Docker 的所有命令,都可以使用 --help 查看帮助手册

docker --help 
docker images --help
docker ps --help
docker network create --help

Docker 命令通用参数总结

显示所有

###### --all / -a ######

# 一些示例
docker images -a
docker ps -a

只显示 Docker 对象 ID

###### --quiet / -q ######

# 一些示例
docker images -q
docker ps -q
docker network ls -q
docker volume ls -q

过滤器

###### --filter / -f ######

# 一些示例
docker ps -f status=exited