从零自制docker-15-【实现 mydocker run -d 支持后台运行容器】

文章目录

  • 实现目的
  • 莫名奇妙的问题
  • 对之前upper层出现root补充
  • 对run某些命令出现找不到文件或目录的原因
  • 代码
  • 效果

实现目的

docker run -d时容器在后台运行,而不会进入命令行交互形式

  1. 首先是需要添加-d选项
  2. 然后设置当添加-d选项时候主进程不会等待子进程,而是直接结束
func Contain_run(cmd string,it bool,resource_config *cgroups.Resource,volume string) {command,writepipe,rooturl:=new_contain_process(it,volume)log.Infof("cmd %s it %t",cmd,it)if err:=command.Start();err!=nil{log.Error(err)}log.Infof("cmd %s",cmd)cmdstring:=strings.Split(cmd, " ")log.Infof("split cmd %v",cmdstring)llkdockercgroups:=cgroups.Cgroups{Cgroups_Name: "llkdockercgroups",Resour:resource_config,Sub:cgroups.Subsystemins,}log.Info(llkdockercgroups.Resour)cgroups_path:=cgroups.Get_cgroups_path("cgroup",llkdockercgroups.Cgroups_Name)log.Info("in run.go get cgroups_path")llkdockercgroups.Move(command.Process.Pid,cgroups_path)llkdockercgroups.Set(cgroups_path)//defer llkdockercgroups.Remove(cgroups_path) //-d后台运行的话不能删除cgroupwrite_to_pipe(cmdstring,writepipe)if it{ //-it实现交互,那么当前终端就不能关闭退出,还需留给子进程使用command.Wait()// 从容器内的命令行中的退出才会wait结束end_volume(rooturl,volume)end_overlays(rooturl)}log.Infof("exit  !!!")}
  1. 最后注意主进程不能删除该进程建立的cgroup,否则会出现下述问题,这个是删除cgroup出现的问题,原因是这个cgroup还包含一些正在运行的进程,那些进程没有结束就删除cgroup会删除失败
    在这里插入图片描述

解决方法:就是在-it的模式下最后删除,但后台运行的不会

if it{ //-it实现交互,那么当前终端就不能关闭退出,还需留给子进程使用command.Wait()// 从容器内的命令行中的退出才会wait结束end_volume(rooturl,volume)end_overlays(rooturl)llkdockercgroups.Remove(cgroups_path) //-d后台运行的话不能删除cgroup}

这个是后台运行docker的
在这里插入图片描述
而最后通过-it运行的结果如下
在这里插入图片描述

莫名奇妙的问题

发现调试的时候,使用log.Infof等其他类似的,最后终端上没有显示全,但通ps -ef|grep -e PPID -e top查看发现其又确实在在运行

例如下面这个9550进程是后台运行的top进程
在这里插入图片描述
但在终端上显示时有时不全,有时也会显示全
在这里插入图片描述
这里我是开了子进程的和当前终端的标准输入输出和错误都一样的,不然看不到相关调试信息

func new_contain_process(it bool,volume string)  (*exec.Cmd,*os.File,string){	readpipe,writepipe,err:=os.Pipe()if err!=nil{log.Fatal(err)}command:=exec.Command("/proc/self/exe","init")command.SysProcAttr=&syscall.SysProcAttr{Cloneflags: syscall.CLONE_NEWUTS | syscall.CLONE_NEWPID | syscall.CLONE_NEWNS |syscall.CLONE_NEWNET | syscall.CLONE_NEWIPC,}//主进程和子进程共用一个终端command.Stdin=os.Stdincommand.Stdout=os.Stdoutcommand.Stderr=os.Stderrlog.Info(command)log.Infof("sucess create a contain process")command.ExtraFiles=[]*os.File{readpipe}mntURL := "./merged"rootURL := "./"command.Dir = mntURLprepare_overlays(rootURL) prepare_volume(rootURL,volume)log.Info(readpipe)return command,writepipe,rootURL}

对之前upper层出现root补充

之前一直是对上一个写的docker复制然后在复制的上面写新的,发现busybox和刚从busybox解压得到缺少了很多东西,然后又重新解压生成了busybox将其使用。然后之前在后面发现upper中出现root是调用相关命令就会出现root,但当时没有啥修改的文件,这次全的busybox发现出现了下面的这个,那么确实就是因为调用命令引起的日志记录的变化导致的
在这里插入图片描述

对run某些命令出现找不到文件或目录的原因

当时是容器在挂载前就找相关命令,找到的这个是宿主机上的,但我们要的是在pivoroot后的根目录下的相关命令的路径,所以后面运行这个宿主机上的路径会显示路径找不到,因为此时是以容器的根目录为相对参考


func Contain_init(){cmd:=readpipe()log.Infof("init %s",cmd)log.Infof("cmd[0] %s",cmd[0]=="/bin/sh")log.Infof("cmd len %d",len(cmd))log.Infof("cmd %s",cmd[0])/*path,err:=exec.LookPath(cmd[0])//挂载前得到相关命令的路径会出现找不到if err!=nil{log.Fatal(err)}argv:=[]string{}for i:=1;i<len(cmd);i++{argv=append(argv,cmd[i-1])}*/log.Infof("prepare for mount ")mount()path,err:=exec.LookPath(cmd[0]) //挂载后再得到相关命令的路径等if err!=nil{log.Fatal(err)}argv:=[]string{}for i:=1;i<len(cmd);i++{argv=append(argv,cmd[i-1])}log.Infof("prepare for exec cmd ")log.Info(path)log.Info(argv)log.Info(os.Environ())if err:=syscall.Exec(path,argv,os.Environ());err!=nil{log.Infof("exec error")log.Info(err)}}

代码

https://github.com/FULLK/llkdocker/tree/main/run_d_docker

效果

最终我启动了sudo ./run_docker run -d top多次,在cgroup.procs中可以看到(一部分是之前sudo ./run_docker run -it /bin/sh加入的,因为我最后关闭了主进程最后自动删除cgroup的函数),最终可以看到top进程在后台运行
`
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

从Python代码到pip包:打包Python项目

大家好&#xff0c;在软件开发的世界中&#xff0c;共享和重用代码是至关重要的。Python社区为我们提供了丰富的资源&#xff0c;使得我们能够轻松地与他人分享我们的工作&#xff0c;并从他人的工作中受益。将代码打包成pip包&#xff08;Python包管理器&#xff09;是一种常见…

Moto和Inter字节序

inter: 低地址按照start_bit位放低字节依次往高字节填充 MotoLsb: 低地址按照start_bit位放高字节&#xff0c;依次往低字节填充MotoMsb&#xff1a;高字节按照start_bit位放低地址&#xff0c;依次往高字节填充

uni-app实现页面之间的跳转传参(八)

界面之间的参数传递在 开发中经常会用到,这节主要将一下uni-app开发应用是的传参情况。如下图所示,我的一级界面将点检分成三类:日点检、周点检和年保养;在点击相应的会导航到相应的功能。 在uni-app中常用的方法有uni.navigateTo(OBJECT)、uni.redirectTo(OBJECT);简单的…

怎么图片转excel表格免费?介绍三个方法

怎么图片转excel表格免费&#xff1f;在日常工作中&#xff0c;我们经常需要将图片中的表格数据转化为可编辑的Excel格式。幸运的是&#xff0c;市面上有多款软件支持这一功能&#xff0c;并且部分软件还提供免费使用的选项。本文将为您详细介绍几款可以免费将图片转换为Excel表…

Flink DataStream API 介绍

一、介绍 官网 DataStream API 得名于特殊的 DataStream 类&#xff0c;该类用于表示 Flink 程序中的数据集合。你可以认为 它们是可以包含重复项的不可变数据集合。这些数据可以是有界&#xff08;有限&#xff09;的&#xff0c;也可以是无界&#xff08;无限&#xff09;的…

快速排序算法备考

快排模板 快速排序(快排) (C语言实现)_c语言快速排序_Brant_zero2022的博客-CSDN博客 快排使用递归来实现 关键思想:划分 //划分 int partion(int A[],int L,int R){int midA[L];while(L<R){//每一次划分:左边元素<枢轴元素<右边元素//R往前找&#xff0c;直到找到一…

IO系列(八) -浅析NIO工作原理

一、简介 现在使用 NIO 的场景越来越多&#xff0c;很多网上的技术框架或多或少的使用 NIO 技术&#xff0c;譬如 Tomcat、Jetty、Netty&#xff0c;学习和掌握 NIO 技术已经不是一个 Java 攻城狮的加分技能&#xff0c;而是一个必备技能。 那什么是 NIO 呢&#xff1f; NIO…

不拍视频,不直播怎么在视频号卖货赚钱?开一个它就好了!

大家好&#xff0c;我是电商糖果 视频号这两年看着抖音卖货的热度越来越高&#xff0c;也想挤进电商圈。 于是它模仿抖音推出了自己的电商平台——视频号小店。 只要商家入驻视频号小店&#xff0c;就可以在视频号售卖商品。 具体怎么操作呢&#xff0c;需要拍视频&#xf…

Redis实践—全国地址信息缓存

一、背景 在涉及全国地址的应用中&#xff0c;地址信息通常被频繁地查询和使用&#xff0c;例如电商平台、物流系统等。为了提高系统性能和减少对数据库的访问压力&#xff0c;可以使用缓存来存储常用的地址信息&#xff0c;其中 Redis 是一个非常流行的选择。 本次在一个企业入…

就业信息|基于SprinBoot+vue的就业信息管理系统(源码+数据库+文档)

就业信息管理系统 目录 基于SprinBootvue的就业信息管理系统 一、前言 二、系统设计 三、系统功能设计 1前台功能模块 2后台功能模块 4.2.1管理员功能 4.2.2学生功能 4.2.3企业功能 4.2.4导师功能 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设…

[力扣]——70.爬楼梯

题目描述&#xff1a; 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢&#xff1f; 本题较为简单&#xff0c;主要用到递归思想 int fun(int n,int memo[]) {if(memo[n]!-1) //如果备忘录中已经有记录了…

学 Go 具体能干什么?

学习 Go (Golang) 后&#xff0c;你可以从事许多不同的工作和项目&#xff0c;Go 语言以其高性能、并发处理和简洁的语法而闻名&#xff0c;特别适合以下几个领域&#xff1a; 1. 后端开发 Go 在后端开发中非常流行&#xff0c;特别适合构建高性能的 Web 服务和 API。 Web 框…

安卓获取内部存储信息

目录 前言获取存储容量 前言 原生系统设置里的存储容量到底是怎么计算的&#xff0c;跟踪源码&#xff0c;涉及到VolumeInfo、StorageManagerVolumeProvider、PrivateStorageInfo、StorageStatsManager......等等&#xff0c;java上层没有办法使用简单的api获取到吗&#xff1f…

【全开源】分类记账小程序系统源码(ThinkPHP+FastAdmin+UniApp)

基于ThinkPHPFastAdminUniAppvk-uView-uiVue3.0开发的一款支持多人协作的记账本小程序&#xff0c;可用于家庭&#xff0c;团队&#xff0c;组织以及个人的日常收支情况记录&#xff0c;支持周月年度统计。 &#xff1a;智能管理您的财务生活 一、引言&#xff1a;财务智能化…

多线程编程(12)之HashMap1.8源码分析

之前已经分析过了一版1.7版本的HashMap&#xff0c;这里主要是来分析一下1.8HashMap源码。 一、HashMap数据结构 HashMap 是一个利用散列表&#xff08;哈希表&#xff09;原理来存储元素的集合&#xff0c;是根据Key value而直接进行访问的数 据结构。 在 JDK1.7 中&#xff…

Text Control 控件 中 Service Pack 3:MailMerge 支持 SVG 图像

图像的合并方式与报告模板中的合并字段相同。占位符在设计时添加&#xff0c;并与文件、数据库或内存中的数据合并。可以将图像对象添加到具有指定名称的模板中。数据列必须包含字节数组形式的二进制图像数据、System.Drawing.Image 类型的对象、文件名、十六进制或 Base64 编码…

产品经理-需求收集(二)

1. 什么是需求 指在一定的时期中&#xff0c;一定场景中&#xff0c;无论是心理上还是生理上的&#xff0c;用户有着某种“需要”&#xff0c;这种“需要”用户自己不一定知道的&#xff0c;有了这种“需要”后用户就有做某件事情的动机并促使达到其某种目的&#xff0c;这也就…

Python 开心消消乐

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

记一次绕过宝塔防火墙的BC站渗透

0x00 信息收集 由于主站存在云waf 一测就封 且初步测试不存在能用得上的洞 所以转战分站 希望能通过分站获得有价值的信息 这是一个查询代理帐号的站 url输入admin 自动跳转至后台 看这个参数 猜测可能是thinkCMF 0x01 getshell thinkcmf正好有一个RCE 可以尝试一下 ?afetc…

01.爬虫---初识网络爬虫

01.初识网络爬虫 1.什么是网络爬虫2.网络爬虫的类型3.网络爬虫的工作原理4.网络爬虫的应用场景5.网络爬虫的挑战与应对策略6.爬虫的合法性总结 1.什么是网络爬虫 网络爬虫&#xff0c;亦称网络蜘蛛或网络机器人&#xff0c;是一种能够自动地、系统地浏览和收集互联网上信息的程…