docker容器基本原理简介

news2024/11/25 11:59:24

一、docker容器实例运行的在linux上是一个进程

1)、我们通过docker run 通过镜像运行启动的在linux上其实是一个进程,例如我们通过命令运行一个redis:

docker run -d --name myredis redis

在这里插入图片描述

2)、可以看到首先我们本地还没有redis镜像

Unable to find image 'redis:latest' locally

然后其就冲远程仓库拉取最新版本的redis镜像

latest: Pulling from library/redis

3)、然后我们可以看到镜像是一层一层的拉取的(镜像是分层的,一层一层从最基础的镜像往上叠)

c7a4e4382001: Pull complete 
4044b9ba67c9: Pull complete 
c8388a79482f: Pull complete 
413c8bb60be2: Pull complete 
1abfd3011519: Pull complete 

4)、拉取下来后,其就运行产生了一个镜像实例d3775e5e4a1659f2ee592a7e69482983d2aa70d35f814b9e4a64fd121c0f42cf

在这里插入图片描述

5)、可以看到linux宿主机已经有这个进程了

6)、然后我们通过docker exec -it d3775e5e4a1659f2ee592a7e69482983d2aa70d35f814b9e4a64fd121c0f42cf /bin/bash进入这个实例

在这里插入图片描述

可以看到我们进入了这个实例,然后其ps命令也没有,这个应该也是docker轻量化的体现,没必要的就不额外加

7)、我们进入到/usr/local/bin下面,就可以看到我们的redis相关的了。

在这里插入图片描述

8)、然后我们通过redis-cli连接下

在这里插入图片描述

二、Linux 联合文件系统

​ Linux 联合文件系统(Union File System,简称 UnionFS 或 UFS)是一种分层的文件系统,它用于将不同的文件系统的文件、目录集合在一起,形成一个单一的文件系统。直观简单来说,就是将不同文件目录整合到一个work工作目录,然后其使用了写时复制(copy-on-write),也就是当我们要对某个文件进行写操作的时候,将原来的再copy一份,在进行写操作的时候,不影响原来的文件,在这个新文件进行写。下面我们就用一个案例来说明

在这里插入图片描述

​ 我们可以看到,这里创建了4个目录:lowner、upper、merged、work:

​ 1、lowner目录我们是只读的,下面两个目录lowner、lowner2两个其下面创建两个文件。

​ 2、upper目录是可写的,我们在其下面创建了upper.txt文件。

​ 3、merged目录是我们联合合并lowner、upper目录形成的统一视图。有点类似于数据库的视图

​ 4、work目录被用于处理这些目录合并操作中的临时文件和元数据

​ 下面我们就通过具体的命令来将其合并:

mount -t overlay overlay -o lowerdir=./lowner/lowner1:./lowner/lowner2,upperdir=./upper,workdir=./work ./merged

在这里插入图片描述

可以看到我们通过overlay挂载形成联合文件系统后,其将只读的lownerupper目录下面的所有文件都整合到merged目录下面了。

在这里插入图片描述

​ 我们进入到merged目录下面

在这里插入图片描述

​ 我们在merged下面将lower1.txtupper.txt进行修改

在这里插入图片描述

​ 可以看到在upper下面,由于我们修改了lower1.txt文件,写时复制,所以在upper可写目录下面产生了新的文件

在这里插入图片描述

​ 新写的不影响原来lowner只读的文件,而upper是可写的,所以upper.txt直接在原来的上面改的。

​ 我们前面在运行redis容器实例拉取镜像的时候,其是一层一层拉取的,,也就是容器镜像也是这样一层、一层由基础的只读、还有可写的联合起来的,最底层的与linux相关的,则是与linux宿主机使用相同的文件,当容器运行时,它会在一个可写的上层(upper layer)中进行修改,而原始镜像层(lower layers)则保持不变,这也是镜像轻量化的一部分使用体现。

三、Namepsace

​ namespace是Linux提供的一种内核级别环境隔离的方法,主要是为了实现资源隔离。例如我们的不同的容器实例,是相互隔离的,它们都可以有pid为1的进程。还有网络隔离,挂载隔离这些。

1、不同Namespace介绍

1. PID Namespace

​ PID Namespace允许进程拥有其自己的PID空间

2. Mount Namespace

​ Mount Namespace允许进程拥有其自己的文件系统挂载点视图。这允许容器在其自己的文件系统树中挂载和卸载文件系统,而不会影响宿主机。

3. UTS Namespace

​ UTS Namespace允许进程拥有其自己的主机名和域名。

4. Network Namespace

​ Network Namespace允许进程拥有其自己的网络栈。这允许容器拥有其自己的网络接口、路由表、防火墙规则等。

5. IPC Namespace

​ IPC Namespace允许进程拥有其自己的IPC资源,如消息队列、信号量等。这有助于隔离进程间的通信。

6、User Namespace

​ User Namespace 主要是用来隔离用户和用户组的。

2、PID案例

我们的Java程序:

import java.util.Random;

public class TestCPU {

    public static void main(String[] args) {
        System.out.println("start exec ");
        while (true){
            Random random = new Random();
            double c =  random.nextDouble() * random.nextDouble();
        }
    }

}

​ 这个也就是一直循环计算一个数。

在这里插入图片描述

下面我们来看一个基本的PID案例:

root@k8s-master namespace]# echo $$
40682
[root@k8s-master namespace]# 
[root@k8s-master namespace]# ls -l /proc/1/ns/
总用量 0
lrwxrwxrwx 1 root root 0 615 22:41 ipc -> ipc:[4026531839]
lrwxrwxrwx 1 root root 0 615 22:41 mnt -> mnt:[4026531840]
lrwxrwxrwx 1 root root 0 615 22:41 net -> net:[4026531956]
lrwxrwxrwx 1 root root 0 615 22:20 pid -> pid:[4026531836]
lrwxrwxrwx 1 root root 0 615 22:41 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 615 22:41 uts -> uts:[4026531838]
[root@k8s-master namespace]# 
[root@k8s-master namespace]# ls -l /proc/40682/ns/
总用量 0
lrwxrwxrwx 1 root root 0 615 22:41 ipc -> ipc:[4026531839]
lrwxrwxrwx 1 root root 0 615 22:41 mnt -> mnt:[4026531840]
lrwxrwxrwx 1 root root 0 615 22:41 net -> net:[4026531956]
lrwxrwxrwx 1 root root 0 615 22:41 pid -> pid:[4026531836]
lrwxrwxrwx 1 root root 0 615 22:41 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 615 22:41 uts -> uts:[4026531838]
[root@k8s-master namespace]# 

​ 在这个案例中我们可以看到通过echo $$输出当前的shell环境线程号PID为40682,由于其本身是从最顶级的父线程1fork的,可以看到我们ls -l /proc/1/ns/ls -l /proc/40682/ns/两个输出的不同namespace的的编号是相同的,然后其的pid都是4026531836,下面我们通过unshare --pid --fork --mount-proc /bin/bash命令,这个命令就是从读取相处fork一个子线程,然后其的pid不共享,也就是独立。

[root@k8s-master home]# ls -l /proc/1/ns
总用量 0
lrwxrwxrwx 1 root root 0 6月  15 22:41 ipc -> ipc:[4026531839]
lrwxrwxrwx 1 root root 0 6月  15 22:41 mnt -> mnt:[4026531840]
lrwxrwxrwx 1 root root 0 6月  15 22:41 net -> net:[4026531956]
lrwxrwxrwx 1 root root 0 6月  15 22:20 pid -> pid:[4026531836]
lrwxrwxrwx 1 root root 0 6月  15 22:41 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 6月  15 22:41 uts -> uts:[4026531838]
[root@k8s-master home]# ls
common  docker  feverasa  package  test  TestCPU.class  TestCPU.java  testq.sh  usspa
[root@k8s-master home]# nohup java TestCPU &
[1] 23952
nohup: 忽略输入并把输出追加到"nohup.out"
[root@k8s-master home]# ps -ef | grep java
root      23952  14436 99 23:34 pts/0    00:00:18 java TestCPU
root      24088  14436  0 23:34 pts/0    00:00:00 grep --color=auto java
[root@k8s-master home]# ls -l /proc/23952/ns
总用量 0
lrwxrwxrwx 1 root root 0 6月  15 23:34 ipc -> ipc:[4026531839]
lrwxrwxrwx 1 root root 0 6月  15 23:34 mnt -> mnt:[4026531840]
lrwxrwxrwx 1 root root 0 6月  15 23:34 net -> net:[4026531956]
lrwxrwxrwx 1 root root 0 6月  15 23:34 pid -> pid:[4026531836]
lrwxrwxrwx 1 root root 0 6月  15 23:34 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 6月  15 23:34 uts -> uts:[4026531838]
[root@k8s-master home]# unshare --pid --fork --mount-proc /bin/bash
[root@k8s-master home]# nohup java TestCPU &
[1] 39
nohup: 忽略输入并把输出追加到"nohup.out"
[root@k8s-master home]# ls -l /proc/39/ns
总用量 0
lrwxrwxrwx 1 root root 0 6月  15 23:36 ipc -> ipc:[4026531839]
lrwxrwxrwx 1 root root 0 6月  15 23:36 mnt -> mnt:[4026532634]
lrwxrwxrwx 1 root root 0 6月  15 23:36 net -> net:[4026531956]
lrwxrwxrwx 1 root root 0 6月  15 23:36 pid -> pid:[4026532635]
lrwxrwxrwx 1 root root 0 6月  15 23:36 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 6月  15 23:36 uts -> uts:[4026531838]
[root@k8s-master home]# ps -ef | grep java
root         39      1 99 23:35 pts/0    00:09:31 java TestCPU
root         73      1  0 23:44 pts/0    00:00:00 grep --color=auto java
[root@k8s-master home]# 

​ 在上面的案例中,我们首先直接在当前shell进程中启动一个java应用23952,其的PID Namespace为pid:[4026531836],与PID1的Namespace是一样的。然后我们通过unshare --pid --fork --mount-proc /bin/bash fork一个新的,PID Namespace隔离其他,再启动一个引用,然后该应用的的pid为39,然后其的pid为4026532635,并且我们ps -ef | grep java可以看到,其只能看到自己的java应用,看不到其父类的java引用,已经隔离了。

在这里插入图片描述

​ 另一个要说明的是,我们右边的窗口是最外面的父类的shell进程,可以看到其能看到自己的java应用23952,也能看到其子的java应用26527,同时这里也表面,子的隔离的PID39是被映射在父类是26527

[root@k8s-master feverasa]# ps -ef | grep java
root      23952  14436 99 23:34 pts/0    00:01:32 java TestCPU
root      26527  25519 99 23:35 pts/0    00:00:20 java TestCPU
root      26989  12613  0 23:35 pts/1    00:00:00 grep --color=auto java
[root@k8s-master feverasa]# 
[root@k8s-master feverasa]# ls -l /proc/23952/ns
总用量 0
lrwxrwxrwx 1 root root 0 6月  15 23:34 ipc -> ipc:[4026531839]
lrwxrwxrwx 1 root root 0 6月  15 23:34 mnt -> mnt:[4026531840]
lrwxrwxrwx 1 root root 0 6月  15 23:34 net -> net:[4026531956]
lrwxrwxrwx 1 root root 0 6月  15 23:34 pid -> pid:[4026531836]
lrwxrwxrwx 1 root root 0 6月  15 23:34 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 6月  15 23:34 uts -> uts:[4026531838]
[root@k8s-master feverasa]# ls -l /proc/26527/ns
总用量 0
lrwxrwxrwx 1 root root 0 6月  15 23:37 ipc -> ipc:[4026531839]
lrwxrwxrwx 1 root root 0 6月  15 23:37 mnt -> mnt:[4026532634]
lrwxrwxrwx 1 root root 0 6月  15 23:37 net -> net:[4026531956]
lrwxrwxrwx 1 root root 0 6月  15 23:37 pid -> pid:[4026532635]
lrwxrwxrwx 1 root root 0 6月  15 23:37 user -> user:[4026531837]
lrwxrwxrwx 1 root root 0 6月  15 23:37 uts -> uts:[4026531838]
[root@k8s-master feverasa]# 

​ Docker容器就是通过Linux 的Namespace来实现不同容器实例的资源隔离的。

四、cgroups

1、基本介绍

cgroups(control groups),是Linux内核的一个功能,用来限制、控制与分离一个进程组的资源,如CPU、内存、磁盘、输入输出等),在2.6.24版本合并到内核中去的。自那以后,又添加了很多功能。

Cgroups提供了以下功能:

​ 1.限制进程组可以使用的资源数量(Resource limiting )。比如:memory子系统可以为进程组设定一个memory使用上限,一旦进程组使用的内存达到限额再申请内存,就会触发OOM(out of memory)。

​ 2.进程组的优先级控制(Prioritization )。比如:可以使用cpu子系统为某个进程组分配特定cpu share。

​ 3.记录进程组使用的资源数量(Accounting )。比如:可以使用cpuacct子系统记录某个进程组使用的cpu时间

​ 4.进程组隔离(Isolation)。比如:使用ns子系统可以使不同的进程组使用不同的namespace,以达到隔离的目的,不同的进程组有各自的进程、网络、文件系统挂载空间。

​ 5.进程组控制(Control)。比如:使用freezer子系统可以将进程组挂起和恢复。

简单来说,其可以精细的控制一个进程对CPU、内存这些资源的使用,例如我们在运行docker实例的时候,控制控制其使用的内存、cpu这些docker run -itd --name test6 --cpu-quota 50000 centos:7 /bin/bash。下面我们就用一个控制CPU使用的案例来说明这点。

2、使用案例

首先我们创建自己的Cgroups

mkdir /sys/fs/cgroup/cpu/my_cgroups_cpu

在这里插入图片描述

​ 我们可以看到/sys/fs/cgroup这个目录下,,就是各种cgroup控制类型的目录,我们创建了一个cpu控制my_cgroups_cpu,其就有对应的目录,这个目录下面就是各种控制类型。

在这里插入图片描述

cpu.cfs_quota_us:表示一个调度周期内可以使用的CPU时间,单位为微秒。要限制CPU使用率为50%,可以将cpu.cfs_quota_us设置为50000(即50毫秒)。因为cpu.cfs_period_us默认为100000,所以50000/100000 = 0.5,即50%的CPU使用率。

​ 我们当前要控制的是cpu.cfs_quota_us,其作用是限制CPU的使用率,我们当前限制其的使用率为50%。

​ 我们先设置当前my_cgroups_cpucpu.cfs_quota_us50000

cgset -r cpu.cfs_quota_us=50000 my_cgroups_cpu

在这里插入图片描述

​ 首先我们运行一个不控制的应用,可以看到其对CPU100%

在这里插入图片描述

​ 下面我们加上控制来运行,将当前执行的java应用添加到cpu的cgroups控制中

cgexec -g cpu:my_cgroups_cpu java TestCPU

在这里插入图片描述

​ 可以看到我们后面启动的java应用对cpu使用率为50%

​ 我们当前通过上面的这几个基础的案例,说明了linux的联合文件系统、Namespace、Cgroups控制组,docker就是对linux这些功能进行封装,来形成docker镜像、容器实例这些。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1830589.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

WPS如何合并多个word文档到一个文档中

将多个Word文档合并成一个 【插入】---》【附件】----》【文件中的文字】----》选择多个需要合并的word文档,点击确定即可。 用的工具是WPS。

12c rac到单机adg开启同步报错ora-01157 ora-01110 temp文件相关错误

问题 处理方法 alter database recover managed standby database cancel; create temporary tablespace TEMP1 tempfile /u01/app/oracle/oradata/standby/temp_01.dbf size 10240m autoextend on; SQL> alter database recover managed standby database disconnect fr…

蜂鸣器(2):12V有源蜂鸣器

蜂鸣器(2):12V有源蜂鸣器 在本教程中,我们将学习如何对Arduino进行编程,以控制12V有源蜂鸣器以产生响亮的声音。如果您想控制 5V 有源/无源蜂鸣器,请查看此 Arduino 压电蜂鸣器教程 Hardware Required 所…

中华老字号李良济,展现百年匠心之魅力,释放千年中医药文化自信

6月14-16日,“潮品老字号 国货LU锋芒”江苏老字号博览会在南京隆重启幕,中华老字号李良济凭借过硬的品牌实力和优质的口碑再次受邀参加,并在展会上绽放百年匠心魅力,彰显千年中医药文化自信! 百年匠心 以实力铸就荣耀…

Java阻塞队列:PriorityBlockingQueue

Java阻塞队列:PriorityBlockingQueue 在Java的并发编程中,阻塞队列是一种非常重要的数据结构。它不仅能在多线程环境下安全地进行数据交换,还能在需要时自动阻塞或唤醒线程。本文将详细介绍阻塞队列中的一种重要实现——PriorityBlockingQue…

【Java】已解决java.lang.ArrayIndexOutOfBoundsException异常

文章目录 一、问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决java.lang.ArrayIndexOutOfBoundsException异常 一、问题背景 java.lang.ArrayIndexOutOfBoundsException 是 Java 中一个非常常见的运行时异常,它表明程序试图访问数…

Python高级用法:路径与文件操作(os与pathlib)

路径与文件 前言导入包判断路径存在判断路径类型(判断文件还是文件夹)获取父路径写入读出文件获得路径中所有子文件/子文件夹获取文件扩展名获取多个文件扩展名获取路径的组件创建目录删除文件或空目录 前言 在Python中,os模块提供了与操作系…

MinIO安装、与SpringBoot整合、常见方法

系统学习:若依框架(整合了MinIO)介绍 | RuoYi MinIO MinIO是一个高性能的对象存储系统,专为大规模数据存储、管理和访问而设计。以下是关于MinIO的详细解析: 1. 基本概念 定义:MinIO是一个基于Amazon S3…

永久删除的文件如何恢复?记好这4个方法,轻松恢复文件!

“在清理电脑时,我一不小心把一些还需要的文件永久删除了,不知道大家有没有方法可以恢复这些文件呢?” 在数字时代,我们的生活和工作几乎都离不开电脑和各类存储设备。然而,随着数据的不断增长,误删文件、格…

用Python分析《三国演义》中的人物关系网

用Python分析《三国演义》中的人物关系网 三国演义获取文本文本预处理分词与词频统计引入停用词后进行词频统计构建人物关系网完整代码 三国演义 《三国演义》是中国古代四大名著之一,它以东汉末年到晋朝统一之间的历史为背景,讲述了魏、蜀、吴三国之间…

哪个牌子充电宝好用?精选四大热门款充电宝品牌!公认好用

在当今快节奏的生活中,充电宝已经成为了我们日常生活中不可或缺的数码伴侣。无论是旅行、出差还是日常通勤,拥有一款好用的充电宝,能够确保我们的手机、平板等设备随时保持充足电量。然而,市场上充电宝品牌繁多,如何选…

JavaWeb之初识Tomcat

Tomcat 轻量级应用服务器、JSP、Servlet Tomcat目录结构 在IDEA中创建web项目 在这里不使用maven构建项目,这种方式后面会更新 新建一个java项目File -> Project Settings -> Facets -> -> Web -> OK ( 此时src目录下有一个web目录 )Edit ->…

IDEA 设置主题、背景图片、背景颜色

一、设置主题 1、点击菜单 File -> Settings : 点击 Settings 菜单 2、点击 Editor -> Color Scheme -> Scheme, 小哈的 IDEA 版本号为 2022.2.3 , 官方默认提供了 4 种主题: Classic Light (经典白) ;Darcula (暗黑主…

【GD32F303红枫派使用手册】第十七节 USART-中断串口收发实验

17.1 实验内容 通过本实验主要学习以下内容: 使用中断进行串口收发 17.2 实验原理 前面章节中我们已经学习了串口的状态标志位,本实验就是使用TBE中断和RBNE中断来实现中断收发数据,实验原理是RBNE中断用来接受数据,IDLE中断用…

2024 年最新 windows 操作系统部署安装 redis 数据库详细教程(更新中)

Redis 数据库概述 Redis 是一个开源的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中介。Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基…

Vmess协议是什么意思? VLESS与VMess有什么区别?

VMess 是一个基于 TCP 的加密传输协议,所有数据使用 TCP 传输,是由 V2Ray 原创并使用于 V2Ray 的加密传输协议,它分为入站和出站两部分,其作用是帮助客户端跟服务器之间建立通信。在 V2Ray 上客户端与服务器的通信主要是通过 VMes…

vue3中如何使用pinia -- pinia使用教程(一)

vue3中如何使用pinia -- pinia使用教程(一) 安装使用创建 store使用 store访问修改 store 使用组合式 api 创建 store -- setup storepinia 和 hook 的完美结合如何解决上面的问题 使用 hook 管理全局状态和 pinia 有何优缺点?参考小结 pinia…

基于springboot+vue的供应商管理系统

一、系统架构 前端:vue2 | element-ui 后端:springboot | mybatis 环境:jdk1.8 | mysql | maven | node 二、代码及数据库 三、功能介绍 01. 员工注册 02. 登录 03. 管理员-首页 04. 管理员-个人中心-修改密码 05. …

CSP-J/S初赛01 计算机基础知识:计算机概述和计算机硬件系统

第1节 计算机概述 1.1 计算机的发展 代别 年代 逻辑(电子)元件 第一代 1946-1958 真空电子管 第二代 1959-1964 晶体管 第三代 1965-1970 集成电路 第四代 1971-至今 大规模、超大规模集成电…

华为 HarmonyOS 中国市场份额一季度超越苹果 iOS

华为 HarmonyOS 中国市场份额一季度超越苹果 iOS 根据最新发布的数据,研究机构Counterpoint Research指出,在2024年第一季度,华为的操作系统HarmonyOS在中国市场超越了苹果的iOS,成为中国市场上的第二大操作系统。 ![在这里插入…