Linux容器LXC学习之Namespace
2016-04-22 22:18
573 查看
Linux Containers即就是Linux容器,是一个加强版的Chroot。容器可以提供轻量级的虚拟化,一遍隔离进程和资源,而且不需要提供指令解释机制以及全虚拟化的其他复杂性。;
LXC主要依赖Linux内核的3种隔离机制(isolation infrastructure):
Chroot 将应用隔离岛一个虚拟的私有root下
Cgroups 实现资源控制,给每个用户实例可以按需提供其计算资源
Namespaces 提供了隔离性,每个用户实例之间相互隔离,互不影响
Linux的3.12内核支持6 种Namespace:
UTS:隔离进程的hostname
IPC:进程间通信
PID:隔离进程间的PID namespace,clone新建的进程PID namespace中PID从 1 开始
NS:mount挂载点
NET:网络访问,包括接口
USER:将本地的虚拟user-id映射到真实的user-id
想要测试LXC的namespace隔离功能,可以使用clone函数,该函数的flag指定了要隔离的类型:
namespace中对应前五种可以使用clone函数的flag激活,如下:
下边对每一种namespace进行实例验证。
ipc namespace测试和上一个程序基本一致,只需要在clone函数中开启CLONE_NEWIPC标志即可,在子进程中创建消息队列,其他进程中看不见,反之亦然。
测试如下所示:
inside
IPC namespace :
outside
IPC namespace:
在clone函数中添加CLONE_NEWPID标志,即就是开启了PID namespace;
在子进程执行的程序中,添加
会输出子进程PID为1,就是因为隔离了父子进程的PID namespace,在父进程时可以使用top 或 “ps exf”命令显示自己和子进程(未映射的)的PID,会发现在子进程时使用ps命令和父进程时的内容一模一样,是因为这些工具否是从真实的”/proc”文件系统中获取信息,而/proc是尚未隔离的。
NS namespace和NET namespace的测试代码地址:
https://github.com/ty92/Linux-LXC
LXC主要依赖Linux内核的3种隔离机制(isolation infrastructure):
Chroot 将应用隔离岛一个虚拟的私有root下
Cgroups 实现资源控制,给每个用户实例可以按需提供其计算资源
Namespaces 提供了隔离性,每个用户实例之间相互隔离,互不影响
Linux的3.12内核支持6 种Namespace:
UTS:隔离进程的hostname
IPC:进程间通信
PID:隔离进程间的PID namespace,clone新建的进程PID namespace中PID从 1 开始
NS:mount挂载点
NET:网络访问,包括接口
USER:将本地的虚拟user-id映射到真实的user-id
想要测试LXC的namespace隔离功能,可以使用clone函数,该函数的flag指定了要隔离的类型:
#include <sched.h>
int clone(int (*fn)(void *), void *child_stack, int flags, void *arg, ... );
fn:子进程要执行的函数
child_stack:子进程的栈空间
flag:创建子进程的标志
arg:传给子进程的参数
namespace中对应前五种可以使用clone函数的flag激活,如下:
下边对每一种namespace进行实例验证。
UTS namespace
#define _GNU_SOURCE //功能测试宏,可以在程序中定义(必须程序开头),也可以在编译时指定 gcc -D_GNU_SOURCE 程序名
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <sched.h>
#include <signal.h>
#include <unistd.h>
#define STACK_SIZE (1024 * 1024)
static char child_stack[STACK_SIZE]; //定义成void *child_stack时,子进程不执行
char * const child_args[] = {
"/bin/bash",
NULL
};
int child_main(void* arg) {
printf("Child inside Namespace\n");
sethostname("In Namespace",12); //子进程中设置hostname,区分父子进程UTS命令空间
execv(child_args[0], child_args);
printf("execv error\n");
return -1;
}
int main()
{
printf("Parent outside Namespace\n");
int child_pid = clone(child_main, child_stack + STACK_SIZE, CLONE_NEWUTS | SIGCHLD, NULL); //函数名代表函数的首地址,此处也可以写成&child_main
//子进程栈空间,不加STACK_SIZE时,无法执行子进程的/bin/bash
if(child_pid == -1)
perror("clone");
waitpid(child_pid, NULL, 0);
printf("child exit...\n");
exit(EXIT_SUCCESS);
}
[ty@tiany docker]$sudo ./a.out
Parent outside Namespace
Child inside Namespace
[root@In Namespace docker]#hostname
In Namespace
[root@In Namespace docker]#exit
exit
child exit...
[ty@tiany docker]$hostname
tiany.com
[ty@tiany docker]$
IPC
ipc namespace测试和上一个程序基本一致,只需要在clone函数中开启CLONE_NEWIPC标志即可,在子进程中创建消息队列,其他进程中看不见,反之亦然。测试如下所示:
inside
IPC namespace :
outside
IPC namespace:
PID Namspace
在clone函数中添加CLONE_NEWPID标志,即就是开启了PID namespace; 在子进程执行的程序中,添加
printf("I am [%5d] child \n",getpid());打印子进程PID,测试如下:
[ty@tiany docker]$sudo ./a.out
I am [13021] parent ?
I am [ 1] child
[root@In Namespace docker]#
会输出子进程PID为1,就是因为隔离了父子进程的PID namespace,在父进程时可以使用top 或 “ps exf”命令显示自己和子进程(未映射的)的PID,会发现在子进程时使用ps命令和父进程时的内容一模一样,是因为这些工具否是从真实的”/proc”文件系统中获取信息,而/proc是尚未隔离的。
NS namespace和NET namespace的测试代码地址:
https://github.com/ty92/Linux-LXC
相关文章推荐
- centos6.5上安装docker
- docker容器的网络信息查看
- DNS完全解惑问答
- 全球路由DNS服务器
- 在windows下的安装Docker的教程
- 8个你可能不知道的Docker知识
- 在Docker中自动化部署Ruby on Rails的教程
- 搭建基于Docker的PHP开发环境的详细教程
- 利用OpenVSwitch在多台主机上部署Docker的教程
- ubuntu14.04+docker的安装及使用
- Docker 清理命令集锦
- 再Docker中架设完整的WordPress站点全攻略
- 基于 Docker 开发 NodeJS 应用
- 使用Docker来加速构建Android应用的基本部署思路解析
- 在Docker上部署Python的Flask框架的教程
- 在Docker上开始部署Python应用的教程
- 详解在Python和IPython中使用Docker
- 使用IPython来操作Docker容器的入门指引
- OSX下brew安装docker(boot2docker)
- docker 设置TLS远程访问