Docker

Docker是一个開放原始碼開放平臺軟體,用于开发应用、交付(shipping)应用和运行应用。Docker允许用户将基础设施(Infrastructure)中的应用单独分割出来,形成更小的颗粒(容器),从而提高交付软件的速度。[2]

Docker
原作者Solomon Hykes
開發者Docker, Inc.
首次发布2013年3月13日 (2013-03-13)
当前版本
  • 26.0.0 (2024年3月20日;穩定版本)[1]
源代码库
编程语言Go
操作系统LinuxWindowsmacOS
平台x86-64ARM、s390x、ppc64le
类型作業系統層虛擬化
许可协议可執行檔:免費增值软件即服务
原始碼:Apache许可证 2.0
网站www.docker.com

Docker容器与虚拟机类似,但二者在原理上不同。容器是将操作系统层虚拟化,虚拟机则是虚拟化硬件,因此容器更具有便携性、更能高效地利用服务器。 容器更多的用于表示软件的一个标准化单元。由于容器的标准化,因此它可以无视基础设施(Infrastructure)的差异,部署到任何一个地方。另外,Docker也为容器提供更强的业界的隔离兼容。[3]

Docker 利用Linux核心中的資源分離機制,例如cgroups,以及Linux核心命名空間(namespaces),來建立獨立的容器(containers)。這可以在單一Linux實體下運作,避免啟動一個虛擬機器造成的額外負擔[4]。Linux核心對命名空間的支援完全隔離了工作環境中應用程式的視野,包括行程樹、網路、用户ID與掛載檔案系統,而核心的cgroup提供资源隔離,包括CPU記憶體、block I/O與網路。從0.9版本起,Dockers在使用抽象虛擬是經由libvirtLXC與systemd - nspawn提供界面的基礎上,開始包括libcontainer函式庫做為以自己的方式開始直接使用由Linux核心提供的虛擬化的設施。[4]

基础架构

专业名词Docker有两个意思:[5]

  • 代指整个Docker项目。
  • 代指Docker引擎。

Docker引擎

Docker引擎(Docker Engine)是一个服务端-客户端结构的应用,主要有这些部分:Docker守护进程、Docker Engine API页面存档备份,存于、Docker客户端。[6]

Docker注册中心

Docker注册中心(Docker registry)是用于存储Docker的镜像。Docker Hub 是一个公共的注册中心,任何人都可以使用,默认配置下,Docker将会在这里寻找镜像。[6]

另外,用户可以自行构建私有注册中心。Docker Datacenter (DDC)的用户,可以直接使用 Docker Trusted Registry (DTR)。[6]

2023年5月,在中国大陆地区被防火墙阻断屏蔽。[9]

对象

Docker的对象是指Images、Containers、Networks、Volumes、Plugins等等。[6]

  • 容器(Containers)是镜像的可运行的实例。容器可通过API或CLI(命令行)进行操控。[6]
  • 镜像(Images)是一个只读模板,用于指示创建容器。[6] 镜像分层(layers)构建的,而定义这些层次的文件叫Dockerfile[10]
  • 服务(Services)允许使用者跨越不同的Docker守护进程(Docker daemons)的情况下增加容器,并将这些容器分为管理者(managers)和工作者(workers),让他们为swarm共同工作。[6]

扩展架构

Docker Compose

Compose可译为组合物。[11]Compose 是用于定义和运行 多个容器Docker应用程序 的工具。通过Compose,你可以使用YAML文件来配置应用程序需要的所有服务,然后通过使用一个命令,就可以创建并启动所有服务。[12][13]Compose对应的命令为docker-compose[14]

Swarm Mode

当说到 Docker Swarm 时,一般是指单独项目 Docker Swarm。而在Docker 1.12时,将swarm mode集成到Docker 引擎中,可用Docker引擎API 和 CLI 命令直接使用。官方推荐用户使用集成的 swarm mode [15]

Swarm Mode 内置 kv 存储功能,提供了众多的新特性,比如:具有容错能力的去中心化设计、内置服务发现、负载均衡、路由网格、动态伸缩、滚动更新、安全传输等。使得 Docker 原生的 Swarm 集群具备与 Mesos、Kubernetes 竞争的实力。[16]

cluster(中文:集群),Docker将集群定义为:一群共同作业并提供高可用性的机器[5] 。swarm(中文:群[17]),是指一个集群的Docker引擎以swarm mode形式运行[5]。swarm mode是指Docker引擎内嵌的集群管理和编排功能。当你初始化了一个swarm(cluster)或者将节点加入一个swarm时,其Docker引擎就会以swarm mode的形式运行。[5]

原理

swarm中的Docker机器中分为 managers(管理者) 和 workers(员工),管理者用于处理集群的关系和委派,员工则用于执行 swarm服务。[18] 当你创建swarm服务时,你可以为其增加各种额外的状态(如:数量、网络、端口、存储资源等等)。Docker会去维持用户想要的状态。如:一个工作节点如果挂了,那么Docker会去把这个节点的任务给另外一个节点。此处的任务(task)是指:被swarm管理者管理的一个运行中的容器。[18]

swarm服务比单独容器好在,修改swarm服务的配置之后不用重启。同时,Docker以swarm mode形式运行时,也可以选择直接启动单独的容器。另外,swarm mode下,你也可以通过 docker stack deploy 使用 Compose file 部署应用栈。[19][18] swarm服务分为两种,一种是replicated services ,可以指定节点任务的总数量;global services,则是每个节点都会运行一个指定任务。[20] swarm管理员使用 ingress 负载均衡使服务可被外部接触。 swarm管理员会自动地给服务分配PublishedPort(或者手动配置)。外部组件,如云负载均衡器能通过集群中任何节点上的PublishedPort去接入服务(不管该服务是否启动)。另外 swarm mode有内部DNS组件,它会为每个服务分配一个DNS条目。swarm管理员使用 internal load balancing 去分发请求时,就是依靠这个DNS组件。[21]

swarm mode的功能是由swarmkit(一个独立项目)提供的,它实现了Docker的编排层。swarm可以直接被Docker使用。[18]

文件格式

Docker有两种文件格式,Dockerfile和Compose file。Dockerfile定义了单个容器的内容和启动时候的行为。Compose file定义了一个多容器应用。[22]

Dockerfile

Docker 可以依照 Dockerfile 的内容,自动化地构建镜像。 Dockerfile 是包含着用户想要如何构建镜像的所有命令的文本。[23]

FROM ubuntu:18.04
COPY . /app
RUN make /app
CMD python /app/app.py

关键词:

  • RUNRUN会在当前镜像的顶层上添加新的一层(layer),并在该层上执行命令,执行结果将会被提交。提交后的结果将会用于Dockerfile的下一步。[24]
  • ENTRYPOINT入口点ENTRYPOINT允许你配置容器,使之成为可执行程序。[25]即,ENTRYPOINT允许你为容器增加一个入口点ENTRYPOINTCMD类似,均在容器启动时执行,但是ENTRYPOINT为了提供稳定且不可被覆盖的操作。[26]通过在命令行中指定--entrypoint 命令的方式,可在运行时将Dockerfile文件中的ENTRYPOINT覆盖。
  • CMD,是command的缩写。CMD用于为已创建的镜像提供默认的操作,当不想要用默认操作时候,可用docker run IMAGE[:TAG|@DIGEST] [COMMAND] 进行替换 。但当Dockerfile拥有入口点时,CMD用于赋予入口点参数。[27]

Compose文件

Compose文件 是一个YAML文件,定义了服务(service)、网络、(volume)。

  • 服务(service)定义 各容器的配置,定义内容将以命令行参数的方式 传给 docker run 命令。
  • 网络(network),类似地,将定义内容传给 docker network create 命令 。
  • 卷(volume),类似地,将定义内容传给 docker volume create 命令。

docker run 命令中有一些选项,和 Dockerfile文件中的指令效果一样(如:CMD, EXPOSE, VOLUME, ENV),如果Dockerfile文件中使用这些指令,那么这些指令就会被视为默认参数,所以开发者无需特意在 Compose文件中再指定一次。[28]

Compose文件 可使用 Shell变量(Variable),如:[29]

db:
  image: "postgres:${POSTGRES_VERSION}"

Compose文件 可通过自身的ARGS变量,将参数传给DockerfileARGS 指令。[30]

网络

参考文档:Docker文档-网络概要页面存档备份,存于

bridge

在Docker裡,网桥网络 使用的是 软件形式的网桥。使用相同的网桥的容器连接进入该网络,而非该网络的容器刷故无法接入。Docker网桥驱动会自动地在Docker主机上安装规则,这些规则让不同桥接网络之间不能直接通信。[31] 桥接经常用于:在单独容器上运行应用时,可通过 网桥 进行通信。[32] 网桥网络 适用于容器运行在相同地Docker守护进程的主机上。不同Docker守护进程主机上的容器,它们之间的通信需要依靠操作系统层次的路由,或者你应该使用 overlay网络 进行代替。[31]

bridge 是网桥驱动,是Docker默认的网络驱动(接口名为 docker0[33]),当你不为容器指定一个网络时候,Docker将会使用该驱动。[32] 可通过 daemon.json 文件修改相关配置。[34]

自定义网桥可通过 brctl 命令进行配置。[35][36]

host

主机模式

host 用于单独容器,该网络下容器只能和Docker主机进行直接连接。host 只适用于 Docker 17.06或以上版本的swarm服务。

host网络和VirtualBox的 仅主机网络(Host-only Networking) 类似。[37]

overlay

overlay (中文:覆盖网络)网络驱动将会创建分布式网络,该网络可以覆盖若干个 Docker守护进程主机。该网络是基于 主机特定网络(host-specific networks),允许 swarm服务 和 容器 进行安全通信(当加密功能开启时)。在该网络下,Docker能够清晰地掌握 数据包的路由 以及 发送接收容器。[38]

overlay 有两种网络类型网络:[38]

  • ingress 网络,可掌控 swarm服务 的网络流量 。该网络是 overlay 的默认网络。
  • docker_gwbridge 网络是 网桥网络。该网络会将 单独的Docker守护进程 连接至 swarm里的另外一个守护进程。

overlay 网络下,单独的容器 和 swarm服务 的行为和配置概念 是不一样的。[38]

该策略不需要 容器们 具有操作系统级别的路由,因为Docker负责路由。[32]

macvlan

Macvlan网络配置提供了一种机制,允许单独的容器具有独立的MAC地址,使得这些容器在网络上表现得如同物理设备。

none

该策略下,容器不使用任何网络。none 常常用于连接自定义网络驱动的情况下。

其他

截止2023年5月18日,Docker官方仓库域名 https://hub.docker.com/ 页面存档备份,存于 在中国大陆被屏蔽,方式为DNS污染。

数据管理

Docker默认下,所有文件将会存储在容器里的可写的容器层(container layer)。[39]

  • 数据与容器为一体。随着容器消失,数据将消失;难以与其他程序(容器)共享。可以采用挂载文件的方式解决。
  • 由于容器的写入层是与宿主机器紧紧耦合。所以你难以移动数据到其他机器。
  • 容器的写入层的是通过 存储驱动页面存档备份,存于(storage driver) 管理文件系统。存储驱动页面存档备份,存于 会使用Linux内核的 链合文件系统(union filesystem)进行挂载。相比起直接操作于宿主机器文件系统的 数据卷,这额外的抽象层将会降低性能。

容器有两种永久化存储方式:卷(volumes)绑定挂载(bind mounts)。另外,Linux用户还可使用 tmpfs 进行挂载;Window用户还可以使用 命名管道(named pipe)。在容器中,不管是哪种永久化存储,表现形式都是一样的。[39]

卷(volumes)是宿主机器的文件系统的一部分,由Docker进行管理( 在Linux,存储于/var/lib/docker/volumes/)。非Docker程序不应该去修改这些文件。Docker推荐使用 卷 进行持久化数据。 卷 可支持 卷驱动(volume drivers),该驱动允许用户将数据存储到 远程主机 或 云服务商(cloud provider)或 其他。[39]

没有名字的卷叫匿名卷(anonymous volume),有名字的卷叫命名卷(named volume)。匿名卷没有明确的名字,当被初始化时,会被赋予一个随机名字。[39]

绑定挂载

绑定挂载(bind mounts)通过将宿主机器的路径挂载到容器里的这种方式,从而数据持续化,因此绑定挂载可将数据存储在宿主机器的文件系统的任何地方。非Docker程序可修改这些文件。 绑定挂载是Docker早期就存在的,相比起卷,绑定挂载十分简单明了。[39] 在开发Docker应用时,应使用命名卷(named volume)代替绑定挂载,因为用户不能对绑定挂载进行 Docker CLI 命令操作。[39]

绑定挂载常用于:[40]

  • 同步配置文件,如: 将 宿主主机的DNS配置文件/etc/resolv.conf)同步至容器中
  • 在开发程序时,将 源代码 或 Artifact 同步至容器中。[40] 这种用法与 Vagrant 类似。

tmpfs

tmpfs 挂载(tmpfs mounts),仅仅存储于内存中,并不操作 宿主机器的文件系统(不持久化于磁盘)。它可用于存储一些 非持久化状态、敏感数据。 举例,swarm服务 通过tmpfssecrets页面存档备份,存于(密码、密钥、证书等)存储到swarm服务。 [39]

命名管道

命名管道(named pipes),通过 npipe 挂载的形式,使 Docker主机 和 容器 之间能互相通讯。常见用例是在容器内运行第三方工具,并使用命名管道连接到Docker Engine API。[39][41]

覆盖问题

当挂载 空的卷 至一个目录中,目录中的内容会被复制于卷中(不会覆盖)。如果挂载 非空的卷 或 绑定挂载 至一个目录中,那么该目录的内容将会被隐藏(obscured ),当卸载后内容将会恢复显示。[42]

日志

UNIX类Unix系统中,常见的 I/O流(英語:) 分为三种:STDIN(输入 )、 STDOUT(正常输出)、STDERR(错误输出)。[43]

默认配置下,Docker的日志(如:docker logsdocker service log)所记载的是命令行的输出结果(STDOUTSTDERR)。而STDOUTSTDERR 对应的文件路径分别是 /dev/stderr/dev/stdout[43] 另外,也可以在宿主主机上查看容器的日志,使用以下命令可以查看到容器的日志位置。[44]

$ docker inspect --format='{{.LogPath}}' $INSTANCE_ID

Kubernetes in docker

kind(全称:Kubernetes IN Docker)是部署本地Kubernetes集群的工具,而集群的节点是由Docker生成的。[45]

操作细节

在安装完kind之后,通过kind create cluster命令生成集群。[45] 生成Kubernetes集群后,可以通过Docker命令进行查看节点概览:

$ docker container ls

CONTAINER ID        IMAGE                  COMMAND                  CREATED             STATUS              PORTS                       NAMES

99c96c1f21ab        kindest/node:v1.17.0   "/usr/local/bin/entr…"   4 minutes ago       Up 4 minutes        127.0.0.1:32769->6443/tcp   kind-control-plane

历史

Docker命令在过去的发展中诞生了40种以上的命令,过多的命令导致混乱以及难以使用tab自动补充,因此在docker 1.13版本(2017.1.19)中,命令行被重构,根据逻辑对象进行划分。官方建议用户使用新的语法进行操作。[46]

已过时

Docker Swarm

参考Swarm Mode章节。

Docker Machine

Docker Machine 是一个工具,它允许你在虚拟宿主机上安装 Docker引擎,并使用 docker-machine 命令管理这些宿主机。你可以使用 Machine 在你本地的 Mac 或 Windows box、公司网络、数据中心、或像 AWS 或 Digital Ocean 这样的云提供商上创建 Docker 宿主机。[47][48]

Docker Machine 最后更新时间是在0.16.0 (2018-11-08)版本[49]。官方建议在1.12以及之后版本使用Docker Desktop for Mac和Docker Desktop for Windows进行代替。[47]

Docker Toolbox

Docker Toolbox是用于帮 Windows系统和Mac系统 安装Docker环境。新版本建议使用Docker Desktop for Mac和Docker Desktop for Windows进行安装。[50]最后更新版本是 19.03.1(2019-08-01)。[51]

安全性爭議

2021年,安全公司Palo Alto Networks研究人員Aviv Sasson,在Docker Hub上發現的惡意容器映像存檔,分別來自10個不同帳號,總下載次數超過2000萬次,其中內含的挖礦軟體。[52]

参考文献

  1. . 2024年3月20日 [2024年3月20日].
  2. . Docker Documentation. 2020-03-20 [2020-03-22]. (原始内容存档于2020-03-22) (英语).
  3. . www.docker.com. [2020-03-22]. (原始内容存档于2018-08-06) (英语).
  4. . docker.readthedocs.org. 2014-01-04 [2014-08-20]. (原始内容存档于2014-08-21).
  5. . Docker Documentation. 2020-02-25 [2020-02-29]. (原始内容存档于2019-12-28) (英语).
  6. . Docker Documentation. 2020-02-14 [2020-02-16]. (原始内容存档于2020-01-06) (英语).
  7. . Docker Documentation. 2020-02-14 [2020-02-16]. (原始内容存档于2020-02-18) (英语).
  8. . Docker Documentation. 2020-02-14 [2020-02-16]. (原始内容存档于2020-02-18) (英语).
  9. . v2ex. [2023-07-07]. (原始内容存档于2023-07-08).
  10. . Docker Documentation. 2020-02-14 [2020-02-16]. (原始内容存档于2020-02-18) (英语).
  11. . WordHippo. [2020-02-16]. (原始内容存档于2020-02-16) (英语).
  12. . www.runoob.com. [2020-02-16]. (原始内容存档于2020-02-16).
  13. . Docker Documentation. 2020-02-14 [2020-02-16]. (原始内容存档于2020-02-18) (英语).
  14. . Docker Documentation. 2020-02-14 [2020-02-16]. (原始内容存档于2020-04-01) (英语).
  15. . Docker Documentation. 2020-02-25 [2020-02-29]. (原始内容存档于2020-04-23) (英语).
  16. . yeasy.gitbooks.io. [2020-03-05]. (原始内容存档于2020-03-20).
  17. . dictionary.cambridge.org. [2020-02-24]. (原始内容存档于2020-04-23) (中文(繁體)).
  18. . Docker Documentation. 2020-02-20 [2020-02-24]. (原始内容存档于2020-02-24) (英语).
  19. . Docker Documentation. 2020-02-25 [2020-02-29]. (原始内容存档于2020-02-29) (英语).
  20. . Docker Documentation. 2020-02-25 [2020-02-29]. (原始内容存档于2020-02-24) (英语).
  21. . Docker Documentation. 2020-02-25 [2020-02-29]. (原始内容存档于2020-02-24) (英语).
  22. . Docker Documentation. 2020-02-14 [2020-02-17]. (原始内容存档于2020-02-17) (英语).
  23. . (原始内容存档于2020-02-18).
  24. . [2020-02-18]. (原始内容存档于2020-02-18).
  25. . [2020-02-27]. (原始内容存档于2020-02-21).
  26. . (原始内容存档于2020-02-02).
  27. . (原始内容存档于2020-02-02).
  28. . [2020-02-19]. (原始内容存档于2020-02-16).
  29. . (原始内容存档于2020-02-16).
  30. . Docker Documentation. 2020-04-09 [2020-04-13]. (原始内容存档于2020-04-11) (英语).
  31. . Docker Documentation. 2020-03-19 [2020-03-20]. (原始内容存档于2020-02-23) (英语).
  32. . Docker Documentation. 2020-03-19 [2020-03-20]. (原始内容存档于2020-04-15) (英语).
  33. . yeasy.gitbooks.io. [2020-03-20]. (原始内容存档于2020-03-20).
  34. . Docker Documentation. 2020-03-19 [2020-03-20]. (原始内容存档于2020-02-23) (英语).
  35. . wiki.debian.org. [2020-03-20]. (原始内容存档于2020-03-20).
  36. . yeasy.gitbooks.io. [2020-03-20]. (原始内容存档于2020-03-20).
  37. . condor.depaul.edu. [2020-03-09]. (原始内容存档于2019-07-25).
  38. . Docker Documentation. 2020-03-19 [2020-03-20]. (原始内容存档于2020-03-20) (英语).
  39. . Docker Documentation. 2020-03-20 [2020-03-21]. (原始内容存档于2020-03-16) (英语).
  40. . Docker Documentation. 2020-03-20 [2020-03-21]. (原始内容存档于2020-03-16) (英语).
  41. . juejin.im. [2020-03-21]. (原始内容存档于2020-03-21).
  42. . Docker Documentation. 2020-03-20 [2020-03-21]. (原始内容存档于2020-03-16) (英语).
  43. . Docker Documentation. 2020-04-17 [2020-04-17]. (原始内容存档于2020-04-16) (英语).
  44. . Docker Documentation. 2020-04-17 [2020-04-18]. (原始内容存档于2020-04-15) (英语).
  45. , Kubernetes SIGs, 2020-05-04 [2020-05-04], (原始内容存档于2022-02-11)
  46. . Docker Blog. 2017-01-19 [2020-03-05]. (原始内容存档于2020-01-09) (美国英语).
  47. . Docker Documentation. 2020-02-25 [2020-03-02]. (原始内容存档于2020-03-02) (英语).
  48. . 知乎专栏. [2020-03-02]. (原始内容存档于2020-03-02) (中文).
  49. . Docker Documentation. 2020-02-25 [2020-03-02]. (原始内容存档于2020-03-02) (英语).
  50. . Docker Documentation. 2020-02-25 [2020-03-02]. (原始内容存档于2020-04-15) (英语).
  51. . GitHub. [2020-03-02]. (原始内容存档于2020-06-11) (英语).
  52. 林妍溱. . ithome. 2021-03-31 [2021-03-31]. (原始内容存档于2021-04-07).

外部連結

参见

This article is issued from Wikipedia. The text is licensed under Creative Commons - Attribution - Sharealike. Additional terms may apply for the media files.