Docker:Docker基础知识

docker是什么

docker 是一个基于Go语言的开源应用容器引擎。

docker可以让开发者打包自己的应用到一个轻量级、可移植的容器中,实现容器化。

不同容器内的程序不会相互影响,想删除某个容器应用,通过直接删除掉容器,能够达到最小残留。

这比起直接安装应用,更加方便管理。

看到这些,感觉docker与虚拟机大同小异,那么他们的区别在哪儿?

docker与虚拟机的区别:

虚拟机运行程序时,如下图:

Docker:Docker基础知识
  • HardWare:计算机硬件资源
  • Kernel:操作系统内核(内核应该包含在操作系统中,为了虚拟机结构图和docker容器结构图区分,单独拿出来了)
  • Host OS:宿主机除内核的操作系统
  • Hypervisor:计算机管理程序,分配管理宿主机的资源,实现硬件资源虚拟化。Hypervisor能够直接管理调用硬件资源,甚至可以不需要底层操作系统。
  • Guest OS:客户机(虚拟机)操作系统
  • Dependencies:相关依赖等
  • APP:程序主体

docker容器的程序运行结构,如下图:

Docker:Docker基础知识
  • Docker daemon:docker守护进程

对比两张结构图:

1、管理

  • 虚拟机需要一层Hypervisor去管理虚拟机的运行情况,Hypervisor能够直接管理调用底层资源,所以它承载着虚拟机(VM)
  • 而docker则是运行一个进程(docker daemon)去管理容器,不属于父子关系。 比如docker一个容器运行mysql,通过ps命令(或者pstree)查看进程,mysql-master容器进程的父进程是-bash,-bash的父级是sshd,sshd的父级是systemd,中间没有经过守护进程,如下图:

Docker:Docker基础知识

2、内核

  • 虚拟机中还有一个Kernel(操作系统内核),所以虚拟机是不依赖宿主机内核的,只要有Hypervisor,虚拟机就都能够运行。
  • docker的容器中没有内核,只有一层操作系统。因为docker容器的运行都依赖于宿主机内核,这意味着docker只能在linux上运行(其他系统都需要有linux虚拟机),且不能在低版本 Linux宿主机 运行 高版本Linux容器。

3、技术

  • 虚拟化,虚拟机的Hypervisor能够直接管理硬件资源,实现硬件隔离。
  • 容器化(容器虚拟化),docker daemon依赖宿主机内核的cGroups与namespace特性,实现对容器的资源限制隔离。

docker的三个基本概念

docker的三个基本概念:

  • 镜像(Image):用于docker容器的创建运行,方便移植。类似于代码,可以放到其他服务器上去运行。
  • 容器(Container):docker运行程序的载体。通过镜像创建容器,可以看成代码运行起来,在内存中开辟的空间,只要有代码都可以运行出同样的程序。此时删除镜像,容器不会发生改变。
  • 仓库(Repository):镜像的存储空间,可以看成代码仓库,比如github。

docekr的配置与使用

[Linux][阿里服务器]CentOS7联网安装docker-ce(yum)

[Linux][阿里服务器]CentOS7离线安装docker-ce

docker如何实现容器化

docker的容器化体现在资源限制与容器间隔离,主要依赖于内核的cgroups与namespace特性。

首先看一下这两个特性的作用

docker容器的资源限制,通过cGroups(control groups)实现,

它最主要的作用,就是限制一个进程组能够使用的资源上限,包括CPU、内存、磁盘、网络带宽等等。以文件目录形式 挂载在 /sys/fs/cgroup。

docker容器间的隔离,是通过 namespace 命名空间进行的划分,在不同的 namespace 下 进程相互不可见。
namespace 也分为:

  • pid ns(管理进程id PID: Process ID)、
  • net ns(管理网络 NET: Networking)、
  • mnt ns(管理挂载点 MNT: Mount)、
  • ipc ns(管理进程间通信 IPC: InterProcess Communication)
  • uts ns(Unix时间系统隔离 UTS: Unix TimesharingSystem)

那么,这两个特性是对进程组的限制,和docker容器有什么关系?

docker容器 实际上就是一个个进程,可以通过 ps -ef 查看运行容器的进程,一个容器可能存在多个进程。

比如,现在我创建一个镜像,里边有一个java程序,一个mysql。

使用docker run运行容器后,该容器至少存在java进程与mysql进程。

这样看来,容器和其中的进程并不能画等号

有时会遇到这样的情况:

内存使用空间过高,导致OOM,

触发的OOM Killer,会杀死容器的某个或某些进程,导致容器存在,但是进程已死 容器无法使用。

解决方案一,

强制kill容器 docker kill <容器别名或者容器id><!--容器别名或者容器id-->
然后启动容器 docker start <容器别名或者容器id><!--容器别名或者容器id-->
解决方案二(此方法由于删除容器,容器数据若无挂载数据卷,将导致数据丢失),

强制移除容器 docker rm -f <容器别名或者容器id><!--容器别名或者容器id-->
然后清理网络占用 docker network disconnect --force bridge <容器别名或者容器id><!--容器别名或者容器id-->

docker的信号机制

docker stop 与 docker kill 均可以将容器停掉,但二者究竟有什么区别呢?首先,摘录一下官网对这两个功能的描述:

docker stop: Stop a running container (send SIGTERM, and then SIGKILL after grace period) […] The main process inside the container will receive SIGTERM, and after a grace period, SIGKILL. [emphasis mine]
docker kill: Kill a running container (send SIGKILL, or specified signal) […] The main process inside the container will be sent SIGKILL, or any signal specified with option –signal. [emphasis mine]

docker stop,支持”优雅退出”。

先发送SIGTERM信号,在一段时间之后(10s)再发送SIGKILL信号。

Docker内部的应用程序可以接收SIGTERM信号,然后做一些”退出前工作”,比如保存状态、处理当前请求等。

docker kill,发送SIGKILL信号,应用程序直接退出。

两种停止容器的方式与 linux下的kill命令的-15(结束必要工作后退出)和-9(强制kill)效果相似。

线上应用优雅退出十分必要。docker stop也不是docker独有的设计,lxc和google borg系统都有类似设计,即在发送SIGKILL之前,发送SIGTERM信号通知任务。

之前有遇到一次因为强制kill导致docker hang死的经历:

当时是由于磁盘使用空间已满,导致一个k8s容器发生故障,清理磁盘后决定重启该容器。

发现无法停止该容器,docker stop后容器依然存在,判断此时容器内进程已停止,使用 docker kill强制停止容器。

重启后发现,容器仍旧没有正常工作,决定重启docker。

停止docker后,发现启动docker后 docker命令无法使用,docker ps 会卡死没有反应。

再次停止docker,检查docker状态,发现停止docker的信号是SIGNKILL,导致docker守护进程没有正常停止。kill 掉守护进程,启动docker之后 可以正常使用。

docker文件目录

不同版本的docker目录不一样,通用目录一般有:

  1. containers:存放容器基本信息。目录名称对应容器ID,
  2. config.v2.json 存储环境变量、容器创建时间、容器路径、容器名称、容器网关,文件驱动、网桥等信息
  3. hostconfig.json 存储容器数据映射、cpu限制、磁盘限制、内存限制、掩码、网关等信息
  4. hostname 存储容器内部的主机名
  5. hosts 存储容器内部的主机配置
  6. image:存放镜像基本信息
  7. network:存放容器网络连接信息
  8. swarm
  9. temp:临时数据
  10. trust:信任文件
  11. volumes:容器卷数据信息
  12. overlay/overlay2/aufs:存储镜像层、容器层文件。
    overlay/overlay2/aufs是三种不同的文件存储驱动,以前docker首选aufs驱动,但是有些linux发行版不支持aufs。目前常见overlay和overlay2。

docker的文件存储驱动

overlayFS是和aufs相似的联合文件系统。

docker的overlay存储驱动利用overlayFS的一些特征来构建管理镜像和容器的磁盘结构。

overlay

Docker:Docker基础知识

overlay应用两个目录,upperdir和lowerdir,分别是容器层和镜像层。
通过联合挂载技术将镜像层和容器层挂载到同一层,提供统一视图。

docker pull 拉取镜像后,在docker目录下的overlay目录中会增加对应的镜像目录,镜像目录的名称和镜像ID并不是对应的(
docker1.10开始,使用基于内容的寻址,因此目录名和镜像层的id不一致)。
镜像目录中的root目录为镜像层的所有目录文件。

docker 启动一个容器后,overlay目录下会生成两个目录,xxx….xx和xxx….xx-init。
xxx….xx为读写层,xxx….xx-init为初始层,初始层存储容器的相关环境信息,对容器的修改都是存在于读写层。

overlay2

overlay2 可以实现多层文件结构,镜像层和容器层都有diff和work两个目录,diff用于存储内容,work用于存储修改时的内容。
容器的读写层 多一个merged目录,该目录为联合挂载后的视图目录,容器内的目录文件就是此文件下的文件结构。

文件存储驱动详解 – doker的overlay文件系统

DOCKER存储驱动之AUFS简介

Original: https://www.cnblogs.com/casoli/p/16128251.html
Author: 曹纾离
Title: Docker:Docker基础知识

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/580425/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 【已解决】wordpress 修改固定链接 伪静态URL出现nginx 404错误

    一、站点设置 打开站点设置,选择伪静态,选择wordpress 二、wordpress设置 打开wordpress后台,选择 设置 —》固定链接 选择一个你喜欢的格式点…

    Java 2023年6月15日
    071
  • 程序员副业之如何借国庆流量,用换头像小程序日赚500?

    你好啊,这里是程序员田同学。 再有二十天就是国庆了,时间快的让人猝不及防……除了缅怀以外,我们还要抓住商机。 今天就教你如何借国庆的流量,搭建国庆换头像小程…

    Java 2023年6月8日
    077
  • Mysql 根据一个表数据更新另外一个表

    方法一: update 更新表 set 字段 = (select 参考数据 from 参考表 where 参考表.id = 更新表.id); update table_2 m se…

    Java 2023年6月5日
    066
  • 如何优雅的定义统一响应对象

    Hope is being able to see there is light despite all of the darkness 目前主流开发方式都是前后端分离的,定义一种…

    Java 2023年6月13日
    063
  • mysql-常用命令

    C1 Mysql常用命令合集 P1.设置方面命令 连接 mysql -u root -p 授权指定ip访问 GRANT ALL PRIVILEGES ON *.* to ‘root…

    Java 2023年6月16日
    059
  • MongoDB实现数组中重复数据删除

    这个功能真的是写死我了,对于MongoDB一点都不熟悉,本来想使用spring与MongoDB的融合mongoDBTemplate,发现压根不是web项目,懒得配置那些配置文件,就…

    Java 2023年6月8日
    075
  • 学习完nio的一个小笔记吧

    这是一个nio网络通信服务端的demo,主要就学习了selector的一些用法,以及它里面的事件类型 selector是对nio的一个优化,它能保证既能高效处理线程中的事件,又能保…

    Java 2023年6月15日
    074
  • Java 判断URL是否有效

    需要针对一些URL地址进行检测是否可用,使用java.net 下的类来实现,主要用到了 URL和HttpURLConnection 二个类 ,URL 是统一资源标识符的引用,一个U…

    Java 2023年5月29日
    065
  • ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE) .append(“Id”,getId())防止内存泄漏

    public String toString() { return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)…

    Java 2023年6月5日
    071
  • 批量转换文件字符集

    操作步骤 先设置输入路径与输出路径 输入路径:需要被转换的文件路径 输出路径:转换后的文件储存路径 我没有写这个属性的交互操作,只是在第一行用字面量进行设置 如果输出路径的目录不存…

    Java 2023年6月15日
    069
  • 【上云】网站备案

    此前因为gitee图床挂了换了github,然后网速一般打算搞七牛云,然而七牛云需要备案域名(不然临时外链只能维持30days) 2022-5-19腾讯云服务器+阿里云域名在腾讯云…

    Java 2023年6月5日
    059
  • 01-RocketMQ介绍

    一、MQ介绍 1、什么是MQ?为什么要用MQ? MQ:MessageQueue,消息队列。 队列,是一种FIFO 先进先出的数据结构。消息由生产者发送到MQ进行排队,然后按原来的顺…

    Java 2023年6月7日
    0126
  • Mybatis多数据源(一) 不同的mapper文件对应不同的数据源

    如果一个系统存在多个业务数据库,那么就意味着在该系统中存在多个数据源,此时针对数据库的操作如何让其具体的落地到某个库中呢? 一个解决办法就是mybatis不同的mapper文件对应…

    Java 2023年5月30日
    078
  • Vue3+Vue-cli4项目中使用腾讯滑块验证码

    Vue3+Vue-cli4项目中使用腾讯滑块验证码 简介: 滑块验证码相比于传统的图片验证码具有以下优点: 验证码的具体验证不需要服务端去验证,服务端只需要核验验证结果即可。 验证…

    Java 2023年6月8日
    069
  • MyBatis(一)-入门

    ==>>MyBatis中文网 1、第一个 mybastis程序 1.1 导入jar包 3.4.1 5.1.47 org.mybatis mybatis ${mybati…

    Java 2023年6月15日
    078
  • maven常用命令和maven指令生命周期以及maven概念模型图

    maven常用命令 clean:把我们自己编译好的项目中的信息删除掉,清除本地编译好的信息 mvn compile:是吧src main下的方法进行编译放置在target目录下 m…

    Java 2023年6月6日
    069
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球