回顾
前一节讲了如何保障api服务器的安全。如果攻击者获得了访问api服务器的权限,他们可以通过在容器镜像中打包自己的代码并在pod中运行来做任何的事,这样并不一定能造成危害,因为容器是与同一宿主节点其他容器隔离开的。不一定能访问所在宿主节点的资源。这节将介绍如何允许pod访问所在节点的宿主资源
在pod中使用宿主节点的linux命名空间
pod中的容器通常在分开的linux命名空间中运行。这些命名空间将容器中的进程与其他容器、宿主机默认命名空间中的进程隔离开来。
如:每一个pod有自己的ip和端口空间,这是因为它拥有自己的网络命名空间。类似的;每个pod拥有自己的进程树,因为它有自己的pid命名空间。同样的,pod拥有自己的ipc命名空间,仅允许同一pod内的进程通过进程间通信机制进行交流
1、在pod中使用宿主节点的网络命名空间
部分pod(特别是系统pod)需要在宿主节点的默认命名空间中运行,以运行它们看到和操作节点级别的资源和设备。如果某个pod需要使用宿主节点上的网络适配器,而不是自己的虚拟网络设备,就可以通过将pod spec 中的hostNetwork设置为true实现。这样这个pod可以使用宿主节点的网络接口,而不是拥有自己独立的网络。这意味着这个pod没有自己的ip地址;如果这个pod中的某个进程绑定了某个端口,那么该进程将被绑定到宿主节点的端口上。
2、绑定宿主节点上的端口而不使用宿主节点的网络命名空间
pod拥有自己的命名空间的同时,端口绑定到宿主节点的端口,可以通过配置pod的spec.containers.ports字段中某个容器某一端口的hostport属性来实现。
注:不要混淆使用hostport的pod和通过nodeport服务暴露的pod。
对于一个使用hostport的pod,到达宿主节点的端口的连接会被直接转发到pod的对应端口上;然而在nodeport服务中,到达宿主节点的端口的连接将被转发到随机选取的pod上(这个pod可能在其他节点上)。另一个区别是,对于使用hostport的pod,仅有运行了这类pod的节点会绑定对应的端口;而nodeport类型的服务会在所有的节点上绑定端口,即使这个节点上没有运行对应的pod。
很重要的一点是,如果一个pod绑定了宿主节点上的一个特定端口,每个宿主节点只能调度一个这样的pod实例,因为两个进程不能绑定宿主机上的同一个端口。调度器在调度pod时会考虑这一点,所以不会把两个这样的pod调度到同一个节点上。
3、使用宿主节点的pid与ipc命名空间
pod spec中的hostPID和hostIPC选项与hostNetwork相似,让他们被设置为true时,pod中的容器会使用宿主节点的PID和IPC命名空间,分别运行它们看到宿主机上的全部进程,或通过IPC机制与他们通信。
将hostIPC设置为true,pod中的进程就可以通过进程间通信机制与宿主机上的其他所有进程进行通信。