一文介绍Docker高级玩法(满满干货)

深入理解Docker

相关内容原文地址:

博客园:EvanLeung:Docker系列文章

一、容器镜像和容器

镜像是一个可执行包,包含运行应用程序所需的所有内容------代码、运行时、库、环境变量和配置文件。容器是通过运行镜像启动容器,是镜像的运行时实例。镜像实际上就是一个容器的模板,通过这个模板可以创建很多相同的容器。

通过Java去类比理解Docker的一些概念:

  • Class文件 - 相当于Docker镜像,定义了类的一些所需要的信息
  • 对象 - 相当于容器,通过Class文件创建出来的实例
  • JVM - 相当于Docker引擎,可以让Docker容器屏蔽底层复杂逻辑,实现跨平台操作

二、容器与虚拟机的区别

容器在Linux上本地运行,并与其他容器共享主机的内核。它运行一个独立的进程,不占用比其他任何可执行程序更多的内存,使其轻量级。

虚拟机(VM) 运行一个成熟的"游客"操作系统,通过虚拟机监控程序对主机资源进行虚拟访问。通常,vm提供的资源比大多数应用程序所需的要多。

总的来说,容器不需要依赖操作系统,减少了很多系统资源开销,使得容器可以更关注应用的需求,而虚拟机可以为每个应用灵活提供不同的操作系统,避免了docker容器直接依赖主体机器操作系统,两者结合使用,可以让整个系统架构更加灵活,扩展性更强。

三、Docker引擎和架构

Docker引擎是一个客户端-服务器应用程序,主要组件如下:

  • 服务器是一种长时间运行的程序,称为守护进程(dockerd)命令)。
  • 一个REST API,它指定了程序可以用来与守护进程对话的接口指导它做什么。
  • 命令行接口(CLI)客户端(docker命令)。

    我们使用的docker指令都是通过docker客户端去与docker服务端进行通讯。

3.1 Docker架构体系

  • Docker使用客户机-服务器架构。
  • Docker客户机与Docker守护进程进行对话,后者负责构建、运行和分发Docker容器。
  • Docker客户机和守护进程可以在同一系统上运行,也可以将Docker客户机连接到远程Docker守护进程。Docker客户机和守护进程通过UNIX套接字或网络接口使用RESTAPI进行通信。

3.2 Docker的镜像分层

Docker镜像是由一系列层构成的。每一层代表镜像Dockerfile中的一条指令。除了最后一层之外,每一层都是只读的。Docker镜像分层最大的好处是共享资源,其他相同环境的软件镜像都共同去享用同一个环境镜像,而不需要每个软件镜像要去创建一个底层环境。

以Tomcat镜像为例子,对于用户而言,用户面向的是一个叠加后的文件系统,我们对Tomcat容器做任何操作都会记录在容器层,底层镜像文件不会受影响。Docker容器底层共享主机内核,只保留少量运行Image必须的组件,在容器启动时不需要启动内核空间,所以启动时比虚机较快,开销少,易迁移。

Docker Image是有多层结构,实际上由一层一层的文件系统组成,底层都是共享宿主Linux内核,Image的分层结构是是为了提高复用性。Image可以看作是Java的class文件,容器可以看成是JAVA的对象去理解,下层的每一层镜像可以看作是JAVA中的父类,上层镜像可以共享底层镜像的组件,类似JAVA中的继承规则。

Docker Image 基于 Union file systems做镜像和容器分层,避免在每次以新容器运行图像时复制一组完整的文件。将更改分隔为其自身层中的容器文件系统,允许将同一容器置于从已知内容重新启动(因为在删除容器时,更改的图层将被关闭)。

面向用户的是Container层,所有用户新增环境依赖和数据都会保存在容器层,下层Image只可读、不可修改。

Container是一种轻量级的虚拟技术,不需要模拟硬件创建虚拟机启动内核空间,因此启动速度很快。

Docker是基于Linux Kernel的Namespace、CGroups、UnionFileSystem等技术封装成的一种自定义容器格式,从而提供一套虚拟运行环境。

Namespace :对全局系统资源的一种封装隔离,使得处于不同namespace的进程拥有独立的全局系统资源,改变一个namespace中的系统资源只会影响当前namespace里的进程,对其他namespace中的进程没有影响,比如pid[进程]、net[网络]、mnt[挂载点]等
CGroups : cgroup和namespace类似,也是将进程进行分组,但它的目的和namespace不一样,namespace是为了隔离进程组之间的资源,而cgroup是为了对一组进程进行统一的资源监控和限制,比如内存、CPU、进程数等
Union file systems:用来做image和container分层。

四、制作Docker Image的两种方式

  1. 通过Dockerfile制作(推荐) - Dockerfile其内部包含了一条条的指令,每一条指令构建一层,因此每一条指令的内容,就是描述该层应当如何构建。
  2. 通过Docker commit操作 - 通过docker commit命令反向基于容器副本创建一个新的镜像文件。但是使用docker commit看不到Image的创建过程,因此对排查问题不友好。

五、Docker数据存储方式

Docker容器对于宿主机器来说只是一个运行在Linux上的应用,因此它的数据存储还是会依赖宿主机器,Docker是通过挂载宿主机文件系统或内存的方式来实现数据存储的,挂载方式有三种:volume、bind mount和tmpfs。

volumes - 在宿主的文件系统上的docker工作路径下创建一个文件夹(/var/lib/docker/volumes)来存储数据,其他非docker进程是不能修改该路径下的文件,完全由docker来管理
bind mounts - 可以存储在宿主机器任何一个地方,但是会依赖宿主机器的目录结构,不能通过docker CLI 去直接管理,并且非docker进程和docker进程都可以修改该路径下的文件
tmpfs - 无论是在Docker主机上还是在容器内,tmpfs挂载都不会持久保存在磁盘上,它会将信息存储在宿主机器内存里。 容器在其生存期内可以使用它来存储非持久状态或敏感信息。 例如,在内部,swarm services 使用tmpfs挂载将机密挂载到服务的容器中 或者 我们一些不需要持久化数据的开发测试环境,可以使用tmpfs

5.1 Volumes

Volumes 是Docker推荐的挂载方式,与把数据存储在容器的可写层相比,使用Volume可以避免增加容器的容量大小,还可以使存储的数据与容器的生命周期独立。

  • 与bind mounts相比,volumes更易于备份或迁移。
  • 可以使用Docker CLI命令或Docker API管理Volumes。
  • volumes在Linux和Windows容器上均可工作。
  • 可以在多个容器之间更安全地共享volumes。
  • volumes驱动程序使您可以将volumes存储在远程主机或云提供程序上,以加密volumes内容或添加其他功能。

5.1.1 通过--mount方式

-v能做的--mount指令都可以做,与-v指令对比,--mount指令更灵活,支持更多复杂操作,并且不需要严格按照参数顺序,通过key value键值对方式进行配置,可读性更高。

--mount有以下几个参数:

  • type - type可以是bind、volume或者tmpfs,默认是volume
  • source - 宿主机上的目录路径,可以用缩写src
  • destination - 目标路径,容器上挂载的路径,可以用dst或者 target
  • readonly - 可选项,如果设置了,那么容器挂载的路径会被设置为只读
  • volume-opt - 可选项,当volume驱动接受同时多个参数作为选项时,可以以多个键值对的方式传入

5.2 bind mounts

与volumes相比,bind mount的功能有限。 使用绑定安装时,会将主机上的文件或目录安装到容器中。 文件或目录由主机上的完整或相对路径引用。 相比之下,当您使用volume时,将在主机上Docker的存储目录中创建一个新目录,并且Docker管理该目录的内容。

该文件或目录不需要在Docker主机上已经存在。 如果尚不存在,则按需创建。 bind mounts性能非常好,但是它们依赖于具有特定目录结构的主机文件系统。 如果要开发新的Docker应用程序,请考虑使用命名volume。 您不能使用Docker CLI命令直接管理bind mounts

5.3 tmpfs

使用tmpfs不会持久化数据,数据只会存放在宿主机器内存中.

六、相关内容拓展:(技术前沿)

近 10 年间,甚至连传统企业都开始大面积数字化时,我们发现开发内部工具的过程中,大量的页面、场景、组件等在不断重复,这种重复造轮子的工作,浪费工程师的大量时间。针对这类问题,低代码把某些重复出现的场景、流程,具象化成一个个组件、api、数据库接口,避免了重复造轮子。极大的提高了程序员的生产效率。

介绍一款程序员都应该知道的软件 JNPF 快速开发平台,基于 Java/.Net 双技术引擎,专注于低代码,采用业内领先的 SpringBoot 微服务架构、支持 SpringCloud 模式,完善了平台的扩增基础,满足了系统快速开发、灵活拓展、无缝集成和高性能应用等综合能力;采用前后端分离模式,前端和后端的开发人员可分工合作负责不同板块,省事又便捷。

免费体验官网:www.jnpfsoft.com?Juejin

相关推荐
阿珊和她的猫26 分钟前
v-scale-scree: 根据屏幕尺寸缩放内容
开发语言·前端·javascript
数据知道2 小时前
容器化部署:用Docker封装机器翻译模型与服务详解
docker·容器·机器翻译
PAK向日葵2 小时前
【算法导论】PDD 0817笔试题题解
算法·面试
加班是不可能的,除非双倍日工资5 小时前
css预编译器实现星空背景图
前端·css·vue3
wyiyiyi5 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
gnip6 小时前
vite和webpack打包结构控制
前端·javascript
excel6 小时前
在二维 Canvas 中模拟三角形绕 X、Y 轴旋转
前端
阿华的代码王国6 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端
一条上岸小咸鱼6 小时前
Kotlin 基本数据类型(三):Booleans、Characters
android·前端·kotlin
Jimmy6 小时前
AI 代理是什么,其有助于我们实现更智能编程
前端·后端·ai编程