当前位置: 首页 > 科技观察

容器的四项基础技术

时间:2023-03-16 15:24:14 科技观察

在这篇文章中,我研究了容器是如何在一些特定的Linux技术之上实现的,包括命名空间和控制组。图1:有助于容器的Linux技术(NivedVelayudhan,CCBY-SA4.0)这些Linux技术构成了在系统上构建和运行容器进程的基础:命名空间控制组(cgroups)SeccompSELinux1。命名空间命名空间命名空间为容器提供了一个隔离层,使它们能够看到看似独占的Linux文件系统。这限制了进程可以访问的内容,从而限制了它可以获得的资源。Docker或Podman等容器技术在创建容器时使用Linux内核中的几个命名空间:[nivedv@homelab~]$dockercontainerrunalpineping8.8.8.8[nivedv@homelab~]$sudolsns-p29413NSTYPENPROCSPIDUSERCOMMAND4026531835cgroup2991root/usr/lib/systemd/systemd--switched...4026531837user2781root/usr/lib/systemd/systemd--switched...4026533105mnt129413rootping8.8.8.84026533106uts129413rootping8.8.8.84026533107ipc129413rootping8.8.8.84026533108pid129413rootping8.8.8.84026533110net129413rootping8.8.8.8用户用户(user)Namespacesisolateusersandgroups在一个容器内。这是通过为容器分配与主机系统不同的UID和GID范围来实现的。用户命名空间使软件能够以根用户身份在容器内运行。如果入侵者攻击容器然后逃到宿主机,他们只能以受限的非root身份运行。挂载mount(mnt)命名空间允许容器拥有自己的文件系统层次结构视图。在Linux系统的/proc//mounts位置可以找到各个容器进程的挂载点。UTSUnix分时系统Unix分时系统(UTS)命名空间允许容器拥有唯一的主机名和域名。运行容器时,即使使用--name标志,也会使用随机ID作为主机名。您可以使用unshare命令查看其工作原理。nivedv@homelab~]$dockercontainerrun-it--namenivedalpinesh/#hostname9c9a5edabdd6/#nivedv@homelab~]$sudounshare-ushsh-5.0#hostnameisolated.hostnamesh-5.0#hostnameisolated.hostnamesh-5.0#sh-5.0#exitexit[nivedv@homelab~]$hostnamehomelab.redhat.comIPC进程间通信进程间通信(IPC)命名空间允许不同的容器进程通过访问共享内存或使用共享消息队列进行通信。[root@demo/]#ipcmk-M10MSharedmemoryid:0[root@demo/]#ipcmk-M20MSharedmemoryid:1[root@demo/]#[root@demo/]#ipcs------MessageQueues--------keymsqidownerpermsused-bytesmessages------SharedMemorySegments--------keyshmidownerpermsbytesnattchstatus0xd1df416a0root6441048576000xbd487a9d1root644209715200------SemaphoreArrays---------keysemidownerpermsnsemsPIDensurerunningprocessIDProcessID(PID)Processesinside容器与外界隔绝。当您在容器内运行ps命令时,由于这种命名空间隔离,您只能看到在容器内运行的进程,而不是在主机上运行的进程。网络(net)命名空间允许容器拥有自己的网络接口、IP地址、路由表、端口号等视图。容器如何与外界通信?您创建的所有容器都连接到一个特殊的虚拟网络接口以进行通信。[nivedv@homelab~]$dockercontainerrun--rm-italpinesh/#ping8.8.8.8PING8.8.8.8(8.8.8.8):56databytes64bytesfrom8.8.8.8:seq=0ttl=119time=21.643ms64bytesfrom8.8.8.8:seq=1ttl=119time=20.940ms^C[root@homelab~]#iplinkshowveth84ea6fcveth84ea6fc@if22:mtu1500qdiscnoqueuemasterdocker0stateUPmodeDEFAULTgroupdefault2。控制组控制组(cgroup)是容器的基本模块。控制组分配和限制容器使用的资源,如CPU、内存、网络I/O等。容器引擎自动创建每种类型的控制组文件系统,并在容器运行时为每个容器设置配额。[root@homelab~]#lscgroup|grepdockercpuset:/dockernet_cls,net_prio:/dockercpu,cpuacct:/dockerhugetlb:/dockerdevices:/dockerfreezer:/dockermemory:/dockerperf_event:/dockerblkio:/dockerpids:/docker容器运行时每个容器都有控制组值设置和所有信息都存储在/sys/fs/cgroup/*/docker。下面的命令会保证容器可以使用50000微秒的CPU时间片,同时设置内存的软硬限制分别为500M和1G。[root@homelab~]#dockercontainerrun-d--nametest-cgroups--cpus0.5--memory1G--memory-reservation500Mhttpd[root@homelab~]#lscgroupcpu,cpuacct:/dockermemory:/dockercpu,cpuacct:/docker/cpu,cpuacct:/docker/c3503ac704dafea3522d3bb82c77faff840018e857a2a7f669065f05c8b2cc84memory:/docker/memory:/docker/c3503ac704dafea3522d3bb82c77faff840018e857a2a7f669065f05c8b2cc84[root@homelabc....c84]#catcpu.cfs_period_us100000[root@homelabc....c84]#catcpu.cfs_quota_us50000[root@homelabc...c84]#catmemory.soft_limit_in_bytes524288000[root@homelabc....c84]#catmemory.limit_in_bytes10737418243。SECCOMPSeccomp的意思是“安全计算”。它是一项Linux功能,用于限制应用程序进行的系统调用集。例如,Docker的默认seccomp配置文件禁用了大约44个系统调用(总共超过300个)。这里的想法是让容器只访问必要的资源。例如,如果您不需要容器更改主机上的时钟时间,您可能不会使用clock_adjtime和clock_settime系统调用,屏蔽它们是合理的。同样,您不希望容器更改内核模块,因此它们不需要使用create_module、delete_module系统调用。4、SELinuxSELinux是“SecurityEnhancedLinux”安全增强型Linux的缩写。如果您在主机上运行RedHat发行版,则默认情况下启用SELinux。SELinux允许您限制应用程序只能访问它自己的文件,并防止任何其他进程访问它们。因此,如果应用程序受到威胁,它将限制应用程序可以影响或控制的文件数量。它通过设置文件和进程的上下文并定义将限制进程可以访问和更改的内容的策略来实现这一点。容器的SELinux策略由container-selinux包定义。默认情况下,容器以container_t标签运行,允许在/usr目录中读取(r)和执行(x),并从/etc目录中读取大部分内容。标签container_var_lib_t是容器相关文件的通用标签。结论容器是当今IT基础架构的重要组成部分,也是一项相当有趣的技术。即使您的工作不直接涉及容器化,了解一些基本的容器概念和方法也会让您了解它们如何帮助您的组织。容器基于开源Linux技术构建,这使它们更加出色。