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. JavaScript | ES6 新增

    Evernote Export body, td { font-family: 微软雅黑; font-size: 10pt; } ES6 重点知识 this关键字以及bind let/const 变量 ...

  2. # "可插拔式"组件设计,领略组件开发的奥秘

    从一个 Confirm 组件开始,一步步写一个可插拔式的组件. 处理一个正常的支付流程(比如支付宝购买基金) 点击购买按钮 如果风险等级不匹配则:弹确认框(Confirm) 用户确认风险后:弹出支付方 ...

  3. 【tf.keras】AdamW: Adam with Weight decay

    论文 Decoupled Weight Decay Regularization 中提到,Adam 在使用时,L2 与 weight decay 并不等价,并提出了 AdamW,在神经网络需要正则项时 ...

  4. 【转】Beyond compare4密钥

    转:https://blog.csdn.net/lemontree1945/article/details/92963423 w4G-in5u3SH75RoB3VZIX8htiZgw4ELilwvPc ...

  5. ConcurrentHashMap源码解析 JDK8

    一.简介 上篇文章详细介绍了HashMap的源码及原理,本文趁热打铁继续分析ConcurrentHashMap的原理. 首先在看本文之前,希望对HashMap有一个详细的了解.不然看直接看Concur ...

  6. 编写SQL查询范围分区类型,MAX分区范围

    需求 对于分区表,对于范围分区类型来说,查询MAX分区及对应的分区范围. ==查询分区表对应的最大分区信息 ==排除了自扩展分区(如果是自扩展分区,但是最大的分区不是自扩展的并未排除在外) ==排除了 ...

  7. Nmap使用教程(一)

    基本扫描技术 扫描单个网络 nmap 192.168.1.1/www.baidu.com 扫描多个网络/目标 nmap 192.168.1.1 192.168.1.2 #将扫描同个网段内不同的ip地址 ...

  8. 5分钟搭建网站实时分析:Grafana+日志服务实战

    原文地址:https://yq.aliyun.com/articles/227006 阿里云日志服务是针对日志类数据一站式服务,用户只需要将精力集中在分析上,过程中数据采集.对接各种存储计算.数据索引 ...

  9. 如梦令编程语言发布 (RML)

    如梦令编程语言是在Rebol语言核心语法的基础上,做了一些自以为是的修改而来.谨以此为Rebol语法的传承,略尽绵薄之力. 基本概念 如梦令语言分属Lisp语系,代码本身是一个层层嵌套的Token列表 ...

  10. MATLAB2017 下载及安装教程

    全文借鉴于软件安装管家 链接: https://pan.baidu.com/s/1-X1Hg35bDG1G1AX4MnHxnA 提取码: ri88 复制这段内容后打开百度网盘手机App,操作更方便哦 ...