Docker:颠覆传统虚拟化的轻量级革命

Docker是一种用于开发、部署和运行应用程序的开放平台。它允许开发者将应用程序及其依赖项打包到一个称为容器的独立实体中。这些容器使用操作系统级虚拟化来隔离进程和资源,确保应用程序可以在任何环境中一致地运行------无论是笔记本电脑、内部数据中心还是云端。

docker

Container 即容器,平时生活中指的是可以装下其它物品的工具,以方便人类归纳放置物品、存储和异地运输,比如人类使用的衣柜、行李箱、背包等可以成为容器,Container 除了容器以外,另一个意思是集装箱,很多码头工人将很多装有不同物品但却整齐划一的箱子装载到停靠在岸边大船,然后方便的运来运去。

早期海运成本远远高于铁路运输的,因为装卸的成本相当高,自从1946年美国人麦克莱恩发明了集装箱,大大降低了成本,仅当于原来的百分五而已,成为当前成本最低的运输方式。

为什么集装箱成本这么低?因为集装箱可以很方便的运来运去,它们大小一致标准化尺寸的箱子,并且可以安全的隔离开,所以当我们使用 Container 来形容容器的时候,就是我们想要让容器达到一个可以打包,符合标准的状态。

但今天我们所说的容器是一种 IT 技术。容器其实是一种沙盒技术。顾名思义,沙盒就是能够像一个集装箱一样,把你的应用装起来。这样,应用与应用之间就有了边界而不会相互干扰;同时装在沙盒里面的应用,也可以很方便的被搬来搬去,这也是 PaaS 想要的最理想的状态(可移植性,标准化,隔离性)。

容器是软件工业上的集装箱的技术,集装箱的标准化,减少了包装成本,大大提高货物运输和装卸效率,是传统运输行业的重大变革。早期的软件项目中软件更新,发布低效,开发测试发布周期很长,很难敏捷。有了容器技术,就可以利用其标准化的特点,大幅提高生产效率。

容器技术是虚拟化、云计算、大数据之后的一门新兴的并且是炙手可热的新技术, 容器技术提高了硬件资源利用率、方便了企业的业务快速横向扩容(可以达到秒级快速容)、实现了业务宕机自愈功能(配合K8S可以实现,但OpenStack无此功能),因此未来数年会是一个容器愈发流行的时代 ,这是 一 个对于 IT 行业来说非常有影响和价值的技术,而对于IT行业的从业者来说,熟练掌握容器技术无疑是一个很有前景的行业工作机会。

Docker 介绍

容器历史

虽然 docker 把容器技术推向了巅峰,但容器技术却不是从 docker 诞生的。实际上,容器技术连新技术都算不上,因为它的诞生和使用确实有些年头了。下面的一串名称可能有的你都没有听说过,但它们的确都是容器技术的应用。

1、Chroot Jail 就是我们常见的 chroot 命令的用法。它在 1979 年的时候就出现了,被认为是最早的容器化技术之一。它可以把一个进程的文件系统隔离起来。

2、The FreeBSD Jail Freebsd Jail (监狱)实现了操作系统级别的虚拟化,它是操作系统级别虚拟化技术的先驱之一。2000年,伴随FreeBSD4.0版的发布。

3、Linux VServer 使用添加到 Linux 内核的系统级别的虚拟化功能实现的专用虚拟服务器。允许创建许多独立的虚拟专用服务器(VPS),这些虚拟专用服务器在单个物理服务器上全速同时运行,从而有效地共享硬件资源。VPS提供与传统Linux服务器几乎相同的操作环境。可以在这样的VPS上启动所有服务(例如ssh,邮件,Web和数据库服务器),而无需(或者在特殊情况下只需进行很少的修改),就像在任何真实服务器上一样。每个VPS都有自己的用户帐户数据库和root密码,并且与其他虚拟服务器隔离,但它们共享相同的硬件资源。

2003年11月1日 VServer 1.0 发布。

官网:http://linux-vserver.org/

4、Solaris Containers 它也是操作系统级别的虚拟化技术,专为 X86 和 SPARC 系统设计。Solaris 容器是系统资源控制和通过 "区域" 提供边界隔离的组合。

5、OpenVZ OpenVZ 是一种 Linux 中操作系统级别的虚拟化技术。它允许创建多个安全隔离的 Linux 容器,即 VPS。

6、Process Containers Process 容器由 Google 的工程师开发,一般被称为 cgroups。

7、LXC LXC为Linux Container的简写。可以提供轻量级的虚拟化,以便隔离进程和资源,而且不需要提供指令解释机制以及全虚拟化的其他复杂性。容器有效地将由单个操作系统管理的资源划分到孤立的组中,以更好地在孤立的组之间平衡有冲突的资源使用需求 Linux Container提供了在单一可控主机节点上支持多个相互隔离的server container同时执行的机制。Linux Container有点像chroot,提供了一个拥有自己进程和网络空间的虚拟环境,但又有别于虚拟机,因为lxc是一种操作系统层次上的资源的虚拟化。

8、Warden 在最初阶段,Warden 使用 LXC 作为容器运行时。如今已被 CloudFoundy 取代。

9、LMCTFY LMCTY 是 Let me contain that for you 的缩写。它是 Google 的容器技术栈的开源版本。Google 的工程师一直在与 docker 的 libertainer 团队合作,并将libertainer 的核心概念进行抽象并移植到此项目中。该项目的进展不明,估计会被libcontainer 取代。

10、Docker Docker 是一个可以将应用程序及其依赖打包到几乎可以在任何服务器上运行的容器的工具。

11、RKT RKT 是 Rocket 的缩写,它是一个专注于安全和开放标准的应用程序容器引擎。

综上所述正如我们所看到的,docker 并不是第一个容器化技术,但它的确是最知名的一个。

Docker 是什么

2010年,Solomon Hykes(Docker CTO)和几个年轻人在美国旧金山成立了一家 PaaS 平台的dotCloud 公司,此公司主要基于PaaS平台为开发者提供技术服务。

Docker(码头工人)是一个开源项目,诞生于 2013 年3月27日,最初是 dotCloud 公司(后由于 Docker 开源后大受欢迎在2013年10月就将公司改名为Docker Inc,总部位于美国加州的旧金山)内部的一个开源的 PAAS 服务 (Platform as a ServiceService )的业余项目。它基于 Google 公司推出的 Go 语言实现。项目后来加入了 Linux 基金会,遵从了 Apache 2.0 协议,项目代码在 GitHub 上进行维护。

Docker 是基于 Linux 内核实现,Docker 最早采用 LXC 技术,LXC 是 Linux 原生支持的容器技术,可以提供轻量级的虚拟化,可以说 docker 就是基于 LXC 发展起来的,提供LXC 的高级封装,标准的配置方法,在LXC的基础之上,docker提供了一系列更强大的功能。而虚拟化技术 KVM(KernelKernel based Virtual Machine Machine)基于模块实现,后来Docker 改为自己研发并开源的 runc 技术运行容器,彻底抛弃了LXC

Docker 相比虚拟机的交付速度更快,资源消耗更低,Docker 采用客户端/服务端架构,使用远程API来管理和创建容器,其可以轻松的创建一个轻量级的、可移植的、自给自足的容器,docker 的三大理念是 build(构建)、ship(运输)、 run(运行),Docker遵从apache 2.0协议,并通过(namespace及cgroup 等)来提供容器的资源隔离与安全保障等,所以Docke容器在运行时不需要类似虚拟机(空运行的虚拟机占用物理机6-8%性能)的额外资源开销,因此可以大幅提高资源利用率,总而言之Docker是一种用了新颖方式实现的轻量级虚拟机。类似于VM但是在原理和应用上和VM的差别还是很大的,并且docker的专业叫法是应用容器(Application Container)。
Docker 主要目标

Build, Ship and Run Any App, Anywhere,即通过对应用组件的封装(Packaging)、分发(Distribution)、部署(Deployment)、运行(Runtime)等生命周期的管理,达到应用组件级别的"一次封装,到处运行"。这里的应用组件,既可以是一个Web应用,也可以是一套数据库服务,甚至是一个操作系统。将应用运行在Docker 容器上,可以实现跨平台,跨服务器,只需一次配置准备好相关的应用环境,即可实现到处运行,保证研发和生产环境的一致性,解决了应用和运行环境的兼容性问题,从而极大提升了部署效率,减少故障的可能性。

使用Docker 容器化封装应用程序的意义

统一基础设施环境-docker环境

  • 硬件的组成配置
  • 操作系统的版本
  • 运行时环境的异构

统一程序打包(装箱)方式-docker镜像

  • java程序
  • python程序
  • nodejs程序

统一程序部署(运行)方式-docker容器

  • java-jar...→ docker run...
  • python manage.py runserver... → docker run...
  • npm run dev ... → docker run...

Docker 和虚拟机,物理主机


容器和虚拟机技术比较

传统虚拟机是虚拟出一个主机硬件,并且运行一个完整的操作系统,然后在这个系统上安装和运行软件。

容器内的应用直接运行在宿主机的内核之上,容器并没有自己的内核,也不需要虚拟硬件,相当轻量化。

每个容器间是互相隔离,每个容器内都有一个属于自己的独立文件系统,独立的进程空间,网络空间,用户空间等,所以在同一个宿主机上的多个容器之间彼此不会相互影响。
容器和虚拟机比较

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

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

根据实验,一个运行着CentOS的KVM虚拟机启动后,在不做优化的情况下,虚拟机自己就需要占用 100~200 MB内存。此外,用户应用运行在虚拟机里面,它对宿主机操作系统的调用就不可避免地要经过虚拟化软件的拦截和处理,这本身又是一层性能损耗,尤其对计算资源、网络和磁盘I/O的损耗非常大。

比如:一台96G内存的物理服务器,为了运行java程序的虚拟机一般需要分配8G内存/4核的资源,只能运行13台左右虚拟机,但是改为在docker容器上运行Java程序,每个容器只需要分配4G内存即可,同样的物理服务器就可以运行25个左右容器,运行数量相当于提高一倍,可以大幅节省IT支出,通常情况下至少可节约一半以上的物理设备。

Docker 的组成

docker 官网:http://www.docker.com

帮助文档链接:https://docs.docker.com/

docker 镜像:https://hub.docker.com/

docker 中文网站:http://www.docker.org.cn/

Docker 主机(Host):一个物理机或虚拟机,用于运行Docker服务进程和容器,也称为宿主机, node节点。

Docker 服务端(Server):Docker守护进程,运行docker容器。

Docker 客户端(Client):客户端使用 docker 命令或其他工具调用docker API。

Docker 镜像(Images):镜像可以理解为创建实例使用的模板,本质上就是一些程序文件的集合。

Docker 仓库(Registry):保存镜像的仓库,官方仓库:https://hub.docker.com/,可以搭建私有仓库 harbor。

Docker 容器(Container):容器是从镜像生成对外提供服务的一个或一组服务,其本质就是将镜像中的程序启动后生成的进程。

Namespace

bash 复制代码
https://man7.org/linux/man-pages/man7/namespaces.7.html
https://en.wikipedia.org/wiki/Linux_namespaces

一个宿主机运行了N个容器,多个容器共用一个 OS,必然带来的以下问题

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

    namespace是Linux系统的底层概念,在LInux内核层实现,即有一些不同类型的命名空间被部署在内核,各个docker容器运行在同一个docker主进程并且共用同一个宿主机系统内核,各docker容器运行在宿主机的用户空间,每个容器都要有类似于虚拟机一样的相互隔离的运行空间,但是容器技术是在一个进程内实现运行指定服务的运行环境,并且还可以保护宿主机内核不受其他进程的干扰和影响,如文件系统空间、网络空间、进程空间等,目前主要通过以下技术实现容器运行空间的相互隔离。
bash 复制代码
隔离类型					功能								系统调用参数		内核版本
MNTNamespace(mount)  	提供磁盘挂载点和文件系统的隔离能力	CLONE_NEWNS	2.4.19
IPC Namespace(Inter- Process Communication)  	提供进程间通信的隔离能力, 包括信号量,消息队列和共享内存	CLONE_NEWIPC	2.6.19
UTS Namespace(UNIX Timesharing System)  	提供内核,主机名和域名隔离能力	CLONE_NEWUTS	2.6.19
PID Namespace(Process Identification)	提供进程隔离能力	CLONE_NEWPID	2.6.24
NetNamespace(network)  	提供网络隔离能力,包括网络设备,网络栈,端口等	CLONE_NEWNET	2.6.29
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, IP addresses, 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 上的用户。
bash 复制代码
[root@ubuntu2404 ~]#lsns --help

Usage:
 lsns [options] [<namespace>]

List system namespaces.

Options:
 -J, --json             使用 JSON 输出格式
 -l, --list             use list format output 使用列表格式的输出
 -n, --noheadings       don't print headings   不打印标题
 -o, --output <list>    define which output columns to use 定义使用哪个输出列
     --output-all       output all columns
 -P, --persistent       namespaces without processes
 -p, --task <pid>       print process namespaces	打印进程名字空间
 -r, --raw              use the raw output format	使用原生格式输出
 -u, --notruncate       don't truncate text in columns 不截断列中的文本
 -W, --nowrap           don't use multi-line representation
 -t, --type <name>      namespace type (mnt, net, ipc, user, pid, uts, cgroup, time)
 -T, --tree <rel>       use tree format (parent, owner, or process)

 -h, --help             display this help
 -V, --version          display version

Available output columns:
          NS  namespace identifier (inode number)名字空间标识符 (inode 号)
        TYPE  kind of namespace 名字空间类型
        PATH  path to the namespace 命令空间路径
      NPROCS  number of processes in the namespace 名字空间中的进程数
         PID  lowest PID in the namespace 名字空间中的最低 PID
        PPID  PPID of the PID      PID 的 PPID
     COMMAND  command line of the  PID PID 的命令行
         UID  UID of the PID       PID的UID
        USER  username of the PID  PID 的用户名
     NETNSID  namespace ID as used by network subsystem
        NSFS  nsfs mountpoint (usually used network subsystem)
         PNS  parent namespace identifier (inode number)
         ONS  owner namespace identifier (inode number)

For more details see lsns(8).

[root@ubuntu2404 ~]#nsenter --help

Usage:
 nsenter [options] [<program> [<argument>...]]

Run a program with namespaces of other processes.

Options:
 -a, --all              enter all namespaces
 -t, --target <pid>     要获取名字空间的目标进程
 -m, --mount[=<file>]   进入mount 名字空间
 -u, --uts[=<file>]     进入UTS 名字空间(主机名等)
 -i, --ipc[=<file>]     进入System V IPC 名字空间
 -n, --net[=<file>]     enter network namespace
 -p, --pid[=<file>]     enter pid namespace
 -C, --cgroup[=<file>]  enter cgroup namespace
 -U, --user[=<file>]    enter user namespace
 -T, --time[=<file>]    enter time namespace
 -S, --setuid[=<uid>]   set uid in entered namespace
 -G, --setgid[=<gid>]   set gid in entered namespace
     --preserve-credentials do not touch uids or gids
 -r, --root[=<dir>]     set the root directory
 -w, --wd[=<dir>]       set the working directory
 -W, --wdns <dir>       set the working directory in namespace
 -e, --env              inherit environment variables from target process
 -F, --no-fork          do not fork before exec'ing <program>
 -Z, --follow-context   set SELinux context according to --target PID

 -h, --help             display this help
 -V, --version          display version
[root@ubuntu2404 ~]#lsns -t net
        NS TYPE NPROCS PID USER    NETNSID NSFS                      COMMAND
4026531840 net     234   1 root unassigned /run/docker/netns/default /sbin/init
[root@ubuntu2404 ~]#ls -l /proc/234/ns
total 0
lrwxrwxrwx 1 root root 0 Apr  3 09:25 cgroup -> 'cgroup:[4026531835]'
lrwxrwxrwx 1 root root 0 Apr  3 09:25 ipc -> 'ipc:[4026531839]'
lrwxrwxrwx 1 root root 0 Apr  3 09:25 mnt -> 'mnt:[4026531841]'
lrwxrwxrwx 1 root root 0 Apr  3 09:25 net -> 'net:[4026531840]'
lrwxrwxrwx 1 root root 0 Apr  3 09:25 pid -> 'pid:[4026531836]'
lrwxrwxrwx 1 root root 0 Apr  3 09:36 pid_for_children -> 'pid:[4026531836]'
lrwxrwxrwx 1 root root 0 Apr  3 09:25 time -> 'time:[4026531834]'
lrwxrwxrwx 1 root root 0 Apr  3 09:36 time_for_children -> 'time:[4026531834]'
lrwxrwxrwx 1 root root 0 Apr  3 09:25 user -> 'user:[4026531837]'
lrwxrwxrwx 1 root root 0 Apr  3 09:25 uts -> 'uts:[4026531838]'

#说明:234为容器在宿主机的Pid,下面表示进入234容器的对应网络名称空间执行命令
[root@ubuntu2404 ~]#nsenter -t 234 -n ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host noprefixroute 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:5c:92:54 brd ff:ff:ff:ff:ff:ff
    altname enp2s1
    altname ens33
    inet 192.168.1.30/24 brd 192.168.1.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe5c:9254/64 scope link 
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 2e:79:73:c9:de:ec brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::2c79:73ff:fec9:deec/64 scope link 
       valid_lft forever preferred_lft forever
272: br-ee1f98fe8eb4: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 4a:5d:83:66:81:7c brd ff:ff:ff:ff:ff:ff
    inet 172.28.0.1/16 brd 172.28.255.255 scope global br-ee1f98fe8eb4
       valid_lft forever preferred_lft forever
    inet6 fe80::485d:83ff:fe66:817c/64 scope link 
       valid_lft forever preferred_lft forever
286: br-24ef6a48134f: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 7a:94:39:3f:8b:a0 brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.1/16 brd 172.18.255.255 scope global br-24ef6a48134f
       valid_lft forever preferred_lft forever
    inet6 fe80::7894:39ff:fe3f:8ba0/64 scope link 
       valid_lft forever preferred_lft forever
298: br-b5f7ce1f2b00: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 42:1b:b1:f8:7e:76 brd ff:ff:ff:ff:ff:ff
    inet 172.19.0.1/16 brd 172.19.255.255 scope global br-b5f7ce1f2b00
       valid_lft forever preferred_lft forever
    inet6 fe80::401b:b1ff:fef8:7e76/64 scope link 
       valid_lft forever preferred_lft forever
301: br-ec7b4a9b9432: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 6a:70:6c:57:4a:54 brd ff:ff:ff:ff:ff:ff
    inet 172.20.0.1/16 brd 172.20.255.255 scope global br-ec7b4a9b9432
       valid_lft forever preferred_lft forever
    inet6 fe80::6870:6cff:fe57:4a54/64 scope link 
       valid_lft forever preferred_lft forever

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 不同版本对比,显然内核较新的支持的功能更多。
centos cgroups

bash 复制代码
[root@rocky9 ~]# grep CGROUP /boot/config-5.14.0-427.13.1.el9_4.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 is not set
# 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
[root@rocky9 ~]# grep MEMCG /boot/config-5.14.0-427.13.1.el9_4.x86_64 
CONFIG_MEMCG=y
CONFIG_MEMCG_KMEM=y

ubuntu cgroups

bash 复制代码
[root@ubuntu2404 ~]#grep CGROUP /boot/config-6.8.0-57-generic 
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_PUNT_BIO=y
# CONFIG_BLK_CGROUP_IOLATENCY is not set
CONFIG_BLK_CGROUP_FC_APPID=y
CONFIG_BLK_CGROUP_IOCOST=y
CONFIG_BLK_CGROUP_IOPRIO=y
# CONFIG_BFQ_CGROUP_DEBUG is not set
CONFIG_NETFILTER_XT_MATCH_CGROUP=m
CONFIG_NET_CLS_CGROUP=m
CONFIG_CGROUP_NET_PRIO=y
CONFIG_CGROUP_NET_CLASSID=y
# CONFIG_DEBUG_CGROUP_REF is not set

cgroups 中内存模块

bash 复制代码
[root@ubuntu2404 ~]#grep MEMCG /boot/config-6.8.0-57-generic 
CONFIG_MEMCG=y
CONFIG_MEMCG_KMEM=y

使用场景

Docker被广泛应用于各种规模的企业中,以加速软件开发周期,简化部署过程,并改善操作效率。典型的应用场景包括但不限于:

  • 微服务架构的支持
  • 持续集成与持续交付(CI/CD)
  • 开发与测试环境的一致性维护

总之,Docker提供了一种强大的工具集,使开发者能够更加快速、可靠地构建、测试和部署应用程序。通过消除"在我机器上可以工作"的问题,Docker促进了团队间的协作,同时提高了应用程序的可移植性和可扩展性。

相关推荐
Dontla6 小时前
Docker多共享网络配置策略(Docker多网络、Docker networks、Docker Compose网络、Docker网络、Docker共享网络)
网络·docker·容器
抓饼先生6 小时前
Linux control group笔记
linux·笔记·bash
挺6的还6 小时前
25.线程概念和控制(二)
linux
wanhengidc6 小时前
云手机运行流畅,秒开不卡顿
运维·网络·科技·游戏·智能手机
Jayin_chan6 小时前
paddlex3.0.1-ocr服务化安装部署(docker)
docker·容器·ocr
您的通讯录好友6 小时前
conda环境导出
linux·windows·conda
ifanatic7 小时前
[每周一更]-(第159期):Go 工程师视角:容器化技术(Docker/Kubernetes)与CI/CD流程的应用场景
docker·golang·kubernetes
笨小孩@GF 知行合一7 小时前
OSPF实验:外部路由引入
运维·网络·hcip·数通·ospf
asdfg12589637 小时前
为什么要在出口路由器router配置NAT与默认路由
运维·网络·计算机网络