• Docker 原理


    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@xyyweb-pc:/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@pddweb-pc:~/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@pddweb-pc:~/ns-share-demo# docker run -d --name nginx -v $(pwd)/nginx.conf:/etc/nginx/nginx.conf --ipc=shareable -p 8080:81 nginx
    9e2f9a2d32195fbac557371674bc967804771dc283dca630e97565394b2c3bb4
    root@pddweb-pc:~/ns-share-demo# docker run -d --name nginx-backend --net=container:nginx --ipc=container:nginx --pid=container:nginx nginx
    1c9af683dbf956ae600f5bd9d644e49f5237bcdf400ed7e01394c859ac0d35d9
    root@pddweb-pc:~/ns-share-demo# curl http://localhost:8080/
     
    

    使用pod的pause共享命名空间

    root@pddweb-pc:~/ns-share-demo# docker run -d --name pause --ipc=shareable -p 8080:80  ran
    cher/mirrored-pause:3.1
    5d75e1d648c02686b02ce127b8065ae5e6337594c696774d252e1515475e80d7
    root@pddweb-pc:~/ns-share-demo# docker run -d --name nginx --net=container:pause --ipc=container:pause --pid=container:pause  nginx
    a4e68b82209a197f675fc30a2b1677f0ca37c8c02eaaf2bca1c27383cd72f4c5
    root@pddweb-pc:~/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)

  • 相关阅读:
    电商项目之购物车
    红队专题-新型webshell的研究
    Windows Access Token
    [语音识别] 基于Python构建简易的音频录制与语音识别应用
    学习HTTP——HTTPS
    Nginx代理服务器和真实后端服务器都配置了跨域导致的跨域问题
    计算机考研数据库题库
    二、进程管理(四)经典同步互斥问题
    【R语言】边缘概率密度图
    Python | 数学计算那点事儿不完全总结 - 计算平均值、几何平均值等等
  • 原文地址:https://blog.csdn.net/qq_37989070/article/details/132901768