#云原生征文#Docker使用Linux内核的技术分析 原创 精华
目录
一、Docker简介
Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。
Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。
Docker 包括三个基本概念:
镜像(Image):Docker 镜像(Image),就相当于是一个 root 文件系统。
容器(Container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
仓库(Repository):仓库可看成一个代码控制中心,用来保存镜像。
Docker 使用客户端-服务器 (C/S) 架构模式,使用远程API来管理和创建Docker容器。
二、什么是容器
在Linux中,容器技术是一种进程隔离的技术,应用可以运行在一个个相互隔离的容器中,与虚拟机相同的是,可以为这些容器设置计算资源限制,挂载存储,连接网络,而与虚拟机不同的是,这些应用运行时共用着一个Kernel。使用了Linux kernel的Namespaces、Cgroups、Selinux等技术实现。
三、什么是Docker
Docker实际上是一家公司,Docker是公司的一个容器管理产品。
Docker的使用是安装一个Docker引擎,安装完Docker引擎之后,就可以在容器中配置应用运行所需的依赖环境,接着安装App就可以运行起来了运行起来了。
四、Docker的基本原理
Docker是一个开源的软件项目,让用户程序部署在一个相对隔离的环境运行,借此在Linux操作系统上提供一层额外的抽象,以及操作系统层虚拟化的自动管理机制。需要额外指出的是,Docker并不等于容器(containers),Docker只是容器的一种,其他的种类的容器还有Kata container,Rocket container等等
Docker利用Linux中的核心分离机制,例如Cgroups,以及Linux的核心Namespace(名字空间)来创建独立的容器。一句话概括起来Docker就是利用Namespace做资源隔离,用Cgroup做资源限制,利用Union FS做容器文件系统的轻量级虚拟化技术。Docker容器的本质还是一个直接运行在宿主机上面的特殊进程,看到的文件系统是隔离后的,但是操作系统内核是共享宿主机OS,所以说Docker是轻量级的虚拟化技术。
五、Linux Namespaces
Linux Namespace 是Linux 提供的一种内核级别环境隔离的方法,使其中的进程好像拥有独立的操作系统环境。Linux Namespace 有 Mount Namespace,UTS Namespace, IPC Namespace, PID Namespace, Network Namespace, User Namespace, Cgroup Namespace。
分类 | 系统调用参数 | 隔离内容 |
---|---|---|
Mount Namespace | CLONE_NEWNS | 文件系统挂载点 |
UTS Namespace | CLONE_NEWUTS | Hostname和domain name |
IPC Namespace | CLONE_NEWIPC | 进程间通信方式,例如消息队列 |
PID Namespace | CLONE_NEWPID | 进程ID编号 |
Network Namespace | CLONE_NEWNET | 网络设备,协议栈,路由表,防火墙规则,端口等 |
User Namespace | CLONE_NEWUSER | 用户及组ID |
Cgroup Namespace | CLONE_NEWCGROUP | Cgroup根目录 |
上述系统调用参数CLONE_NEWNS等主要应用于以下三个系统调用: |
1.clone
创建新进程并设置它的Namespace,类似于fork系统调用,可创建新进程并且指定子进程将要执行的函数,通过上述CLONE_NEWNS等参数使某类资源处于隔离状态。
函数声明 :
#include <sched.h>
int clone(int (*fn)(void *), void *child_stack,
int flags, void arg, …
/ pid_t *ptid, struct user_desc *tls, pid_t *ctid */ );
例如:
int pid = clone(call_function, stack_size, CLONE_NEWPID | SIGCHLD, NULL);
会让新创建的该进程执行call_function,例如/bin/bash,且该进程的PID进程编号是隔离状态,也就是新的PID编号,该进程ps将会看到它的PID是1。
如果多次执行上述clone就会创建多个PID Namespace,而每个Namespace里面的应用进程都认为自己是当前容器里的1号进程,它们既看不到宿主机里的真实进程空间,也看不到其他PID Namespace里面的具体情况。
代码编译运行结果:
2.unshare
int unshare(int flags) 使进程脱离某个Namespace,flags参数和clone的用法一致。
3.setns
int setns(int fd, int nstype) 使进程进入某个已经存在的Namespace。经常用于从宿主机进入已经启动的容器Network Namespace,然后设置它的网络。
六、Linux Cgroups
Docker 容器运行起来是一个直接运行在宿主机上面的进程,那么如果限定每个容器最多消耗多少CPU资源呢?如果一个容器疯狂的消耗资源岂不是会影响同一宿主机上面其他的容器?所以Docker就需要一个限制容器能够使用资源上限的机制,那就是Linux Cgroup技术。Linux Cgroup 全称是Linux Control Group。它最主要的作用是限制一个进程组能够使用的资源上限,包括CPU,MEM,DISK,NET等等。
1.编写一个计算密集型的程序:
2.使用cgroups之前
编译运行程序:
top命令查看:
CPU占有率100%
程序运行时间:Program complete time: 3.908352
3.使用cgroup之后
创建后,系统会自动生成一堆文件:
配置cgroup子系统,设置只能使用10%的CPU时间片。
修改cup.cfs_period_us, cpu.cfs_quota_us两个文件。
ubuntu安装Cgroup工具
使用cgroup工具运行程序
top命令查看cpu占有率平均在10%左右:
运行时间:Program complete time: 10.011074 限制CPU占有率之后,程序的运行时间明显增长。
七、Linux Selinux
SELinux(security enhanced linux)安全增强型Linux系统,它是一个linux内核模块,也是Linux的一个安全子系统。
Selinux的主要作用就是最大限度地减小系统中服务进程可访问的资源(最小权限原则)
【本文正在参加云原生有奖征文活动】,活动链接:https://ost.51cto.com/posts/12598
666
厉害了,好像对docker的原理有那么点理解了