docker容器基本原理简介

一、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镜像、容器实例这些。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Aigtek功率放大器参数怎么选型的

功率放大器是电子系统中重要的组成部分,选型合适的功率放大器对系统的性能和可靠性至关重要。本文下面安泰电子将介绍如何选型功率放大器的关键步骤和考虑因素。 首先,确定应用需求。在选型功率放大器之前,确定应用需求是至关重要的第一步。了…

高中数学:数列-等比数列

一、概念 二、通项公式 1、与函数的关系 类似一个指数函数 2、重要性质 三、求和公式 错位相减法 四、练习 例题1 例题2

基于GTX的64B66B编码IP生成(高速收发器二十)

点击进入高速收发器系列文章导航界面 1、配置GTX IP 相关参数 前文讲解了64B66B编码解码原理,以及GTX IP实现64B66B编解码的相关信号组成,本文生成64B66B编码的GTX IP。 首先如下图所示,需要对GTX共享逻辑进行设置,为了便于扩展&a…

如何废掉一个项目经理?

1、缺乏明确的目标和方向: 一个项目经理如果没有清晰的目标和方向,就像一艘没有指南针的船,很容易迷失在茫茫大海中。 解决方案:项目经理需要与上级、客户和团队成员共同制定明确的项目目标,并确保这些目标被充分理解…

LORA、UNB无线网关物联网锁助力人才公寓智慧化管理

吸引和留住青年人才是城市持续发展的关键,解决青年人才住房问题又是其中重要一环。“人才跟着产业走、公寓跟着人才建”已成为全国各地新建及改造人才公寓的目标,“引才聚才”离不开人才公寓行业布局与发展。 人才公寓不同于普通的长短租公寓&#xff0c…

CSRF、XSS、盗链攻击解释

CSRF(Cross-Site Request Forgery,跨站请求伪造) CSRF是什么 CSRF 是一种攻击方式,攻击者通过利用用户在已认证的应用程序中的身份,伪造用户的请求来执行未经授权的操作。 这种攻击可以导致用户在不知情的情况下完成…

工程设计问题---焊接梁设计

参考文献: [1] 吴擎, 徐惟罡, 张春江. 基于师生交流机制的改进类电磁机制算法[J]. 计算机集成制造系统, 2020, 26(4): 1033-1042.

深入理解 Java 中的 volatile 关键字

暮色四合,晚风轻拂,湖面上泛起点点波光,宛如撒下了一片星河。 文章目录 前言一、CPU 三级缓存二、JMM三、并发编程正确性的基础四、volatile 关键字五、volatile 可见性六、volatile 有序性6.1 指令重排序6.2 volatile 禁止指令重排6.3 vola…

六西格玛培训:一次学习,终身受益!

六西格玛培训,这个听起来就充满智慧的名字,其实是一种追求卓越的管理哲学。它的核心理念在于减少缺陷、降低变异,以提升企业的运营效率和质量水平。对于我们这些渴望在职场中更上一层楼的人来说,六西格玛培训无疑是一把打开成功之…

结合gin框架在沙箱环境下实现电脑网站支付和当面支付

文章目录 配置支付宝开放平台编写代码测试电脑网站支付当面扫码支付 配置支付宝开放平台 支付宝开放平台 点击链接,扫码进入后,点击沙箱: 点击沙箱应用,可以看到APPID,接口加签方式选择系统默认密钥就行&#xff0…

C的I/O操作

目录 引言 一、文件与目录操作 1. 打开与关闭文件 2. 文件读写操作 3. 文件定位与错误处理 二、字符流与字节流 1. 字符流处理 2. 字节流处理 三、序列化与反序列化 1. 序列化 2. 反序列化 四、新的I/O(NIO) 表格总结 文件与目录操作 字符…

nuxt3+vue3+vite+TS实现国际化

前言 博主最近打算用Nuxt3重构了自己SSR博客,打算添加国际化功能,众所周知,实现国际化已是一个很常见的功能。用户可以根据自己的喜好,设置页面的自己合适的语言,从而实现国际化浏览。这样用户体验度会大大提升。博客…

使用Midjourney为产品创建出色效果图-关键词

使用MJ为产品创建效果图并不难,可以使用这个固定提示词公式。 Mockup empty, blank [ product ], [ decorating items ] [ background or context ], [ 1- 3 descriptive style], [ color palette ] 创建产品形象 首先,你需要准备一个透明背景的产品。…

Python中文自然语言处理(NLP)中文分词工具库之pkuseg使用详解

概要 在中文自然语言处理(NLP)中,分词是一个基础且关键的任务。pkuseg 是由北京大学开发的一个中文分词工具,专为处理现代汉语而设计。它采用了先进的深度学习技术,能够准确地进行中文分词,同时支持自定义词典和多领域分词。本文将详细介绍 pkuseg 库,包括其安装方法、…

动态 SQL

动态 SQL 是 MyBatis 的强大特性之一&#xff0c;能够完成不同条件下不同的 sql 拼接。也就是说执行的 SQL 语句并不是固定的&#xff0c;而是不同人的不同操作执行的语句会有所差异。MyBatis 通过使用 标签 的方式来实现这种灵活性的。 <if>标签 例如在有一些网站进行…

一些个人电脑用的小工具软件

1 个人电脑信息管理 如下&#xff1b; 整理自己的电脑信息&#xff1b;录入&#xff0c;保存&#xff0c;查询&#xff1b;添加和更新界面如下&#xff0c; 每次添加、更新之后重新点一下菜单的浏览&#xff1b; 下载&#xff0c; https://download.csdn.net/download/bcb…

如何使用 pip 卸载所有已安装的 Python 包?

在开发过程中&#xff0c;我们可能会安装许多 Python 包&#xff0c;有时需要彻底清理环境&#xff0c;以便从头开始或者解决冲突问题。下面将介绍如何使用 pip 命令卸载所有已安装的 Python 包。 一、列出所有已安装的包 首先&#xff0c;需要列出当前环境中所有已安装的包。…

Vue49-props属性

一、当同一个组件标签被使用多次 因为data属性写的是函数形式&#xff01; 二、需求&#xff1a;老王也想用<Student>组件&#xff0c;但是需要动态把老王想要的值传进来。 2-1、使用props属性接收参数 使用props属性&#xff0c;接收的这三个参数&#xff0c;是被保存在…

入门机器视觉的正确打开方式——徒手撸一个python+opencv实现的机器视觉简易调试工具(上)

目录 1.引言2.框架思路3.环境搭建4.图像处理流程化的实现5.流水线上的算法块5.1 算法块的可视化 6.总结7.调试工具成品链接PS.扩展阅读ps1.六自由度机器人相关文章资源ps2.四轴机器相关文章资源ps3.移动小车相关文章资源 1.引言 在当今AI时代&#xff0c;关于视觉识别似乎已被…

位运算算法:编程世界中的魔法符号

✨✨✨学习的道路很枯燥&#xff0c;希望我们能并肩走下来! 文章目录 目录 文章目录 前言 一. 常见位运算总结 二、常见位运算题目 2.1 位1的个数 2.2 比特数记位&#xff08;典型dp&#xff09; 2.3 汉明距离 2.4 只出现一次的数字&#xff08;1&#xff09; 2.5 只出…