Docker Tutorial
大佬slides的结构
Docker的定义
Docker架构
*:不同系统下的架构
Docker优势
Docker三个基本概念
- Image
- Container
- Repository
Docker常用command
Dockerfile
构建镜像
使用的命令行/参数
*:layered architecture
构建成功之后的代码运行界面
Docker文件系统
- AUFS/创建容器时AUFS产生的变化
- Volumes
- Bind mounts
Docker容器连接
Docker容器互联
*:网络结构图
Docker Compose
Docker仓库管理
References
安装
(However, to get the best experience, we recommend that you install Rosetta 2)
自带的tutorial命令行
docker run -d -p 80:80 docker/getting-started
![Screen Shot 2022-02-21 at 16.38.18](https://raw.githubusercontent.com/HenryVarro666/images/master/uPic/Screen Shot 2022-02-21 at 16.38.18.png)
参考资料
文档
视频
- https://www.youtube.com/watch?v=iqqDU2crIEQ
- https://www.youtube.com/watch?v=pTFZFxd4hOI
- https://www.youtube.com/watch?v=3c-iBn73dDE
- https://www.youtube.com/watch?v=fqMOX6JJhGo
- https://www.bilibili.com/video/BV1s54y1n7Ev?from=search&seid=6545698363302615398&spm_id_from=333.337.0.0
Slides结构
什么是Docker
https://docs.docker.com/get-started/overview/
What can I use Docker for?
https://docs.docker.com/get-started/overview/
https://www.runoob.com/docker/docker-tutorial.html
和传统的虚拟化方式比较
Linux容器基础之LXC技术介绍:
描述:Docker引擎的基础是Linux容器(Linux Containers,LXC)技术,容器有效的将各个操作系统管理的资源划分到孤立的组,以便更好的在孤立的组之间平衡有冲突的资源使用需求。
容器可以在核心CPU本地运行指令,并不需要任何专门的解释机制;最早的容器技术可以追溯到1982年Unix系列操作系统上的chroot工具;用户操作容器就像操作一个轻量级虚拟机那样简单,也可以将容器比作为一种沙盒(Sandbox)传统虚拟化
Docker
https://www.bilibili.com/read/cv15180540
https://yeasy.gitbook.io/docker_practice/introduction/why
传统虚拟化方式是在硬件层面实现虚拟化,需要有额外的虚拟机管理应用和虚拟机操作系统层,然后在该系统上运行业务所需程序;
Docker虚拟化方式是在宿主系统层面上实现虚拟化,直接复用本地主机的操作系统与内核,容器内没有自己的内核,所以容器内的应用进程实际运行于宿主机内核,因此更加轻量级
什么是虚拟化技术?
虚拟化技术是一个通用的概念,在不同的领域有不同的理解;在计算机领域一般指的是计算机虚拟化(Computer Virtualization)或者说是服务器虚拟化;虚拟化的核心是对资源进行抽象和管理,目标往往是为了在同一个主机上运行多个系统或者应用,从而提高系统资源的利用率,同时带来降低成本,方便管理和容错和容灾等好处;硬件虚拟化:真正意义上的基于它的技术不多见,少数网卡中的单根多IO虚拟化等技术;
软件虚拟化(Virtualization)
1.应用虚拟化
2.平台虚拟化:细分
2.1 完全虚拟化
2.2 硬件辅助虚拟化:利用硬件CPU辅助支持虚拟化技术Intel-VT和AND-V处理铭感指令来实现完全虚拟化的功能;
2.3 部分虚拟化:只对部分硬件资源进行虚拟化,客户端系统需要进行修改;
2.4 准虚拟化(Paravirtualization):如xen
2.5 操作系统级虚拟化:内核通过创建多个虚拟化的操作系统实例内核和库来隔离不同的进程,dokcer以及其他容器都在这个范畴之内; 作者:WeiyiGeek https://www.bilibili.com/read/cv15180540 出处:bilibili
为什么要用Docker
Docker的体系(architecture)
daemon
A background process that handles requests for services such as print spooling and file transfers, and is dormant when not required.
(指在某种条件得到满足时能自动进行工作的计算机程序),守护程序
监听 Docker API 请求并管理 Docker 对象,如图像、容器、网络和卷。守护进程还可以与其他守护进程通信,以管理 Docker 服务。
完整的Docker组成
(1) 守护进程(Daemon):Docker守护进程(dockerd)侦听Docker API请求并管理Docker对象,,如图像、容器、网络和卷。守护进程还可以与其他守护进程通信来管理Docker服务。
(2) REST API: 主要与Docker Daemon进行交互,比如Docker Cli或者直接调用REST API;
(3) 客户端(Docker Client): 它是与Docker交互的主要方式通过命令行接口(CLI)客户端(docker命令),客户机将命令通过REST API发送给并执行其命令;()
(4) Register Repository 镜像仓库: Docker注册表存储Docker镜像,可以采用Docker Hub是公共注册仓库,或者采用企业内部自建的Harbor私有仓库;
(5) Image 镜像: 映像是一个只读模板,带有创建Docker容器的指令。映像通常基于另一个映像,还需要进行一些额外的定制,你可以通过Docker Hub公共镜像仓库进行拉取对应的系统或者应用镜像;
(6) Container 容器: 容器是映像的可运行实例。您可以使用Docker API或CLI创建、启动、停止、移动或删除容器。您可以将一个容器连接到一个或多个网络,将存储附加到它,甚至根据它的当前状态创建一个新映像。
(7) Services : Docker引擎支持集群模式服务允许您跨多个Docker守护进程()扩展管理容器,服务允许您定义所需的状态,例如在任何给定时间必须可用的服务副本的数量。默认情况下,服务在所有工作节点之间进行负载平衡。对于使用者来说Docker服务看起来是一个单独的应用程序
Docker内部的具体实现
Docker资源隔离
Docker 本质是宿主机上的一个进程
•通过namespace实现资源隔离以及轻量级虚拟化容器服务
•通过cgroup实现了资源限制
•通过写时复制技术(Copy-on-write)实现了高效的文件操作
Docker通过由内核namespace提供实现的隔离,namespace的API包括还有在/proc下的部分文件
•进程隔离:每个容器都运行在自己的进程环境中
•网络隔离:容器间的虚拟网络接口和 IP 地址都是分开的
•文件系统隔离:每个容器都有自己的 root 文件系统
•资源隔离和分组:使用 cgroups 将 CPU 和内存之类的资源独立分配给每个 Docker 容器
Namespace的六项隔离
Docker常见概念
概念 | 说明 |
---|---|
Docker 镜像(Images) | Docker 镜像是用于创建 Docker 容器的模板,比如 Ubuntu 系统。 |
Docker 容器(Container) | 容器是独立运行的一个或一组应用,是镜像运行时的实体。 |
Docker 客户端(Client) | Docker 客户端通过命令行或者其他工具使用 Docker SDK (https://docs.docker.com/develop/sdk/) 与 Docker 的守护进程通信。 |
Docker 主机(Host) | 一个物理或者虚拟的机器用于执行 Docker 守护进程和容器。 |
Docker Registry | Docker 仓库用来保存镜像,可以理解为代码控制中的代码仓库。Docker Hub(https://hub.docker.com) 提供了庞大的镜像集合供使用。一个 Docker Registry 中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。 |
Docker Machine | Docker Machine是一个简化Docker安装的命令行工具,通过一个简单的命令行即可在相应的平台上安装Docker,比如VirtualBox、 Digital Ocean、Microsoft Azure |
指令+重要概念
image 镜像
images 类似于虚拟机镜像,借鉴了Git利用分成分层优点,通过文件系统分层的概念实现了分层复用,极大的节约了磁盘空间;
简单的您可以将它理解成为一个面向Docker引擎的只读模板包含文件系统
创建镜像的方法
- 从已有镜像的容器创建
- 基于本地模板导入:使用操作系统模板导入一个镜像文件
- 基于Dockerfile导入
1 | ######### 从已有镜像创建 ############ |
当该镜像在容器运行存在的时候,镜像文件默认是无法被删除的;必须停止/删除容器ID才能删除镜像文件
1 | #当同一个镜像有多个标签的时候rmi命令只是删错了该进行的标签而且,并不影响镜像文件 |
镜像操作常用命令
1 | #搜索关于Archlinux镜像,输出信息不截断显示 |
save和export的区别
save 与 load 命令对应即导出与导入镜像,而export与import命令对应即导出导入容器;
save 保存后 load 加载的镜像没有丢失历史和层(Layer),而容器export导出然后import导入时所有的提交历史将会丢失,这意味着您无法回滚到之前的层;
补充:通过import导入的方式镜像只有一层,而通过commit的方式生成的镜像实际是在原有的Base Image(即复写层)上又生成了一层
Container 容器
镜像自身只读的,容器从镜像启动的时候会在镜像的最上层创建一个可写层,镜像本身将保持不变
创建并运行容器的标准操作
- 检查本地是否存在指定镜像,不存在就从公有仓库下载
- 利用镜像创建并启动一个容器
- 分配一个文件系统,并在只读的镜像层外面挂载一个可读写层
- 从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
- 从地址池配置一个IP地址给容器
- 执行用户指定的应用程序
- 执行完毕后容器被终止
启动容器有两种方式
- 一种是基于镜像新建一个容器并启动
- 另外一个是将在终止状态(stopped)的容器重新启动
容器操作常用命令
1 | #创建容器但处于停止状态 |
Docker load 与 Docker import 的比较
描述:导入容器和导入镜像是差不多的但是实际上又是有所区别的
load:导入镜像存储文件到本地镜像库
import:导入一个容器快照到本地镜像库
容器快照:文件将丢失所有的历史记录和元数据信息(即保留容器当时的快照状态),导入的时候还需要重新制定标签等元数据信息;
镜像存储:文件将保存完整的记录,并且体积也要大
rm和rmi的区别
- docker rm : 删除一个或多个 容器
- docker rmi : 删除一个或多个 镜像
- docker prune : 用来删除不再使用的 docker 对象
仓库
一个 Docker Registry 中可以包含多个 仓库(Repository);每个仓库可以包含多个 标签(Tag);每个标签对应一个镜像。
通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。
如果不给出标签,将以 latest 作为默认标签。
分为公开(Public)和私有(Private)。前者有多个版本,后者为用户自己搭建
Public
Docker Registry 公开服务是开放给用户使用、允许用户管理镜像的 Registry 服务。一般这类公开服务允许用户免费上传、下载公开的镜像,并可能提供收费服务供用户管理私有镜像。
最常使用的 Registry 公开服务是官方的 Docker Hub,这也是默认的 Registry,并拥有大量的高质量的 官方镜像。
除此以外,还有 Red Hat 的 Quay.io;Google 的 Google Container Registry,Kubernetes 的镜像使用的就是这个服务;代码托管平台 GitHub 推出的 ghcr.io。
Private
Docker 官方提供了 Docker Registry 镜像,可以直接使用做为私有 Registry 服务。
开源的 Docker Registry 镜像只提供了 Docker Registry API 的服务端实现,足以支持 docker 命令,不影响使用。但不包含图形界面,以及镜像维护、用户管理、访问控制等高级功能。
镜像仓库操作常用命令
1 | #连接并初始化hub仓库 需要输入用户名和密码认证,然后存放于/root/.docker/config.json 文件中 |
创建和使用私有仓库
1 | $ docker run -d -p 5000:5000 registry |
curl命令
curl是一个开源的用于数据传输的命令行工具与库,它使用URL语法格式,支持众多传输协议。作用是发出网络请求,然后获取数据,显示在”标准输出”(stdout)上面。
自动创建(Automated Builds)
对于需要经常升级镜像内程序来说十分的方便
- 创建登录Docker Hub 绑定Github;
- 在Docker Hub中配置一个自动创建
- 选取一个目标网站中的项目(需要Dockerfile和分支)
- 指定Dockerfile的位置并提交创建,可以在”自动创建页面”跟踪每次创建的状态;
总结:仓库管理镜像的设计理论与Git差不多,工作流程为文件分发和合作带来的众多优势
Dockerfile
Dockerfile是一个文本格式的配置文件,其内包含了一条条的指令(Instruction),每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。
用户可以使用Dockerfile快速创建自定义的镜像;通过它所支持的内部指令,以及使用它创建镜像的基本过程,Docker拥有”一点修改代替大量更新”的灵活之处
文本化的镜像生成操作让其方便版本管理和自动化部署
方便部署
每条命令对应镜像的一层,细化操作后保证其可增量更新,复用镜像块减小镜像体积
减小体积
总结为一点就是**将每一层修改、安装、构建、操作命令都写入到一个脚本之中**。
[一个镜像构建时不能超过 127 层,我们需要保证了稳定的变化的命令至于上层保证了每层打包出来的 Layer 能够尽可能的复用,而不会徒增镜像的大小,影响后续拉取镜像的速度 ]
基本结构
•基础镜像信息:FROM <image> 或者 FROM <image>:<tag>
•维护者信息: MAINTAINER (建议使用LABEL标签进行替代,先已丢弃)
•镜像标签信息: LABEL
•镜像操作指令: RUN
•容器启动时执行指令: CMD
在编写完成Dockerfile之后可以通过docker build 命令来创建镜像,该命令读取指定路径下(包括子目录)的dockerfile(实际上是构建上下文Context),并将该路径下的内容发送给Docker服务端由它创建镜像; 因此一般建议放置Dockerfile的目录为空另外可以通过dockerignore文件(每一行添加一条匹配模式)会让Docker忽略路径下的目录和文件
docker 镜像生成常用命令
docker build [选项]
- t :指定标签信息
–build-arg <参数名>=<值>
构建镜像的几种方式:
1 | #docker build [选项] |
Dockerfile指令
FROM - 基础镜像信息
描述:
尽可能使用官方镜像或者信任的镜像作为你构建镜像的基础设施,推荐使用Alpine镜像,因为它被严格控制并保持最小尺寸(目前小于 6 MB),但它仍然是一个完整的发行版。
1 | #基础语法 |
LABEL - 标签信息
描述:
可以给镜像添加标签来帮助组织镜像、记录许可信息、辅助自动化构建等
注意:如果你的字符串包含空格,那么它必须被引用或者空格必须被转义。如果您的字符串包含内部引号字符(”),则也可以将其转义。
1 | #基础语法:每个标签一行,由 LABEL 开头加上一个或多个标签对。 |
在 1.10 之前,建议将所有标签合并为一条LABEL指令,以防止创建额外的层,但是现在这个不再是必须的了
MAINTAINER - 维护者信息
1 | #基础语法 |
RUN - 镜像操作命令
描述:
为了保持 Dockerfile 文件的可读性,以及可维护性,建议将长的或复杂的RUN指令用反斜杠\分割成多行。
RUN 指令最常见的用法是安装包用的apt-get,因为该指令会安装包
有几个问题需要注意 :
- 不要使用 RUN apt-get upgrade 或 dist-upgrade , 如果基础镜像中的某个包过时了,你应该联系它的维护者。
- 如果你确定某个特定的包比如 foo 需要升级,使用 apt-get install -y foo 就行,该指令会自动升级 foo 包。
- 最好将 RUN 多条语句汇集成为一条 apt-get update 和 apt-get install 以及 rm -rf /var/lib/apt/lists* 组合成一条 RUN 声明
1 | #基础语法 |
CMD- 容器启动时执行指令
描述:
指令用于执行目标镜像中包含的软件和任何参数, 实际上为容器提供一个默认的执行命令。
在Dockerfile中CMD被用来为ENTRYPOINT指令提供参数,则CMD和ENTRYPOINT指令都应该使用exec格式
当基于镜像的容器运行时将会自动执行CMD指令, 并且如果在docker run命令中指定了参数,这些参数将会覆盖在CMD指令中设置的参数。
多数情况下CMD 都需要一个交互式的 shell (bash, Python, perl 等),例如 CMD [“perl”, “-de0”],或者 CMD [“PHP”, “-a”]。使用这种形式意味着,当你执行类似docker run -it python时,你会进入一个准备好的 shell 中。
1 | #基础语法 |
注意事项:
(1)如果用户启动容器指定了运行命令则会覆盖掉CMD指定命令,注意每个Dockerfile只能有一条CMD命令,如果指定了多条命令只有最后一条执行;
(2)CMD 在极少的情况下才会以 CMD [“param”, “param”] 的形式与ENTRYPOINT协同使用,除非你和你的镜像使用者都对 ENTRYPOINT 的工作方式十分熟悉。
EXPOSE - 端口映射指令
描述:
EXPOSE指令用于指定容器将要监听的端口即默认向外部的暴露的服务端口。因此你应该为你的应用程序使用常见的端口。
对于外部访问,用户可以在执行 docker run 时使用一个标志来指示如何将指定的端口映射到所选择的端口。
#基础语法
EXPOSE
1 | #基础示例 |
ENV - 修改环境变量指令
描述:
为了方便新程序运行,你可以使用ENV来为容器中安装的程序更新 PATH 环境变量。例如使用ENV PATH /usr/local/nginx/bin:$PATH来确保CMD [“nginx”]能正确运行。类似于程序中的常量,该方法可以让你只需改变 ENV 指令来自动的改变容器中的软件版本。
1 | #基础语法 |
ARG - 构建参数
描述:
构建参数和 ENV 的效果一样都是设置环境变量不同点就是容器构建完成则失效
1 | ARG <参数名> [=<默认值>] |
ADD - 添加指定目录文件到镜像指令
描述:
该命令将复制指定的源文件
1 | #基础语法 |
注意事项:
(1)为了让镜像尽量小,最好不要使用 ADD 指令从远程 URL 获取包,而是使用 curl 和 wget。
1 | #你可以在文件提取完之后删掉不再需要的文件来避免在镜像中额外添加一层 |
COPY - 复制指定文件或者目录到容器中
描述:
COPY只支持简单将本地文件拷贝到镜像中它比 ADD 更透明,所以ADD和COPY功能类似但一般优先使用 COPY ;
COPY 指令将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置。
当目标路径不存在时候自动创建,当使用本地目录作为源目录时候推荐使用COPY:
1 | #基础语法 |
Tips:
对于其他不需要 ADD 的自动提取功能的文件或目录,你应该使用 COPY。
采用CPOY –from 从上一个构建阶段拷贝文件时,使用的路径是相对于上一阶段的根目录的,此时建议复制成果时候采用绝对路径;
ENTRYPOINT - 配置容器启动进入后的执行命令-应用运行前的准备工作
描述:
该指令是设置镜像的主命令,其作用是允许将镜像当成命令本身来运行(使用终端提供默认选项)
1 | #基础示例 |
补充说明:
1.ENTRYPOINT 指令也可以结合一个辅助脚本使用,和前面命令行风格类似,即使启动工具需要不止一个步骤。
2.通过ENTRYPOINT指令可以将容器设置作为可执行的文件
注意:当指定多个ENTRYPOINT时候只有最后一个生效;
VOLUME- 创建本地主机或其他主机挂载点-定义匿名卷
描述:
指令用于暴露任何数据库存储文件,配置文件,或容器创建的文件和目录。强烈建议使用 VOLUME来管理镜像中的可变部分和用户可以改变的部分。
- VOLUME指令只是起到了声明了容器中的目录作为匿名卷,但是并没有将匿名卷绑定到宿主机指定目录的功能;
- 镜像run了一个容器的时候,docker会在安装目录下的指定目录下面生成一个目录来绑定容器的匿名卷(这个指定目录不同版本的docker会有所不同)
1 | # 基础示例: |
USER- 指定容器运行时名用户名或者UID
描述:
如果某个服务不需要特权执行,建议使用 USER 指令切换到非 root 用户。
注意事项:
1.在镜像中用户和用户组每次被分配的 UID/GID 都是不确定的,下次重新构建镜像时被分配到的 UID/GID 可能会不一样。
如果要依赖确定的 UID/GID 你应该显示的指定一个 UID/GID。
1 | # 方式1 |
2.应该避免使用 sudo 命令因为它不可预期的 TTY 和信号转发行为可能造成的问题比它能解决的问题还多。如果你真的需要和 sudo 类似的功能(例如以 root 权限初始化某个守护进程,以非 root 权限执行它)你可以使用 gosu 命令; 最后为了减少层数和复杂度,避免频繁地使用 USER 来回切换用户。
1 | # 基础示例 |
WORKDIR - 配置工作目录
描述:为了清晰性和可靠性,你应该总是在WORKDIR中使用绝对路径。另外你应该使用 WORKDIR 来替代类似于 RUN cd … && do-something 的指令,后者难以阅读、排错和维护。
1 | # 基础示例 |
ONBUILD - 为他人做嫁衣裳
描述:ONBUILD是一个特殊的指令在当前镜像构建时并不会被执行。**只有当以当前镜像为基础镜像去构建下一级镜像的时候才会被执行**。它后面跟的是其它指令比如 RUN, COPY 等
Dockerfile 中的其它指令都是为了定制当前镜像而准备的,唯有 ONBUILD 是为了帮助别人定制自己而准备的。
STOPSIGNAL - 指定所创建镜像启动的容器接收退出的信号值
描述: 该指令设置将发送到的系统调用信号容器退出,如果不定义信号名称默认是 SIGTERM。
此信号可以是格式中的 SIG
1 | # 实际示例 |
SHELL - 指定其他命令执行时默认使用shell的类型
描述:
该指令允许使用 shell 形式覆盖命令,
- Linux中默认的Shell是[“/bin/sh”, “-c”]
- Windows中默认的Shell是[“cmd”, “/S”, “/C”]
- 如果Linux中还存在备用的shell例如(zsh、csh、tcsh),我们也可以采用此种方法指定。
1 | # 实际示例 |
HEALTHCHECK - 健康检查
描述:该命令设置检查容器健康状况的命令,它与 kubernetes 中的 Pod 探针类似
在没有 HEALTHCHECK 指令前Docker 引擎只可以通过容器内主进程是否退出来判断容器是否状态异常。很多情况下这没问题,但是如果程序进入死锁状态,或者死循环状态,应用进程并不退出,但是该容器已经无法提供服务了。
在 1.12 以前,Docker 不会检测到容器的这种状态,从而不会重新调度,导致可能会有部分容器已经无法提供服务了却还在接受用户请求。
从 Docker 1.12 引入该指令HEALTHCHECK 指令是告诉 Docker 应该如何进行判断容器的状态是否正常,从而比较真实的反应容器实际状态。
当在一个镜像指定了 HEALTHCHECK 指令后,用其启动容器,初始状态会为 starting,在 HEALTHCHECK 指令检查成功后变为 healthy,如果连续一定次数失败,则会变为 unhealthy。
1 | # 基础语法 |
Docker容器文件系统
- Docker 镜像代表了容器的文件系统里的内容,是容器的基础,镜像一般是通过 Dockerfile 生成的
- Docker 的镜像是分层的,所有的镜像(除了基础镜像)都是在之前镜像的基础上加上自己这层的内容生成的
- Docker 中每一层镜像的元数据都是存在 json 文件中的,除了静态的文件系统之外,还会包含动态的数据
- Docker 镜像生产容器后会在此基础之上加入挂载点到安装Docker宿主机文件系统之中,并提供一个读写层(Read-Write Layer),所以容器进程的所有操作都在读写层进行
Volume 数据卷
数据卷
是一个可供一个或多个容器使用的特殊目录,它绕过 UFS,可以提供很多有用的特性:
- 数据卷可以在容器之间共享和重用
- 对 数据卷 的修改会立马生效
- 对 数据卷的更新,不会影响镜像
- 数据卷 默认会一直存在,即使容器被删除
注意:
数据卷
的使用,类似于 Linux 下对目录或文件进行 mount,镜像中的被指定为挂载点的目录中的文件会复制到数据卷中(仅数据卷为空时会复制)。
容器中管理数据的主要两种方式
- 数据卷: Data Volumes
- 数据卷容器: Data Volume Dontainers
数据管理共享的方式
- 使用数据卷容器在容器和主机
- 容器和容器之间共享数据
数据卷命令行
使用 --mount
标记可以指定挂载一个本地主机的目录到容器中去
本地目录的路径必须是绝对路径,以前使用 -v
参数时如果本地目录不存在 Docker 会自动为你创建一个文件夹,现在使用 --mount
参数时如果本地目录不存在,Docker 会报错。
Docker 挂载主机目录的默认权限是 读写
,用户也可以通过增加 readonly
指定为 只读
1 | $ docker run -d -P \ |
--mount
标记也可以从主机挂载单个文件到容器中
1 | $ docker run --rm -it \ |
?: mount和–volumes-from的关系
1 | #创建一个数据卷 |
1 | #### 创建一个web容器并创建一个数据卷挂载到容器的/webapp目录下(默认将宿主机/根映射到容器中webapp目录中) |
数据卷容器命令行
1 | #首先创建一个数据卷容器dbdata并在其中创建一个数据卷挂载到/dbdata上 |
数据卷容器迁移数据
1 | ##可以利用数据卷容器对其中的数据卷进行备份、恢复以实现数据的迁移 |
Z和z的区别
1 | #配置selinux标签如果使用selinux,可以添加z或z选项来修改挂载到容器中的主机文件或目录的selinux标签 |
总结说明
- 推荐直接挂载文件目录到容器中,如果直接挂载一个文件到容器中在使用文本编辑工具时候可能会报错;
- 可以多次使用–volumes-from参数从来多个容器挂载多个数据卷;锁挂载的容器自身并不需要保持在运行状态
- 推荐使用数据卷和数据容器之外的物理备份存储系统,如RAID或者分布式系统如Ceph,GPFS,HDFS等
联合文件系统(UnionFS)
联合文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。
联合文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
另外,不同 Docker 容器就可以共享一些基础的文件系统层,同时再加上自己独有的改动层,大大提高了存储的效率。
Docker 中使用的 AUFS(Advanced Multi-Layered Unification Filesystem)就是一种联合文件系统。 AUFS
支持为每一个成员目录(类似 Git 的分支)设定只读(readonly)、读写(readwrite)和写出(whiteout-able)权限, 同时 AUFS
里有一个类似分层的概念, 对只读权限的分支可以逻辑上进行增量地修改(不影响只读部分的)。
Docker 目前支持的联合文件系统包括 OverlayFS
, AUFS
, Btrfs
, VFS
, ZFS
和 Device Mapper
。
在可能的情况下,推荐 使用 overlay2
存储驱动,overlay2
是目前 Docker 默认的存储驱动,以前则是 aufs
。你可以通过配置来使用以上提到的其他类型的存储驱动。
Question:存储驱动
Question:engine
Question: 容器格式
Docker Compose (需要加强学习)
Compose 定位是 「定义和运行多个 Docker 容器的应用(Defining and running multi-container Docker applications)
Docker Compose 是 Docker 官方编排(Orchestration)项目之一,负责实现对 Docker 容器集群的快速编排。
它允许用户通过一个单独的 docker-compose.yml 模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)
Docker Compose重要概念
- 服务 (
service
):一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。 - 项目 (
project
):由一组关联的应用容器组成的一个完整业务单元,在docker-compose.yml
文件中定义。
Compose 的默认管理对象是项目,通过子命令对项目中的一组容器进行便捷地生命周期管理。
Compose 项目由 Python 编写,实现上调用了 Docker 服务提供的 API 来对容器进行管理。因此,只要所操作的平台支持 Docker API,就可以在其上利用 Compose来进行编排管理。
Docker Machine
Docker Machine 是一种可以让您在虚拟主机上安装 Docker 的工具,并可以使用 docker-machine 命令来管理主机。
Docker Machine 也可以集中管理所有的 docker 主机,比如快速的给 100 台服务器安装上 docker。
Docker Machine 管理的虚拟主机可以是机上的,也可以是云供应商,如阿里云,腾讯云,AWS,或 DigitalOcean。
使用 docker-machine 命令,您可以启动,检查,停止和重新启动托管主机,也可以升级 Docker 客户端和守护程序,以及配置 Docker 客户端与您的主机进行通信。
容器连接
https://www.bilibili.com/read/cv15185166?spm_id_from=333.999.0.0
Question:网络连接的原理
实现通过端口连接到一个docker容器
网络端口映射
- -P :是容器内部端口随机映射到主机的端口。
- -p : 是容器内部端口绑定到指定的主机端口。
1 | #创建了一个 python 应用的容器 |
上面的例子中,默认都是绑定 tcp 端口,如果要绑定 UDP 端口,可以在端口后面加上 /udp
Question: udp?
容器的链接(Linking)系统是除了端口映射外的另一种可以与容器中应用进行交换的方式;它会在源和接收容器之间创建一个隧道,接收容器可以看到源容器指定的信息
Docker两种方式为容器公开连接信息:
- 环境变量
- 更新/etc/hosts
1 | #首先创建一个新的数据库容器,启动db容器的时候并没有使用-p与-P标记,避免了暴露数据库端口到外部网络上 |
跨主机实现互通
还可以通过通过添加路由route的方式进行跨主机实现互通,但是通常情况下我们不会如此操作,只在特殊环境中使用测试。
比如:Docker1: 172.18.0.1/24 <--> Gateways <--> 192.168.1.99
总结
用户可以链接多个子容器到父容器中比如连接多个web到db容器上;
学习额外的机制比如SDN(软件定义网络)或者NFV(网络功能虚拟化)的相关技术
容器互联
端口映射并不是唯一把 docker 连接到另一个容器的方法。
docker 有一个连接系统允许将多个容器连接在一起,共享连接信息。
docker 连接会创建一个父子关系,其中父容器可以看到子容器的信息。
随着 Docker 网络的完善,强烈建议大家将容器加入自定义的 Docker 网络来连接多个容器,而不是使用 --link
参数。
https://www.bilibili.com/read/cv15185166?spm_id_from=333.999.0.0
Question: bridge 和 overlay
1 | #创建一个新的Docker网络 |
Question:
Question: swarm集群要不要讲
Question:存储驱动
Question:engine
Question: 容器格式
后续
kerbernets
docker网络
挂载
提问
最大区别:
进程/程序
轻量,简单