Docker的基本使用

1.初识Docker

1.1 为什么会有docker出现?

(1)假定您在开发一个电商项目,您使用的是一台笔记本电脑而且您的开发环境具有特定的配置。其他开发人员身处的环境配置也各有不同。您正在开发的应用依赖于您当前的配置且还要依赖于某些配置文件。此外,您的企业还拥有标准化的测试和生产环境,且具有自身的配置和一系列支持文件。您希望尽可能多在本地模拟这些环境而不产生重新创建服务器环境的开销。
请问?您要如何确保应用能够在这些环境中运行和通过质量检测?并且在部署过程中不出现令人头疼的版本、配置问题,也无需重新编写代码和进行故障修复?
答案就是使用容器。Docker之所以发展如此迅速,也是因为它对此给出了一个标准化的解决方案-----系统平滑移植,容器虚拟化技术
(2)环境配置相当麻烦,换一台机器,就要重来一次,费力费时。很多人想到,能不能从根本上解决问题,软件可以带环境安装?也就是说,安装的时候,把原始环境一模一样地复制过来。开发人员利用 Docker 可以消除协作编码时“在我的机器上可正常工作”的问题。
(3)之前在服务器配置一个应用的运行环境,要安装各种软件,就拿电商项目的环境来说,Java/RabbitMQ/MySQL/JDBC驱动包等。安装和配置这些东西有多麻烦就不说了,它还不能跨平台。假如我们是在 Windows 上安装的这些环境,到了 Linux 又得重新装。况且就算不跨操作系统,换另一台同样操作系统的服务器,要移植应用也是非常麻烦的。
(4)传统上认为,软件编码开发/测试结束后,所产出的成果即是程序或是能够编译执行的二进制字节码等(java为例)。而为了让这些程序可以顺利执行,开发团队也得准备完整的部署文件,让运维团队得以部署应用程序,开发需要清楚的告诉运维部署团队,用的全部配置文件+所有软件环境。不过,即便如此,仍然常常发生部署失败的状况。
(5)Docker的出现使得Docker得以打破过去「程序即应用」的观念。透过镜像(images)将作业系统核心除外,运作应用程序所需要的系统环境,由下而上打包,达到应用程序跨平台间的无缝接轨运作。

1.2 docker的理念

(1)Docker是基于Go语言实现的云开源项目。Docker的主要目标是“Build,Ship and Run Any App,Anywhere”,也就是通过对应用组件的封装、分发、部署、运行等生命周期的管理,使用户的APP(可以是一个WEB应用或数据库应用等等)及其运行环境能够做到“一次镜像,处处运行”。
(2)Docker如何解决大型项目依赖关系复杂,不同组件依赖的兼容性问题?
①Docker允许开发中将应用、依赖、函数库、配置一起打包,形成可移植镜像
②Docker应用运行在容器中,使用沙箱机制,相互隔离

在这里插入图片描述
(3)Docker如何解决开发、测试、生产环境有差异的问题?
Docker镜像中包含完整运行环境,包括系统函数库,仅需依赖系统的Linux内核,因此可以在任意的Linux操作系统上运行。
即 Docker = jar/war + 环境

1.3 Docker和虚拟机的区别

(1)虚拟机是虚拟出一套硬件后,在其上运行一个完整的操作系统,在该系统上再运行所需的应用进程
(2)docker容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核也没有硬件虚拟。因此容器要比传统虚拟机更为轻便
(3)Docker体积小、启动速度快、性能好;虚拟机体积大、启动速度慢、性能一般

1.3.1 普通系统中的程序运行原理

程序是一个对计算机硬件资源调度使用的指令序列

在这里插入图片描述

1.3.2 传统虚拟技术

传统的虚拟技术是在物理机的操作系统之上安装一个虚拟机管理程序,例如 VMware、VirtualBox 等。在其管理下
可以创建很多个虚拟机。每个虚拟机需要安装自己独立的操作系统,而应用就是安装在虚拟机操作系统之上的程序,
应用程序通过调用各种命令或库函数来使用其需要的各种系统资源。对于完全相同的两个应用,其若需要运行在两
个虚拟机中,则就需要两套完全相同的虚拟机操作系统与 bins/libs,存在大量的资源占用冗余。形成资源浪费。

在这里插入图片描述

1.3.3 容器虚拟化技术

Docker 容器运行在 Docker 引擎之上,所有 Docker 容器共享同一个 Docker 引擎, 但它
们的运行又是相互隔离、互不干扰的。 由于 Docker 容器不需要进行虚拟硬件及操作系统,
而是共享的宿主机的硬件与操作系统,所以 Docker 容器对系统资源的占用很少,其仅包含www.bjpowernode.com 4 / 566 Copyright© 动力节点
运行时必须的一些资源。所有 Docker 容器对于系统资源的使用都是由 Docker 引擎统一进行
管理,所以对系统资源的利用率很高。无论是应用执行速度、内存损耗或者文件存储速度,
都要比传统虚拟机技术更高效。

1.4 Docker的基本组成(docker的三要素)

Docker 本身是一个容器运行载体或称之为管理引擎。我们把应用程序和配置依赖打包好形成一个可交付的运行环境,这个打包好的运行环境就是image镜像文件。只有通过这个镜像文件才能生成Docker容器实例(类似Java中new出来一个对象)。
image文件可以看作是容器的模板。Docker 根据 image 文件生成容器的实例。同一个 image 文件,可以生成多个同时运行的容器实例。

1.4.1 镜像

(1)Docker 镜像(Image)就是一个只读的模板。镜像可以用来创建 Docker 容器,一个镜像可以创建很多容器。
(2)它也相当于是一个根文件系统。比如官方镜像 centos:7 就包含了完整的一套 centos:7 最小系统的根文件系统。
(3)docker镜像相当于容器的“源代码”,docker镜像文件类似于Java的类模板,而docker容器实例类似于java中new出来的实例对象。

1.4.2 容器

(1)从面向对象角度
Docker是 利用容器(Container)独立运行的一个或一组应用,应用程序或服务运行在容器里面,容器就类似于一个虚拟化的运行环境,容器是用镜像创建的运行实例。就像是Java中的类和实例对象一样,镜像是静态的定义,容器是镜像运行时的实体。容器为镜像提供了一个标准的和隔离的运行环境,它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台
(2) 从镜像容器角度
可以把容器看做是一个简易版的 Linux 环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。

1.4.3 仓库

仓库是集中存放镜像文件的场所。类似于maven仓库,存放各种jar包。仓库分为公开仓库(Public)和私有仓库(Private)两种形式。
①最大的公开仓库是 Docker Hub(https://hub.docker.com/),Docker公司提供的官方registry被称为Docker Hub,存放各种镜像模板的地方。
②从国外服务器上下载Docker安装包非常慢,可以从国内服务器上下载。国内也有类似于DockerHub的公共服务,比如网易云镜像服务、阿里云镜像库等。
③Dockerhub、阿里云这样的公共镜像仓库可能不太方便,涉及机密的公司不可能提供镜像给公网,所以需要创建一个本地私人仓库供给团队使用,基于公司内部项目构建镜像。Docker Registry是官方提供的工具,可以用于构建私有镜像仓库

1.4.3.1 本地镜像发布到私有库流程

在这里插入图片描述

(1)下载镜像Docker Registry:docker pull registry
(2)运行私有库Registry,相当于本地有个私有Docker hub:
docker run -d -p 5000:5000 -v /zzyyuse/myregistry/:/tmp/registry --privileged=true registry
默认情况,仓库被创建在容器的/var/lib/registry目录下,建议自行用容器卷映射,方便于宿主机联调
(/zzyyuse/myregistry/是宿主机绝对路径目录,/tmp/registry为容器内目录 )
(3)首先需要commit我们自己的新镜像
(4)修改配置文件使之支持http(docker默认不允许http方式推送镜像,通过配置选项来取消这个限制。–> 修改完后如果不生效,建议重启docker)
vim命令新增如下内容:vim /etc/docker/daemon.json
{
“insecure-registries”: [“ip地址:5000”]
}
(5)curl验证私服库上有什么镜像: curl -XGET http://ip地址:5000/v2/_catalog
(6)按照公式修改为符合私服规范的Tag:docker tag 镜像:Tag Host:Port/Repository:Tag
在这里插入图片描述
(7)将符合私服规范的镜像推送到私有库:docker push IP地址:5000/zzyyubuntu:1.2
(8)curl再次验证私服库上有什么镜像
(9)pull到本地并运行:
在这里插入图片描述

1.5 Docker的架构

Docker是一个CS架构的程序,
(1)服务端:Docker守护进程,负责处理Docker指令,管理镜像、容器等
(2)客户端:通过命令或RestAPI向Docker服务端发送指令。可以在本地或远程向服务端发送指令

1.6 Docker 引擎的启停

(1)启动docker:systemctl start docker
(2)停止docker:systemctl stop docker
(3)重启docker:systemctl restart docker
(4)查看docker状态:systemctl status docker
(5)开机自动启动docker:systemctl enable docker
(6)查看docker概要信息:docker info
(7)查看docker总体帮助文档:docker --help
(8)查看docker命令帮助文档:docker 具体命令 --help

2.Docker 镜像

2.1 镜像是什么?

镜像是一种轻量级、可执行的独立软件包,它包含运行某个软件所需的所有内容,我们把应用程序和配置依赖打包好形成一个可交付的运行环境(包括代码、运行时需要的库、环境变量和配置文件等),这个打包好的运行环境就是image镜像文件。只有通过这个镜像文件才能生成Docker容器实例(类似Java中new出来一个对象)。

2.2 分层的镜像

以我们的pull为例,在下载的过程中我们可以看到docker的镜像好像是在一层一层的在下载
在这里插入图片描述

2.3 UnionFS(联合文件系统)

(1)UnionFS(联合文件系统):UnionFS是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。UnionFS(联合文件系统)是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像,可以制作各种具体的应用镜像。
(2)特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录

2.4 docker镜像加载原理

(1)docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统就叫(联合文件系统)UnionFS。
(2)bootfs(boot file system)主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启动时会加载bootfs文件系统
(3)在Docker镜像的最底层就是引导文件系统bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
(4)rootfs (root file system) ,是在bootfs之上。包含的就是典型 Linux 系统中的 /dev, /proc, /bin, /etc 等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。
(5)平时我们安装进虚拟机的CentOS都是好几个G,为什么docker这里才200M??
对于一个精简的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序库就可以了,因为底层直接使用Host的kernel,自己只需要提供 rootfs 就行了。由此可见对于不同的linux发行版, bootfs基本是一致的, rootfs会有差别, 因此不同的发行版可以公用bootfs。

2.5 为什么 Docker 镜像要采用这种分层结构呢?

镜像分层最大的一个好处就是共享资源,方便复制迁移,就是为了复用。
比如说有多个镜像都从相同的 base 镜像构建而来,那么 Docker Host 只需在磁盘上保存一份 base 镜像;
同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。

2.6 docker commit提交容器副本使之成为一个新的镜像

(1)语法:docker commit -m=“提交的描述信息” -a=“作者” 容器ID 要创建的目标镜像名:[标签名]
(2)原始的默认Ubuntu镜像是不带着vim命令的

在这里插入图片描述

在这里插入图片描述
ctrl+p+q退出
在这里插入图片描述

2.7 镜像命令

(1)docker images:列出主机上的镜像
(OPTIONS说明:
-a :列出本地所有的镜像(含历史映像层)
-q :只显示镜像ID。)
在这里插入图片描述
①REPOSITORY:表示镜像的仓库源
②TAG:镜像的标签版本号
③IMAGE ID:镜像ID
④CREATED:镜像创建时间
⑤SIZE:镜像大小

(2)docker search 某个镜像名字:搜索某个镜像是否在远程仓库

在这里插入图片描述

(3)docker pull 镜像名字[:TAG] : 下载某个镜像(没有TAG就是最新版)
(4)docker system df:查看镜像/容器/数据卷所占的空间
(5)docker rmi 某个镜像名字ID:删除某个镜像(如果镜像正在被某个容器使用就需要强制-f删除)

在这里插入图片描述

2.8 虚悬镜像

(1)虚悬镜像是什么?
仓库名、标签都是<none>的镜像,俗称dangling image
(2)查看有哪些虚悬镜像
docker image ls -f dangling=true
(3)虚悬镜像已经失去存在价值,可以删除
docker image prune

3.Docker 容器

3.1 容器启动流程

在这里插入图片描述

3.2 容器运行本质

(1)Docker 容器存在的意义就是为了运行容器中的应用,对外提供服务,所以启动容器的
目的就是启动运行该容器中的应用。 容器中的应用运行完毕后,容器就会自动终止。所以,
如果不想让容器启动后立即终止运行,则就需要使容器应用不能立即结束。 通常采用的方式
有两种,使应用处于与用户交互的状态等待状态
(2)对于容器的运行,有两种运行模式:交互模式与分离模式

3.3 容器命令

(1)新建+启动容器:docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
OPTIONS说明:有些是一个减号,有些是两个减号
--name="容器新名字": 为容器指定一个名称;
②-d: 后台运行容器并返回容器ID,也即启动守护式容器(后台运行);
③-i:以交互模式运行容器,通常与 -t 同时使用;
-t:为容器重新分配一个伪输入终端,通常与 -i 同时使用;
也即启动交互式容器(前台有伪终端,等待交互);
④-P: 随机端口映射,大写P
⑤-p: 指定端口映射,小写p
hostPort:宿主机端口(相当于Docker) containerPort:容器端口(相当于Docker内运行的容器)
在这里插入图片描述

在这里插入图片描述

使用镜像centos:latest以交互模式启动一个容器,在容器内执行/bin/bash命令。
docker run -it centos /bin/bash
参数说明:
①-i: 交互式操作。
②-t: 分配伪终端。
③centos : centos 镜像。
④/bin/bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 /bin/bash。
⑤要退出终端,直接输入 exit:
(2)docker ps [OPTIONS]:列出当前所有正在运行的容器
OPTIONS说明:
①-a :列出当前所有正在运行的容器+历史上运行过的
②-l :显示最近创建的容器,无论该容器是否处于运行状态
③-n:显示最近n个创建的容器,无论该容器是否处于运行状态(如:docker ps -n 2)
④-q :静默模式,只显示容器编号。
(3)退出容器
①run进去容器,exit退出,容器停止
②run进去容器,ctrl+p+q退出,容器不会停止
(4)启动已停止运行的容器:docker start 容器ID或者容器名
(5)重启容器:docker restart 容器ID或者容器名
(6)停止容器:docker stop 容器ID或者容器名
(7)强制停止容器:docker kill 容器ID或容器名
(8)删除已停止的容器:docker rm 容器ID
一次性删除多个容器实例:
docker rm -f $(docker ps -a -q)
docker ps -a -q | xargs docker rm
(9) 使用镜像centos:latest以后台模式启动一个容器:docker run -d centos
问题:然后docker ps -a 进行查看, 会发现容器已经退出
很重要的要说明的一点: Docker容器后台运行,就必须有一个前台进程.
容器运行的命令如果不是那些一直挂起的命令(比如运行top,tail),就是会自动退出的。
这个是docker的机制问题,比如你的web容器,我们以nginx为例,正常情况下,
我们配置启动服务只需要启动响应的service即可。例如service nginx start
但是,这样做,nginx为后台进程模式运行,就导致docker前台没有运行的应用,
这样的容器后台启动后,会立即自杀因为他觉得他没事可做了.
所以,最佳的解决方案是,将你要运行的程序以前台进程的形式运行,
常见就是命令行模式,表示我还有交互操作,别中断
(后台启动一般启动像redis这种有前台进程的)
(10)查看容器日志:docker logs 容器ID
docker logs 查看的是所有容器中应用的运行日志。 这个日志对于不同的容器来说,其日
志内容是不同的。由 docker run 命令的[command]决定(如果没有则由 Dockerfile 中的 CMD
指令决定)。
①通过添加选项-n 或--tail 可以指定要显示的最后几条日志
②通过添加选项--since 可以指定要显示自从指定时间以来的日志。这个时间可以是一个绝
对时间,也可以是一个相对时长。

  • 下面使用的是绝对时间:显示自从 2022 年 8 月 1 日后产生日志的最后 3 条。
    在这里插入图片描述

  • 下面使用的是相对时长:显示自从 30 分钟之前产生日志中的最后 3 条。其中 m 表示分,
    可以使用 s 表示秒, h 表示小时。

在这里插入图片描述

③通过添加选项--until 可以指定要显示截止到指定时间之前的日志。这个时间可以是一个
绝对时间,也可以是一个相对时长。

  • 下面使用的是绝对时间:显示截止到 2022 年 8 月 8 日前产生日志的最后 3 条。
    在这里插入图片描述
  • 下面使用的是相对时长:显示截止到 5 分钟之前产生日志中的最后 3 条。

在这里插入图片描述
④如果要查看某日志的详细时间戳,可以使用-t 选项。下面的命令查看的是最后 3 条日志
的时间戳,并与不添加-t 的输出进行了对比。
在这里插入图片描述

⑤通过添加选项-f 可以查看运行中容器的动态日志

(11)docker top 命令用于查看指定的正在运行的容器中正在运行的进程详情,这个详情包括
当前这个进程正在运行的命令。
在这里插入图片描述

当然,如果容器中运行的进程较多,也可以通过 grep 对结果进行过滤。
在这里插入图片描述

(12)查看容器内部细节:docker inspect 容器ID
(13)重新进入容器(例如进入ctrl+p+q退出的)
当我们以分离模式运行了一个容器,或以交互模式运行了一个容器,但容器内部执行的
命令占用了交互命令行,而此时我们又想进入到容器中对容器内部进行一些操作,此时就需
要用到 exec/attach 命令了
①docker exec -it 容器ID bashShell(bashShell指的是例如/bin/bash)
②docker attach 容器ID
上述两个区别:
①attach 直接进入容器启动命令的终端,不会启动新的进程。用exit退出,会导致容器的停止。
②exec 是在容器中打开新的终端,并且可以启动新的进程,用exit退出,不会导致容器的停止。
(推荐大家使用 docker exec 命令,因为退出容器终端,不会导致容器的停止)
(14)从容器内拷贝文件到主机上:docker cp 容器ID:容器内路径 目的主机路径
(15)导入和导出容器
在这里插入图片描述

4.Dockerfile解析

4.1 Dockerfile是什么?

Dockerfile是用来构建Docker镜像的脚本文件,由一系列指令组成。通过docker build命令构建镜像时,Dockerfile中的指令会由上到下依次执行,每条指令都会构建出一个镜像,这就是镜像的分层。因此,指令越多,层次就越多,创建的镜像就越多,效率就越低。所以在定义Dockerfile时,能在一个指令完成的动作就不要分为两条。

4.2 构建Dockerfile三步骤

(1)编写Dockerfile文件
(2)docker build命令构建镜像
(docker build 命令中的最后是一个 PATH 路径,其具有两个功能)
①指定要查找 Dockerfile 的路径
②Dockerfile 中的 ADD 与 COPY 指令中的<src>路径是相对于该路径的

(3)docker run依照新编写好的镜像运行容器实例

4.3 Dockfile基础内容

(1)每条保留字指令大小写字母都可以(惯例大写)且后面要跟随至少一个参数
(2)指令按照从上到下,顺序执行
(3)#表示注释
(4)每条指令都会创建一个新的镜像层并对镜像进行提交

4.4 Docker执行Dockerfile的流程

(1)docker从基础镜像运行一个容器
(2)执行一条指令并对容器作出修改
(3)执行类似docker commit的操作提交一个新的镜像层
(4)docker再基于刚提交的镜像运行一个新容器
(5)执行dockerfile中的下一条指令直到所有指令都执行完成

4.5 Dockerfile、Docker镜像与Docker容器

(1)从应用软件的角度来看,Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段,
①Dockerfile是软件的原材料
②Docker镜像是软件的交付品
③Docker容器则可以认为是软件镜像的运行态,也即依照镜像运行的容器实例
Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及部署与运维,三者缺一不可,合力充当Docker体系的基石。
(2)Dockerfile,需要定义一个Dockerfile,Dockerfile定义了进程需要的一切东西。Dockerfile涉及的内容包括执行代码或者是文件、环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、服务进程和内核进程(当应用进程需要和系统服务和内核进程打交道,这时需要考虑如何设计namespace的权限控制)等等;
(3)Docker镜像,在用Dockerfile定义一个文件之后,docker build时会产生一个Docker镜像,当运行 Docker镜像时会真正开始提供服务;
(4)Docker容器,容器是直接提供服务的。

4.6 DockerFile常用保留字指令

(1)FROM:基础镜像,当前新镜像是基于哪个镜像的,指定一个已经存在的镜像作为模板,第一条必须是from
(2)MAINTAINER:镜像维护者的姓名和邮箱地址
(3)RUN:容器构建时需要运行的命令(RUN是在 docker build时运行)
①shell格式
在这里插入图片描述
②exec格式
在这里插入图片描述
(4)EXPOSE:当前容器对外暴露出的端口
(5)WORKDIR:指定在创建容器后,终端默认登陆的进来工作目录,一个落脚点
(6)USER:指定该镜像以什么样的用户去执行,如果都不指定,默认是root
(7)ENV:用来在构建镜像过程中设置环境变量
ENV MY_PATH /usr/mytest
这个环境变量可以在后续的任何RUN指令中使用,这就如同在命令前面指定了环境变量前缀一样;
也可以在其它指令中直接使用这些环境变量
(8)ADD:将宿主机目录下的文件拷贝进镜像且会自动处理URL和解压tar压缩包
(9)COPY:类似ADD,拷贝文件和目录到镜
像中。
将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置
(10)VOLUME:容器数据卷,用于数据保存和持久化工作
(11)CMD:指定容器启动后的要干的事情
Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效,CMD 会被 docker run 之后的参数替换
(12)ENTRYPOINT
【语法 1】 ENTRYPOINT [“EXECUTABLE”,“PARAM1”,“PARAM2”, …]
【解析】 在容器启动过程中,即在执行 docker run 时, 会调用执行"EXECUTABLE"指定的应用
程序,并使用后面第二、三等参数作为应用程序的运行参数。
【语法 2】 ENTRYPOINT command param1 param2, …
【解析】 这里的 command 就是 shell 命令。在容器启动过程中,即在执行 docker run 时,会
运行指定的 shell 命令。

5.Docker-compose

5.1 Docker-compose能干嘛

docker建议我们每一个容器中只运行一个服务,因为docker容器本身占用资源极少,所以最好是将每个服务单独的分割开来但是这样我们又面临了一个问题?

如果我需要同时部署好多个服务,难道要每个服务单独写Dockerfile然后在构建镜像,构建容器,这样累都累死了,所以docker官方给我们提供了docker-compose多服务部署的工具

例如要实现一个Web微服务项目,除了Web服务容器本身,往往还需要再加上后端的数据库mysql服务容器,redis服务器,注册中心eureka,甚至还包括负载均衡容器等等。

Compose允许用户通过一个单独的docker-compose.yml模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)。

可以很容易地用一个配置文件定义一个多容器的应用,然后使用一条指令安装这个应用的所有依赖,完成构建。Docker-Compose 解决了容器与容器之间如何管理编排的问题。

5.2 compose文件

5.2.1 文件简介

(1)Docker Compose 使用 YAML 文件来定义服务。 官方推荐的默认文件名为 compose.yml ,但同时也支持 docker-compose.yml。
(2)由于一个 compose 文件中定义的为一个项目的所有服务,所以一般为在创建 compose文件之前先新建一个目录,目录名称一般为项目名称,然后再将项目所需的所有镜像、微服务的 Dockerfile 放入该目录,并在该目录中新建 compose 文件。
(3)compose 文件中包含 6 个顶级属性: version、 services、 networks、 volumes、 configs 与secrets,及很多的它们下面所包含的属性。

5.2.2 version

version 是一个顶级属性,但已经过时,不再需要在 compose 文件中出现了。

5.2.3 networks

networks 作为一个顶级属性,用于定义和创建应用中所使用到的所有网络。其下包含的
第一级属性即为网络名称,这个网络名称可以随意命名。而在网络名称下还可包含很多的属
性,常用属性如下:

services:
	app:
		networks:
			- app_bridge: #这里使用的并不是网络名称
networks:
	app_bridge:
		name: appBGnet # 这才是网络名称		
		driver: bridge

(1)name
networks 下的第一级属性—网络名称,并不是真正的网络名称,而仅仅是网络名称的一
部分。在真正生成网络后,其真正的网络名称格式为:当前 compose 文件所在目录名_
networks 下的第一级属性。
但如果设置了name属性,则网络名称即为这里指定的名称,不会出现名称再合成情况。

5.2.4 serivces

services 是一个顶级属性, 用于定义一个应用中所包含的服务。 Docker Compose 会将每
个服务部署在各自的容器中。 其下包含的第一级的属性即为服务名称,这个名称可以根据服
务内容随意命名。而在服务名称下还可包含很多的属性, 常用属性如下:
(1)build
用于指定一个 Dockerfile 的路径。而该 Dockerfile 则是用于创建当前服务镜像的。这个
路径可以是以斜杠(/)开头的绝对路径,也可以是相对于当前 compose 文件的、以点(.)号开头
的相对路径。
如果 Dockerfile 文件名不是默认名称,则需要通过 build 下的 context 属性指定路径,
dockerfile 属性指定文件名。
(2)image
①用户指定当前服务所需要使用的镜像,这个镜像可以是本地镜像,也可以是远程镜像仓库中的
镜像(会自动 pull)。
②如果设置了 build, 此时再设置的 image 属性即为构建出的镜像的名称与 Tag。
(3) container_name
①该属性用于设置容器名称,但并不是必须的。如果没有设置该属性,容器名称则会采用
“合成方式”。而合成时需要用到 services 下的第一级属性。
②在 services 下存在一级属性,称为服务名称。该级属性是作为 services 下的第一级属性
出现的。服务名称将来会作为容器名称的一部分出现。 容器的名称格式为:当前 compose
文件所在目录名_ 服务名称。
③如果在 services 下没有指定 image 属性,而是使用 bild 属性,即没有现成的镜像,而是
根据 build 下指定的 Dockerfile 生成镜像,此时生成的镜像名称格式为: 当前 compose 文件
所在目录名-服务名称。
(4) ports
一个列表。前面为暴露出的端口号,后面为容器中应用的端口号。 如果仅设置了一个端
口号,那么这个端口号是容器中应用的端口号,其暴露到宿主机的端口号会被随机分配。

ports:
- 80:80 # 绑定容器的 80 端口到主机的 80 端口
- 9000:80 # 绑定容器的 80 端口到主机的 9000 端口
- 443 # 绑定容器的 443 端口到主机的任意端口,容器启动时随机分配绑定的主机端口号

(5) command
用于覆盖 Dockerfile 中的 CMD 指令内容,即启动该服务容器后立即运行的命令。如果
直接按照Dockerfile中的CMD指令内容执行即可,则compose文件中无需该command属性。
(6) depends_on
一个列表。用于指定当前服务的启动所依赖的应用名称。即列表中指定的服务会先于当前服务启动

5.3 常用命令

Docker Compose通过docker-compose系列命令查看和控制compose中的所有服务容器
(1)docker-compose pull
拉取 compose 中服务依赖的全部镜像或指定镜像。通过在命令后添加服务名称来指定。
(2)docker-compose config
检查 compose 文件是否正确。可添加选项-q,表示只有存在问题时才有输出。
(3)docker-compose up
启动 compose 中的所有容器。 -d 选项表示后台启动。
(4)docker-compose logs
查看 comopse 中所有服务或指定服务的运行日志。通过在命令后添加服务名称来指定。
默认情况下,将对不同的服务日志使用不同的颜色来区分。
(5)docker-compose ps
列出 compose 中所有服务或指定服务。通过在命令后添加服务名称来指定。
(6)docker-compose top
列出 compose 中当前正在运行的所有服务或指定服务。通过在命令后添加服务名称来指定。
(7)docker-compose images
列出 compose 中所有服务或指定服务对应的镜像。通过在命令后添加服务名称来指定。
(8)docker-compose port
列出指定服务容器的指定端口所映射的宿主机端口。
(9)docker-compose run
在指定服务上执行一条命令。
(10)docker-compose exec
进入指定服务容器。 通过在命令后添加服务名称来指定。
(11)docker-compose pause
暂停 compose 中所有服务容器或指定服务容器。 通过在命令后添加服务名称来指定。
(12)docker-compose unpause
恢复 compose 中处于暂停状态的所有服务容器或指定服务容器。 通过在命令后添加服
务名称来指定。
(13)docker-compose stop
停止 compose 中所有服务容器或指定服务容器。 通过在命令后添加服务名称来指定。
(14)docker-compose restart
重启 compose 中所有服务容器或指定服务容器。 通过在命令后添加服务名称来指定。
(15)docker-compose start
启动 compose 中所有服务容器或指定服务容器。 通过在命令后添加服务名称来指定。
(16)docker-compose kill
通过发送 SIGKILL 信号停止指定服务的容器。
(17)docker-compose rm
删除compose中的、处于停止状态的所有服务容器或指定服务容器。 通过在命令后添加服务名称来指定
(18)docker-compose down
停止并删除 compose 中的所有服务容器、网络、镜像、数据卷

6.数据卷

Docker 提供了三种实时同步(宿主机与容器 FS 间数据的同步)方式:
(1)数据卷
(2)Bind mounts(绑定挂载)
(3)tmpfs(临时文件系统)

6.1 数据卷概述

(1) 数据卷简介
①数据卷是宿主机中的一个特殊的文件/目录,这个文件/目录与容器中的另一个文件/目
录进行了直接关联,在任何一端对文件/目录的写操作,在另一端都会同时发生相应变化。
②在宿主机中的这个文件/目录就称为数据卷,而容器中的这个关联文件/目录则称为该数据卷在
该容器中的挂载点。
③数据卷的设计目的就是为了实现数据持久化,其完全独立于容器的生命周期,属于宿主
机文件系统,但不属于 UnionFS。因此,容器被删除时,不会删除其挂载的数据卷。
(2)数据卷的特性
①数据卷在容器启动时初始化,如果容器启动后容器本身已经包含了数据,那么,这些数
据会在容器启动后直接出现在数据卷中,反之亦然
②可以对数据卷或挂载点中的内容直接修改,修改后对方立即可看到
③数据卷会一直存在,即使挂载数据卷的容器已经被删除
④数据卷可以在容器之间共享和重用

6.2 创建读写数据卷

读写数据卷指的是容器对挂载点具有读写权限
(1)命令
①数据卷是在使用 docker run 启动容器时指定的,其语法格式为:
docker run –it –v /宿主机目录绝对路径:/容器内目录绝对路径 镜像
②注:无论是宿主机中的数据卷还是容器中的挂载点,如果指定的目录不存在,那么 docker
引擎都会自动创建。既使是多级目录不存在
(2)数据卷/挂载点互操作
①宿主机数据卷目录与容器挂载点目录中进行文件修改互操作,修改完毕后,对方都可立即看到修改。
②在宿主机数据卷目录中创建一个新的文件,在容器中可以查看到该文件出现了。在容器中对文件内容进行修改,
在宿主机中可以查看到该修改过的文件内容。
(3)停止容器后的操作
即使容器停止了,在宿主机中只要修改了数据卷目录内容,在重新启动容器后,该修改
过的数据仍会出现在容器中。因为容器是一个 UnionFS,是一个存在于宿主机中的文件系统,
无论容器是否运行,该 FS 都是存在的。
(4)查看数据卷详情
通过 docker inspect [容器] 命令可以查看到当前容器中挂载点与数据卷的绑定关系。

6.3 创建只读数据卷

①只读数据卷,指的是容器对挂载点的操作权限是只读的。宿主机对数据卷的操作权限始
终是读写的。
②有些情况下,为了防止容器在运行过程中对文件产生修改,就需要创建只读数据卷
(1) 命令
该命令仅比之前的命令仅多了:ro,具体语法如下:
docker run –it –v /宿主机目录绝对路径:/容器内目录绝对路径:ro 镜像
(2) 数据卷/挂载点互操作
在容器中修改挂载点中的文件,系统会给出只读文件系统的提示。说明容器对数据卷是只读的。
(3)查看数据郑详情
通过 docker inspect [容器] 命令可以查看到该数据卷的只读属性。

6.4 数据卷共享

当一个容器与另一个容器使用相同的数据卷时,就称这两个容器实现了“数据卷共享”。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值