Docker是一个开源的应用容器引擎,是近些年最火的技术之一,Docker公司从Docker项目开源之后发家致富把公司商标改为了Docker,收购了fit项目,整合为了docker-compose,前景一片大好,但是据说Docker在社区中话语权过于强硬,得罪了不少公司,google与rethub等牵头发起了kubernetes项目,虽说让Docker在市场上损失很大,但为相信Docker未来前景会很好,k8s虽然强大,但主流也是采用了Docker的容器规范,只会更好。

Docker创建一个容器的方式很简单,使用docker run命令。

docker run -it busybox /bin/sh

-it 参数告诉了Docker项目在启动容器后,需要给我们分配一个文本输入输出环境,也就是TTY,跟容器的标准输入相关联,这样我们就可以和这个Docker容器进行交互了。

/bin/sh 就是我们要在 Docker 容器里运行的程序。

所以,上面这条指令翻译过来就是:请帮我启动一个容器,在容器里执行/bin/sh,并且给我分配一个命令行终端跟这个容器交互。

在这之前,我们先看看宿主机存在的进程。

可以看到当前管理员下sudo的PID为4987,在此基础上我们bash的PID为4988,bash中执行了ps命令,PID与PPID的关系很明显。

此时运行我们的docker容器。

在容器中查看该容器中的进程,出去这个ps,只有一个PID为1的/bin/sh进程。

再来从我们的宿主机查看一下进程信息,排除掉sudo,bash和ps的进程,只有一个sh,可以与容器中的/bin/sh容器作联系,可以看到他的进程PID是7355,父进程是7332。

找到PPID为7332的这个进程,可以知道是一个叫containerd-shim的进程创建了该容器。

先不考虑containerd-shim进程的事,你应该已经注意到容器是什么了,其实就是一个“特殊”的进程。

特殊在何处?

我们宿主机ps查看进程是可以看到容器进程的,而在容器中使用ps命令查看却只能看到容器他本身,一个PID为1的进程,PID为1在Linux有着特殊的意义。

PID为0的进程是idle进程,是由系统自动创建,运行在内核态,创建第一个用户进程,也就是PID为1的init进程,init进程是linux系统中其它所有用户进程的祖先进程,主要作用是处理僵尸进程。

当某个父进程比子进程提前消亡时,父进程会给子进程重新寻找“养父进程”,一般就是init进程,由init进程负责处理该子进程的消亡。

在容器中的进程居然是一个PID为1的进程,他可以管理他所能看到的进程生死,而看不到外面的宿主机进程,一叶障目,不见泰山。

这时候引入一张Docker商标图片最为合适了。

鲸鱼背上的一个个集装箱就是所谓的容器,完全封闭起来,我们可以看到它,在它里面却不知道我们。

这就是Docker的容器封闭技术了。

他的实现其实很简单,Linux的进程创建函数clone,可以接受一个参数CLONE_NEWPID,这样创建的这个进程将会“看到”一个全新的进程空间,在这个进程空间里,它的PID是1。之所以说“看到”,是因为这只是一个“障眼法”,在宿主机真实的进程空间里,这个进程的 PID 还是真实的数值。

int pid = clone(main_function, stack_size, CLONE_NEWPID | SIGCHLD, NULL);

这种技术叫做NameSpace,上面说的是PID NameSpace,当然Linux其他的东西也可以有NameSpace,比如说Mount、UTS、IPC、Network和User。

Mount NameSpace可以让被隔离进程只看到当前Namespace里的挂载点信息,

Network Namespace,用于让被隔离进程看到当前Namespace里的网络设备和配置。

综上,可以发现容器其实就是一个带了NameSpace参数特殊创建的进程。

这暴露出了几个问题,第一是所有容器都是共用了同一个宿主机的操作系统内核,第二是如果我们在低版本的Linux上使用高版本的容器,是会出现问题的,还有第三是这种NameSpace的隔离并不如虚拟化技术隔离的彻底。

Linux中其实有很多资源都是无法做到隔离的,比如说时间,如果你的容器中尝试使用修改时间的系统调用,就会影响到宿主机的时间。

所以说,Docker的容器其实还是有未知的隐患存在。

容器虽然觉得自己是PID为1的init进程,但是对于我们宿主机来说,他是一个正常的进程,和其它进程一样,竞争着系统中的资源。

为此,Linux内核诞生了一个新特性,Linux Cgroups,可以为进程设置资源限制指标。

Linux Control Group,就是限制一个进程组能够使用的资源上限,包括 CPU、内存、磁盘、网络带宽等等。

Cgroups的使用接口是利用文件系统开放的,你可以在这个目录下发现很多以资源命名的文件。

在创建容器的时候你可以指定资源分配的参数,如下。

docker run -it --cpu-period=100000 --cpu-quota=20000 busybox /bin/sh

使用该命令创建运行容器之后,可以看到运行的容器id为f0c0f3e5d0d2。

此时你可以在之前所说的sys/fs/cgroup下找到一个docker目录,其中就有一个f0c0f3e5d0d2开头的目录。

在这个目录中就可以找到容器f0c0f3e5d0d2的资源分配参数,提供给Cgroups,来为Docker容器分配资源。

还有一个重要地方,是关于容器本身的文件系统,当然和PID NameSpace一样,是利用Mount NameSpace实现的,独立出一片独立空间的文件系统。

虽说是这样,但有一点细节需要知道,Mount NameSpace创建一片独立空间时是会继承宿主机本身的已挂载空间的,所以在创建之后需要重新挂载所有节点。

此处细节,可以看左耳朵耗子的这篇博客,非常详细。

https://coolshell.cn/articles/17010.html

Docker容器到底是什么?的更多相关文章

  1. 浅析Docker容器的应用场景

    本文来自网易云社区 作者:娄超 过去几年开源界以openstack为代表的云计算持续火了好久,这两年突然又冒出一个叫Docker的容器技术,其发展之迅猛远超预料.网上介绍Docker容器的文章已经很多 ...

  2. Prometheus 到底 NB 在哪里?- 每天5分钟玩转 Docker 容器技术(84)

    本节讨论 Prometheus 的核心,多维数据模型.我们先来看一个例子. 比如要监控容器 webapp1 的内存使用情况,最传统和典型的方法是定义一个指标 container_memory_usag ...

  3. Docker容器入门

    为什么要看docker 从去年起就或多或少的接受了docker的熏陶,主要还是Infoq在去年有很多关于docker的实践视频讲座,记得有一篇是<Docker在雪球的技术实践>,当时听的也 ...

  4. 【原创】Docker容器及Spring Boot微服务应用

    Docker容器及Spring Boot微服务应用 1 什么是Docker 1.1 Docker的出现 问题一:项目实施环境复杂问题 传统项目实施过程中经常会出现“程序在我这跑得好好的,在你那怎么就不 ...

  5. 数据管理 - 每天5分钟玩转 Docker 容器技术(147)

    本章将讨论 Kubernetes 如何管理存储资源. 首先我们会学习 Volume,以及 Kubernetes 如何通过 Volume 为集群中的容器提供存储:然后我们会实践几种常用的 Volume ...

  6. Why Helm? - 每天5分钟玩转 Docker 容器技术(160)

    本章我们将学习 Helm,Kubernetes 的包管理器. 每个成功的软件平台都有一个优秀的打包系统,比如 Debian.Ubuntu 的 apt,Redhat.Centos 的 yum.而 Hel ...

  7. 理解 docker 容器中的 uid 和 gid

    默认情况下,容器中的进程以 root 用户权限运行,并且这个 root 用户和宿主机中的 root 是同一个用户.听起来是不是很可怕,因为这就意味着一旦容器中的进程有了适当的机会,它就可以控制宿主机上 ...

  8. Docker 容器技术

    前言: 之前感觉Docker是一种小虚拟机,docker和KVM虚拟机之间有什么区别.联系.可以应用在什么样的生产环境? 一.Docker是什么以及和KVM的区别 1.docker概念? Docker ...

  9. Docker容器镜像瘦身的三个小窍门(转)

    [转自:http://dockone.io/article/8174] 在构建Docker容器时,我们应尽可能减小镜像的大小.使用共享层的镜像尺寸越小,其传输和部署速度越快. 不过在每个RUN语句都会 ...

随机推荐

  1. Spring Boot从零入门2_核心模块详述和开发环境搭建

    目录 1 前言 2 名词术语 3 Spring Boot核心模块 3.1 spring-boot(主模块) 3.2 spring-boot-starters(起步依赖) 3.3 spring-boot ...

  2. 用Python爬取了考研吧1000条帖子,原来他们都在讨论这些!

    写在前面 考研在即,想多了解考研er的想法,就是去找学长学姐或者去网上搜索,贴吧就是一个好地方.而借助强大的工具可以快速从网络鱼龙混杂的信息中得到有价值的信息.虽然网上有很多爬取百度贴吧的教程和例子, ...

  3. Linux上的Tomcat地址映射,且404错误解决

    问题:现在想要加一个下载文件功能,但是文件地址不在tomcat的webapps下,需要通过地址映射到tomcat下面再通过链接执行下载文件功能. 解决方法有两种: 方法一: 用方法一的前提是不用启动服 ...

  4. ST表竞赛模板

    void RMQ_init(){//ST表的创建模板 ;i<n;i++) d[i][]=mo[i]; ;(<<j)<=n;j++) ;i+(<<j)-<n;i ...

  5. 简单 hash 入门题目

    题目描述 NOIP 复赛之前,HSD 桑进行了一项研究,发现人某条染色体上的一段 DNA 序列中连续的 kkk 个碱基组成的碱基序列与做题的 AC 率有关!于是他想研究一下这种关系.现在给出一段 DN ...

  6. Redis 分布式锁的正确实现方式( Java 版 )

    前言 分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基于Redis的分布式锁:3. 基于ZooKeeper的分布式锁.本篇博客将介绍第二种方式,基于Redis实现分布式锁.虽然网上已经有各种介 ...

  7. LeetCode10 Hard,带你实现字符串的正则匹配

    本文始发于个人公众号:TechFlow 这是LeetCode的第10题,题目关于字符串的正则匹配,我们先来看题目相关信息: Link Regular Expression Matching Diffi ...

  8. GitHub高级搜索指南

    还在为自学时找不到适合练手的项目而苦恼? 还在好奇别人是如何在GitHub众多项目中找到高质量代码的? 真的是因为他们独具慧眼吗? 不,其实他们只是掌握了正确的搜索方法. 下面介绍几种常用的GitHu ...

  9. Qt Installer Framework翻译(5-1)

    创建离线安装程序 脱机安装程序在安装过程中根本不会尝试连接在线存储库.但是,元数据配置(config.xml)使用户可以在线添加和更新组件. 在公司防火墙不允许用户连接到Web服务器的情况下,脱机安装 ...

  10. 龙芯 3B1500 Fedora28 安装笔记

    版权声明:原创文章,未经博主允许不得转载 龙芯 3A4000 已经发布,十年前的 3B1500 早就落伍了.但我还是打算把它作为寒假刷 ACM 题的主力机 并将此当作年后收到 4000 的预习. 龙芯 ...