切换主题
Docker
Docker官网:https://www.docker.com/
Docker教程:https://www.runoob.com/docker/docker-tutorial.html
win10家庭版安装Docker:https://blog.csdn.net/m0_37802038/article/details/129893827
使用 docker 打包构建部署 Vue 项目,一劳永逸解决node-sass安装问题:https://segmentfault.com/a/1190000044148106
数据卷(Volumes)简介
Docker网络基础
Docker的基本概念
其包括三个基本概念,理解了这三个概念,就理解了 Docker 的整个生命周期。
镜像(Image)
容器(Container)
仓库(Repository)
核心概念:镜像、容器、仓库
Docker镜像
Docker镜像类似于虚拟机镜像,可以理解为一个面向Docker引擎的只读模板,包含了文件系统。
镜像是创建Docker容器的基础。通过版本管理和增量的文件系统,Docker提供了一套简单的机制来创建和更新现有的镜像,用户设置可以从网上下载一个已经做好的应用镜像,并通过简单的命令就可以直接使用。
操作系统分为 内核 和 用户空间。对于 Linux 而言,内核启动后,会挂载 root 文件系统为其提供用户空间支持。而 docker镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:18.04 就包含了完整的一套 Ubuntu 18.04 最小系统的 root 文件系统。docker镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像 不包含 任何动态数据,其内容在构建之后也不会被改变。
因为镜像包含操作系统完整的 root 文件系统,其体积往往是庞大的,因此在 Docker 设计时,将其设计为分层存储的架构。所以严格来说,镜像并非是像一个 ISO 那样的打包文件,镜像只是一个虚拟的概念,其实际体现并非由一个文件组成,而是由一组文件系统组成,或者说,由多层文件系统联合组成。
镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。比如,删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。在最终容器运行的时候,虽然不会看到这个文件,但是实际上该文件会一直跟随镜像。因此,在构建镜像的时候,需要额外小心,每一层尽量只包含该层需要添加的东西,任何额外的东西应该在该层构建结束前清理掉。
分层存储的特征还使得镜像的复用、定制变的更为容易。甚至可以用之前构建好的镜像作为基础层,然后进一步添加新的层,以定制自己所需的内容,构建新的镜像。
Docker容器
Docker容器类似于一个轻量级的沙箱,Docker利用容器来运行和隔离应用。容器是从镜像创建的应用运行实例,可以将其启动、开始、停止、删除,而这些容器都是互相隔离、不可见的。
容器可以看做一个简易版的Linux系统环境(包括root用户权限、进程空间、用户空间和网络空间等),以及运行在其中的应用程序打包成应用盒子。
镜像自身是只读的。容器从镜像启动的时候,Docker会在镜像的最上层创建一个可写层,镜像本身保持不变。
镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
容器的实质是进程,但与直接在宿主执行的进程不同,容器进程运行于属于自己的独立的命名空间。因此容器可以拥有自己的 root 文件系统、自己的网络配置、自己的进程空间,甚至自己的用户ID空间。容器内的进程是运行在一个隔离的环境里,使用起来,就好像是在一个独立于宿主的系统下操作一样。这种特性使得容器封装的应用比直接在宿主运行更加安全。也因为这种隔离的特性,很多人初学 Docker 时常常会混淆容器和虚拟机。
前面讲过镜像使用的是分层存储,容器也是如此。每一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,我们可以称这个为容器运行时读写而准备的存储层为容器存储层。容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡。因此,任何保存于容器存储层的信息都会随容器删除而丢失。
按照 Docker 最佳实践的要求,容器不应该向其存储层内写入任何数据,容器存储层要保持无状态化。所有的文件写入操作,都应该使用数据卷(Volume)或者绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。因此,使用数据卷后,容器删除或者重新运行之后,数据却不会丢失。
Docker仓库
注册服务器是存放仓库的地方,不能将Docker仓库和注册服务器(Registry)混为一谈。
Docker仓库类似于代码仓库,是Docker集中存放镜像文件的场所。每个仓库放着某一类镜像,往往包括多个镜像文件,通过不同的标签(tag)来区分。 根据所存储的镜像公开与否,Docker仓库可以分为公开仓库和私有仓库两种形式。目前最大的公开仓库是Docker Hub,存放了数量庞大的镜像供用户下载。国内的公开仓库包括Docker Pool等,可以提供稳定的国内访问。Docker也支持用户在本地网络创建一个只能自己访问的私有仓库。
镜像构建完成后,可以很容易的在当前宿主机上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry就是这样的服务。一个 Docker Registry 中可以包含多个仓库(Repository),每个仓库可以包含多个标签(Tag),每个标签对应一个镜像。
通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签>
的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。
Docker Registry 公开服务,Docker Registry 公开服务是开放给用户使用、允许用户管理镜像的 Registry 服务。一般这类公开服务允许用户免费上传、下载公开的镜像,并可能提供收费服务供用户管理私有镜像。
最常使用的 Registry 公开服务是官方的Docker Hub,这也是默认的 Registry,并拥有大量的高质量的官方镜像。由于某些原因,在国内访问这些服务可能会比较慢。国内的一些云服务商提供了针对 Docker Hub 的镜像服务(Registry Mirror),这些镜像服务被称为加速器。常见的有阿里云加速器、DaoCloud加速器等。使用加速器会直接从国内的地址下载 Docker Hub 的镜像,比直接从 Docker Hub 下载速度会提高很多。后续讲解怎么配置加速器。
什么是Docker?
Docker开源项目
Docker是基于Go语言实现的云开源项目,诞生于2013年初,最初发起者为dotCloud公司。Docker项目目前已加入Linux基金会,遵循Apache2.0协议,全部开源代码均在https://github.com/docker/docker上进行维护。
Docker的主要目标是”Build,ship and Run Any App,Anywhere“,即通过对应用组件的封装、分发、部署、运行等生命周期的管理,达到应用级别的”一次封装,到处运行“。这里的应用组件,可以是一个Web应用,也可以是一套数据库服务,甚至是一个操作系统或编译器。
Linux容器技术
Docker引擎的基础是Linux容器(Linux Containers,LXC)技术(容器有效第将由单个操作系统管理的资源划分到孤立的组中,以便更好第在孤立的组之间平衡有冲突的资源使用需求。与虚拟化相比,这样既不需要指令级模拟,也不需要即时编译。容器可以在核心CPU本地运行指令,儿不需要任何专门的解释机制。此外,也避免了准虚拟化和系统调用替换中的复杂性。)
从Linux容器到Docker
在Linux容器的基础上,Docker进一步优化了容器的使用体验。Docker提供了各种容器管理工具(如分发、版本、移植等)让用户无需关注底层的操作,可以简单明了地管理和使用容器。
可以简单地将Docker容器理解为一种沙盒。每个容器内运行一个应用,不同的容器相互隔离,容器之间也可以建立通信机制。容器的创建和停止都十分快速,容器自身对资源的需求也十分有限,远远低于虚拟机。很多时候,甚至直接把容器当作应用本身也没有任何问题。
为什么使用Docker?
Docker容器虚拟化的好处
高效地构建应用
Docker在开发和运维中的优势
- 更快的交付和部署。使用Docker,开发人员可以使用镜像来快速构建一套标准的开发环境;测试和运维人员可以直接使用相同的开发环境来部署代码。Docker可以快速创建和删除容器,实现快速迭代,大量节约开发、测试、部署的时间。并且各个步骤都有明确的配置和操作,整个过程全程课件,使团队更容易理解应用的创建和工作过程。
- 更高效的资源利用。Docker容器的运行不需要额外的虚拟化管理程序支持,它是内核级的虚拟化,可以实现更高的性能,同时对资源的额外需求很低。
- 更轻松的迁移和扩展。Docker容器几乎可以在任意的平台上运行,包括物理机、虚拟机、公有云、私有云、个人电脑、服务器等。
- 更简单的更新管理。使用Dockerfile,只需要小小的配置修改,就可以替代以往大量的更新工作。并且所有修改都可以以增量的方式进行分发和更新,从而实现自动化并且高效的容器管理。
Dcoker与虚拟机比较
- Docker容器很快,启动和停止可以在秒级实现。
- Docker容器对系统资源需求很少,一台主机可以同时运行数千个Docker容器。
- Docker通过类似Git的操作来方便用户获取、分发和更新应用镜像,指令简明,学习成本较低。
- Docker通过Dockerfile配置文件来支持灵活的自动化创建和部署机制,提高工作效率。
特性 | 容器 | 虚拟机 |
---|---|---|
启动速度 | 秒级 | 分钟级 |
硬盘使用 | 一般为MB | 一般为GB |
性能 | 接近原生 | 弱于 |
系统支持量 | 单机支持上千个容器 | 一般几十个 |
隔离性 | 安全隔离 | 完全隔离 |
虚拟化与Docker
在计算领域,一般指的是计算虚拟化,或通常说的服务器虚拟化。(维基百科:在计算机技术中,虚拟化是一种资源管理技术,是将计算机的各种实体资源,如服务器、网络、内存及存储等,予以抽象、转换后呈现出来,打破实体结构间的不可切割的障碍,使用户可以用比原本的组态更好的方式来应用这些资源。)
虚拟化技术分类
- 基于硬件的虚拟化(不常见)
- 基于软件的虚拟化
- 应用虚拟化
- 平台虚拟化
- 完全虚拟化。虚拟机模拟完整的底层硬件环境和特权指令的执行过程,客户操作系统无需进行修改。
- 硬件辅助虚拟化:利用硬件辅助支持处理敏感指令来实现完全虚拟化的功能,客户操作系统无需进行修改。
- 部分虚拟化:只针对部分硬件资源进行虚拟化,客户操作系统需要进行修改。
- 超虚拟化:部分硬件接口以软件的形式提供给客户机操作系统,客户操作系统需要进行修改。
- 操作系统及虚拟化:内核通过创建多个虚拟的操作系统实例来隔离不同的进行。容器相关技术属于这个范畴。
Docker和传统虚拟机方式的不同之处
Docker的核心概念和安装
三大核心概念:镜像、容器、仓库
Docker镜像管理
04.Docker常用基础操作(容器镜像)
Docker镜像管理
镜像是 Docker 的三大组件之一。Docker 运行容器前需要本地存在对应的镜像,如果本地不存在该镜像,Docker 会从镜像仓库下载该镜像,Docker Hub上有大量的高质量的镜像可以用。
镜像是Docker的三大核心概念之一。Docker运行容器前需要本地存在对应的镜像,如果镜像不存在本地,Docker会尝试先从默认镜像仓库下载,用户也可以通过配置,使用自定义的镜像仓库。
获取镜像
镜像是Docker运行容器的前提。使用docker pull
命令从网络上下载镜像。
bash
docker pull NAME[:TAG]
1
若不显式地指定TAG,则默认会选择latest标签,即下载仓库的最新版本的镜像。
bash
docker pull ubuntu
# 指定TAG
docker pull ubuntu:14.04
# 已下载
Using default tag: latest
latest: Pulling from library/ubuntu
c64513b74145: Already exists
01b8b12bad90: Already exists
c5d85cf7a05f: Already exists
b6b268720157: Already exists
e12192999ff1: Already exists
Digest: sha256:aade50db36e1ed96716662cfe748789e154c213a711931c66746c42ce34aa296
Status: Downloaded newer image for ubuntu:latest
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
下载过程可以看出,镜像文件一般由若干层组成,行首的c64513b74145代表了各层的ID。下载过程中会获取病输出镜像的各层信息。层其实是AUFS(Advanced Union File System,一种联合文件系统)中的重要概念,是实现增量保存与更新的基础。
两条安装命令相当于:docker pull registry.hub.docker.com/ubuntu:latest
,即从默认的注册服务器registry.hub.docker.com中的ubuntu仓库下载标记为latest的镜像。
指定完整的仓库注册服务器地址。例如从DockerPool社区的镜像源下载
bash
docker pull dl.dockerpool.com:5000/ubuntu
1
使用镜像创建容器并运行bash应用
bash
docker run -t -i ubuntu /bin/bash
1
查看镜像信息
bash
# 列出本地主机上已有的镜像
docker images
# 来源仓库 标签 镜像的ID号 创建时间 大小
# REPOSITORY TAG IMAGE ID CREATED SIZE
1
2
3
4
2
3
4
TAG信息用来标记来自同一个仓库的不同镜像。仓库中有多个镜像,通过TAG信息来区分发行版本。
bash
# 使用docker tag为本地镜像添加新的标签
docker tag dl.dockerpool.com:5000/ubuntu:latest ubuntu:latest
1
2
2
不同标签的镜像的ID完全一致的,说明它们实际上指向了同一个镜像文件,只是别名不同。标签起到了引用或快捷方式的作用。
docker inspect
可以获取镜像的详细信息,docker inspect
命令返回的是一个JSON格式的消息,若只要其中一项内容,可以使用-f参数指定。
bash
docker inspect 2cb0d9787c4d
# 指定镜像ID时,通常使用该ID的前若干个字符组成的可区分字串来替代完整ID
docker inspect -f {{".Architecture"}} 550
1
2
3
4
2
3
4
搜寻镜像
使用docker search
命令可以搜索远端仓库中的共享的镜像,默认搜索Docker Hub官方仓库中的镜像。
支持的参数:
--automated=false
仅显示自动创建的镜像--no-trunc=false
输出信息不截断显示-s,--starts=0
指定仅显示评价为指定星级以上的镜像
删除镜像
使用docker rmi
可以删除镜像
bash
# IMAGE可以为标签或ID
docker rmi IMAGE
# -f 参数强制执行
docker rmi -f ubuntu
1
2
3
4
2
3
4
当一个镜像拥有多个标签时,docker rmi
只是删除了该镜像多个标签中的指定标签而已,并不影响镜像文件。但当只剩下一个标签时,执行docker rmi
命令会删除这个镜像文件的所有AUFS层。
当使用docker rmi
命令后面跟上镜像ID(也可以是ID能进行区分的部分前缀串)时,会先尝试删除所有指定该镜像的标签,然后删除镜像文件本身。
当有镜像创建的容器存在时,镜像文件默认是无法被删除的。
bash
# 删除依赖该镜像的所有容器
docker rm ubuntu
# 然后再删除镜像
docker rmi ubuntu
1
2
3
4
2
3
4
创建镜像
三种方法:基于已有镜像的容器创建、基于本地模板导入、基于Dockerfile创建
基于已有镜像的容器创建
使用docker commit
命令,格式:
bash
docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]]
1
主要选项包括:
- -a,--author=""作者信息
- -m,--message=""提交信息
- -p,--pause=true提交时暂停容器运行
bash
# 演示
docker run -ti ubuntu /bin/bash
root@32fe63d85c53:/# touch test
root@32fe63d85c53:/# exit
docker commit -m "add a new file " 32fe63d85c53 test
sha256:4ff6ec596961a2c5f25bcd31e912abd40cc108b7e7e35d53d239b1ef4ff13233
# 使用docker images查看本地镜像列表
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
test latest 4ff6ec596961 6 seconds ago 83.5MB
1
2
3
4
5
6
7
8
9
10
11
12
2
3
4
5
6
7
8
9
10
11
12
基于本地模板导入
使用OpenVZ提供的模板创建。OPENVZ模板的下载地址为https://download.openvz.org/template/precreated/ 导入命令
bash
cat ubuntu-14.04-x86_64-minimal.tar.gz | docker import - ubuntu:14.04
1
存出和载入镜像
可以使用docker save
和docker load
命令来存出和载入镜像
存出镜像
bash
docker save -o ubuntu_14.04.tar ubuntu:14.04
1
载入镜像
bash
docker load --input ubuntu_14.04.tar
docker load < ubuntu_14.04.tar
1
2
3
2
3
上传镜像
使用docker push
命令上传镜像到仓库,默认上传到DockerHub官方仓库(需要登录),命令格式为docker push NAME[:NAME]
,第一次使用时,会提示输入登录信息或进行注册。
拉取镜像
从 Docker 镜像仓库获取镜像的命令是 docker pull。
其命令格式为: $ docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签] 示例: $ docker pull ubuntu:18.04 具体的选项可以通过 docker pull --help 命令看到,这里我们说一下镜像名称的格式。
上面的命令中没有给出 Docker 镜像仓库地址,因此将会从 Docker Hub (docker.io)获取镜像。而镜像名称是 ubuntu:18.04,因此将会获取官方镜像 library/ubuntu 仓库中标签为 18.04 的镜像。docker pull 命令的输出结果最后一行会给出镜像的完整名称,即: docker.io/library/ubuntu:18.04。
如果从 Docker Hub 下载镜像非常缓慢,可以配置国内镜像加速器。
列出镜像
要想列出已经下载下来的镜像,可以使用 docker image ls 命令或者docker images命令。
$ docker image ls
$ docker images
1
2
2
列出的结果会包含了仓库名、标签、镜像ID、创建时间以及所占用的空间。其中仓库名、标签在之前的基础概念章节已经介绍过了。镜像 ID 则是镜像的唯一标识,一个镜像可以对应多个标签。
或者根据仓库名列出镜像,当镜像较多的时候,这个比较有用;
$ docker image ls ubuntu
1
悬挂镜像:这个镜像既没有仓库名,也没有标签,均为 <none>
,一般来说,虚悬镜像已经失去了存在的价值,是可以随意删除的,可以用下面的命令删除。
$ docker image prune
1
镜像详情: 可以通过以下命令展示镜像的细节,包括镜像层数据和元数据:
$ docker image inspect 镜像ID或者镜像名
1
删除镜像
当不需要某个镜像时,可以使用 docker image rm 命令删除本地的镜像,其格式为:
$ docker image rm [选项] <镜像1> [<镜像2> ...]
1
其中,<镜像>
可以是 镜像ID、镜像名。当镜像存在关联容器时,不允许删除该镜像。
- 通过IMAGE ID删除: $ docker image rm 501ad78535f0
- 通过镜像名删除: $ docker image rm centos:latest
Docker容器管理
容器时Docker的另一个核心概念,容器就是镜像的一个运行实例,不同的是,它带有额外的可写文件层。
创建和运行容器
新建容器
使用docker create
命令新建一个容器
bash
docker create -it ubuntu:latest
fb461fbaa2ffe5ebab82548feb5898a1b35b7a3d678b52e1085d94db0f08c6e5
docker ps -a
fb461fbaa2ff ubuntu:latest "/bin/bash" 23 seconds ago Up 5 seconds heuristic_lamport
1
2
3
4
2
3
4
使用docker create
新建的容器处于停止状态,可以使用docker start
启动。
新建并启动容器
启动容器的方式有两种
- 基于镜像新建一个容器并启动
- 将在终止状态的容器重新启动
docker run
=docker create
+docker start
bash
# 使用如下命令输出一个‘hello world’,之后容器自动终止
docker run ubuntu /bin/echo 'hello world'
1
2
2
当利用docker run
创建并启动容器时,Docker在后台运行的标准操作:
- 检查本地是否存在指定的镜像,不存在就从共有仓库下载。
- 利用镜像创建并启动一个容器。
- 分配一个文件系统,并在只读的镜像层外挂载一层可读写层。
- 从宿主主机配置的网桥接口中桥接一个虚拟接口道容器中去。
- 从地址池配置一个IP地址给容器。
- 执行用户指定的应用程序。
- 执行完毕后容器被终止。
下面命令启动一个bash终端,允许用户进行交互
bash
docker run -t -i ubuntu:latest /bin/bash
1
-t:让Docker分配一个伪终端并绑定到容器的标准输出上 -i:让容器的标准输入保持打开
bash
docker run -ti ubuntu /bin/bash
root@d3df425445cf:/# ls
bin dev home lib64 mnt proc run srv tmp var
boot etc lib media opt root sbin sys usr
root@d3df425445cf:/# pwd
/
root@d3df425445cf:/# ps
PID TTY TIME CMD
1 pts/0 00:00:00 bash
11 pts/0 00:00:00 ps
root@d3df425445cf:/# exit
exit
# 使用exit退出后,容器自动处于终止状态
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
守护态运行
-d
参数可以让Docker容器在后台以守护态形式运行
bash
➜ ~ docker run -d ubuntu /bin/bash -c "while true;do echo hello world;sleep 1;done"
9c9db4515c703021cd2fc3e4583291cb62007ecafa28709f898cf2183eb914c1
➜ ~ docker logs 9c9db4515c703
hello world
hello world
➜ ~ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9c9db4515c70 ubuntu "/bin/bash -c 'while…" 41 seconds ago Up 40 seconds elastic_brattain
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
终止容器
docker stop
可以用来终止一个运行中的容器,命令格式docker stop [-t|--time[=10]]
它会首先向容器发送SIGTERM信号,等待一段时间后(默认为10s),再发送SIGKILL信号终止容器,当Docker容器中指定的应用终结时,容器也自动终止。
处于终止状态的容器,可以通过docker start
重新启动
docker restart
可以重启一个运行中的容器。
进入容器
attach命令
bash
➜ ~ docker run -idt ubuntu
a9e625b70f57ec70c242e5baf5c9a4431515e0e4d239b81a4729fcc4c08a0eef
➜ ~ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a9e625b70f57 ubuntu "/bin/bash" 5 seconds ago Up 4 seconds hungry_brown
➜ ~ docker attach hungry_brown
root@a9e625b70f57:/# ls
bin dev home lib64 mnt proc run srv tmp var
boot etc lib media opt root sbin sys usr
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
但是使用attach命令有时候并不方便。当多个窗口同时attach到同一个容器时,所有的窗口都会同步显示。当某个命令因命令阻塞时,其他窗口也无法执行操作。
exec命令
Docker自1.3版本起,提供了exec工具,可以直接在容器内运行命令。
bash
docker exec -ti a9e625 /bin/bash
1
nsenter工具
nsenter工具在util-linux包2.33版本后包含。
删除容器
docker rm
可以删除处于终止状态的容器,命令格式为docker rm [OPTION] CONTAINER [CONTAINER...]
支持的选项包括:
- -f,--force=false强行终止并删除一个运行中的容器
- -l,--link=false删除容器的连接,但保留容器
- -v,--volume=false删除容器挂载的数据卷
导入和导出容器
导出容器
导出容器是指导出一个已经创建的容器到一个文件,不管此时这个容器是否处于运行状态,可以使用docker export
命令,命令格式为docker export CONTAINER
.
bash
docker export ce4 > test_for_run.tar
1
导入容器
docker import
可以导入文件成为镜像
bash
cat test_for_run.tar | docker import - test/ubuntu:v1.0
1
与docker load的区别: docker load命令导入镜像存储文件到本地的镜像库 docker import命令导入一个容器快照到本地镜像库 容器快照文件将丢弃所有的历史记录和元数据信息(仅保留容器当时的快照状态),而镜像存储文件保留完整记录,体积也更大。此外,从容器快照文件导入可以重新指定标签等元数据信息。
Docker仓库管理
仓库是集中存放镜像的地方,注册服务器是存放仓库的具体服务器,每个服务器上可以有多个仓库,每个仓库下面有多个镜像。仓库地址dl.dockerpool.com/ubuntu,dl.dockerpool.com是注册服务器,ubuntu是仓库名。
Docker Hub
基础操作
- docker pull 下载镜像到本地
- docker search 搜索公共仓库镜像
- docker push 将本地奖项推动到Docker Hub
镜像资源分为两类
- 类似ubuntu这样的基础镜像,成为基础或根镜像。这些镜像由Docker公司创建、验证、支持、提供,这样的镜像往往使用单个单词作为名字
- 类似user/ubuntu这样的镜像,它是由DockerHub的用户user闯将并维护的,带有用户名称前缀,
查找时可以通过-s N参数指定仅显示评价为N星以上的镜像。
自动创建
自动创建使用户通过Docker Hub指定跟踪一个目标网站(目前支持GitHub或BitBucket)上的项目,一旦项目发现新的提交,则自动执行创建。 步骤:
- 创建并登陆Docker Hub,以及目标网站;*在目标网站中连接账户到Docker Hub
- 在Docker Hub中配置一个自动创建
- 选取一个目标网站中的项目(需要含Dockerfile)和分支
- 指定Dockerfile的位置,并提交创建。 之后可以在Docker Hub的“自动创建”页面中跟踪每次创建的动态。
创建和使用私有仓库
使用registry镜像创建私有仓库
通过官方的registry镜像简单搭建一套本地私有仓库环境:
bash
docker run -d -p 5000:5000 registry
1
Docker基础技术概览
Docker使用 Google公司推出的go语言进行开发实现,基于 Linux 内核的一些技术,对进程进行封装隔离,属于操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。
1、docker与虚拟机
Docker Docker技术比虚拟机技术更为轻便、快捷。因为Docker 在容器的基础上,进行了进一步的封装,从文件系统、网络互联到进程隔离等,极大的简化了容器的创建和维护。
虚拟机 传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。
2、docker优势
作为一种新兴的虚拟化方式,Docker 跟传统的虚拟化方式相比具有众多的优势。
高效的利用系统资源 由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,Docker 对系统资源的利用率更高。无论是应用执行速度、内存损耗或者文件存储速度,都要比传统虚拟机技术更高效。因此,相比虚拟机技术,一个相同配置的主机,往往可以运行更多数量的应用。
快速的启动时间 传统的虚拟机技术启动应用服务往往需要数分钟,而 Docker 容器应用,由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间。
一致的运行环境 开发过程中一个常见的问题是环境一致性问题。由于开发环境、测试环境、生产环境不一致,导致有些 bug 并未在开发过程中被发现。而 Docker 的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现 「这段代码在我机器上没问题啊」 这类问题。
持续交付和部署 对开发和运维人员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。使用 Docker 可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过Dockerfile来进行镜像构建,并结合持续集成系(CI)统进行集成测试,而运维人员则可以直接在生产环境中快速部署该镜像,甚至结合持续部署系统(CD)进行自动部署。
而且使用Dockerfile使镜像构建透明化,不仅仅开发团队可以理解应用运行环境,也方便运维团队理解应用运行所需条件,帮助更好的生产环境中部署该镜像。
更轻松的迁移 由于 Docker 确保了执行环境的一致性,使得应用的迁移更加容易。Docker 可以在很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运行结果是一致的。因此用户可以很轻易的将在一个平台上运行的应用,迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。
更轻松的维护和扩展 Docker 使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。此外,Docker 团队同各个开源项目团队一起维护了一大批高质量的官方镜像,既可以直接在生产环境使用,又可以作为基础进一步定制,大大的降低了应用服务的镜像制作成本。
3、docker安装与基本概念
6、docker容器
容器是 Docker 另一核心概念。简单的说,容器是独立运行的一个或一组应用,以及它们的运行态环境。对应的,虚拟机可以理解为模拟运行的一整套操作系统(提供了运行态环境和其他系统环境)和跑在上面的应用。现在具体介绍如何来管理一个容器,包括创建、启动、停止和删除等。
启动容器
启动容器有两种方式,一种是基于镜像新建一个容器并启动,另外一个是将在终止状态的容器重新启动。
新建并启动容器 所需要的命令主要为 docker container run或者docker run。该命令可以携带很多参数,下面以两个代码示例讲解:
$ docker run -t -i ubuntu:18.04 /bin/bash
1
该命令启动一个容器,并且以Bash Shell作为其应用,-it终端可以将当前终端连接到容器的shell终端之上。其中,-t 选项让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上, -i 则让容器的标准输入保持打开,同时进入容器内部。上述容器会在Bash Shell退出后终止运行,或者kill容器中的pid为1的进程,容器也会终止。如果想退出容器而不终止容器运行,可以同时按下Ctrl - PQ组合键。
还有几个常用的参数,-d 参数可以实现Docker 在后台运行而不是直接把执行命令的结果输出在当前宿主机下;-p参数可以实现容器内部端口映射到宿主机上端口;-v参数将容器数据与宿主机上数据映射,实现容器中数据持久化存储;以下是使用例子:
shell
docker run -itd --name milvus-local
-p 19530:19530 -p 19121:19121 -p 9091:9091
-v /home/user/milvus/db:/var/lib/milvus/db
-v /home/user/milvus/conf:/var/lib/milvus/conf
-v /home/user/milvus/wals:/var/lib/milvus/wals
milvus:latest
1
2
3
4
5
6
2
3
4
5
6
启动终止的容器 可以利用 docker container start 命令或者docker start命令,直接将一个已经终止的容器启动运行。
重启容器
处于终止状态的容器,可以通过 docker container start或者docker restart命令来重新启动。此外,重启容器的命令会将一个运行态的容器终止,然后再重新启动它。
进入容器
如果容器以守护进程启动时,即容器启动时使用了 -d 参数,容器启动后会进入后台。某些时候需要进入容器进行操作,可以使用 docker exec 命令进入容器。
docker exec 后边可以跟多个参数,一般要有 -i -t 参数。只用 -i 参数时,由于没有分配伪终端,界面没有我们熟悉的 Linux 命令提示符,但命令执行结果仍然可以返回。当 -i -t 参数一起使用时,则可以看到我们熟悉的 Linux 命令提示符。
$ docker exec -it milvus-local bash
1
如果从这个 stdin 中 exit,不会导致容器停止,更多参数说明请使用 docker exec --help 查看
列出容器
可以使用docker container ls或者docker ps命令来列出正在运行的容器,如果想列出包括停止的所有容器,使用-a参数:
$ docker container ls -a
$ docker ps -a
1
2
2
如果想查看某个容器详情,可以运行以下命令:
$ docker container inspect <容器名或容器ID>
$ docker inspect <容器名或容器ID>
1
2
2
停止容器
可以使用 docker container stop
或者docker stop
来终止一个运行中的容器。
此外,当 Docker 容器中指定的应用终结时,容器也自动终止。例如对于第一个代码示例中只启动了一个终端的容器,用户通过 exit 命令或 Ctrl+d
来退出终端时,所创建的容器立刻终止。
删除容器
可以使用 docker container rm
来删除一个处于终止状态的容器。例如
$ docker container rm milvus-local
$ docker rm milvus-local
1
2
2
如果要删除一个运行中的容器,可以添加 -f 参数。Docker 会发送 SIGKILL 信号给容器。
如果要清理所有处于终止状态的容器,当要删除的容器数量太多要一个个删除可能会很麻烦,用下面的命令可以清理掉所有处于终止状态的容器。
$ docker container prune
1
7、docker仓库以及镜像推送到仓库
仓库(Repository)是docker技术中又一个核心概念,是集中存放镜像的地方。有很多的镜像仓库,包括国内的和国外的远程服务商提供的,但是仓库的操作基本一致。下面以docker官方仓库 Docker Hub的介绍为例:
目前 Docker 官方维护了一个公共仓库Docker Hub。大部分需求都可以通过在 Docker Hub 中直接下载镜像来实现。
7.1、注册账号
在 https://hub.docker.com 免费注册一个 Docker 账号,有了账号之后才可以将自己制作的镜像上传到仓库。
登录和退出
可以通过界面和命令行进行登录操作,登录需要输入用户名和密码,登录成功后,我们就可以从 docker hub 上拉取自己账号下的全部镜像或者上传镜像到仓库。下面以命令行为例:
$ docker login
1
退出 docker hub 可以使用以下命令:
$ docker logout
1
7.2、拉取镜像
利用 docker pull 命令来将它下载到本地。
$ docker pull ubuntu
1
在下载镜像前,如果不知道具体的镜像名,可以用关键词进行搜索:
$ docker search ubuntu
1
7.3、推送镜像
用户登录后,可以通过 docker push
命令将自己的镜像推送到 Docker Hub。推送的镜像有一定命名规范,是<用户名>/<镜像名>
的命名方式才能推送到自己的仓库下。以下命令中的 username 请替换为你的 Docker 账号用户名。
$ docker push username/ubuntu:18.04
$ docker search username/ubuntu
1
2
2
8、docker保存、加载容器和镜像
Docker是基于镜像的。镜像类似于已经包含了文件、配置和安装好的程序的虚拟机镜像。同样的,可以像启动虚拟机一样启动多个镜像实例。运行中的镜像称为容器。你可以修改容器(比如删除一个文件),但这些修改不会影响到镜像。
8.1、镜像保存(save)
Save命令用于持久化镜像(不是容器)。所以,可以通过以下方法得到镜像名称:
从容器导出镜像
docker commit <container-id> <image-name> # 该命令可以把一个正在运行的容器变成一个新的镜像。
docker save -o image_name.tar <image-name> # 该命令将镜像保存为tar文件
1
2
2
8.2、镜像加载(load)
docker load < /home/save.tar # 导入镜像
1
或者
docker load -i /home/save.tar # 通过-参数指定
1
容器保存(export) Export命令用于持久化容器(不是镜像)。所以,可以通过以下方法得到容器ID:
sudo docker export <CONTAINER ID> > /home/export.tar
1
8.3、容器加载(import)
导入export.tar文件
sudo docker import export.tar export:v1 # 将镜像导入,同时命名为新的镜像名export:v1 区别 那,它们之间到底存在什么不同呢?用docker images 查看导入镜像,发现docker import加载后的版本会比原来的版本稍微小一些。那是因为加载后,会丢失历史和元数据。执行下面的命令就知道了:
8.4、显示镜像的所有层(layer)
sudo docker history <image_id>
1
导出后再导入(exported-imported)的镜像会丢失所有的历史,而保存后再加载(saved-loaded)的镜像没有丢失历史和层(layer)。这意味着使用导出后再导入的方式,你将无法回滚到之前的层(layer),同时,使用保存后再加载的方式持久化整个镜像,就可以做到层回滚(可以执行docker tag <LAYER ID> <IMAGE NAME>
来回滚之前的层)。
9、docker删除镜像、容器和卷
Docker 类似于虚拟机,它可以轻松安装应用程序和关联包,因此我们可以在任何地方运行它。但当我们使用 Docker 时,也很容易累积过多的无用镜像,容器和卷。他们非常占用空间和资源。
9.1、清除所有未使用或未挂载的镜像,容器,卷和网络配置
Docker 提供了一个命令,该命令将清除未挂载(不与容器关联)的所有资源(镜像,容器,卷和网络):
docker system prune
1
返回内容:
WARNING! This will remove:
- all stopped containers # 停止的容器
- all networks not used by at least one container # 未使用的网络
- all dangling images # 未挂载的镜像
- all dangling build cache # 镜像缓存
Are you sure you want to continue? [y/N] 风险:删除所有停止的容器和所有未使用的镜像(不仅仅是未挂载的镜像),添加命令参数-a:
docker system prune -a # 这也会删除与正在运行的容器没有关联的任何镜像。这可能有点极端,但Docker会重新下载它需要的任何镜像。
9.2、删除 Docker 镜像
删除一个或多个指定镜像
查看列表
docker images -a # 以找到所有的镜像 ID
1
执行删除
docker rmi image_id # 使用名称来删除指定镜像。
1
注意:如果一个镜像是另一个镜像的引用镜像,它是无法被删除的。
删除虚悬镜像(dangling image)
Docker 镜像由多层组成。有些镜像被命名为 <none>
,这些镜像是被新镜像覆盖后,老版本镜像会变成 <none>
。这些镜像被称之为虚悬镜像。这些镜像已经没有任何用处且占用磁盘空间。我们可以通过在命令中添加参数-f 来定位它们。确定要删除它们时,可以使用以下命令:
列出dangling镜像
docker images -f "dangling=true"
1
删除dangling镜像
docker image prune
1
注意: 如果你创建的镜像没有tag,那么这个镜像也会出现在虚悬镜像列表中。要避免这种情况发生,我们可以在创建镜像时,给他们添加上 tag ,之后也可以通过 docker tag 来查找这些镜像
根据模式删除镜像
我们可以通过grep来按需查找到我们需要删除的镜像文件,可以查找某一类属性的镜像文件。然后我们可以通过使用awk将ID传递给docker rmi来删除它们。具体可以看接下来的实例。
查看名字包含“pattern”的镜像列表
docker images -a | grep "pattern"
1
执行删除
docker images -a | grep "pattern" | awk '{print $3}' | xargs docker rmi
1
删除所有镜像
我们用docker images -a命令来查看所有镜像。确定要全部删除后,我们添加参数-q
把需要删除的镜像ID传给docker rmi
查看列表
docker images -a
1
执行删除
docker rmi $(docker images -a -q)
1
9.3、Docker删除容器
删除一个或多个指定容器 使用docker ps -a命令来查找要删除的容器名或ID:
查看列表
docker ps -a
1
执行删除
docker rm ID_or_Name
1
退出时删除容器 如果我们在创建容器时就知道用完后不用保留这个容器,那么我们可以在运行这个容器时,添加参数rm。docker run --rm,这样在执行完成时,此容器会被自动删除。
docker run --rm image_name # 以这种方式运行容器
1
删除所有退出的容器
我们可以通过docker ps -a轻松查找并通过容器当前状态进行筛选:创建、重启、运行、暂停、退出。如果我们要查看已退出的容器列表,我们可以添加参数-f来查看,删除时用-q传递给删除命令docker rm
查看所有退出的容器列表
docker ps -a -f status=exited
1
执行删除
docker rm $(docker ps -a -f status=exited -q)
1
删除筛选出的容器
我们可以通过 Docker ps的参数赋值来进行“或”的查询和删除。只要满足任意条件,删除命令即会把它们删除掉。例如,我们想要删除容器被标记为 Created (使用无效命令运行容器时,可能导致的状态)或者 Exited 的容器,我们则可以使用两个过滤器:
查看列表
docker ps -a -f status=exited -f status=created
1
删除容器
docker rm $(docker ps -a -f status=exited -f status=created -q)
1
根据模式删除容器
我们可以通过grep来按需查找到我们需要删除的容器,可以查找某一类属性的容器。然后我们可以通过使用awk将ID传递给docker rmi来删除它们。
查看列表:
查看列表
docker ps -a | grep "pattern”
1
执行删除
docker ps -a | grep "pattern" | awk '{print $3}' | xargs docker rmi
1
或者执行
sudo docker rm `docker ps -a|grep ‘pattern’|awk '{print $1}'`
1
9.4、停止并删除所有容器
我们可以使用docker ps -a命令来查看所有容器。确定要删除这个列表中的全部容器后,我们在命令结尾添加参数-q 然后传给docker stop 和 docker rm命令即可
查看列表
docker ps -a
1
停止命令
docker stop $(docker ps -a -q)
1
删除命令
docker rm $(docker ps -a -q)
1
Docker删除卷 删除一个或多个指定的卷 使用docker volume ls命令找到要删除的卷名。然后,我们可以用docker volume rm命令删除一个或多个卷:
查看列表
docker volume ls
1
删除操作
docker volume rm volume_name
1
9.5、删除虚悬卷(dangling volumes)
由于卷的位置要独立于容器而存在,因此在删除容器时,不会同时自动删除卷。当一个卷存在并且不再连接到任何容器时,称为虚悬卷(dangling volumes) ****。要找到它们并删除可以用docker volume ls命令加上过滤器即可。确定列表中都是想要删除的卷后,我们可以使用docker volume prune命令将它们全部删除:
查询列表
docker volume ls -f dangling=true
1
执行删除
docker volume prune
1
9.6、移除容器及对应的卷
我们可以使用docker rm -v来删除指定容器并同时删除为此容器分配的卷。在执行删除命令后,当容器已经成功删除时,会显示此容器的 ID。另外要注意的是,此命令只会删除容器和此容器对应的未命名卷。如果卷被命名了,它不会被此命令删除,仍然会保留在系统中。
执行删除
docker rm -v container_name
1
10、docker查看正在运行的容器启动命令
- 通过docker ps命令 该命令主要是为了详细展示查看运行时的command参数
docker ps -a --no-trunc | grep container_name
# 通过docker --no-trunc参数来详细展示容器运行命令
1
2
2
- 通过docker inspect命令 使用docker inspect,但是docker inspect打印的是json文件,需要挑选字段查看,容器的参数信息都能从json文件中解析出来。
1,在容器外部,物理机上,可以用下面命令
docker inspect <container_name> # 可以是container_name或者container_id
1
默认的输出信息很多,可以通过-f, --format格式化输出:
docker inspect --format='{{.NetworkSettings.Networks.bridge.IPAddress}}' <container_name>
# format是go语言的template,还有其他的用法
1
2
2
2,如果在容器内部。可以用下面命令
ps -ef # 其中1号进程就是command启动命令
1
- 通过runlike三方包 通过runlike去查看一个容器的docker run启动参数
安装runlike安装包
pip install runlike
1
运行命令
runlike -p <container_name> # 后面可以是容器名和容器id,-p参数是显示自动换行
1
Docker知识点
08.容器的端口映射与服务暴露
09.自定义Dockerfile
10.多阶段构建优化镜像
11.Docker容器的健康检查
12.数据卷与Bind Mount区别
13.Docker Registry与私有仓库
14.Docker网络与多容器通信
15.容器资源限制(CPU&内存)
16.Docker容器的隔离性与安全
17.Docker镜像清理与优化
18.使用Docker Volume备份数据
19.容器性能监控与日志管理
20.Docker与CI&CD集成
21.Docker Swarm集群管理
22.使用Kubernetes部署Docker容器
23.搭建Web应用(Nginx+PHP)
24.部署数据库容器(MySQL&PostgreSQL)
25.使用Docker部署Redis缓存
26.容器日志收集与集中管理
27.容器化Java Spring Boot应用
28.在云上使用Docker(AWS&ECS)
29.常见Docker问题与故障排查
总结与未来学习路线
Docker 系列教程规划(30 天)
以下是为期 30 天的 Docker 系统教程计划,每天一篇文章,涵盖 Docker 的基础、进阶应用与实战项目。
第一周:基础入门
- Docker 简介与安装
- 介绍容器技术,安装 Docker(Windows、Linux、Mac)。
- Docker 基本命令
- 启动、停止容器 (
docker run
、docker stop
)。
- 启动、停止容器 (
- Docker 镜像操作
- 拉取、列出、删除镜像,创建自定义镜像 (
docker build
)。
- 拉取、列出、删除镜像,创建自定义镜像 (
- Docker 容器管理
- 进入容器 (
docker exec
、docker attach
),查看日志。
- 进入容器 (
- 数据卷(Volumes)简介
- 容器与主机的数据共享与持久化。
- Docker 网络基础
- 网络模式:bridge、host、none 详解。
- Docker Compose 简介
- 使用
docker-compose
进行多容器管理。
- 使用
第二周:进阶操作
- 容器的端口映射与服务暴露
- 使用
-p
参数映射端口,创建外部服务。
- 使用
- 自定义 Dockerfile
- 编写 Dockerfile 创建应用镜像。
- 多阶段构建优化镜像
- 通过多阶段构建减少镜像体积。
- Docker 容器的健康检查
- 设置
HEALTHCHECK
监控容器状态。
- 数据卷与 Bind Mount 区别
- 比较卷与绑定挂载的适用场景。
- Docker Registry 与私有仓库
- 推送与拉取镜像到 Docker Hub 或私有仓库。
- Docker 网络与多容器通信
- 创建自定义网络,确保容器间通信。
第三周:安全与性能优化
- 容器资源限制(CPU/内存)
- 使用
--memory
、--cpus
限制资源占用。
- Docker 容器的隔离性与安全
- 使用
seccomp
与AppArmor
强化安全性。
- Docker 镜像清理与优化
- 清理未使用的镜像与容器。
- 使用 Docker Volume 备份数据
- 卷数据的备份与恢复策略。
- 容器性能监控与日志管理
- 监控工具(如 cAdvisor、Grafana)。
- Docker 与 CI/CD 集成
- 在 Jenkins 中使用 Docker。
第四周:高级应用与实战
- Docker Swarm 集群管理
- 创建和管理集群模式。
- 使用 Kubernetes 部署 Docker 容器
- 基础的 Kubernetes 配置与操作。
- 搭建 Web 应用(Nginx+PHP)
- 使用 Docker Compose 部署 LEMP 堆栈。
- 部署数据库容器(MySQL/PostgreSQL)
- 持久化数据库数据。
- 使用 Docker 部署 Redis 缓存
- 介绍 Redis 容器的常见使用场景。
- 容器日志收集与集中管理
- 使用 ELK 堆栈收集日志。
- 容器化 Java Spring Boot 应用
- 使用 Docker 部署 Java 后端服务。
- 在云上使用 Docker(AWS/ECS)
- 将容器化应用部署到云端。
最后两天:总结与提升
- 常见 Docker 问题与故障排查
- 排查启动失败、网络问题、性能瓶颈。
- 总结与未来学习路线
- 介绍容器技术的未来趋势(如 Podman、K8s 进阶)。