基础概念
镜像
- Docker 镜像是一个只读模板,它包含了运行一个容器所需的文件系统和应用程序。镜像可以被看作是容器运行的基础,它定义了容器启动时的初始状态。
- 一旦镜像被创建,其内容就不可更改。如果需要修改镜像中的内容,必须重新构建一个新的镜像。这种不可变性使得镜像具有很强的稳定性和一致性。例如,在开发环境中构建好的镜像,部署到生产环境时,其行为和功能是可预期的,因为镜像的内容不会发生变化。
- Docker 镜像是由一系列的层(Layer)组成的。每一层代表了镜像构建过程中的一个操作。例如,安装一个软件包、复制文件等操作都会生成新的层。这种分层结构使得镜像的构建更加高效。当构建新的镜像时,如果某些层已经存在,Docker 可以重用这些层,而不需要重新构建,从而节省时间和存储空间
容器
- Docker 容器是镜像的运行实例。它是一个隔离的、轻量级的运行环境,基于镜像创建。容器可以包含应用程序及其依赖项,并在隔离的环境中运行。
- 容器之间是相互隔离的,每个容器都有自己独立的文件系统、网络接口、进程空间等。例如,一个容器中的进程无法直接访问另一个容器中的文件,这使得容器之间的运行互不干扰,提高了系统的安全性。
镜像和容器的关系
- 镜像是容器的模板
- 容器是基于镜像创建的,镜像定义了容器的初始状态,包括文件系统、应用程序及其依赖项等。一个镜像可以创建多个容器实例,每个容器都是独立运行的。
- 容器是镜像的运行实例
- 容器是镜像的动态表现形式,它在运行时可以对镜像的内容进行修改(如生成临时文件、运行应用程序等)。容器的运行状态和数据是独立于镜像的,但容器的初始状态是由镜像决定的。
常用命令
docker pull
1 2 3
| docker pull [OPTIONS] NAME[:TAG | @DIGEST] docker pull ubuntu:14.04 docker pull ubuntu #默认latest
|
docker run
docker run命令首先在指定的映像上创建一个可写的容器层,然后使用指定的命令启动它。这个实际上会自动从官方仓库中下载本地没有的镜像。更多是使用会在后面创建容器的部分介绍
1
| docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
|
1
| sudo docker run --rm -it --gpus all --name test -v /home/mydataroot:/tcdata:ro nvidia/cuda:10.0-base /bin/bash
|
- -d 启动Docker容器时,必须首先确定是要在后台以“分离”模式还是在默认前台模式下运行容器:-d,这里没有指定-d则是使用默认前台模式运行。两种模式下,部分参数配置不同,这部分细节可以参考文档:https://docs.docker.com/engine/reference/run/#detached-vs-foreground
使用镜像nvidia/cuda:10.0-base创建容器,并对容器起一个别名test。
- 对于该容器,开启gpu支持,并且所有GPU都可用,但是前提你得装好nvidia-docker。
- –rm 表示退出容器的时候自动移除容器,在测试环境等场景下很方便,不用再手动删除已经创建的容器了。
- -t 和 -i:-i 保持 STDIN 打开,-t 分配一个伪终端。
- 后面的/bin/bash的作用是表示载入容器后运行bash。docker中必须要保持一个进程的运行,要不然整个容器启动后就会马上kill itself,这样当你使用dockerps查看启动的容器时,就会发现你刚刚创建的那个容器并不在已启动的容器队列中。这个/bin/bash就表示启动容器后启动bash。
- -v表示将本地的文件夹以只读(:ro,读写可以写为:rw,如果不加,则默认的方式是读写)的方式挂载到容器中的/tcdata目录中。
- -p
-p 8080:80
将容器的 80 端口映射到宿主机的 8080 端口
docker load
docker load是Docker提供的一个命令,它用于从文件中加载之前保存的镜像。这个文件可以是镜像的tar归档文件,通常是由dockersave命令生成的。使用dockerload可以方便地在不同的Docker主机之间迁移镜像,或者在重新安装Docker后恢复镜像。
1
| docker load -i myimage.tar
|
docker rmi
删除指定的镜像
- 使用IMAGE ID:docker rmi fd484f19954f
- 使用TAG: docker rmi test:latest
- 使用DIGEST: docker rmi localhost:5000/test/busybox@sha256:cbbf2f9a99b47fc460d422812b6a5adff7dfee951d8fa2e4a98caa0382cfbdbf
docker save
docker save是一个Docker命令,用于将本地Docker镜像保存为一个tar文件。这个文件可以用于备份、传输或存储镜像。保存的文件包含了镜像的所有层以及相关的元数据。
1
| docker save -o myimage.tar myimage:latest
|
其他
- 创建容器
docker create --name mycontainer ubuntu
- 停止容器
docker stop mycontainer
- 启动容器
docker start mycontainer
- 重启容器
docker restart mycontainer
- 删除容器
docker rm mycontainer
- 列出容器
docker ps
- 列出所有容器(包括未运行的)
docker ps -a
- 查看容器日志
docker logs mycontainer
- 进入容器
docker exec -it mycontainer bash
在名为 mycontainer 的容器内启动一个交互式的 Bash shell
- 复制文件
docker cp mycontainer:/path/in/container /path/on/host
- 附加到容器
docker attach mycontainer
- 分离
docker detach mycontainer
- 查看容器信息
docker inspect mycontainer
- 暂停容器
docker pause mycontainer
- 恢复容器
docker unpause mycontainer
- 导入容器
docker import mycontainer.tar mycontainer:backup
- 查看镜像
docker image
建立镜像和容器
dockerfile
- FROM
- 设置基础镜像,所有后续的指令都基于此镜像。
FROM ubuntu:20.04
- LABEL
- 为镜像添加元数据
LABEL <key>=<value> <key>=<value> ...
- RUN
- 执行命令,可以是安装软件包、创建文件等。
RUN apt-get update && apt-get install -y nginx
- CMD
- 指定容器启动时运行的命令。
CMD ["nginx", "-g", "daemon off;"]
- ENTRYPOINT
- 配置容器启动时执行的命令,可以与 CMD 指令组合使用。
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2
- EXPOSE
- 声明容器运行时监听的端口(其实只是告诉容器这些端口开放)。
EXPOSE 80 443
- ADD
- 将文件、目录或者远程文件(URL)从构建上下文(build context)或远程位置复制到新镜像的指定路径
ADD localfile.txt /app/
复制本地文件到镜像中的 /app 目录
ADD http://example.com/remotefile.txt /app/
从URL下载文件,并将其保存到镜像中的/app 目录
- COPY
- 文件或目录从构建上下文(build context)复制到 Docker 镜像中指定的路径
COPY ./file.txt /app/
- WORKDIR
为 Docker 镜像设置一个工作目录
WORKDIR /path/to/workdir
- USER
- 指定运行容器时使用的默认用户
USER <user>[:<group>]
- VOLUME
- STOPSIGNAL
- 指定停止容器时 Docker 发送到容器的信号
STOPSIGNAL 9
- HEALTHCHECK
HEALTHCHECK --interval=5s --timeout=3s CMD curl -f http://localhost/ || exit 1
--interval=
设置健康检查的时间间隔(默认是 30 秒)
--timeout=
设置检查超时时间(默认是 30 秒)
--retries=
设置在认为容器不健康之前,需要连续多少次检查失败(默认是 3 次)
--start-period=
设置容器启动后多长时间开始执行健康检查(仅在 Docker 1.12 及以后版本中可用)。
CMD
指定执行健康检查的命令
- ARG
- 用于定义一个变量,这个变量可以在构建过程中被使用,也可以在构建时通过命令行参数传入
ARG <name>[=<default value>]
网络
brige
这是 Docker 默认的网络模式,适用于同一宿主机上的容器通信。创建 Bridge 网络并连接容器的命令如下
1 2
| docker network create my-bridge-network docker run -d --name my-container --network my-bridge-network --ip 192.168.1.100 nginx
|
host网络
1
| docker run -d --name my-container --network host nginx
|
None 网络
1
| docker run -d --name my-container --network none nginx
|
Overlay网络
用于跨多个 Docker 主机的容器间通信,适用于 Docker Swarm 集群。创建并连接到 Overlay 网络的命令如下
1 2 3
| #还有其他流程 docker network create --driver overlay my-overlay-network docker run -d --name my-container --network my-overlay-network nginx
|
Macvlan 网络
1 2
| docker network create -d macvlan --subnet=192.168.1.0/24 --gateway=192.168.1.1 -o parent=eth0 my-macvlan-network docker run -d --name my-container --net my-macvlan-network nginx
|