容器技术介绍和特性

 

 

 

容器技术和 Docker 介绍

容器和虚拟机,物理主机

image

 

 容器和虚拟机技术比较

image

 

传统虚拟机是虚拟出一个主机硬件,并且运行一个完整的操作系统 ,然后在这个系统上安装和运行软件
容器内的应用直接运行在宿主机的内核之上,容器并没有自己的内核,也不需要虚拟硬件,相当轻量化
每个容器间是互相隔离,每个容器内都有一个属于自己的独立文件系统,独立的进程空间,网络空间,用户空间等,所以在同一个宿主机上的多个容器之间彼此不会相互影响

容器和虚拟机比较

image

 

资源利用率更高: 开销更小,不需要启动单独的虚拟机OS内核占用硬件资源,可以将服务器性能压榨至极致.虚拟机一般会有5-20%的损耗,容器运行基本无损耗,所以生产中一台物理机只能运行数十个
虚拟机,但是一般可以运行数百个容器
启动速度更快: 可以在数秒内完成启动
占用空间更小: 容器一般占用的磁盘空间以MB为单位,而虚拟机以GB
集成性更好: 和 CI/CD(持续集成/持续部署)相关技术结合性更好,实现打包镜像发布测试可以一键运行,做到自动化并快速的部署管理,实现高效的开发生命周期

使用虚拟机是为了更好的实现服务运行环境隔离,每个虚拟机都有独立的内核,虚拟化可以实现不同操
作系统的虚拟机,但是通常一个虚拟机只运行一个服务,很明显资源利用率比较低且造成不必要的性能
损耗,我们创建虚拟机的目的是为了运行应用程序,比如Nginx、PHP、Tomcat等web程序,使用虚拟
机无疑带来了一些不必要的资源开销,而容器技术则基于减少中间运行环节带来较大的性能提升。

 

容器的核心技术

Namespace

https://man7.org/linux/man-pages/man7/namespaces.7.html
https://en.wikipedia.org/wiki/Linux_namespaces

 

一个宿主机运行了N个容器,多个容器共用一个 OS,必然带来的以下问题:
怎么样保证每个容器都有不同的文件系统并且能互不影响?
一个docker主进程内的各个容器都是其子进程,那么如果实现同一个主进程下不同类型的子进程?
各个容器子进程间能相互通信(内存数据)吗?
每个容器怎么解决IP及端口分配的问题?
多个容器的主机名能一样吗?
每个容器都要不要有root用户?怎么解决账户重名问题?

 

image

 

 

namespace是Linux系统的底层概念,在LInux内核层实现,即有一些不同类型的命名空间被部署在内
核,各个docker容器运行在同一个docker主进程并且共用同一个宿主机系统内核,各docker容器运行在
宿主机的用户空间,每个容器都要有类似于虚拟机一样的相互隔离的运行空间,但是容器技术是在一个
进程内实现运行指定服务的运行环境,并且还可以保护宿主机内核不受其他进程的干扰和影响,如文件
系统空间、网络空间、进程空间等,目前主要通过以下技术实现容器运行空间的相互隔离:

 

隔离类型 功能 系统调用参数 内核
版本
MNT Namespace(mount)
提供磁盘挂载点和文件系统的
隔离能力 CLONE_NEWNS 2.4.19


PID Namespace(Process
Identification) 提供进程隔离能力 CLONE_NEWPID 2.6.24

 

IPC Namespace(InterProcess Communication)
提供进程间通信的隔离能力,

包括信号量,消息队列和共享
内存

CLONE_NEWIPC 2.6.19


Net Namespace(network) 提供网络隔离能力,包括网络
设备,网络栈,端口等 CLONE_NEWNET 2.6.29


UTS Namespace(UNIX
Timesharing System)
提供内核,主机名和域名隔离
能力 CLONE_NEWUTS 2.6.19


User Namespace(user)
提供用户隔离能力,包括用户
和组 CLONE_NEWUSER 3.8

 

Pid namespace

  • 不同用户的进程就是通过Pid namespace 隔离开的,且不同namespace 中可以有相同Pid。
  • 有了Pid namespace, 每个namespace 中的Pid 能够相互隔离。

net namespace

  • 网络隔离是通过net namespace 实现的, 每个net namespace 有独立的network devices, IPaddresses, IP routing tables, /proc/net 目录。
  • Docker 默认采用veth 的方式将container 中的虚拟网卡同host 上的一个docker bridge: docker0连接在一起。

ipc namespace

  • Container 中进程交互还是采用linux 常见的进程间交互方法(interprocess communication –IPC), 包括常见的信号量、消息队列和共享内存。
  • container 的进程间交互实际上还是host上具有相同Pid namespace 中的进程间交互,因此需要在IPC 资源申请时加入namespace 信息- 每个IPC 资源有一个唯一的32 位ID。

mnt namespace
mnt namespace 允许不同namespace 的进程看到的文件结构不同,这样每个namespace 中的进程所看到的文件目录就被隔离开了

uts namespace
UTS(“UNIX Time-sharing System”) namespace允许每个container 拥有独立的hostname 和domain name, 使其在网络上可以被视作一个独立的节点而非Host 上的一个进程。

user namespace
每个container 可以有不同的user 和group id, 也就是说可以在container 内部用container 内部的用户执行程序而非Host 上的用户。


范例:内核的 namespace

[root@master1 ~]# 
[root@master1 ~]# uname -r
5.14.0-611.5.1.el9_7.x86_64
[root@master1 ~]# grep -A10 CONFIG_NAMESPACES /boot/config-5.14.0-611.5.1.el9_7.x86_64 
CONFIG_NAMESPACES=y
CONFIG_UTS_NS=y
CONFIG_TIME_NS=y
CONFIG_IPC_NS=y
CONFIG_USER_NS=y
CONFIG_PID_NS=y
CONFIG_NET_NS=y
CONFIG_CHECKPOINT_RESTORE=y
CONFIG_SCHED_AUTOGROUP=y
CONFIG_RELAY=y
CONFIG_BLK_DEV_INITRD=y

 

 

Control groups
Linux Cgroups的全称是Linux Control Groups,是Linux内核的一个功能.最早是由Google的工程师(主要是Paul Menage和Rohit Seth)在2006年发起,最早的名称为进程容器(process containers)。

在2007年时,因为在Linux内核中,容器(container)这个名词有许多不同的意义,为避免混乱,被重
命名为cgroup,并且被合并到2.6.24版的内核中去。自那以后,又添加了很多功能。


如果不对一个容器做任何资源限制,则宿主机会允许其占用无限大的内存空间,有时候会因为代码bug
程序会一直申请内存,直到把宿主机内存占完,为了避免此类的问题出现,宿主机有必要对容器进行资
源分配限制,比如CPU、内存等

 

Cgroups 最主要的作用,就是限制一个进程组能够使用的资源上限,包括CPU、内存、磁盘、网络带宽
等等。此外,还能够对进程进行优先级设置,资源的计量以及资源的控制(比如:将进程挂起和恢复等操
作)。
Cgroups在内核层默认已经开启,从CentOS 和 Ubuntu 不同版本对比,显然内核较新的支持的功能更多。

 

范例

[root@master1 ~]# grep CGROUP /boot/config-5.14.0-611.5.1.el9_7.x86_64 
CONFIG_CGROUPS=y
# CONFIG_CGROUP_FAVOR_DYNMODS is not set
CONFIG_BLK_CGROUP=y
CONFIG_CGROUP_WRITEBACK=y
CONFIG_CGROUP_SCHED=y
CONFIG_CGROUP_PIDS=y
CONFIG_CGROUP_RDMA=y
CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_HUGETLB=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_CGROUP_PERF=y
CONFIG_CGROUP_BPF=y
CONFIG_CGROUP_MISC=y
# CONFIG_CGROUP_DEBUG is not set
CONFIG_SOCK_CGROUP_DATA=y
CONFIG_BLK_CGROUP_RWSTAT=y
CONFIG_BLK_CGROUP_IOLATENCY=y
CONFIG_BLK_CGROUP_FC_APPID=y
CONFIG_BLK_CGROUP_IOCOST=y
# CONFIG_BLK_CGROUP_IOPRIO is not set
# CONFIG_BFQ_CGROUP_DEBUG is not set
CONFIG_NETFILTER_XT_MATCH_CGROUP=m
CONFIG_NET_CLS_CGROUP=y
CONFIG_CGROUP_NET_PRIO=y
CONFIG_CGROUP_NET_CLASSID=y
# CONFIG_DEBUG_CGROUP_REF is not set

 

 

 

posted @ 2026-06-30 06:50  minger_lcm  阅读(12)  评论(0)    收藏  举报