Docker

介绍

Docker是开发,运行和部署应用程序的开放管理平台。

  • 开发人员能利用Docker开发和运行应用程序。
  • 运维人员能利用Docker部署和管理应用程序。

可以简单理解为:使用主机内核的虚拟机,不需要和虚拟机一样需要自己独立的操作系统,因此比虚拟机更轻量。

作用及解决

  • Docker可以将应用程序和基础架构分开,便于程序和软件的交付。
  • 借助Docker可以像管理应用程序一样管理基础架构。
  • 借助Docker可以快速进行传输、测试和部署,可以缩短代码的编写和在生产环境运行之间的时间差。

Docker主要解决的问题:

  • 保证程序运行环境的一致性。
  • 降低配置开发环境和生产环境的复杂度和成本。
  • 实现程序的快速部署和开发。

Docker引擎

Docker Engine是一个包含以下组件的客户端-服务端(C/S)应用程序。

  • 服务端:一个长时间运行的守护进程(Docker Daemon)。
  • Rest API:一套用于与Docker Daemon通信并指示其执行操作的接口。
  • 客户端:命令行接口CLI(Command Line Interface)。
  • CLI利用Docker命令通过Rest API直接操作Docker Daemon运行。
  • Docker Daemon负责创建并管理Docker的对象(镜像、容器、网络、数据卷)。

Docker结构

image-20231108212141416

  • Docker客户端(Docker Client):

    • 是用户与Docker进行交互的最主要方式。当在终端输入docker命令时,对应的就会在服务端产生。对应的作用,并把结果返回给客户端。Docker Client除了连接本地服务端,通过更改或指定DOCKER_ HOST连接远程服务端。
  • Docker服务端(Docker Server):

    • Docker Daemon其实就是Docker 的服务端。它负责监听Docker APl请求(如Docker Client)并管理Docker对象。
  • Docker Registries:

    • 俗称Docker仓库,专门用于存储镜像的云服务环境。Docker Hub就是一个公有的存放镜像的地方,类似Github存储代码文件。同样的也可以类似Github那样搭建私有的仓库。
  • Docker对象(Docker Objects):

    • 镜像:一个Docker的可执行文件,其中包括运行应用程序所需的所有代码内容、依赖库、环境变量和配置文件等。
    • 容器:镜像被运行起来后的实例。
    • 网络:外部或者容器间如何互相访问的网络方式,如host模式、bridge模式。
    • 数据卷:容器与宿主机之间、容器与容器之间共享存储方式,类似虚拟机与主机之间的共享文件目录。

底层技术

Docker使用Go语言实现,利用Linux内核的几个特性来实现:

  • 命名空间(Name Space):为Docker容器提供操作系统层面的隔离。
  • 控制组(Control Groups):为Docker容器提供硬件层面的隔离。
  • 联合文件系统(Union File Systems):利用分层思想管理镜像和容器。

而Windows和MacOS则借助了虚拟化技术,使其在这些操作系统上得以运行Docker。

容器格式

Docker Engine将Linux的三个特性进行组合成一个package,这就是一个容器格式(Container Format)。

Docker通过package对这三个特性进行管理控制实现容器的创建和生命周期的管理。

容器格式有很多种,其中Docker目前使用的容器格式称为libcontrainer。

版本

  • Docker-CE:Docker社区版,由社区维护和提供技术支持,是免费版本,适合个人开发和小团队使用。
  • Docker-EE:Docker企业版,是收费版本,有售后团队和技术团队提供技术支持,专为企业开发和IT团队设计,在社区版的基础上增加一些额外功能,提供了更重要的安全保障。

其中,Stable版按季度发布,更加稳定;Edge版按月发布,供测试使用。

各平台安装

CentOS中安装

Install Docker Engine on CentOS | Docker Docs

  1. 卸载
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
  1. 更新系统工具
sudo yum install -y yum-utils
  1. 添加软件源
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo

可替换阿里云源:https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

或在 /etc/yum.repos.d/docker-ce.repo中将download.docker.com​替换为mirrors.aliyun.com/docker-ce

  1. 安装Docker
sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
  1. 启动Docker
sudo systemctl start docker
  1. 查看安装
sudo docker run hello-world

Ubuntu中安装

Install Docker Engine on Ubuntu | Docker Docs

  1. 卸载
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done
  1. 更新apt及安装证书
sudo apt-get update

sudo apt-get install ca-certificates curl gnupg

sudo install -m 0755 -d /etc/apt/keyrings

curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

sudo chmod a+r /etc/apt/keyrings/docker.gpg

echo \
"deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
"$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt-get update

可替换阿里云源:https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg

  1. 安装并启动Docker
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
  1. 查看安装
sudo docker run hello-world

MacOS中安装

Install Docker Desktop on Mac | Docker Docs

Windows中安装

Install Docker Desktop on Windows | Docker Docs

Docker镜像加速

容器镜像服务 (aliyun.com)

  • https://docker.1panel.dev
  • https://dockerpull.org
  • https://docker.unsee.tech
  • https://docker.m.daocloud.io

Ubuntu/CentOS镜像加速

  1. 创建配置文件夹
sudo mkdir -p /etc/docker
  1. 写入配置
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://xxx.mirror.aliyuncs.com"]
}
EOF

加速器地址请自行替换。

  1. 重载进程
sudo systemctl daemon-reload
  1. 重启Docker
sudo systemctl restart docker

服务端配置

为了让其他第三方客户端连接到Docker Server,我们需要进行一些配置。

  1. 编辑配置文件
vim /usr/lib/systemd/system/docker.service
  1. ExecStart​行尾添加-H tcp://0.0.0.0:2375
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock -H tcp://0.0.0.0:2375
  1. 重启服务
sudo systemctl daemon-reload

sudo systemctl restart docker
  1. CentOS开启2375端口
# 开放端口
sudo firewall-cmd --zone=public --add-port=2375/tcp --permanent
# 重载防火墙
sudo firewall-cmd --reload
# 查看开放端口
sudo firewall-cmd --list-ports

镜像

介绍

Docker镜像是一个轻量级、可执行的独立软件包,它包含了运行某个应用所需要的所有内容,包括代码、运行时环境、库、环境变量和配置文件等。镜像是 Docker 容器的基础,容器通过镜像创建并运行。

特点:

  1. 只读层: Docker镜像的每一层都是只读的,当你创建一个新的镜像时,Docker会通过层叠的方式将每个更改应用到现有镜像的基础上。每一层都代表着 Docker 镜像的某个状态,比如安装一个新的包或更改配置文件。
  2. 层次结构: 镜像的构建是层叠的。每个命令(如 RUN​、COPY​ 等)都会在镜像中生成一个新的层。这使得 Docker 在存储和管理镜像时非常高效,因为相同的层可以被多个容器共享,而不必重复存储。
  3. 可复用性: 因为镜像是基于层的,Docker 提供了镜像复用机制。如果多个镜像使用了相同的底层镜像,那么这些镜像共享底层层,节省存储空间。
  4. 跨平台性: Docker镜像可以在不同的操作系统和架构上运行,只要Docker引擎支持该平台。通常,镜像包含了与应用相关的所有依赖,使得在不同环境中部署应用变得更加容易。

镜像管理

搜索

作用:搜索Docker Hub 镜像仓库的镜像。

命令格式:

docker search [OPTIONS] TERM

命令参数(OPTIONS):

  • -f,–filter filter:根据提供的格式筛选结果(如-f is-official=true​、-f is-automated=true​)。
  • –format string:使用Go语言format格式化输出结果。
  • –limit int:展示最大结果数,默认25个。
  • –no-trunc:完全内容展示。

查看

作用:列出本地镜像。

命令格式:

docker images [OPTIONS] [REPOSITORY[:TAG]]
# 或
docker image ls [OPTIONS] [REPOSITORY[:TAG]]

命令参数(OPTIONS):

  • -a,–all:展示所有镜像(默认隐藏底层镜像)。
  • –no-trunc:完全内容展示。
  • -q,–quiet:只展示镜像ID。

下载

作用:拉取远程镜像仓库(如:Docker Hub 镜像仓库)到本地。

命令格式:

docker pull [OPTIONS] NAME[:TAG|@DIGEST]

命令参数(OPTIONS):

  • -a,–all-tags:下载所有符合tag的镜像。
  • –platform:指定镜像运行的平台(arm64、amd64)。

删除

作用:删除一个或多个本地镜像。

命令格式:

docker rmi [OPTIONS] IMAGE [IMAGE...]
# 或
docker image rm [OPTIONS] IMAGE [IMAGE...]

命令参数(OPTIONS):

  • -f,–force:强制删除。

删除所有镜像:

docker rmi -f `docker images -aq`

保存

作用:将一个或多个本地镜像保存为本地tar文件(输出到STDOUT)。

命令格式:

docker save [OPTIONS] IMAGE [IMAGE...]

命令参数:

  • -o,–output string:指定导出的文件名和路径(使用>​重定向也可)。

加载

作用:将保存的tar文件加载到本地镜像库。

命令格式:

docker load [OPTIONS]

命令参数(OPTIONS):

  • -i,–input string:指定导入文件路径(加载到STDIN)。
  • -q,–quiet:不打印加载信息。

改名

作用:将本地镜像的NAME、TAG进行重命名,并产生一个新镜像引用。

命令格式:

docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]

详情

作用:查看一个或多个本地镜像详情信息。

命令格式:

docker image inspect [OPSTION] IMAGE [IMAGE...]
# 或
docker inspect [POSTION] IMAGE [IMAGE...]

可搭配| grep keyword​输出指定字段信息。

命令参数(OPSTIONS):

  • -f,–format string:使用Go语言format格式化输出结果。

历史

作用:查看本地镜像的历史(分层)信息。

命令格式:

docker history [OPTIONS] IMAGE

命令参数(OPTIONS):

  • -H,–human:优化打印创建时间、大小(默认为true)。
  • -q,–quiet:只显示镜像ID。
  • –no-trunc:完全内容展示。

容器

容器(Container)是一种轻量级、可移植、可将程序打包的技术,使应用程序可以在几乎任何地方以相同的方式运行。

Docker将镜像文件运行起来后,产生的对象就是容器,容器相当于是镜像运行起来的一个实例,具备一定的生命周期。

容器与虚拟机

相同点:

  • 都会对物理硬件资源进行共享使用。
  • 生命周期比较相似(创建、运行、暂停、关闭等等)。
  • 都可以安装各种应用,如redlis、 mysql、 nginx等。
  • 资源会存储在宿主机上:linux上位于 /var/lib/docker/containers下。

不同点:

  • 虚拟机的生命周期基于一个完整的操作系统,而容器则直接运行在宿主的内核上,由一系列进程结合。
  • 虚拟机是重量级的,会消耗更多资源,而容器是轻量级的,不需要额外的资源来管理(Hypervisor、GuestOS)程序。

生命周期

image-20231109152004579

容器管理

创建

作用;使用镜像创建一个Created状态的待启动的容器。

命令格式:

docker create [OPTIONS] IMAGE [COMMAND] [ARG...]

命令参数(OPTIONS):

  • -i,–interactive:关联STDIN。
  • -t,–tty:分配一个伪TTY(虚拟终端)。
  • –name:容器命名。
  • –rm:关闭容器时自动删除容器。

命令参数(COMMAND/ARG):

  • COMMAND:容器启动后,在容器内执行的命令,也是容器的主进程。
  • ARG:COMMAND执行时提供的参数。

启动

作用:启动一个或多个容器。

命令格式:

docker start [OPTIONS] CONTAINER [CONTAINER...]

命令参数(OPTIONS):

  • -a,–attach:关联STDOUT/STDERR。
  • -i,–interactive:关联STDIN。

重启

作用:重启一个或多个容器。

命令格式:

docker restart [OPTIONS] CONTAINER [CONTAINER...]

命令参数(OPTIONS):

  • -t,–time int:等待N秒后重启容器(默认10s)。

运行

作用:使用镜像创建并启动一个容器。

指令格式:

docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
# 等价
docker create + docker start -a

命令参数(OPTIONS):

  • -i,–interactive:保持STDIN打开。
  • -t,–tty:分配一个伪TTY(虚拟终端)。
  • -d,–detach:容器运行在后台并打印容器ID。
  • -e,–env list:设置容器中运行时的环境变量。
  • -a,–attach list:关联STDIN、STDOUT、STDERR。
  • -v,–volume list:绑定数据卷。
  • –rm:关闭容器时自动删除容器。
  • –restart string:重启配置(默认no​,如always​)

暂停

作用:暂停一个或多个容器的所有进程。

命令格式:

docker pause CONTAINER [CONTAINER...]

恢复

作用:恢复一个或多个暂停的容器。

命令格式:

docker unpause CONTAINER [CONTAINER...]

关闭

作用:关闭一个或多个运行/暂停的容器。

命令格式:

docker stop [OPTIONS] CONTAINER [CONTAINER...]

先发送SIGTERM​,后发送SIGKILL​。

命令参数(OPTIONS):

  • -t,–time int:等待N秒后关闭容器(默认10s)。

杀死

作用:杀死一个或多个运行/暂停的容器。

命令格式:

docker kill [OPTIONS] CONTAINER [CONTAINER...]

直接发送SINGKILL

命令参数(OPTONS):

  • -s,–signal:发送一个信号给容器(默认kill​)。

删除

作用:删除一个容器。

命令格式:

docker rm [OPTIONS] CONTAINER [CONTAINER...]

命令参数(OPTIONS):

  • -f,–force:强制删除一个运行中的容器。
  • -l,–link:删除指定链接。
  • -v,–volumes:删除指定数据卷。

详情

作用:查看一个或多个本地容器的详情信息。

命令格式:

docker container inspect [OPTIONS] CONTAINER [CONTAINER...]
# 或
docker inspect [OPTIONS] CONTAINER [CONTAINER...]

可搭配| grep keyword​输出指定字段信息。

命令参数(OPTIONS):

  • -f,–format string:使用Go语言format格式化输出结果。
  • -s,–size:显示总大小。

日志

作用:查看容器日志信息(来自COMMAND产生的STDOUT)。

命令格式:

docker logs [OPTIONS] CONTAINER

命令参数(OPTIONS):

  • –details:显示额外信息。
  • -f,–follow:动态跟踪显示日志信息。
  • –until string:只显示某时间节点之前的信息。
  • –since string:只显示某时间节点之后的信息。
  • –tail string:显示倒数几条信息(默认全部)。
  • -t,–timestamps:显示timestamps时间。

改名

作用:重命名一个容器。

命令格式:

docker rename CONTAINER NEW_NAME

拷贝

作用:用于宿主机与容器之间、容器与容器之间的文件拷贝。

命令格式:

docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|SRC_PATH CONTAINER:DEST_PATH

命令参数(OPTIONS):

  • -a,–archive:归档模式(复制所有uid/gid等信息)。
  • -L,–follow-link:在SRC_PATH携带link符号。
  • -q,–quiet:拷贝过程中不输出内容。

运行操作

连接

作用:将当前终端的STDIN、STDOUT、STDERR关联到正在运行容器的主进程上实现连接。

命令格式:

docker attach [OPTIONS] CONTAINER

退出会关闭主进程而导致容器关闭。

命令参数(OPTIONS):

  • –no-stdin:不关联STDIN。
执行

作用:在容器中运行命令。

命令格式:

docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

退出不会影响主进程,因此退出不会导致容器关闭。

命令参数(OPTIONS):

  • -d,–detach:后台运行命令。
  • -i,–interactive:关联STDIN。
  • -t,–tty:分配一个伪TTY(虚拟终端)。
  • -w,–workdir string:指定到容器的工作目录。
  • -e,–env list:设置容器运行时的虚拟环境。

命令参数(COMMAND/ARG):

  • COMMAND:在容器内执行的命令。
  • ARG:COMMAND执行时提供的参数。

容器与镜像的关系

关系图

image-20231109182315023

操作

提交

作用:根据容器生成一个镜像(基于该容器)。

命令格式:

docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

命令参数(OPTIONS):

  • -a,–author string:指定作者。
  • -c,–change list:添加Dockerfile命令。
  • -m,–message string:提交时添加注释。
  • -p,–pause:提交时暂停容器(默认true)。

导出

作用:将容器当前的文件系统导出为tar文件。

命令格式:

docker export [OPTIONS] CONTAINER

命令参数(OPTIONS):

  • -o,–output string:指定导出的文件名和路径(默认STDOUT)。

导入

作用:将导出的tar文件导入到本地镜像库为一个新镜像。

命令格式:

docker import [OPTIONS] file|URL|- [REPOSITORY[:TAG]]

命令参数(OPTIONS):

  • -c,–change list:添加Dockerfile命令。
  • -m,–message string:导入时添加注释

联合文件

Docker镜像与容器的底层都是基于联合文件系统的。

image-20231109191757777

通过inspect​命令可以查看镜像的Layer层级,通过commit​命令修改文件系统会覆盖Layer。

image-20231109185812609

image-20231109190024949

通过create​命令会创建一层可读写的Layer,通过commit​命令会将可读写Layer添加为一层只读Layer,与之前的Layer合并为一个镜像。

image-20231109191245557

image-20231109191358752

image-20231109191607957

网络

作用

容器的网络默认与宿主机、与其他容器都是相互隔离的。

在开发和使用过程中,容器与宿主机之间、容器与容器之间通常都是有网络需求的,此时我们就可以使用Docker中的网络管理对其进行操作。

驱动模式

Docker有5种内置网络驱动模式

  • Bridge network模式(网桥):默认的网络模式,类似虚拟机的nat模式(应用较多)。
  • Host network模式(主机):容器直接使用宿主机的网络(性能最好)。
  • None network模式(null):容器禁用所有网络。
  • Overlay network模式(覆盖):利用VXLAN实现的bridge模式。
  • Macvlan network模式(Mac):容器具备Mac地址,使其显示为网络上的物理设备。

特殊的驱动模式:Container network模式(应用较多)。

bridge网络模式

image-20231110133659640

  • 宿主机上需要单独的bridge网卡,如docker默认创建的docker0。
  • 容器与容器、容器与主机之间的网络通信,是借助每一个容器生成的一对veth pair虚拟网络设备对进行通信的。
  • 每创建一个bridge网络的容器,都会在宿主机上创建一个vethxxx的虚拟网络设备。
  • 外部无法直接访问容器,需要端口映射才能访问。
  • 容器借助veth虚拟设备通过docker0这种bridge网络设备进行通信。
  • 每一个容器具备独立IP。

host网络模式

image-20231110140548333

  • 容器完全共享宿主机的网络,无网络隔离。
  • 容器和宿主机上的应用所使用的端口不能重复。
  • 外部可以直接访问容器,不需要端口映射。
  • 容器IP就是宿主机的IP。

none网络模式

  • 容器上无网络,也没有任何网络设备。
  • 如果需要使用网络,需要用户自行安装与配置。
  • 适合高度定制网络的情景使用。

overlay网络模式

image-20231110143655679

  • 网络的实现方式和方案有很多,Docker中是基于VXLAN隧道技术(会在TCP/IP的网络层封装一个自己的IP和Mac地址传输到各个容器)实现。
  • 主要用于实现跨主机容器之间的通信,适合涉及跨主机的容器集群管理的情景使用。

macvlan网络模式

image-20231110145004309

  • 网络通信直接基于Mac地址进行转发,让容器像一个真实物理设备。
  • 宿主机充当二层交换机,Docker会维护一个Mac地址表,根据地址表找到对应的容器并进行传输。
  • 容器之间可以直接通过IP互通,通过宿主机上内建的虚拟网络设备,但是与主机无法直接使用IP互通。
  • 对于每个外来数据报都是与容器Mac地址进行通信的场景使用。

container网络模式

image-20231110150314824

会将指定的容器作为“主机”并共享其网络,与指定的容器无网络隔离。

docker run/create --network container:CONTAINER ...

网络管理

查看

作用:查看已经建立的网络对象。

命令格式:

docker network ls [OPTIONS]

命令参数(OPTIONS):

  • -f,–filter filter:根据提供的格式筛选结果。
  • –format string:使用Go语言format格式化输出结果。
  • –no-trunc:完全内容展示。
  • -q,–quiet:只输出网络对象的ID。

创建

作用:创建新的网络对象。

命令格式:

docker network create [OPTIONS] NETWORK

命令参数(OPTIONS):

  • -d,–driver string:指定网络的驱动(默认bridge)。
  • –subnet string:指定子网网段(如192.168.0.0/16)。
  • –ip-range string:指定容器IP范围,subnet子集。
  • –gateway string:指定子网IPv4或IPv6网关(如192.168.0.1)。

注意:

  • host、none模式网络只能存在一个。
  • Docker自带的overlay模式创建依赖Docker swarm(集群负载均衡)服务。
  • 192.168.0.0/16 == 192.168.0.0 ~ 192.168.255.255
  • 172.88.0.0/24 == 172.88.0.0 ~ 172.88.0.255

删除

作用:删除一个或多个网络。

命令格式:

docker network rm NETWORK [NETWORK]

详情

作用:查看一个或多个网络的详情信息。

命令格式:

docker network inspect [OPTIONS] NETWORK [NETWORK...]
# 或
docker inspect [OPTIONS] NETWORK [NETWORK...]

命令参数(OPTIONS):

  • -f,–format string:使用Go语言format格式化输出结果。

使用

作用:为启动的容器指定网络。

命令格式:

docker run/create --network NETWORK ...

默认使用名为bridge的网络。

连接/断开

作用:连接/断开指定容器与网络。

命令格式:

docker network connect/disconnect [OPTIONS] NETWORK CONTAINER

命令参数(OPTIONS):

  • -f,–force:强制断开连接。

注意:

  • 不能用于host网络、overlay网络的连接与断开。
  • none网络、overlay网络和其他网络不能同时连接。
  • bridge网络和macvlan网络可以同时连接多个。

端口映射

作用:用于bridge网络模式下,外部访问容器内部服务。

命令格式:

docker run/create -P/-p ...

命令参数:

  • -P,–publish-all:将容器内所有暴露的端口进行随机映射。
  • -p,–publish list:手动指定端口映射。

注意:

-p [HOST_IP]:[HOST_PORT]:CONTAINER_PORT

  • -p ::80​:将容器的80端口随机映射到主机任意IP随机端口。
  • -p :16379:6379​:将容器的6379端口映射到主机任意IP的16379端口。
  • -p 192.168.0.0::3306​:将容器的3306端口映射到主机该IP的随机端口。
  • -p 192.168.0.1:13306:3306​:将容器的3306端口映射到主机该IP的13306端口。

数据卷

简介

问题:

  • 宿主机无法直接访问容器中的文件。
  • 容器中的文件无法持久化,导致容器删除后,文件数据也随之丢失。
  • 容器之间也无法直接访问互相的文件

数据卷解决:

  • 容器与主机之间、容器与容器之间共享文件。
  • 容器中的数据持久化。
  • 容器中的数据备份、迁移、恢复。

特点

  • 数据卷存在于宿主机的文件系统中,独立于容器,和容器的生命周期是分离的。
  • 数据卷可以目录也可以是文件,容器可以利用数据卷与宿主机进行数据共享,实现了容器间的数据共享和交换。
  • 容器启动初始化时,如果容器使用的镜像包含了数据,这些数据会拷贝到数据卷中。
  • 容器对数据卷的修改是实时进行的。
  • 数据卷的变化不会影响镜像的更新。数据卷是独立于联合文件系统,镜像是基于联合文件系统。镜像与数据卷之间不会有相互影响。

挂载方式

  • bind mounts:将宿主机上的文件或目录挂载到容器上。
  • volume mounts:由Docker创建和管理的。
  • tmps mounts:基于内存的临时文件系统,不会存储在磁盘上。

挂载

bind挂载

命令格式:

docker run/create -v,--volume HOST_DIR:CONTAINER_DIR ...
# 或
docker run/create --mount type=bind,src=HOST_DIR,dst=CONTAINER_DIR ...

注意:

  • 路径必须是绝对路径。
  • src指定的路径必须存在。

volume挂载

命令格式:

docker run/create -v,--volume VOLUME_NAME:CONTAINER_DIR ...
# 或
docker run/create --mount type=volume,src=VOLUME_NAME,dst=CONTAINER_DIR ...

注意:

  • VOLUME_NAME是数据的名称,会将容器的目录挂载到宿主机的 /var/lib/docker/volumes/VOLUME_NAME/_data上。
  • 如果不指定VOLUME_NAME,则会使用随机名称。
  • VOLUME_NAME不存在则会创建,存在则直接使用。

temps挂载

命令格式:

docker run/create --tmpfs CONTAINER_DIR [CONTAINER_DIR...] ...
# 或
docker run/create --mount type=tmpfs,dst=CONTAINER_DIR ...

数据卷容器挂载

作用:使用另一个容器的数据卷达到数据卷共享。

命令格式:

docker run/create --volumes-from CONTAINER ...

数据卷管理

查看

作用:查看所有volume对象。

命令格式:

docker volume ls [OPTIONS]

命令参数(OPTIONS):

  • -f,–filter filter:根据提供的格式筛选结果(如dangling=true​)。
  • –format string:使用Go语言format格式化输出结果。
  • -q,–quiet:只展示数据卷ID。

详情

作用:查看一个或多个数据卷的详情信息。

命令格式:

docker volume inspect [OPTIONS] VOLUME [VOLUME...]
# 或
docker inspect [OPTIONS] VOLUME [VOLUME...]

命令参数(OPTIONS):

  • -f,–format string:使用Go语言format格式化输出结果。

创建

作用:创建一个volume对象。

命令格式:

docker volume create [OPTIONS] [VOLUME]

命令参数(OPTIONS):

  • -d,-- driver string:指定数据卷driver(默认local)。
  • –label list:设置元信息。
  • -o,–opt map:设置driver指定选项(默认map[])。

删除

作用:删除一个或多个数据卷对象。

命令格式:

docker volume rm [OPTIONS]

命令参数(OPTIONS):

  • -f,–force:强制删除。

清理

作用:删除未被使用的数据卷对象。

命令格式:

docker volume prune [OPTIONS]

命令参数(OPTIONS):

  • -a,–all:删除所有未被使用的数据卷。
  • –filter filter:根据提供的格式删除数据卷(如label=LABEL​)。
  • -f,–force:强制删除。

注意事项

  • 如果挂载一个空的数据卷到容器中的一个非空目录中,那么容器目录下的文件会被复制到宿主机的数据卷中。
  • 如果挂载一个非空的数据卷到容器中的一个目录中,那么容器中的目录中会显示数据卷中的数据。如果原来容器中的目录中有数据,那么这些原始数据会被隐藏掉。

这两个规则都非常重要,灵活利用第一个规则可以帮助我们初始化数据卷中的内容。掌握第二个规则可以保证挂载数据卷后的数据总是你期望的结果。

远程仓库

简介

Docker仓库上存放docker镜像,可以通过pull命令下载的云环境。

分为公有仓库和私有仓库。知名的公有仓库有 Docker Hub

仓库搭建

无认证私有仓库的搭建

  1. 在服务器上安装并配置docker。
  2. 启动仓库。
docker run -dti --restart always \
--name my-registry -p 5000:5000 \
-v /my-registry/registry:/var/lib/registry \
registry

registry镜像默认开放5000端口,默认镜像存放路径是 /var/lib/registry

带认证私有仓库的搭建

  1. 在服务器上安装并配置docker。
  2. 创建存放认证用户名和密码。
mkdir /my-registry/auth -p
  1. 创建验证文件。
docker run --entrypoint htpasswd registry \
-Bbn USER_NAME PASSWORD > /my-registry/auth/htpasswd

"htpasswd": executable file not found in $PATH解决思路:

安装签证工具:

# CentOS
yum -y install httpd-tools

# Ubuntu
apt-get install apache2-utils

创建验证文件:

htpasswd -Bbn  USER_NAME PASSWORD > /my-registry/auth/htpasswd
  1. 启动仓库。
docker run -d -p 5000:5000 --restart always \
--name my-registry \
-v /my-registry/registry:/var/lib/registry \
-v /my-registry/auth:/auth \
-e "REGISTRY_AUTH=htpasswd" \
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
-e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" \
registry

仓库管理

可使用HOST_IP:PORT/v2/_catalog​查看仓库的镜像。

登录

在带认证私有仓库进行上传和下载镜像时,需要先进行登录。

docker login -u USER_NAME -p PASSWORD HOTS_IP:PORT

注销

执行完毕后,可退出该认证。

docker logout HOST_IP:PORT

上传

  1. 重命名:想要对上传的镜像进行重命名,命名格式如下。
docker tag IMAGE HOST_IP:PORT/IMAGE_NAME
  1. 上传镜像:将重命名后镜像上传到服务器的私有仓库。
docker push HOST_IP:PORT/IMAGE_NAME

出现https错误,是因为创建的仓库默认使用http协议,而push默认使用https协议。

解决思路:使用http协议,修改配置文件 /etc/docker/daemon.json,添加"insecure-registries":["HOST_IP:PORT"]​,重启Docker。

下载

从指定的无认证私有仓库下载镜像。

docker pull HOST_IP:PORT/IMAGE_NAME

Dockerfile

简介

是根据特定的语法格式撰写出来的一个普通文件。

利用docker build命令(基于commit命令)依次执行在Dockerfile中定义的一系列命令,最终生成一个新镜像(定制镜像)。

各大官方镜像Dockerfile文档

使用

使用Dockerfile进行构建。

命令格式:

docker build [OPTIONS] PATH|URL|-

命令参数(OPTIONS):

  • -t,–tag list:指定镜像名及版本。
  • -f,–file string:指定自定义Dockerfile文件。

注意:

  • Dockerfile中的每一步操作都会产生一层历史记录。
  • 第一次构建后,后面的构建过程中,会在更改的位置及之后的步骤重新执行,否则将会使用已有的镜像缓存。

Dockerfile指令

Dockerfile reference

常用指令如下:

  • FROM:指定基础镜像。
  • RUN:构建镜像过程中需要执行的命令(一般使用shell方式)。
  • CMD:添加启动容器时需要执行的命令,只会执行最后一条,且会被覆盖(一般使用exec方式)。
  • ENTRYPOINT:同CMD,且必须执行,不会被覆盖(一般使用exec方式)。
  • LABEL:给镜像添加对应的说明数据。
  • MAINTAINER:指定镜像作者(已被遗弃)。
  • EXPOSE:设置对外暴露的端口,用于端口映射。
  • ENV:设置执行命令时的环境变量,在构建完后依然生效。
  • ARG:设置只在构建过程中使用的环境变量,构建完后失效。
  • COPY:将本地文件或目录拷贝到镜像的文件系统中。
  • ADD:同COPY,且解压特定格式文件,可使用URL。
  • VOLUME:添加数据卷。
  • USER:指定以哪个用户的权限执行RUN、CMD、ENTRYPOINT等命令。
  • WORKDIR:设置工作目录。
  • ONBUILD:在引用另一个Dockerfile之前,执行一些操作。
  • STOPSIGNAL:设置容器退出时发出的关闭信号。
  • HEALTHCHECK:设置容器状态检查。
  • SHELL:更改执行shell命令的程序(Linux默认为["/bin/sh", "-c"]​、Windows默认为["cmd", "/S", "/C"]​。

示例

如:构建一个 Flask 项目的 Dockerfile

# 1. 使用 Python 官方镜像作为基础镜像
FROM python:3.9-slim

# 2. 设置工作目录
WORKDIR /app

# 3. 复制 requirements.txt 文件到容器中
COPY requirements.txt /app/

# 4. 安装项目依赖
RUN pip install --no-cache-dir -r requirements.txt

# 5. 复制项目文件到容器中
COPY . /app/

# 6. 暴露容器端口,Flask 默认使用 5000 端口
EXPOSE 5000

# 7. 设置容器启动时执行的命令,启动 Flask 应用
CMD ["python", "app.py"]

Docker Compose

简介

Docker Compose 是用于定义和运行多容器 Docker 应用程序的工具。 借助 Compose,我们可以使用 YAML 文件来配置应用程序的服务。 只需一个命令,即可创建并启动所有服务。一般与Dockerfile搭配使用。

安装

Mac和Windows安装Docker后会携带Docker Compose,而Linux则需要额外安装,由于我们在安装docker时已经一起安装了,如未安装可按以下方式安装。

查看docker-compose版本:

docker compose version

出现版本即已安装。

自动安装

# Ubuntu
sudo apt-get update
sudo apt-get install docker-compose-plugin

# CentOS
sudo yum update
sudo yum install docker-compose-plugin

手动安装

  1. 下载安装包
DOCKER_CONFIG=${DOCKER_CONFIG:-$HOME/.docker}

mkdir -p $DOCKER_CONFIG/cli-plugins

curl -SL https://github.com/docker/compose/releases/download/v2.23.0/docker-compose-linux-x86_64 -o $DOCKER_CONFIG/cli-plugins/docker-compose

arm架构的可下载:https://github.com/docker/compose/releases/download/v2.23.0/docker-compose-linux-aarch64

其他版本请参考:Releases · docker/compose

  1. 执行文件
chmod +x $DOCKER_CONFIG/cli-plugins/docker-compose

TOP配置参数

Compose file官方文档

Docker Compose File顶级配置项:

  • version、name:指定Docker Compose File版本号、名称。
  • services:定义多个服务并配置启动参数。
  • network:指定在多个服务中共同使用的网络对象。
  • volumes:声明或创建在多个服务中共同使用的数据卷。
  • config:声明在本服务中要使用的一些配置文件。
  • secrets:声明在本服务中要使用的一些密钥、密码文件。
  • x-***:自定义配置,用于复用多个服务的相同配置。

单机部署

使用Docker Compose File在单个机器部署一系列服务。

使用Node.js和MongoDB的docker-compose.yaml​:

version: '3.8'

services:
webapp:
image: node:14
container_name: my_webapp
working_dir: /app
ports:
- "3000:3000"
volumes:
- ./webapp:/app
env_file:
- .env
command: npm start
depends_on:
- database
networks:
- my_network

database:
image: mongo:latest
container_name: my_mongo
ports:
- "27017:27017"
volumes:
- mongo_data:/data/db
env_file:
- .env

networks:
my_network:
driver: bridge

volumes:
mongo_data:

其中的.env​文件内容如下:

# .env
NODE_ENV=development
DEBUG=my_webapp:*

MONGO_INITDB_ROOT_USERNAME=root
MONGO_INITDB_ROOT_PASSWORD=123456

集群部署

集群部署的方案有很多,可以使用docker内置的Swarm,也可以使用Kubernetes