Docker 原理

2023-09-15 14:41:12
  1. 基础技术试验
    1. 进程
      1. linux namespace
        1. Mount(mnt) namespace 可以在不影响宿主机文件系统的基础上挂载或者取消挂载文件系统了;
        2. PID(Process ID) 在一个pid namespace中,第一个进程的 pid 为1,所有在此 namespace 中的其他进程都是此进程的子进程,操作系统级别的其他进程不需要在此进程中;
        3. network(netns) namespace 会虚拟出新的内核协议栈,每个 network namespace 包括自己的网络设备、路由表等;
        4. IPC(Interprocess Communication) namespace 用来隔离处于不同 IPC namespace 的进程间通信资源,如共享内存等;
        5. UTS: UTS namespace 用于隔离 hostname 与 domainname 
        6. User
      2. linux control group(cgroup)
        1. /proc下的树形文件系统
          1. /proc/{pid}/mountinfo 里面有cgroup所在位置信息
          2. /proc/self 指向当前进程
          3. /sys/fs/cgroup 下面有系统预定义的一些cgroup
        2. memory
        3. cpu
      3. IPC linux管道
        1. 一个进程默认有3个文件描述符:stdin stdout stderr
        2. 通过ExtraFiles的形式传入管道句柄
        3. 管道结束前是阻塞进程的
    2. 文件系统
      1. aufs
        1. 旧版docker用这个,新版已淘汰
      2. overlay2
        1. 现在docker默认是这个
      3. docker支持的文件系统类型:Docker storage drivers | Docker Documentation
  2. 构造容器,基于go
    1. 创建进程
      1. 子进程覆盖初始化进程,让自己的pid为1
        1. execve(2)
        2. go下:func Exec(argv0 string, argv []string, envv []string) (err error
      2. 为进程添加namespace限制
        1. 添加Cloneflags属性
    2. 为进程添加cgroup限制
      1. 分别在/sys/fs/cgroup对应的预定义限制下,创建文件夹
      2. 写入限制属性
      3. tasks文件里添加进程pid
    3. 使用linux管道传长参数
  3. 构造镜像
    1. pivot_root
    2. 直接打包mnt的busybox
    3. 使用overlay2挂解压的镜像、临时写目录、数据卷
    4. 运行的容器打包镜像
  4. 完善容器
    1. 用detach实现后台运行,
      1. wsl下的现象是:容器内进程挂到父进程下面,父进程退出自动挂到祖父进程
    2. 其他附带探索
      1. java调用go研究 cgo+jnr 打通java(kotlin)和go
    3. 容器信息持久化
      1. 可以实现docker ps 容器查询命令
      2. stdout重定向到文件,可以执行docker log命令
    4. docker exec
      1. 使用cgo进入进程的namespace
    5. 支持多容器、多镜像
      1. 面向对象化
      2. 容器镜像分开文件夹,多对一的关系
    6. 启停、删除
      1. 清理步骤,杀进程,卸载挂载点,删文件夹
    7. 环境变量配置
      1. 容器进程环境变量 
      2. exec进程环境变量
  5. linux网络
    1. 容器网络 
    2. net namespace
      1. 下面所有概念的命名空间
    3. 虚拟网卡
      1. linux bridge网桥
      2. veth网卡对
        1. 串联两个netns
    4. iptables
      1. snat
        1. 作用是内部能访问出去
        2. 试验没成功
      2. dnat
        1. 把端口暴露出来
        2. 外部能访问进来
      3. 4表5链
      4. 是否本机ip走向不同
  6. 现有容器格局
    1. runC
      1. containerd
        1. docker
        2. cri-shim
          1. kubelet
            1. k8s

overlay2

# 参考一个overlayfs的例子
# https://www.cnblogs.com/arnoldlu/p/13055501.html
mount -t overlay -o lowerdir=lower,upperdir=upper,workdir=work overlay merge
 
# 组合命令:
# 在linux目录运行成功,直接挂载windows目录有问题,文件写入失败
mkdir image-layer4 image-layer3 image-layer2 image-layer1 container-layer work mnt
mount -t overlay -o lowerdir=./image-layer4:./image-layer3:./image-layer2:./image-layer1,upperdir=./container-layer,workdir=./work overlay ./mnt
 

linux namespace

从 container 到 pod (morven.life)

直接使用命令行创建namespace,在另外namespace运行程序

unshare --fork --pid --mount-proc bash
 
# 查看当前的namespace
root@fingard-sunht:/mnt/c/Users/ZJBR# lsns
        NS TYPE   NPROCS PID USER COMMAND
4026531835 cgroup      2   1 root bash
4026531837 user        2   1 root bash
4026531992 net         2   1 root bash
4026532233 ipc         2   1 root bash
4026532243 uts         2   1 root bash
4026532347 mnt         2   1 root bash
4026532348 pid         2   1 root bash
 
# 直接在某个cgroup下运行
cgcreate -a morven -g memory:mycgrp
echo 1000 > /sys/fs/cgroup/memory/mycgrp/memory.limit_in_bytes
cgexec -g memory:mycgrp java -version

docker可以做到容器间共享namespace

root@fingard-sunht:~/ns-share-demo# cat nginx.conf
error_log stderr;
events { worker_connections  1024; }
http {
    access_log /dev/stdout combined;
    server {
        listen 81 default_server;
        error_log stderr;
        server_name example.com www.example.com;
        location / {
            proxy_pass http://127.0.0.1:80;
        }
    }
}
 
root@fingard-sunht:~/ns-share-demo# docker run -d --name nginx -v $(pwd)/nginx.conf:/etc/nginx/nginx.conf --ipc=shareable -p 8080:81 nginx
9e2f9a2d32195fbac557371674bc967804771dc283dca630e97565394b2c3bb4
root@fingard-sunht:~/ns-share-demo# docker run -d --name nginx-backend --net=container:nginx --ipc=container:nginx --pid=container:nginx nginx
1c9af683dbf956ae600f5bd9d644e49f5237bcdf400ed7e01394c859ac0d35d9
root@fingard-sunht:~/ns-share-demo# curl http://localhost:8080/
 

使用pod的pause共享命名空间

root@fingard-sunht:~/ns-share-demo# docker run -d --name pause --ipc=shareable -p 8080:80  ran
cher/mirrored-pause:3.1
5d75e1d648c02686b02ce127b8065ae5e6337594c696774d252e1515475e80d7
root@fingard-sunht:~/ns-share-demo# docker run -d --name nginx --net=container:pause --ipc=container:pause --pid=container:pause  nginx
a4e68b82209a197f675fc30a2b1677f0ca37c8c02eaaf2bca1c27383cd72f4c5
root@fingard-sunht:~/ns-share-demo# curl http://localhost:8080/
 

cgroup

官方文档 

Control Groups version 1 — The Linux Kernel documentation

Control Group v2 — The Linux Kernel documentation

Linux的cgroup功能(二):资源限制cgroup v1和cgroup v2的详细介绍By李佶澳 (lijiaocn.com)

K8S 问题排查: cgroup 内存泄露问题 - Vermouth | 血衫非弧の一存 (kelu.org)

更多推荐

【Linux网络编程】序列化与反序列化

我们网络收发数据实际上只能接收到字符串,但是在现实生活中描述一个客观物体都是以很多属性来描述的,所以在网络中结构体类型的数据更常见,那我们如何发送结构体数据呢?这里就涉及到协议的概念了。我们想象一个场景,在特种兵执行任务时,他们有特定的战术手语,这样他们就能根据手语进行相应的战术配合了。所以协议也是一样,客户端和服务器

【计算机网络】IP协议

文章目录TCP与IP之间的关系IP地址的认识协议报头格式1.报头和有效载荷如何分离?2.8位协议3.4位版本4.8位服务类型5.16位总长度6.8位生存时间TTL网段划分IP地址的划分子网划分CIDR的提出如何理解CIDRTCP与IP之间的关系如:假设你上高中时,班里有个同学叫张三,他的老爹是学校的校长你感觉每次考试都

微前端qiankun简易上手指南

微前端架构一、什么是微前端架构微前端是一种多个团队通过独立发布功能的方式来共同构建现代化web应用的技术手段及方法策略。微前端借鉴了微服务的架构理念,将一个庞大的前端应用才分为多个独立灵活的小型应用,每个应用都可以独立开发,独立运行,独立部署,再将这些小型应用联合为一个完整的应用。微前端既可以将多个项目融合为一,又可以

Pixea Plus for Mac:极简图片浏览,高效图片管理

在处理和浏览图片时,我们往往需要一个得心应手的工具,尤其是当你的图片库包含了各种不同格式,例如JPEG、HEIC、psd、RAW、WEBP、PNG、GIF等等。今天,我们要推荐的,就是一款极简、高效的Mac图片浏览和管理工具——PixeaPlus。PixeaPlusMac版是一款专为Mac用户设计的图片浏览器和管理工具

【Linux】自动化构建工具 —— make/makefile&&Linux第一个小程序 - 进度条

​​📝个人主页:@Sherry的成长之路🏠学习社区:Sherry的成长之路(个人社区)📖专栏链接:Linux🎯长路漫漫浩浩,万事皆有期待上一篇博客:Linux编译器gcc/g++的使用&&初识动静态链接库文章目录一、前言二、概念三、代码实现四、实现原理1、依赖关系和依赖方法2、清理①.PHONY伪目标②.PHO

ZABBIX 6.4安装部署

ZABBIX6.4安装部署zabbix的主要组成:1、ZabbixServer6.4:Zabbix服务端,是Zabbix的核心组件。它负责接收监控数据并触发告警,还负责将监控数据持久化到数据库中。2、ZabbixAgent:Zabbix客户端,部署在被监控设备上,负责采集监控数据,采集后的数据发送给ZabbixServ

林木种苗生产vr虚拟实训教学降低培训等待周期

林业种植管理在保护水土流失、气候变化及经济社会发展中发挥重要的作用,林业教学往往需要进入林区进行实操察验,在安全性、时间及效率上难以把控,因此有更多林业畜牧院校创新性地引进VR虚拟现实技术。在林业领域,实地调查是获取准确数据和深入了解森林生态的重要手段。然而,传统的实地调查方法存在诸多问题,如时间成本高、人力物力投入大

每天一个面试题之类加载机制、spirngboot的启动机制

jvm类加载机制Java虚拟机(JVM)的类加载机制是Java的关键部分,它负责加载、链接和初始化类。类加载机制的主要任务是将Java类的字节码文件转换为可以在JVM上执行的运行时数据结构。这个过程包括以下三个主要步骤:加载(Loading):在此阶段,类加载器负责查找并加载类的字节码文件。这个过程通常从类路径(Cla

搭建私人图床结合内网穿透实现公网访问,让您的摄影作品连接世界

文章目录1.树洞外链网站搭建1.1下载安装树洞外链1.2树洞外链网页测试1.3cpolar的安装和注册2.本地网页发布2.1Cpolar临时数据隧道2.2Cpolar稳定隧道(云端设置)2.3Cpolar稳定隧道(本地设置)3.公网访问测试社交平台具有庞大的用户基础和活跃的社交功能,我们将图片发布到社交平台可以让照片更

Learn Prompt-ChatGPT 精选案例:内容总结

ChatGPT可以通过分析内容并生成一个浓缩版本来总结文本。这对节省时间和精力很有帮助,特别是在阅读长篇文章、研究论文或报告时。通用总结​你所要做的就是把具体的文字复制并粘贴到提示中,并要求ChatGPT对所选文本进行简化总结。这里我们参考openai官网提供的例子Summarizefora2ndgrader来总结一下

想学嵌入式开发,薪资怎么样?

想学嵌入式开发,薪资怎么样?对于嵌入式工程师来说呢,它重点学习内容就是首先一定要打好基础,如果从编程语言角度来讲,那么可以在语言上选C或者C++,你可以选择其中任何一门语言作为你的入门。最近很多小伙伴找我,说想要一些嵌入式机学习资料,然后我根据自己从业十年经验,熬夜搞了几个通宵,精心整理了一份「嵌入式入门到高级教程+工

热文推荐