Linux内核学习轨迹第四部: 命名空间Namespace基础(容器底层)(第八小节)
10. 命名空间Namespace基础容器底层Linux Namespace命名空间是内核提供的资源隔离机制它把系统的全局资源封装到不同的命名空间中每个命名空间内的进程只能看到本命名空间内的资源无法看到其他命名空间的资源实现了进程级别的资源隔离。Namespace是容器技术Docker、Kubernetes的底层核心基石容器本质上就是一组隔离的Namespace每个容器有自己的PID、文件系统、网络、主机名等资源和宿主机以及其他容器完全隔离。本章节完整拆解Linux Namespace的核心设计、每种Namespace的隔离效果、内核实现、相关系统调用以及容器的底层实现原理。10.1 Namespace的核心设计思想传统的Linux系统中所有进程共享系统的全局资源比如PID编号、主机名、用户、网络栈、文件系统挂载点等。而Namespace的核心设计思想是资源的虚拟化隔离给不同的进程组提供独立的全局资源视图每个Namespace内的资源都是独立的和其他Namespace互不干扰。举个最简单的例子宿主机的PID命名空间中进程的PID从1号init进程开始依次递增一个新的PID Namespace中会有自己的1号init进程PID编号从1开始和宿主机的PID完全隔离容器内的进程看不到宿主机的进程宿主机可以看到容器内的进程但PID不同。Namespace的核心特性隔离性每个Namespace内的资源是独立的进程无法访问其他Namespace的资源层级化Namespace是层级化的子Namespace继承父Namespace的部分属性父Namespace可以看到子Namespace内的资源反之不行生命周期Namespace的生命周期由引用计数决定当Namespace内的最后一个进程退出、最后一个打开的文件描述符关闭时Namespace会被内核自动销毁细粒度隔离Linux提供了8种不同类型的Namespace分别隔离不同类型的资源可以按需选择需要隔离的资源类型不需要全部隔离。10.2 Linux支持的8种NamespaceLinux内核目前支持8种不同类型的Namespace分别隔离不同类型的系统资源每种Namespace都有对应的CLONE_NEW*标志在clone()系统调用中使用创建新的Namespace。Namespace类型隔离的资源对应CLONE标志内核版本引入UTS Namespace主机名和域名CLONE_NEWUTS2.6.19IPC NamespaceSystem V IPC和POSIX消息队列CLONE_NEWIPC2.6.19PID Namespace进程ID编号CLONE_NEWPID2.6.24MNT Namespace文件系统挂载点CLONE_NEWNS2.4.19NET Namespace网络栈、网卡、IP、端口、路由表、防火墙规则CLONE_NEWNET2.6.24USER Namespace用户和用户组IDCLONE_NEWUSER3.8CGROUP Namespacecgroup控制组根目录CLONE_NEWCGROUP4.6TIME Namespace系统时钟单调时间CLONE_NEWTIME5.610.2.1 UTS NamespaceUTSUNIX Time-sharing SystemNamespace隔离了系统的主机名和域名每个UTS Namespace内的进程可以独立设置自己的主机名和域名不会影响宿主机和其他Namespace。核心作用容器可以设置自己的主机名通常是容器ID和宿主机区分开这是容器最基础的隔离。内核实现每个UTS Namespace对应一个struct uts_namespace结构体保存了主机名和域名进程的nsproxy结构体中的uts_ns指针指向所属的UTS Namespace。10.2.2 IPC NamespaceIPC Namespace隔离了System V IPC对象信号量、共享内存、消息队列和POSIX消息队列。每个IPC Namespace内的IPC对象只能被本Namespace内的进程访问其他Namespace的进程无法访问。核心作用避免不同容器之间通过IPC对象通信实现IPC资源的隔离防止容器之间的IPC攻击。10.2.3 PID NamespacePID Namespace隔离了进程ID编号每个PID Namespace有自己独立的PID编号空间从1号init进程开始依次递增。不同PID Namespace中的进程PID可以重复互不干扰。核心特性层级化结构PID Namespace是层级化的父Namespace可以看到子Namespace内的所有进程并且可以通过信号控制子Namespace的进程子Namespace看不到父Namespace和其他Namespace的进程1号init进程每个PID Namespace都有自己的1号init进程它是Namespace内的第一个进程负责管理Namespace内的其他进程收养孤儿进程处理信号。如果1号进程退出内核会给Namespace内的所有进程发送SIGKILL信号销毁整个NamespacePID映射每个进程在不同的PID Namespace中有不同的PID比如容器内的1号进程在宿主机的PID Namespace中是一个普通的PID比如12345。核心作用容器内的进程只能看到自己Namespace内的进程看不到宿主机和其他容器的进程实现了进程视图的隔离这是容器最核心的隔离之一。内核实现每个PID Namespace对应一个struct pid_namespace结构体管理该Namespace的PID分配、层级关系、init进程。进程的PID在每个Namespace中都有对应的编号内核用struct pid结构体管理进程在不同Namespace中的PID。10.2.4 MNT NamespaceMNTMountNamespace隔离了文件系统的挂载点每个MNT Namespace内的进程有自己独立的挂载点视图挂载和卸载文件系统只会影响本Namespace内的进程不会影响其他Namespace和宿主机。核心特性挂载隔离在MNT Namespace内挂载的文件系统只有本Namespace内的进程可以看到其他Namespace看不到初始挂载创建新的MNT Namespace时会复制父Namespace的所有挂载点作为子Namespace的初始挂载视图传播类型挂载点的传播类型决定了挂载事件是否会传播到其他Namespace包括私有挂载、共享挂载、从属挂载、不可绑定挂载默认是私有挂载挂载事件不会传播chroot的增强版MNT Namespace比传统的chroot更强大不仅可以改变根目录还可以隔离整个挂载点视图实现更彻底的文件系统隔离。核心作用容器的根文件系统隔离每个容器有自己的根文件系统通过MNT Namespace挂载和宿主机的文件系统完全隔离这是容器文件系统隔离的核心。内核实现每个MNT Namespace对应一个struct mnt_namespace结构体管理该Namespace内的所有挂载点。进程的nsproxy结构体中的mnt_ns指针指向所属的MNT Namespace。10.2.5 NET NamespaceNET Namespace隔离了整个网络栈每个NET Namespace有自己独立的网络网卡设备物理网卡、虚拟网卡veth、loopbackIP地址、路由表、ARP表端口号、防火墙规则iptables/nftables网络连接、socket、网络统计信息核心特性完全网络隔离每个NET Namespace有自己独立的网络栈不同Namespace的网络完全隔离默认无法通信loopback网卡每个NET Namespace有自己独立的lo回环网卡127.0.0.1只能访问本Namespace内的服务虚拟网卡veth pair用于连接不同的NET Namespace实现跨Namespace的网络通信容器的网络通信就是通过veth pair和网桥实现的物理网卡绑定一个物理网卡只能属于一个NET Namespace可以把物理网卡移动到某个NET Namespace中只有该Namespace内的进程可以使用这个网卡。核心作用容器的网络隔离每个容器有自己独立的网络栈、IP地址、端口不会和宿主机以及其他容器冲突实现了容器的网络虚拟化。