前言

视频参考:b站狂神(讲的很好)

一、Docker 概述

Docker 出现的背景

Docker 出现之前,开发和运维之间经常出现:开发人员能运行,运维不能运行的问题,本质上就是环境和配置的问题。

Docker 针对这一问题,给出了一个标准化的解决方案,即将整体(代码、配置、系统、数据…)打包给运维。

传统:只交代码

现在:交整个环境(镜像)

Docker 简介

Docker 是一种开源的容器化平台,可以帮助开发人员、系统管理员和运维团队更轻松地打包、交付和运行应用程序。使用 Docker,你可以将应用程序及其所有依赖项打包到一个称为容器的标准化单元中。

特点:

  • 轻量级的容器化技术
  • 快速部署
  • 环境一致性
  • 资源隔离
  • 可移植性
  • 方便管理

容器化技术和虚拟机技术的区别:

二、Docker 常用命令

查看信息(Engine)

1
2
3
4
5
# 查看版本信息
docker -v

# 查看系统信息
docker info

镜像命令(Images)

查看本机所有镜像

docker images

1
2
3
4
5
6
7
8
9
[root@VM-12-10-centos ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE

# 解释
REPOSITORY 镜像的仓库源
TAG 镜像的标签
IMAGE ID 镜像的 id
CREATED 镜像的创建时间
SIZE 镜像的大小

搜索镜像

docker search

1
2
3
4
5
6
7
[root@VM-12-10-centos ~]# docker search mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mariadb MariaDB Server is a high performing open sou… 5722 [OK]
mysql MySQL is a widely used, open-source relation… 15008 [OK]

# 过滤,例如 STARS 3000以上
docker search mysql --filter=STARS=3000

下载镜像

docker pull

1
2
3
4
5
[root@VM-12-10-centos ~]# docker pull mysql
Using default tag: latest

# 选择版本
docker pull 镜像:版本

删除镜像

docker rmi

1
2
3
4
5
6
# 删除单个
docker rmi -f 镜像id
# 删除多个
docker rmi -f 镜像id 镜像id 镜像id
# 删除所有
docker rmi -f $(docker images -aq)

容器命令(Container)

注意:有了镜像之后才可以创建容器

1
2
# 例如,下载 centos 镜像
docker pull centos

新建容器并启动

docker run

1
2
3
4
5
6
7
8
docker run [OPTIONS] IMAGE

# 常用参数
--name="xxx" 容器名
-d 后台方式运行
-it 使用交互方式运行
-p 指定容器的端口
-P 随机指定端口

列出运行的容器

docker ps

1
2
3
4
5
6
7
[root@VM-12-10-centos ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

# 常用参数
-a 列出所有运行过的容器
-n=? 显示最近的容器
-q 只显示容器的id

退出容器

  • exit:停止容器并退出
  • ctrl + P + Q:容器不停止退出

删除容器

docker rm

1
2
docker rm 容器id
docker rm -f $(docker ps -aq)

启动和停止容器

1
2
3
4
docker start 容器id     # 启动
docker restart 容器id # 重启
docker stop 容器id # 停止
docker kill 容器id # 强制停止

进入当前正在运行的容器

1
2
3
4
5
# 1.exec,开启新的终端
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

# 2.attach,进入正在执行的终端
docker attach [OPTIONS] CONTAINER

从容器内拷贝到主机

1
docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH

查看日志

1
docker logs [OPTIONS] CONTAINER

查看容器中的进程信息

1
docker top CONTAINER [ps OPTIONS]

查看容器元数据

1
docker inspect [OPTIONS] NAME|ID [NAME|ID...]

附:Docker 命令示意图

三、Docker 镜像

什么是镜像

Docker 镜像是一个轻量级、独立的、可执行的软件包,其中包含了运行一个特定应用程序所需的所有内容,包括代码、运行时、库、环境变量和配置文件等。

所有应用直接打包成 Docker 镜像,就能直接运行。

获得镜像的方式:

  • 远程仓库下载
  • 拷贝
  • 自己制作一个 DockerFile

镜像加载原理

Docker 镜像加载的原理涉及到 Docker 的分层存储和联合文件系统。

  1. 分层存储:Docker 镜像采用分层存储的方式组织。每个镜像由多个只读层(layers)组成,每一层包含了文件系统的一部分。这些层是按照添加的顺序叠加在一起的,最底部是基础镜像的层,然后是每次修改的增量层。这种设计使得镜像可以有效地共享公共部分,节省存储空间,并且提高了镜像的构建和传输效率。
  2. 联合文件系统:Docker 使用联合文件系统(UnionFS)来将这些层组合成一个单独的文件系统。联合文件系统允许将多个只读文件系统挂载到同一个目录下,使得它们看起来像是一个单独的文件系统。当一个容器基于某个镜像运行时,Docker 会将这个镜像的各个层加载到容器的文件系统中,形成一个统一的文件系统视图。
  3. 加载过程
    • 当你运行一个基于 Docker 镜像的容器时,Docker 首先会检查本地是否已经存在相应的镜像。如果本地不存在,Docker 就会从远程仓库下载镜像。
    • 下载完成后,Docker 会将镜像的各个层加载到本地,并在内存中构建一个容器的文件系统。这个文件系统包含了镜像的所有内容,但是是一个只读文件系统。
    • 接下来,Docker 在容器的顶部添加一个可写层,这个可写层用于容器中的文件写操作。这样,容器就可以在只读的基础上进行文件的修改和添加,而不会影响到原始的镜像。

通过分层存储和联合文件系统,Docker 实现了高效的镜像加载和容器运行机制,使得容器可以快速启动并且占用较少的系统资源。

commit 镜像

使用 docker commit 命令可以将一个正在运行的容器保存为一个新的镜像:

1
2
3
4
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]

# 例如:
docker commit -a="作者" -m="描述" 容器id 镜像名:标签

四、容器数据卷

什么是容器数据卷

容器数据卷(Container Volumes)是 Docker 中用于持久化数据的一种机制。它允许容器与宿主机之间或者容器之间共享数据,并且可以在容器之间持久化存储数据,即使容器被删除也不会丢失。

容器数据卷的使用

命令行方式:

1
docker run -v /host/path:/container/path ...

Dockerfile 中定义:

1
VOLUME /data

示例:MySQL 持久化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 1.获取镜像
docker pull mysql

# 2.启动容器
# 官方命令:docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tagdocker run -d -p
docker run -d -p 服务器端口:容器端口 -v /home/mysql:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=数据库密码 --name mysql01 mysql

# 3.测试连接
# 我使用的 navicat,主机添服务器 ip,密码添上边设置的密码

# 4.删除 mysql 容器
docker rm mysql01

# 5.本地查看数据文件
cd /home/mysql
ls
# 可以发现数据卷挂载到本地后,即使删除了容器,数据也不会丢失

具名挂载和匿名挂载

卷命令:docker volume

1
2
3
4
5
6
7
8
# 查看所有卷
docker volume ls

# 我们可以看到 VOLUME NAME 由一群看不懂的数字和字母组成,这就是匿名挂载
local 3a1345898f97e14edbd3fe8...

# 具名挂载
docker run -d -P --name=xxx -v 具名:容器内路径 容器id

通过具名挂载,可以很方便的找到卷。

挂载分类:

1
2
3
-v 容器内路径 # 匿名挂载
-v 具名:容器内路径 # 具名挂载
-v /宿主机路径:容器内路径 # 指定路径挂载

拓展知识:设置文件权限

1
2
3
4
# ro 只读,只能通过宿主机操作文件
docker run -d -P --name xxx -v xxx:/...:ro CONTAINER
# rw 读写
docker run -d -P --name xxx -v xxx:/...:rw CONTAINER

容器间的数据共享

除了容器与宿主机之间的数据共享外,容器间也可以数据共享。

1
2
3
4
5
# 创建一个容器和数据卷
docker run --name 父容器 -v /data centos

# 容器挂载
docker run --name 新的容器 --volumes-from 父容器 -d CONTAINER

示例:多个 MySQL 实现数据共享

1
2
3
4
5
# 新建一个 MySQL 容器
docker run -d -p 服务器端口:容器端口 -v /etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=数据库密码 --name mysql01 mysql

# 另一个 MySQL 容器
docker run -d -p 服务器端口:容器端口 -e MYSQL_ROOT_PASSWORD=数据库密码 --name mysql02 --volumes-from mysql01 mysql

五、Dockerfile

Dockerfile 介绍

Dockerfile 是一种用于定义 Docker 镜像的文本文件。它包含了一系列的指令,这些指令描述了在基础镜像上执行的操作,以及如何构建最终的镜像。使用 Dockerfile,开发人员可以自动化地构建定制化的镜像,这些镜像包含了他们的应用程序及其运行所需的所有环境和依赖项。

Dockerfile 通常由以下几个部分组成:

  1. 基础镜像选择:指定要使用的基础镜像,可以是官方提供的镜像,也可以是其他已有的自定义镜像。
  2. 环境配置:安装所需的软件包、库和依赖项,设置环境变量等。
  3. 文件复制:将本地文件复制到镜像中,以包含应用程序代码、配置文件等。
  4. 运行命令:定义容器启动时要执行的命令,通常是启动应用程序的命令。
  5. 暴露端口:指定容器中的应用程序将监听的端口。
  6. 其他定制化操作:根据需要执行其他定制化操作,比如设置工作目录、执行脚本等。

Dockerfile 中的常用指令

1
2
3
4
5
6
7
8
9
10
FROM         # 基础镜像
RUN # 镜像中执行命令
ADD # 将文件从本地系统复制到镜像中。支持更高级的功能,例如解压文件
COPY # 将文件从本地系统复制到镜像中
WORKDIR # 设置工作目录
EXPOSE # 指定容器运行时监听的端口
VOLUME # 创建挂载点
CMD # 定义容器启动时要执行的命令。CMD 用于指定默认的容器执行命令
ENTRYPOINT # 定义容器启动时要执行的命令。ENTRYPOINT 用于配置容器的执行入口
ENV # 设置环境变量
  • CMD 和 ENTRYPOINT 区别

    CMD 指定默认命令;ENTRYPOINT 指定执行入口,可以与用户提供的命令参数组合使用。

Dockerfile 构建镜像

docker build

1
docker build -f dockerfile路径 -t 镜像名:[tag] .

发布镜像

  1. 官网注册:https://hub.docker.com/

  2. 服务器上登录

    1
    docker login -u username
  3. 提交镜像

    1
    docker push username/name:tags