Docker 是什么

  1. 容器化技术
  2. 沙箱环境
  3. 开源
  4. 虚拟机

它是 dotCloud 公司内部的项目,在 2013 年 3 月进行了开源。开源后受到了大家的喜爱,以及在开源社区的帮助下,快速迭代完善。目前来说已经是比较主流的工程化技术
同时 dotCloud 公司看到它这么火,在 2013 年年底公司改名为 docker

实现的基本原理是技术 linux 内部的容器化技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。

Docker 它的优势

传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;
而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。

更高效的利用系统资源

由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,Docker 对系统资源的利用率更高。无论是应用执行速度、内存损耗或者文件存储速度,都要比传统虚拟机技术更高效。因此,相比虚拟机技术,一个相同配置的主机,往往可以运行更多数量的应用。

更快速的启动时间

传统的虚拟机技术启动应用服务往往需要数分钟,而 Docker 容器应用,由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间。

一致的运行环境

开发过程中一个常见的问题是环境一致性问题。由于开发环境、测试环境、生产环境不一致,导致有些 bug 并未在开发过程中被发现。而 Docker 的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现 「这段代码在我机器上没问题啊」 这类问题。

持续交付和部署

对开发和运维人员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。

使用 Docker 可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过 Dockerfile来进行镜像构建,并结合持续集成(Continuous Integration)系统进行集成测试,而运维人员则可以直接在生产环境中快速部署该镜像,甚至结合 持续部署(Continuous Delivery/Deployment)系统进行自动部署。

而且使用 Dockerfile 使镜像构建透明化,不仅仅开发团队可以理解应用运行环境,也方便运维团队理解应用运行所需条件,帮助更好的生产环境中部署该镜像。

更轻松的迁移

由于 Docker 确保了执行环境的一致性,使得应用的迁移更加容易。Docker 可以在很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运行结果是一致的。因此用户可以很轻易的将在一个平台上运行的应用,迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。

更轻松的维护和扩展

Docker 使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。此外,Docker 团队同各个开源项目团队一起维护了一大批高质量的 官方镜像,既可以直接在生产环境使用,又可以作为基础进一步定制,大大的降低了应用服务的镜像制作成本。

对比传统虚拟机总结

特性 容器 虚拟机
启动 秒级 分钟级
硬盘使用 一般为 MB 一般为 GB
性能 接近原生 弱于
系统支持量 单机支持上千个容器 一般几十个

Docker 基本概念

  1. 镜像
  2. 容器
  3. 仓库

Docker 操作镜像

获取镜像

docker search name

Docker Hub上搜索镜像

docker pull name

Docker Hub上下载镜像

1
docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]

具体的选项可以通过 docker pull --help 命令看到,这里我们说一下镜像名称的格式。

列出镜像

docker images

默认的 docker images 命令将显示所有顶级镜像,其存储库和标签,以及它们的大小。

1
2
3
4
5
6
7
8

docker images

# 展示所有可用的帮助
docker images --help

# 过滤支持多个条件 格式为 "key=value"
docker images --filter

删除

1
2
3

docker rmi [OPTIONS] IMAGE [IMAGE...]

部分可选参数

参数 描述 是否可多传
-f - 强制删除 不可
–no-prune - 不移除该镜像的过程镜像,默认移除 不可

制作一个镜像

1
2
3
4
5

docker build -t <imageTag> .

docker build -t myweb:v1.0.0 .

Docker 操作容器

生成

1
2
3
4

docker run -d --name myweb1 -p 8080:80 myweb:v1.0.0

docker run -d --name myweb1 -p 8080:80 -v /Users/cander/code/docker/web/html:/usr/share/nginx/html myweb:v1.0.0

部分可选参数

参数 描述 是否可多传
-d - 是否后台(守护)运行 不可
–name 指定的容器名称 容器名称 不可
-p 物理机端口:容器内端口 端口映射 可以
-v 物理机路径:容器内路径 文件路径映射 可以
-e key=”value” 设置环境变量 可以

列出容器

1
2
3
4
5
# 查看正在运行的容器
docker ps

# 查看所有包含未启动的容器
docker ps -a

日志相关

创建一个容器的时候,对于未加 -d 参数的容器。默认是将日志打印到宿主机的终端,而加了 -d的容器,默认会被保存,使用以下命令可查看

1
2
3
4
5
6
7
# 查新容器的日志
docker logs 容器ID/容器名称

docker logs

docker logs ff7dde02c0c9 --tail=2 --since=2022-06-11T06:58:54.285623583Z

部分可选参数

参数 描述 是否可多传
-f - 是否跟踪日志 不可
-t - 显示日志的时间 docker 自己记录的时间 不可
–tail 数字 从最新像前输出的日志 不可以
–since 时间戳(docker)自身 显示自某个 timestamp 之后的日志,或相对时间,如 42m(即 42 分钟) 不可以

删除

1
docker rm 容器ID/容器名称 容器ID/容器名称

重启容器

1
docker start 容器ID/容器名称 容器ID/容器名称

停止容器

1
docker stop 容器ID/容器名称 容器ID/容器名称

进入容器

1
docker exec -it 容器ID/容器名称 bash

私有仓库

登录

1
2
# 登录到目标仓库
docker login <仓库地址 默认官方仓库> -u 用户名 -p 密码

登录后会在 ~/.docker/config.json中存储你的登录信息。一般来说一次登录即可

推送

1
2
3
4
5
6
# 登录到目标仓库
docker login <仓库地址 默认官方仓库> -u 用户名 -p 密码

docker push 仓库地址:imageTag

docker push 127.0.0.1:5000/ubuntu:latest

拉取

1
2
3
4
5
docker login <仓库地址 默认官方仓库> -u 用户名 -p 密码
# 私有仓库
docker pull image <仓库地址 默认官方仓库> -u 用户名 -p 密码

docker pull 127.0.0.1:5000/ubuntu:latest

Docker 配置文件 DockerFile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
FROM  镜像名称:tag

# 设置环境变量
ENV NODE_MODEL="devlop"

# 执行某些命令
RUN mkdir -p /user/cander

# 指定工作的目录
WORKDIR /user/cander

# 复制文件
COPY 文件地址 目标文件地址

# curl -s http://myip.ipip.net
# 容器启动时执行的命令
CMD [ "curl", "-s", "http://myip.ipip.net" ]

# 容器启动时执行的命令
ENTRYPOINT [ "curl", "-s", "http://myip.ipip.net" ]
# ENTRYPOINT 和 CMD 均可以字符串 或 数组形式存在
# 区别在于容器启动时 如果有 新的参数传入时 CMD会启动失败
# 例如 现在我们有一个镜像 myIp
# docker run myIp -i 时 CMD形式镜像会报错

# 对外的端口 运行时 可指定宿主机像这些端口的映射
EXPOSE 8001 8002