1.Docker概述
1.1.官方网站
dockerhub
:https://hub.docker.com/
docker-destop
:https://www.docker.com/products/docker-desktop/
1.2.什么是Docker?
Docker
本身是一个软件容器平台。也就是说,平常我们经常说的【使用Docker
】,实际上是【使用这个平台上的容器】。
在Docker
中存在三个重要概念:镜像、容器和仓库。使用Docker
的过程一般如下:
-
dockerfile
,自动化脚本,主要用来创建镜像。 -
image
,镜像,约等于一个虚拟机的快照,里面包含了要部署的应用程序和它关联的所有库。 -
通过镜像,我们可以创建许多个
container
,容器。容器互不影响,容器里面直接运行了应用程序。所以镜像和容器的关系就像是类和实例的关系。
1.2.1.镜像(Image):特殊的文件系统
Docker
镜像,就相当于是一个 root
文件系统,且是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。
镜像不包含任何动态数据,其内容在构建之后也不会被改变。Docker
设计时,就充分利用 Union FS
的技术,将其设计为分层存储的架构。
镜像实际是由多层文件系统联合组成。镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。 比如,删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。 所以在最终容器运行的时候,虽然不会看到这个文件,但是实际上该文件会一直跟随镜像。
分层存储的特征还使得镜像的复用、定制变的更为容易。甚至可以用之前构建好的镜像作为基础层,然后进一步添加新的层,以定制自己所需的内容,构建新的镜像。
1.2.2.容器(Image):镜像运行时的实体
容器可以被创建、启动、停止、删除、暂停等 。容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间。前面讲过镜像使用的是分层存储,容器也是如此。
按照 Docker
最佳实践的要求,容器不应该向其存储层内写入任何数据 ,容器存储层要保持无状态化。所有的文件写入操作,都应该使用数据卷(Volume)、或者绑定宿主目录。
在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。因此, 使用数据卷后,容器可以随意删除、重新run
,数据却不会丢失。
1.2.3.仓库(Repository):集中存放镜像文件的地方
一个 Docker Registry
中可以包含多个仓库;每个仓库可以包含多个标签(Tag
);每个标签对应一个镜像。通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本 。
我们可以通过<仓库名>:<标签>
的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest
作为默认标签.。
而 Docker Registry
服务还分为公有和私有的概念。最常使用的 Registry
公开服务是官方的 Docker Hub
,其实就类似Github
啦。
除了直接通过Docker Hub
网站搜索镜像这种方式外,我们还可以通过 docker search
这个命令搜索 Docker Hub
中的镜像,搜索的结果是一致的。
➜ ~ docker search mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 8763 [OK]
mariadb MariaDB is a community-developed fork of MyS… 3073 [OK]
mysql/mysql-server Optimized MySQL Server Docker images. Create… 650 [OK]
国内也有一些云服务商提供类似于 Docker Hub
的公开服务。比如 网易云镜像服务、阿里云镜像库等。
1.3.Docker(容器) vs 虚拟机(VM)
如果你开发了一款软件,想要发布到云上给用户使用。那么你需要保证该用户的环境能够保证运行该软件。最简单地就是保证该用户的环境与你本地环境一致。
此时我们会想到虚拟机,但是虚拟机需要模拟硬件来运行整个操作系统,不但体积臃肿、内存占用高,还会影响程序的性能。
这时,我们就可以引入Docker
来帮助我们,或者说,引入容器来帮助我们。
容器在概念上与虚拟机非常类似,但轻量很多。因为容器虚拟化的是操作系统,而不是硬件,具体可见下图(图来源javaGuide
):
- 虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;
- 而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。
因此容器更容易移植,效率也更高。
一句话概括容器:容器就是将软件打包成标准化单元,以用于开发、交付和部署。
在应用层面上来说,
- 云服务提供商通常采用虚拟机技术隔离不同的用户。
- 而
Docker
通常用于隔离不同的应用 ,例如前端,后端以及数据库。
1.4.常见命令
1.4.1.查看和拉取
docker version # 查看docker版本
docker images # 查看所有已下载镜像,等价于:docker image ls 命令
docker container ls # 查看所有容器
docker ps #查看正在运行的容器
docker search mysql # 查看mysql相关镜像,默认源是docker hub
docker pull mysql:5.7 # 拉取mysql镜像,默认源是docker hub
1.4.2.构建镜像
# Dockerfile的文件名不必须为 Dockerfile,也不一定要放在构建上下文的根目录中。
# 使用 -f 或 --file 选项,可以指定任何位置的任何文件作为 Dockerfile。
# imageName 是镜像名称,1.0.0 是镜像的版本号或标签
docker build -t imageName:1.0.0 .
1.4.3.暂停容器、删除镜像
首先要确保这个镜像没有被容器引用。通过我们前面讲的docker ps
命令即可查看。
➜ ~ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c4cd691d9f80 mysql:5.7 "docker-entrypoint.s…" 7 weeks ago Up 12 days 0.0.0.0:3306->3306/tcp, 33060/tcp mysql
可以看到 mysql
正在被 id 为 c4cd691d9f80
的容器引用。
我们需要首先通过 docker stop c4cd691d9f80
或者 docker stop mysql
暂停这个容器。
然后查看mysql
镜像的 id
➜ ~ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql 5.7 f6509bac4980 3 months ago 373MB
通过 IMAGE ID
或者 REPOSITORY
名字即可删除
docker rmi f6509bac4980 # 或者 docker rmi mysql
除此之外,我们还可以用docker image prune
来清理临时的、未被使用的镜像文件。-a或者--all
可以删除所有没有用的镜像,而不仅仅是临时文件;
1.4.4.推送镜像
# harbor.example.com是私有镜像仓库的地址,ubuntu是镜像的名称,18.04是镜像的版本标签
docker push harbor.example.com/ubuntu:18.04
务必先登录到对应的镜像仓库。