分类归档

Docker教程

FWQ
Docker教程
Docker的内核知识之cgroups资源限制
上一篇,我们了解了Docker背后使用的资源隔离技术namespace,通过系统调用构建一个相对隔离的shell环境,也可以称之为一个简单的“容器”。本文我们则要开始讲解另一个强大的内核工具-cgroups。他不仅可以限制被namespace隔离起来的资源,还可以为资源设置权重、计算使用量、操控进程启停等等。在介绍完基本概念后,我们将详细讲解Docker中使用到的cgroups内容。希望通过本文,让读者对Docker有更深入的了解。   一、 cgroups是什么 cgroups(Control Groups)最初叫Process Container,由Google工程师(Paul Menage和Rohit Seth)于2006年提出,后来因为Container有多重含义容易引起误解,就在2007年更名为Control Groups,并被整合进Linux内核。顾名思义就是把进程放到一个组里面统一加以控制。官方的定义如下: cgroups是Linux内核提供的一种机制,这种机制可以根据特定的行为,把一系列系统任务及其子任务整合(或分隔)到按资源划分等级的不同组内,从而为系统资源管理提供一个统一的框架。 通俗的来说,cgroups可以限制、记录、隔离进程组所使用的物理资源(包括:CPU、memory、IO等),为容器实现虚拟化提供了基本保证,是构建Docker等一系列虚拟化管理工具的基石。 对开发者来说,cgroups有如下四个有趣的特点: cgroups的API以一个伪文件系统的方式实现,即用户可以通过文件操作实现cgroups的组织管理。 cgroups的组织管理操作单元可以细粒度到线程级别,用户态代码也可以针对系统分配的资源创建和销毁cgroups,从而实现资源再分配和管理。 所有资源管理的功能都以“subsystem(子系统)”的方式实现,接口统一。 子进程创建之初与其父进程处于同一个cgroups的控制组。 本质上来说,cgroups是内核附加在程序上的一系列钩子(hooks),通过程序运行时对资源的调度触发相应的钩子以达到资源追踪和限制的目的。 二、cgroups的作用 实现cgroups的主要目的是为不同用户层面的资源管理,提供一个统一化的接口。从单个进程的资源控制到操作系统层面的虚拟化。Cgroups提供了以下四大功能 资源限制(Resource Limitation):cgroups可以对进程组使用的资源总额进行限制。如设定应用运行时使用内存的上限,一旦超过这个配额就发出OOM(Out of Memory)。 优先级分配(Prioritization):通过分配的CPU时间片数量及硬盘IO带宽大小,实际上就相当于控制了进程运行的优先级。 资源统计(Accounting): cgroups可以统计系统的资源使用量,如CPU使用时长、内存用量等等,这个功能非常适用于计费。 进程控制(Control):cgroups可以对进程组执行挂起、恢复等操作。…
2024-11-18 阅读全文 →
FWQ
Docker教程
Docker的内核知识之Namespace资源隔离
Docker这么火,喜欢技术的朋友可能也会想,如果要自己实现一个资源隔离的容器,应该从哪些方面下手呢?也许你第一反应可能就是chroot命令,这条命令给用户最直观的感觉就是使用后根目录/的挂载点切换了,即文件系统被隔离了。然后,为了在分布式的环境下进行通信和定位,容器必然需要一个独立的IP、端口、路由等等,自然就想到了网络的隔离。同时,你的容器还需要一个独立的主机名以便在网络中标识自己。想到网络,顺其自然就想到通信,也就想到了进程间通信的隔离。可能你也想到了权限的问题,对用户和用户组的隔离就实现了用户权限的隔离。最后,运行在容器中的应用需要有自己的PID,自然也需要与宿主机中的PID进行隔离。   由此,我们基本上完成了一个容器所需要做的六项隔离,Linux内核中就提供了这六种namespace隔离的系统调用,如下表所示。 Namespace 系统调用参数 隔离内容 UTS CLONE_NEWUTS 主机名与域名 IPC CLONE_NEWIPC 信号量、消息队列和共享内存 PID CLONE_NEWPID 进程编号 Network CLONE_NEWNET 网络设备、网络栈、端口等等 Mount CLONE_NEWNS 挂载点(文件系统) User CLONE_NEWUSER 用户和用户组 表 namespace六项隔离 实际上,Linux内核实现namespace的主要目的就是为了实现轻量级虚拟化(容器)服务。在同一个namespace下的进程可以感知彼此的变化,而对外界的进程一无所知。这样就可以让容器中的进程产生错觉,仿佛自己置身于一个独立的系统环境中,以此达到独立和隔离的目的。 需要说明的是,本文所讨论的namespace实现针对的均是Linux内核3.8及其以后的版本。接下来,我们将首先介绍使用namespace的API,然后针对这六种namespace进行逐一讲解,并通过程序让你亲身感受一下这些隔离效果(参考自http://lwn.net/Articles/531114/)。…
2024-11-18 阅读全文 →
FWQ
Docker教程
Docker资源管理探秘-Cgroups机制
随着Docker技术被越来越多的个人、企业所接受,其用途也越来越广泛。Docker资源管理包含对CPU、内存、IO等资源的限制,但大部分Docker使用者在使用资源管理接口时往往只知其然而不知其所以然。 本文将介绍Docker资源管理背后的Cgroups机制,并且列举每一个资源管理接口对应的Cgroups接口,让Docker使用者对资源管理知其然并且知其所以然。   一、Docker资源管理接口概览 格式 描述 -m, –memory bytes 内存使用限制。 数字需要使用整数,对应的单位是b, k, m, g中的一个。最小取值是4M。 -m, –memory=” <数字>[<单位>]” –memory-swap bytes 总内存使用限制 (物理内存 + 交换分区,数字需要使用整数,对应的单位是b, k, m, g中的一个。 –memory-swap=”<数字>[<单位>]” –memory-reservation…
2024-11-18 阅读全文 →
FWQ
Docker教程
GO中new 和 make的区别
一、make make 只能为 slice、map或 channel 类型分配内存并初始化,同时返回一个有初始值的 slice、map 或 channel 类型引用,不是指针。   通过下表再来看 make 的具体应用: Call Type T Result make(T, n) slice slice of type T with length n…
2024-11-18 阅读全文 →
FWQ
Docker教程
Go中的os包之目录和文件(file)的操作
go中对文件和目录的操作主要集中在os包中,下面对go中用到的对文件和目录的操作,做一个总结笔记。在go中的文件和目录涉及到两种类型,一个是 type File struct,另一个是type Fileinfo interface,来看下这两种类型的定义:   一、 type File struct 的定义 type File struct { *file // os specific } type file struct { fd int name…
2024-11-18 阅读全文 →
FWQ
Docker教程
Go新建文件权限与设置不符
问题: fileName := "/Users/my/tests/perm_file" f, _ := os.OpenFile(fileName, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666) f.Close() 上述代码是打开一个文件,如果文件不存在则创建一个新文件,同时权限设置为0666(-rw-rw-rw-),但实际生成的文件权限可能与你认为的不一致:   # ll perm_file -rw-r--r--  1 my  staff  0  1 12 16:06 perm_file 这个跟umask值相关,下面说明下umask 功能说明:指定在建立文件时预设的权限掩码。 语  法:umask…
2024-11-18 阅读全文 →
FWQ
Docker教程
Goroutine和channel的详细理解(一)
如果不是我对真正并行的线程的追求,就不会认识到Go有多么的迷人。 Go语言从语言层面上就支持了并发,这与其他语言大不一样,不像以前我们要用Thread库 来新建线程,还要用线程安全的队列库来共享数据。 以下是我入门的学习笔记。   一、Go语言的goroutines、信道和死锁 1. goroutine Go语言中有个概念叫做goroutine, 这类似我们熟知的线程,但是更轻。 以下的程序,我们串行地去执行两次loop函数: func loop() {     for i := 0; i < 10; i++ {         fmt.Printf("%d ", i)…
2024-11-18 阅读全文 →
FWQ
Docker教程
Goroutine和channel的详细理解(三)
Go语言并发的设计模式和应用场景 以下设计模式和应用场景来自Google IO上的关于Goroutine的PPT:https://talks.golang.org/2012/concurrency.slide 本文的示例代码在: https://github.com/hit9/Go-patterns-with-channel 生成器 在Python中我们可以使用yield关键字来让一个函数成为生成器,在Go中我们可以使用信道来制造生成器(一种lazy load类似的东西)。当然我们的信道并不是简单的做阻塞主线的功能来使用的哦。 下面是一个制作自增整数生成器的例子,直到主线向信道索要数据,我们才添加数据到信道 func xrange() chan int{ // xrange用来生成自增的整数     var ch chan int = make(chan int)     go func() { // 开出一个goroutine…
2024-11-18 阅读全文 →