从零开始写 Docker(十三)---实现 mydocker rm 删除容器

mydocker-rm.png

本文为从零开始写 Docker 系列第十三篇,实现类似 docker rm 的功能,使得我们能够删除容器。


完整代码见:https://github.com/lixd/mydocker
欢迎 Star

推荐阅读以下文章对 docker 基本实现有一个大致认识:

  • 核心原理:深入理解 Docker 核心原理:Namespace、Cgroups 和 Rootfs
  • 基于 namespace 的视图隔离:探索 Linux Namespace:Docker 隔离的神奇背后
  • 基于 cgroups 的资源限制
    • 初探 Linux Cgroups:资源控制的奇妙世界
    • 深入剖析 Linux Cgroups 子系统:资源精细管理
    • Docker 与 Linux Cgroups:资源隔离的魔法之旅
  • 基于 overlayfs 的文件系统:Docker 魔法解密:探索 UnionFS 与 OverlayFS
  • 基于 veth pair、bridge、iptables 等等技术的 Docker 网络:揭秘 Docker 网络:手动实现 Docker 桥接网络


开发环境如下:

root@mydocker:~# lsb_release -a
No LSB modules are available.
Distributor ID:	Ubuntu
Description:	Ubuntu 20.04.2 LTS
Release:	20.04
Codename:	focal
root@mydocker:~# uname -r
5.4.0-74-generic

注意:需要使用 root 用户

1. 概述

之前实现了 mydocker stop 能够停止后台运行的容器,那么,对于已经处于停止状态的容器,还剩余一个删除操作来补全容器的整个生命周期。

本篇就会完成这最后一步的清理工作,实现mydocker rm 命令,让我们能够直接删除已经停止的容器。

2. 实现

mydocker rm 实现起来很简单,主要是文件操作,因为容器对应的进程已经被停止,所以只需要将对应记录文件信息的目录删除即可。

docker 可以通过 -f 强制删除运行中的容器,具体见 moby/delete.go#L92,这里也加一下,指定 force 时先 stop 再删除即可。

removeCommand

同样是先定义 removeCommand,然后再添加到 main 函数中。

var removeCommand = cli.Command{Name:  "rm",Usage: "remove unused containers,e.g. mydocker rm 1234567890",Flags: []cli.Flag{cli.BoolFlag{Name:  "f", // 强制删除Usage: "force delete running container,",}},Action: func(context *cli.Context) error {if len(context.Args()) < 1 {return fmt.Errorf("missing container id")}containerId := context.Args().Get(0)force := context.Bool("f")removeContainer(containerId, force)return nil},
}

这里只做参数解析,拿到 containerId 传递给 removeContainer 即可。

removeContainer

removeContainer 则是 rm 命令的真正实现,根据 Id 拿到容器信息,然后先判断状态:

  • STOP 状态,则直接删除
  • RUNNING 状态,如果带了 force flag 则先 Stop 然后再删除,否则打印错误信息
func removeContainer(containerId string, force bool) {containerInfo, err := getInfoByContainerId(containerId)if err != nil {log.Errorf("Get container %s info error %v", containerId, err)return}switch containerInfo.Status {case container.STOP: // STOP 状态容器直接删除即可dirPath := fmt.Sprintf(container.InfoLocFormat, containerId)if err = os.RemoveAll(dirPath); err != nil {log.Errorf("Remove file %s error %v", dirPath, err)return}case container.RUNNING: // RUNNING 状态容器如果指定了 force 则先 stop 然后再删除if !force {log.Errorf("Couldn't remove running container [%s], Stop the container before attempting removal or"+" force remove", containerId)return}stopContainer(containerId)removeContainer(containerId, force)default:log.Errorf("Couldn't remove container,invalid status %s", containerInfo.Status)return}
}

3. 测试

删除 STOP 状态容器

首先创建一个 detach 容器

root@mydocker:~/feat-rm/mydocker# go build .
root@mydocker:~/feat-rm/mydocker# ./mydocker run -d -name rm1 top
{"level":"info","msg":"createTty false","time":"2024-01-30T15:11:20+08:00"}
{"level":"info","msg":"resConf:\u0026{ 0  }","time":"2024-01-30T15:11:20+08:00"}
{"level":"info","msg":"busybox:/root/busybox busybox.tar:/root/busybox.tar","time":"2024-01-30T15:11:20+08:00"}
{"level":"error","msg":"mkdir dir /root/merged error. mkdir /root/merged: file exists","time":"2024-01-30T15:11:20+08:00"}
{"level":"error","msg":"mkdir dir /root/upper error. mkdir /root/upper: file exists","time":"2024-01-30T15:11:20+08:00"}
{"level":"error","msg":"mkdir dir /root/work error. mkdir /root/work: file exists","time":"2024-01-30T15:11:20+08:00"}
{"level":"info","msg":"mount overlayfs: [/usr/bin/mount -t overlay overlay -o lowerdir=/root/busybox,upperdir=/root/upper,workdir=/root/work /root/merged]","time":"2024-01-30T15:11:20+08:00"}
{"level":"info","msg":"command all is top","time":"2024-01-30T15:11:20+08:00"}

mydocker ps 查看一下:

root@mydocker:~/feat-rm/mydocker# ./mydocker ps
ID           NAME        PID         STATUS      COMMAND     CREATED
0394026801   rm1         181151      running     top         2024-01-30 15:11:20

可以看到,容器正处于 running 状态。

尝试直接删除容器:

root@mydocker:~/feat-rm/mydocker# ./mydocker rm 0394026801
{"level":"error","msg":"Couldn't remove running container [0394026801], Stop the container before attempting removal or force remove","time":"2024-01-30T15:12:12+08:00"}

根据错误信息可知,不能直接删除运行中的容器

于是先把容器 stop 掉:

root@mydocker:~/feat-rm/mydocker# ./mydocker stop 0394026801
root@mydocker:~/feat-rm/mydocker# ./mydocker ps
ID           NAME        PID         STATUS      COMMAND     CREATED
0394026801   rm1                     stopped     top         2024-01-30 15:11:20

此时已经是 stopped 状态,可以执行删除了。

root@mydocker:~/feat-rm/mydocker# ./mydocker rm 0394026801
root@mydocker:~/feat-rm/mydocker# ./mydocker ps
ID          NAME        PID         STATUS      COMMAND     CREATED

可以看到,容器信息已经不见了,说明删除成功。

强制删除 RUNNING 状态容器

再测试一下指定 -f 时能否删除 RUNNING 状态的容器。

首先,也是启动一个 detach 容器

root@mydocker:~/feat-rm/mydocker# ./mydocker run -d -name rm2 top
{"level":"info","msg":"createTty false","time":"2024-01-30T15:13:44+08:00"}
{"level":"info","msg":"resConf:\u0026{ 0  }","time":"2024-01-30T15:13:44+08:00"}
{"level":"info","msg":"busybox:/root/busybox busybox.tar:/root/busybox.tar","time":"2024-01-30T15:13:44+08:00"}
{"level":"error","msg":"mkdir dir /root/merged error. mkdir /root/merged: file exists","time":"2024-01-30T15:13:44+08:00"}
{"level":"error","msg":"mkdir dir /root/upper error. mkdir /root/upper: file exists","time":"2024-01-30T15:13:44+08:00"}
{"level":"error","msg":"mkdir dir /root/work error. mkdir /root/work: file exists","time":"2024-01-30T15:13:44+08:00"}
{"level":"info","msg":"mount overlayfs: [/usr/bin/mount -t overlay overlay -o lowerdir=/root/busybox,upperdir=/root/upper,workdir=/root/work /root/merged]","time":"2024-01-30T15:13:44+08:00"}
{"level":"info","msg":"command all is top","time":"2024-01-30T15:13:44+08:00"}

查看容器信息

root@mydocker:~/feat-rm/mydocker# ./mydocker ps
ID           NAME        PID         STATUS      COMMAND     CREATED
9293725578   rm2         181202      running     top         2024-01-30 15:13:44
root@mydocker:~/feat-rm/mydocker# ps -ef|grep top
root      181202       1  0 15:13 pts/10   00:00:00 top

普通删除和强制删除

root@mydocker:~/feat-rm/mydocker# ./mydocker rm 9293725578
{"level":"error","msg":"Couldn't remove running container [9293725578], Stop the container before attempting removal or force remove","time":"2024-01-30T15:15:10+08:00"}
root@mydocker:~/feat-rm/mydocker# ./mydocker rm -f 9293725578

普通删除提示失败,强制删除则成功了,看下是否真的删掉了

root@mydocker:~/feat-rm/mydocker# ./mydocker ps
ID          NAME        PID         STATUS      COMMAND     CREATED
root@mydocker:~/feat-rm/mydocker# ps -ef|grep top
root      181231  177607  0 15:15 pts/10   00:00:00 grep --color=auto top

容器信息删除了,进程也消失了,说明删除是成功的。

4. 小结

本篇主要实现 mydocker rm 命令,根据 containerId 找到记录容器信息的目录,然后删除该目录以实现删除容器的效果。

对于 RUNNING 状态容器可以指定-f 强制删除,或者先执行 stop 命令停止容器。


**【从零开始写 Docker 系列】**持续更新中,搜索公众号【探索云原生】订阅,文章。



完整代码见:https://github.com/lixd/mydocker
欢迎关注~

相关代码见 feat-rm 分支,测试脚本如下:

需要提前在 /root 目录准备好 busybox.tar 文件,具体见第四篇第二节。

# 克隆代码
git clone -b feat-rm https://github.com/lixd/mydocker.git
cd mydocker
# 拉取依赖并编译
go mod tidy
go build .
# 测试 
./mydocker run -d -name c1 top
# 查看容器 Id
./mydocker ps
# stop 停止指定容器
./mydocker stop ${containerId}

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

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

相关文章

谷歌CEO最新访谈:AI浪潮仍处于早期阶段,公司未来最大威胁是执行力不足

作为搜索领域无可争议的霸主&#xff0c;谷歌改变了我们生活的方方面面&#xff0c;从日常琐事到工作事务&#xff0c;再到我们的沟通方式。多年来&#xff0c;谷歌一直是互联网的窗口&#xff0c;为我们提供大量知识和信息&#xff0c;但如今&#xff0c;随着其他类似平台的崛…

HarmonyOS开发之ArkTS使用:用户登录页面应用

目录 目录 前言 关于HarmonyOS 环境准备 新建项目 设计用户登录页面 1. 布局设计 2. 编写ArkTS代码 运行和测试 结束语 前言 随着HarmonyOS&#xff08;鸿蒙操作系统&#xff09;的不断发展&#xff0c;越来越多的开发者开始投入到这个全新的生态系统中&#xff0c;而…

车载测试系列:车载测试Bug定位与分析

车载Bug定位 1.1 模拟复现条件 能够复现bug才能对问题进行定位、解决以及验证。找到bug存在的特定的条件&#xff0c;进行重现。对于依赖外部输入的条件&#xff0c;如果条件比较复杂难以模拟可以在程序里预设直接进入对应状态。 1.2 打印Log 根据问题的现象&#xff0c;在…

Spring-依赖来源

依赖来源 1 Spring BeanDefinition&#xff08;xml,注解&#xff0c;BeanDefinitionBuilder, 还有API实现的单例对象&#xff09; 2 Spring 内建BeanDefinition 3 内建单例对象 依赖注入和依赖查找的区别 Context.refresh() 的时候会调用这个方法&#xff1a;prepareBeanF…

扩展学习|结合故事的力量和数字的力量:混合方法研究和混合研究综述

文献来源&#xff1a;Pluye, Pierre, and Quan Nha Hong. "Combining the power of stories and the power of numbers: mixed methods research and mixed studies reviews." Annual review of public health 35 (2014): 29-45. 文献获取&#xff1a;链接&#xff1…

最靠谱线上线下相亲交友婚恋脱单渠道指南大全,单身必看!

刚好在30岁的年纪把自己嫁出去啦。以下这些都是我经历过的相亲途径&#xff0c;分享出来&#xff0c;希望能帮到大家 一.线上小程序/App 1.单身狗解救平台&#xff08;高质量人多&#xff0c;工作学历实名认证&#xff0c;你可能看到眼花&#xff0c;自己得有自己辨别力&#x…

<sa8650> snapdragon-auto-hqx-4-5-6-0基线代码camera开发错误记录

<sa8650> snapdragon-auto-hqx-4-5-6-0基线代码camera开发错误记录 一、 qcxserver自启动关不掉二、 qcxserver启动后串行器(MAX96717)detect不到?三、 qcarcam_test运行后系统log提示QCarCamReserve错误四、 tuning错误导致的异常DumpCore本文主要记录CAMERA开发过程中的一…

[ 项目 ] tcmalloc简化版—高并发内存池

目录 前言 基本介绍 高并发 内存池 定长内存池 基本介绍 框架设计 具体实现 性能测试 整体框架介绍 申请内存过程 threadcache 1.基本介绍 2.具体实现 centralcache 1.基本介绍 2.具体实现 pagecache 1.基本介绍 2.具体实现 申请内存连通 释放内存过…

探索智能编程新境界:我与Baidu Comate的独特体验之旅

文章目录 一、认识Baidu Comate二、VS Code安装Baidu Comate教程三、Baidu Comate功能体验功能概览具体功能1.根据注释自动生成代码2.函数注释3.行间注释4.代码解释5.生成单元测试6.代码优化7.答疑解惑 四、交互体验五、总结 一、认识Baidu Comate ✨Baidu Comate插件是一款基…

QT---day4事件

1、思维导图 2、 头文件 #ifndef MYWIDGET_H #define MYWIDGET_H #include <QWidget> #include<QIcon> //图标类 #include<QLabel> //标签类 #include<QMovie> //动图类 #include<QLineEdit> //行编辑器类 #include<QPushButton> //按钮…

阿里云开发uniapp之uni-starter

一、为什么使用uni-starter uni-starter是集成商用项目常见功能的、云端一体应用快速开发项目模版。 一个应用有很多通用的功能&#xff0c;比如登录注册、个人中心、设置、权限管理、拦截器、banner... uni-starter将这些功能都已经集成好&#xff0c;另外&#xff0c;uni-s…

Baidu Comate智能编码助手

Baidu Comate智能编码助手 &#x1f388;1.Baidu Comate的简介&#x1f388;2.安装Baidu Comate&#x1f388;3.Baidu Comate实现功能&#x1f388;4.使用注释进行智能代码提示&#x1f388;5.结束语 &#x1f388;1.Baidu Comate的简介 根据官网的介绍&#xff0c;我们了解到B…

力扣每日一题113:路径总和||

题目 中等 给你二叉树的根节点 root 和一个整数目标和 targetSum &#xff0c;找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。 叶子节点 是指没有子节点的节点。 示例 1&#xff1a; 输入&#xff1a;root [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSu…

完成单位投稿任务找投稿渠道不用精选10个1个就够了

在单位担任信息宣传员的这几年,我深刻体会到了“笔耕不辍”的艰辛与挑战。起初,面对单位的宣传需求,我遵循传统的投稿路径,即通过电子邮件的方式,一家接一家地向各大媒体投递稿件。那时的我,以为只要稿件质量上乘,自然能够获得青睐,却未曾料到,这是一条漫长而曲折的道路。 邮箱…

算法day03

第一题 179. 查找总价格为目标值的两个商品 本题采用前后指针和单调性规律可解&#xff1b; 解题思路如下&#xff1a; 1、设置前后指针 2、前后指针所指的两数之和大于目标数&#xff0c;右指针左移&#xff1b; 前后指针所指的两数之和小于目标数&#xff0c;左指针右移&…

“视频剪辑新境界:批量高效处理,画面虚化与播放速度调整一气呵成!“

在视频制作的广阔天地中&#xff0c;剪辑是赋予作品生命的关键环节。然而&#xff0c;面对大量的视频素材&#xff0c;如何高效地进行剪辑、调整&#xff0c;使每一帧画面都充满魅力&#xff0c;成为许多创作者面临的挑战。今天&#xff0c;我们为您带来一款颠覆性的视频剪辑工…

学习笔记:【QC】Android Q - IMS 模块

一、IMS init 流程图 高清的流程图参考&#xff1a;【高清图&#xff0c;保存后可以放大看】 二、IMS turnon 流程图 高清的流程图参考&#xff1a;【高清图&#xff0c;保存后可以放大看】 三、分析说明 1、nv702870 不创建ims apn pdp 2、nv702811 nv702811的时候才创建…

Objective-C的对象复制与拷贝选项

对象复制与拷贝 文章目录 对象复制与拷贝copy与mutablecopycopy与mutablecopy的简介示例&#xff1a;不可变对象的复制可变对象的复制 NSCopying和NSMutableCopying协议深复刻和浅复刻浅拷贝&#xff08;Shallow Copy&#xff09;&#xff1a;深拷贝&#xff08;Deep Copy&…

同步电机原理解析

同步电机 同步带年纪&#xff0c;顾名思义无论负载如何&#xff0c;都能以恒定的速度运转&#xff0c;它以高效率著称 这种恒速特性是通过恒定磁场和旋转磁场的相互作用实现的&#xff0c;与其他电机一样&#xff0c;同步电机由定子和转子组成&#xff0c;定子铁芯由硅片层叠而…

无人直播需要什么软件系统?最新AI实景自动无人直播软件:智能化引领直播拓客新时代

随着互联网的快速发展&#xff08;无人直播招商加盟&#xff1a;hzzxar&#xff09;直播行业已经成为商家品牌推广和商品销售的热门方式。近年来&#xff0c;人工智能技术的飞速发展&#xff0c;催生了一款令人惊叹的AI实景自动无人直播软件&#xff0c;为商家提供了全新的直播…