Linux 的 namespace

Linux Namespace提供了一种内核级别隔离系统资源的方法,通过将系统的全局资源放在不同的Namespace中,来实现资源隔离的目的。不同Namespace的程序,可以享有一份独立的系统资源。目前Linux中提供了六类系统资源的隔离机制,分别是:

  • Mount: 隔离文件系统挂载点
  • UTS: 隔离主机名和域名信息
  • IPC: 隔离进程间通信
  • PID: 隔离进程的ID
  • Network: 隔离网络资源
  • User: 隔离用户和用户组的ID

namespace API 的使用方法:clone()unshare()setns()系统调用会使用CLONE_NEW*常量来区别六种不同的 namespace 类型。以及还有/proc下的部分文件。

  • CLONE_NEWNS: 用于指定Mount Namespace
  • CLONE_NEWUTS: 用于指定UTS Namespace
  • CLONE_NEWIPC: 用于指定IPC Namespace
  • CLONE_NEWPID: 用于指定PID Namespace
  • CLONE_NEWNET: 用于指定Network Namespace
  • CLONE_NEWUSER: 用于指定User Namespace

注意:可以通过挂载的方式打开文件描述符(只要文件描述符是被打开的,即使当初创建它的进程被销毁,ns会依然存在):

touch ~/mnt
mount --bind /proc/${pid}}/ns/mnt~/mnt

/proc/${pid}/ns

readlink /proc/${pid}/ns/net
该目录下的每个软链接的内容是一串字符,由 namespace 类型和 inode number 组成:

$ ll /proc/${pid}/ns/
cgroup -> cgroup:[4026531835]ipc -> ipc:[4026531839]
mnt -> mnt:[4026531840]
net -> net:[4026534999]
pid -> pid:[4026531836]
pid_for_children -> pid:[4026531836]
user -> user:[4026531837]
uts -> uts:[4026531838]

特点:

  • 若几个进程中对应 namespace 软链接内容一致,则这几个进程同属于同一个 namespace;
  • 即使 namespace 中的进程全部终结了,只要其软链接文件一直处于 open 状态,则 namespace 将一直存在;

network namespace

CLONE_NEWNET指代的是 network namespace

  1. 创建namespace:clone()系统调用
  2. 维持namespace存在:/proc/${pid}/ns
  3. 往namespace里添加进程:setns()系统调用
  4. 帮助进程逃离namespace:unshare()系统调用

docker network

四种模式:docker network ls

  • none 模式(= clone(CLONE_NEWNET) )
  • bridge 桥接模式(= clone(CLONE_NEWNET ) && netlink add)
  • host 模式(=/proc/1/ns/net)
  • container 模式(=/proc/${container_pid}/ns/net)

docker run时使用 –net= 参数指定,默认是 bridge 模式。

  • 父进程通过clone创建子进程时,使用namespace技术,实现子进程与其他进程(包含父进程)的命名空间隔离;
  • 子进程创建完毕之后,使用cgroup技术来处理子进程,实现进程的资源使用限制;
  • 系统在子进程所处namespace内部,创建需要的隔离环境,如隔离的网络栈等;
  • namespace和cgroup两种技术都用上之后,进程所处的“隔离”环境才真正建立,这时“容器”才真正诞生!

Kubernetes 的 Pod 网络

Kubernetes的Pod网络采用的是Docker的container模式网络(pause container --net=none)。两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信。

kubernetes中的pause容器主要为每个业务容器提供以下功能(pause clone flags=CLONE_NEW*|):

  • PID命名空间:Pod中的不同应用程序可以看到其他应用程序的进程ID。
  • 网络命名空间:Pod中的多个容器能够访问同一个IP和端口范围。
  • IPC命名空间:Pod中的多个容器能够使用SystemV IPC或POSIX消息队列进行通信。
  • UTS命名空间:Pod中的多个容器共享一个主机名;Volumes(共享存储卷):
  • Pod中的各个容器可以访问在Pod级别定义的Volumes。
docker run -d --name pause_test  --net=none -p 8880:80 ${psimg}  // default is --net=bridge
docker inspect pause_testdocker run -d --name nginx_test --net=container:pause_test --ipc=container:pause_test --pid=container:pause_test nginx# k8s 的 Pod 创建方式,以下是 CNI 的操作简要步骤
ip link add dev tt0 type veth peer tt1
ip link set tt0 name eth0 netns net
ip netns exec net ip link set lo up
ip netns exec net ip link set eth0 up
ip netns exec net ip add  add 192.168.0.10/24 dev eth0
ip netns exec net ip route add default via 192.168.0.1

pause 源码
pause 就是占坑用的(pid下使用了隔离的ns)。

syscall

clone fork vfork 区别

  const int clone_flags = (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SYSVSEM| CLONE_SIGHAND | CLONE_THREAD| CLONE_SETTLS | CLONE_PARENT_SETTID| CLONE_CHILD_CLEARTID| 0);

coding

setns(pidns)

docker ps |grep ${pod_name}
docker inspect ${pscid} -f {{.State.Pid}}
ll /proc/{ps_pid}/ns/ // pause 容器和第二个容器共享一个netns,如果是hostnetwork的pod,则跟pid=1共享一个netns

对应的docker 命令

#define _GNU_SOURCE
#include <fcntl.h>
#include <sched.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>#define STACK_SIZE (1024 * 1024)   int idle(void *args)
{printf("I'm child process, and my pid is: %d\n", getpid());for (;;) {sleep(1);}return 0;
}pid_t clone_wrapper(int (*func)(void *), int flag, void *args)
{char *stack, *stack_top;stack = (char *)malloc(STACK_SIZE);if (stack == NULL) {printf("alloc stack for child failed!\n");return -1;}/* 栈空间为什么传尾指针,因为栈是反着的 */stack_top = stack + STACK_SIZE;  /* Assume stack grows downward */return clone(func, stack_top, flag , args);
}char *get_pid_ns(int pid)
{char bytes[32];sprintf(bytes, "/proc/%d/ns/pid", pid);return strdup(bytes);
}int main(void)
{pid_t childs[2];char *ns_file;int fd;printf("I'm parent, and my pid is: %d\n", getpid());childs[0] = clone_wrapper(idle, CLONE_NEWPID, NULL);if (childs[0] == -1) {printf("error: create child thread failed!\n");return ;}printf("first child's pid is: %d\n", childs[0]);ns_file = get_pid_ns(childs[0]);if (!ns_file) {printf("get child pid ns failed!\n");return -1;}fd = open(ns_file, O_RDONLY);if (fd == -1) {printf("open child pid ns failed!\n");return -1;}if (setns(fd, 0) == -1) {printf("set ns failed!\n");return -1;}printf("I'm parent, and my pid is: %d\n", getpid());childs[1] = clone_wrapper(idle, 0, NULL);if (childs[1] == -1) {printf("error: create child thread failed!\n");return -1;}printf("second child's pid is: %d\n", childs[1]);sleep(3);kill(childs[0], SIGTERM);kill(childs[1], SIGTERM);waitpid(childs[0], NULL, 0);waitpid(childs[1], NULL, 0);return 0;
}

其中,父进程在创建第一个子进程时指定了 CLONE_NEWPID,然后父进程调用 setns(), 将父进程的 pid namespace 设置为第一个子进程的 pid namespace,接下来父进程又创建了第二个子进程,则此时,第一个进程和第二个处在同一个 pid namespace 中,在父进程的 pid namespace 中,它们的 PID 分别是:18612、18613,在子进程的 pid namespace 中,它们的 PID 分别是:1、2。

Pause(Infra)容器相关推荐

  1. kubernetes中infra容器的理解

    1. infra容器和用户容器的关系 1.1 pause 是k8s的基础设施的一部分,pod中其他容器通过pause容器跟其他pod进行通信. 1.2 pod中其他容器跟pause容器共享命名空间 1 ...

  2. Kubernetes 上调试 distroless 容器

    作者 | Addo Zhang 来源 | 云原生指北 Distroless 镜像 Distroless 容器,顾名思义使用 Distroless 镜像[1]作为基础镜像运行的容器. "Dis ...

  3. pause容器作用_kubernetes中的Pause容器如何理解?

    前几篇文章都是讲的Kubernetes集群和相关组件的部署,但是部署只是入门的第一步,得理解其中的一些知识才行.今天给大家分享下Kubernets的pause容器的作用. Pause容器 全称infr ...

  4. Kubernetes Pod 网络精髓:pause 容器详解

    福利 文末留言送 5 本由浙大SEL实验室硕士杜军大佬撰写的<Kubernetes 网络权威指南:基础.原理与实践>,希望大家点击文末的留言小程序积极留言,每个人都有机会. 前言 当检查你 ...

  5. kubernetes---Pause容器---Infra

    在Kubernetes中最基础的单元是pod , 每个pod都有一个基础容器,这几容器就是pause容器. Pause容器 全称infrastucture container(又叫infra)基础容器 ...

  6. k8s之pause容器

    Pause容器 全称infrastucture container(又叫infra)基础容器. 我们在kubelet的配置文件中心都指定了如下参数,这是指定拉取的pause镜像地址. more /et ...

  7. 容器编排之战——kubernetes

    目录 一.kubernetes简介 1.基本概念 1.传统的应用部署方式 2.新的应用部署方式(部署容器) 3.容器编排工具中的战斗机--------Kubernetes 2.Kubernetes核心 ...

  8. centos7下安装docker(11容器操作总结)

    这段时间主要是学习了对容器的操作,包括:容器的状态:start,stop,restart,rename,pause,unpause,rm,attach,exec,kill,logs:还学习了对容器的资 ...

  9. 容器技术 - docker

    文章目录 一.Docker简介 1.1 Docker诞生 1.2 Docker相关解释 1.3 Docker与传统虚拟化对比 1.4 Docker的构成 二.Docker安装 2.1 Docker的安 ...

  10. 为什么我们需要Pod?(容器设计模式sidecar)

    Pod,是 Kubernetes 项目中最小的 API 对象 容器的本质是进程,就是未来云计算系统中的进程:容器镜像就是这个系统里的".exe"安装包 Kubernetes 就是操 ...

最新文章

  1. js折线图设置y轴刻度_手绘风格的 JS 图表库:Chart.xkcd
  2. 关于PR转PO的注意事项
  3. 多线程环境下调用 HttpWebRequest 并发连接限制
  4. html和css可以用在ssh里面么,在网站中使用SSH
  5. 智领云荣登“中国大数据企业50强” | 2020大数据产业生态大会盛大召开 智领云斩获多项殊荣
  6. cad画流程图的插件_盘一盘,那些提效/创意的 vscode 插件
  7. 数据安全:通过Oracle的基本函数实现简单加密脱敏函数
  8. 京东CEO徐雷:京东抗疫救灾 从来不惜力不算账
  9. windows 64位PHP5.5配置xhprof
  10. ASCII、Unicode、UTF、base64
  11. 发那科机器人xyz的方向_最全 | 发那科工业机器人示教器详细介绍
  12. 机器学习老中医:利用学习曲线诊断模型的偏差和方差
  13. 生存分析统计方法选择,可以避免的一些坑
  14. Leecode 1658. 将 x 减到 0 的最小操作数 滑动窗口
  15. 拼多多2021笔试真题集 -- 1. 多多的数字组合
  16. C语言编程实现,计算每天进步一点点一年后的效果
  17. android自定义手势,Android编程实现自定义手势的方法详解
  18. radial-gradient
  19. 网易工作经验,这篇博文挺有意思的
  20. python快递费用计算公式_python2.4项目:快递计价程序

热门文章

  1. 深圳市注册新公司的流程
  2. CAN SPLIT功能作用和SPLIT电容作用
  3. c语言输出姓名JACK,C语言讲义——变量的输出
  4. CRM系统是什么?它有什么作用?
  5. 威纶触摸屏与三菱PLC的以太网通讯
  6. Elasticsearch-2.4.3的单节点安装(多种方式图文详解)
  7. pySpark创建DataFrame的方式
  8. Editorial Board 、co-editor、ediitor、editor-in-chief的区别
  9. 2020年柒月份生活随笔
  10. 一个简单的购物商城,记录一下。