Docker容器到底是什么?
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容器到底是什么?的更多相关文章
- 浅析Docker容器的应用场景
本文来自网易云社区 作者:娄超 过去几年开源界以openstack为代表的云计算持续火了好久,这两年突然又冒出一个叫Docker的容器技术,其发展之迅猛远超预料.网上介绍Docker容器的文章已经很多 ...
- Prometheus 到底 NB 在哪里?- 每天5分钟玩转 Docker 容器技术(84)
本节讨论 Prometheus 的核心,多维数据模型.我们先来看一个例子. 比如要监控容器 webapp1 的内存使用情况,最传统和典型的方法是定义一个指标 container_memory_usag ...
- Docker容器入门
为什么要看docker 从去年起就或多或少的接受了docker的熏陶,主要还是Infoq在去年有很多关于docker的实践视频讲座,记得有一篇是<Docker在雪球的技术实践>,当时听的也 ...
- 【原创】Docker容器及Spring Boot微服务应用
Docker容器及Spring Boot微服务应用 1 什么是Docker 1.1 Docker的出现 问题一:项目实施环境复杂问题 传统项目实施过程中经常会出现“程序在我这跑得好好的,在你那怎么就不 ...
- 数据管理 - 每天5分钟玩转 Docker 容器技术(147)
本章将讨论 Kubernetes 如何管理存储资源. 首先我们会学习 Volume,以及 Kubernetes 如何通过 Volume 为集群中的容器提供存储:然后我们会实践几种常用的 Volume ...
- Why Helm? - 每天5分钟玩转 Docker 容器技术(160)
本章我们将学习 Helm,Kubernetes 的包管理器. 每个成功的软件平台都有一个优秀的打包系统,比如 Debian.Ubuntu 的 apt,Redhat.Centos 的 yum.而 Hel ...
- 理解 docker 容器中的 uid 和 gid
默认情况下,容器中的进程以 root 用户权限运行,并且这个 root 用户和宿主机中的 root 是同一个用户.听起来是不是很可怕,因为这就意味着一旦容器中的进程有了适当的机会,它就可以控制宿主机上 ...
- Docker 容器技术
前言: 之前感觉Docker是一种小虚拟机,docker和KVM虚拟机之间有什么区别.联系.可以应用在什么样的生产环境? 一.Docker是什么以及和KVM的区别 1.docker概念? Docker ...
- Docker容器镜像瘦身的三个小窍门(转)
[转自:http://dockone.io/article/8174] 在构建Docker容器时,我们应尽可能减小镜像的大小.使用共享层的镜像尺寸越小,其传输和部署速度越快. 不过在每个RUN语句都会 ...
随机推荐
- Spring boot项目搭建及简单实例
Spring boot项目搭建 Spring Boot 概述 Build Anything with Spring Boot:Spring Boot is the starting point for ...
- [小技巧] Windows 命令行显示英文
在 Windows 里 " 运行" 使用 cmd 进行命令行, 如果是Windows 中文版的话,里面的命令输出是中文. 如果要显示英文的话,可以使用如下的命令: chcp 437 ...
- 最强常用开发库总结 - JSON库详解
最强常用开发库总结 - JSON库详解 JSON应用非常广泛,对于Java常用的JSON库要完全掌握.@pdai JSON简介 JSON是什么 JSON 指的是 JavaScript 对象表示法(Ja ...
- .Net Framework为什么需要联网?
.Net Framework在安装时需要从微软官方网站下载语言包,所以需要联网. 如果想要真正离线安装,需要先把所需的语言包下载下来.
- 2018 Multi-University Training Contest 10
Recently, TeaTree acquire new knoledge gcd (Greatest Common Divisor), now she want to test you. As ...
- Heroku学习 - 利用Heroku app实现 OrgA 查询Org B 的数据数据
最近研究了一番如何通过Heroku应用对OrgA开放一个接口,参数传递的是一个SQL,APP的负责将SQL通过callout的形式调用目标OrgB Rest API来获取数据并返回给OrgA.我是用的 ...
- Qt Installer Framework翻译(3-1)
初始化安装 下图说明了安装应用程序的默认工作流程: 本节使用在macOS上运行的Your Application Installer示例来说明默认工作流程.安装程序具有本地化外观,并可感知每个受支持的 ...
- Java入门 - 高级教程 - 09.文档注释
原文地址:http://www.work100.net/training/java-documentation.html 更多教程:光束云 - 免费课程 文档注释 序号 文内章节 视频 1 概述 2 ...
- 18年第一弹射 和网络有关; 艾曲塞嗯诶系列篇 san
62: 管理员想要更新 AR2200路由器的VRP, 正确的方法: 1)管理员把 AR2200 配置为FTP客户端,通过FTP来传输VRP软件 2)管理员把AR2200 配置为FTP服务器,通过FTP ...
- FLASK 三剑客 request jinjia2
Flask Web 框架Django 15 优势 : 组件全 - admin - Model ORM - Forms 教科书式 劣势 : 加载所有组件 - 占用资源较高 重型框架 Flask 3 优势 ...