Docker入门教程:镜像、容器、仓库详解及常用命令
Docker入门教程:镜像、容器、仓库详解及常用命令
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
务必先登录到对应的镜像仓库。