Docker

基本组成

镜像image

镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。

docker镜像就类似于一个模板,可以通过镜像来创建容器服务。

容器container

通过docker镜像可以创建一个或多个容器,容器提供服务。也可以理解为一个实例。

仓库repository

存放镜像的地方

  • 公有仓库

  • 本地仓库

流程概述

image-20230714110859753

常用命令

镜像

  • 查看本地镜像

docker images
-a #列出所有镜像
-q #只显示镜像ID
  • 搜索镜像

docker search 镜像名
  • 下载镜像

docker pull 镜像名[:tag]
  • 删除镜像

docker rmi -f 镜像ID

容器

  • 运行一个容器

docker run [options] image
--name=“” #给容器起名称
-d        #后台方式运行
-it       #使用交互方式运行,进入容器查看内容
-p        #指定容器的端口
    -p [ip:]主机端口:容器端口
    -p 容器端口
-P        #随机指定端口
  • 查看当前运行的容器

docker ps
-a            #列出当前运行的容器和历史运行过的容器
-n=          #显示最近创建的容器
-q            #只显示容器编号
  • 退出容器

exit   #退出并停止容器
Ctrl+p+q    #退出但是不停止容器
  • 删除容器

docker rm 容器ID
docker rm $(docker ps -aq) #删除所有容器
  • 容器状态操作

docker start 容器ID      #启动容器
docker restart 容器ID    #重启容器
docker stop 容器ID       #停止容器
docker kill 容器ID       #强制停止容器

其他

  • 查看日志

docker logs [options] 容器ID
-tf              #显示日志
--tail number    #显示number条日志
  • 查看容器内部的进程信息

docker top 容器ID
  • 查看容器元数据

docker inspect 容器ID
  • 进入当前正在运行的容器

# 方法一:
# 进入容器后开启一个新的终端
docker exec -it 容器ID /bin/bash
# 方法二:
# 进入容器正在运行的终端,不会启动新的进程
docker attach 容器ID
  • 从容器内拷贝文件到主机上

docker cp 容器ID:容器内路径 宿主主机路径
  • 从主机内拷贝文件到容器中

docker cp 宿主主机路径 容器ID:容器内路径

提交镜像

命令:

docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]

默认提交到本地

容器数据卷

什么是容器数据卷?

假如我们的数据都存在容器中,那么删除容器会导致数据也被删除。可是我们需要的是持久化数据并且可以将数据存储到宿主机上。所以容器数据卷应运而生。

综上,Docker 容器的数据卷是用于在容器和主机之间持久化存储和共享数据的一种机制。数据卷可以在容器中的指定路径挂载一个目录或文件,使得容器中的数据能够跨多个容器实例、容器的重启以及容器与主机之间进行共享。

使用数据卷

使用命令来挂载 -v

docker run -it -v 主机目录:容器内目录 image
  • 查看所有数据卷的信息

docker volume ls

匿名挂载

当我们在挂载的时候指定了容器内路径却没有指定容器外路径时,就是匿名挂载

具名挂载

当我们在挂载时指定了卷名和容器内路径,但是没有指定容器外路径时就是具名挂载

例如:

docker run it --name test -v 卷名:容器内路径[:ro或rw] image
ro #只读,只能通过宿主机进行操作,容器内部无法修改
rw #可读可写

数据卷容器

  • 两个或多个容器同步数据

image-20230728112142160

  • 命令

docker run -it --name=xxx --volumes-from 父容器名 image

Dockerfile

Dockerfile是用于定义Docker镜像构建过程的文本文件(可以理解成脚本文件)。它包含了一系列指令和配置,用于指导Docker引擎在构建Docker镜像时执行的操作。通过编写Dockerfile,您可以自动化定义和构建镜像,以便重复部署和扩展应用程序。

步骤:

  1. 编写一个dockerfile

  2. build出一个镜像

  3. 运行镜像生成容器

  4. 发布镜像

一个简单的dockerfile

# 设置基础镜像
FROM <base_image>

# 将工作目录切换至 /app
WORKDIR /app

# 复制所需文件到容器中
COPY . /app

# 执行安装或构建操作
RUN <install_command>

# 暴露容器的端口(如果需要)
EXPOSE <port>

# 定义容器启动时要执行的命令
CMD [ "<command>" ]

指令

注意

  • 每个关键字都必须大写

  • 执行顺序从上到下

  • #表示注释

  • 每一个指令都会创建提交一个新的镜像层并提交

指令名

内容

FROM

基础镜像

MAINTAINER

镜像作者信息,一般是名称+邮箱

RUN

镜像构建时执行的命令

ADD

用于将源文件、目录或远程 URL 添加到容器的文件系统中。会自动解压文件。

WORKDIR

镜像的工作目录

VOLUME

挂载的容器卷路径

EXPOSE

指定对外的端口

CMD

指定这个容器启动的时候要运行的命令(容器内执行),只有最后一个CMD命令会生效。

ENTRYPOINT

指定这个容器启动的时候要运行的命令(容器内执行)

COPY

将我们文件拷贝到镜像中

ENV

构建的时候设置环境变量

CMD

CMD是Dockerfile中的一条指令,用于定义容器启动时要执行的命令。

在Dockerfile中,可以有多个CMD指令,但只有最后一个CMD指令会生效。CMD指令有以下几种形式:

  1. 执行可执行文件:

    CMD ["executable", "param1", "param2"]

    例如:

    CMD ["npm", "start"]

    这表示在容器启动时,会执行npm start命令。

  2. 作为参数传递给ENTRYPOINT指令:

    CMD ["param1", "param2"]

    ENTRYPOINT指令配合使用,将CMD指定的参数作为ENTRYPOINT指定的可执行文件的参数。 例如:

    ENTRYPOINT ["echo", "Hello"]
    CMD ["World"]

    这样,在容器启动时,会执行echo Hello World命令。

  3. 作为默认命令:

    CMD command param1 param2

    当没有显式的ENTRYPOINT指令时,CMD指定的命令会作为容器启动时的默认命令。 例如:

    CMD npm start

    这表示在容器启动时,默认执行npm start命令。

CMD指令可以在Dockerfile中出现多次,但只有最后一个CMD指令会生效。如果在使用docker run命令启动容器时提供了参数,这些参数将会覆盖CMD指令中的默认命令。

通过dockerfile构建镜像

docker build -f dockerfile路径 -t 镜像:[版本号] .

docker build 命令中,. 表示当前上下文路径。它告诉 Docker 在当前目录中查找 Dockerfile 和构建上下文。构建上下文是指在构建过程中将传递给 Docker 守护程序的文件和目录。这些文件和目录将被打包并发送到 Docker 守护程序,用于构建镜像。Docker 守护程序在构建时会基于此上下文进行操作。通过将 . 作为构建上下文,可以将当前目录中的所有文件和目录都包含在构建过程中,从而使Dockerfile 中的相关指令能够访问这些文件和目录。

发布镜像

发布到阿里云

  • 登录阿里云

  • 申请镜像仓库

  • 使用方法见阿里云官方文档

Docker网络

原理:

我们每启动一个docker容器,docker就会给docker容器分配一个IP,我们只要安装了docker,就会有一个网卡docker0,桥接模式,使用的技术是veth-pair技术。

veth-pair就是一对虚拟设备接口,一端连着协议,一端彼此相连

理解Docker0

docker0 是 Docker 在安装时创建的默认网络接口。它是一个虚拟以太网桥,用于连接 Docker 主机和容器。

当 Docker 在主机上启动时,会创建一个名为 docker0 的虚拟网络接口,并分配一个 IP 地址。这个接口充当了主机和容器之间的桥梁,使得容器可以通过这个接口与主机进行通信,同时也可以通过该接口与其他容器进行通信。

默认情况下,docker0 接口的 IP 地址为 172.17.0.1,并且它作为 Docker 主机的默认网关和默认路由器。此外,每当启动一个新的容器时,Docker 会为其分配一个在 docker0 网络上的唯一 IP 地址,这样容器就可以与主机和其他容器进行通信。

通过 ifconfigip addr 命令,可以查看到 docker0 接口及其配置信息。

需要注意的是,如果您使用了自定义的 Docker 网络配置,可能不会出现默认的 docker0 接口。在某些情况下,也可以使用其他名称的接口来替代 docker0

图解

veth-pair充当的就是桥

image-20230728213604613

--link

语法:

docker run -d --name 容器名1 --link 容器名2 镜像名

注意:

  • --link是单向链接,也就是在容器1中可以ping通容器2,反之则ping不通

  • --link本质上是修改了本地的hosts文件

自定义网络

查看所有的docker网络

docker network ls

网络模式:

名称

功能

bridge

桥接模式,默认

none

不配置网络

host

和宿主机共享网络

container

容器网络连通

命令

docker network create --friver 网络模式 --subnet 子网范围 --gateway 网关 自定义网络名称

网络连通

假设以下情景

image-20230728221804232

我们想要将一个子网中的一个容器与另一个子网相连,直接ping是不通的。可以通过

docker network connect 自定义网络名 容器名

这种连通方式是一个容器多个IP,类似于公网和内网IP。