Linux 容器的基本概念
最怕你一生碌碌无为,还安慰自己说平凡可贵。
概念
容器是一种虚拟化技术,它将应用程序及其依赖项打包在一起,并提供了一种独立于底层操作系统的运行环境。容器通过与主机操作系统共享内核资源,实现了轻量级的隔离和沙箱化。
Linux 有两个重要的内核功能,分别是命名空间(namespaces)和控制组(control groups)(在主机中,容器与容器之间的隔离正是由这两个内核功能实现的)
为了更好的理解 Linux 容器的基本概念,我们可以想象现实生活中的公寓大楼。虽然公寓楼是一个大的整体,但是在大楼内部,房间与房间之间是相互隔离的,每个房间都有自己的水、电、气。我们用钢筋、水泥这些建筑材料来实现这种隔离。除非被邀请进入他人的房间,我们是不能非法闯入他人的房屋的。
而一个主机就好比这样的公寓大楼,容器就是楼中的一个个房间。每个容器有自己的CPU、内存、IP 地址、挂载点、进程,这就好比每个房间自己的水电气。而实现容器与容器间隔离的“钢筋水泥”正是命名空间和控制组。
Linux命名空间
创建容器就是创建一个隔离良好的环境来运行服务(进程)。为了达到这种级别的隔离,容器应该要有自己的文件系统、IP 地址、挂载点、进程 ID 等,这就需要使用 Linux 命名空间来实现这一点。
命名空间为容器设置了边界,让容器拥有了自己的挂载点、用户、IP 地址、以及进程管理等。
重要的命名空间
- pid 命名空间:负责隔离进程(PID:Process ID)。
- net 命名空间:负责管理网络接口(NET:网络)。
- ipc 命名空间:负责管理对 IPC 资源的访问(IPC:进程间通信)。
- mnt 命名空间:负责管理文件系统挂载点(MNT:Mount)。
- uts 命名空间:隔离内核和版本标识符。(UTS:Unix 分时系统)。
- usr 命名空间:隔离用户 ID。简单来说,它隔离了主机和容器之间的用户 ID。
- Cgroup 命名空间:将控制组信息与容器进程隔离。
使用这些命名空间,容器可以拥有自己的网络接口、IP 地址等。每个容器都拥有自己的命名空间,并且在该命名空间内运行的进程在其他命名空间中没有任何权限。
Linux控制组
当我们启动服务时,我们不会自己指定划分任何内存或者 CPU 限制,而是让内核来为服务划分优先级和分配资源。
但是,我们可以使用 Linux 的内核功能控制组 CGroups,为我们自己的服务设置明确的 CPU 和内存限制。但它不是一种很直接的方法,我们还需要进行一些额外的配置和调整。
由于我们可以在主机内运行多个容器,因此应该有一种机制来限制资源的使用、设备的访问等。而这里正是控制组的用武之地。
Linux 控制组管理着容器使用的资源,我们可以限制容器的 CPU、内存、网络和 IO 资源。
那么如果我们不限制容器的 CPU 和内存资源又会怎样呢?
如果不限制,单个容器可能最终会占用所有的主机资源,无资源可用就会导致其他容器的崩溃。