自己动手写Docker系列 -- 4.1使用busybox创建容器

flink集群(docker版)配置及使用 的启用、存储方式、存储位置,在应用代码中配置,其中存储方式、存储位置,也可以在flink-conf.yaml文件中通过state.backend、state.checkpoints.dir参数配置全局参数,但应用代码中配置优先级更高。(3) Flink Checkpoint是Flink自身的系统行为,用户无法对其进行交互,用户可以在程序启动之前,设置好实时程序Checkpoint相关参数,当程序启动之后,剩下的就全交给Flink自行管理。Checkpoint是增量做的,每次的时间较短,数据量较小。 阅读详情

简介

目前docker demo中还是使用的系统原有proc,不怎么纯净,本篇中使用busybox来更换docker demo的系统挂载点

源码说明

同时放到了Gitee和Github上,都可进行获取

本章节对应的版本标签是:4.1,防止后面代码过多,不好查看,可切换到标签版本进行查看

效果查看

下面是在没有修改代码前的我们的docker的挂载情况,可以看到非常的庞大,不纯净

➜  dockerDemo git:(main) ✗ ./main run -ti /bin/sh
{"level":"info","msg":"conmand all is /bin/sh","time":"2022-03-17T05:44:58+08:00"}
{"level":"info","msg":"memory cgroup path: /sys/fs/cgroup/memory/mydocker-cgroup","time":"2022-03-17T05:44:58+08:00"}
{"level":"info","msg":"memory cgroup path: /sys/fs/cgroup/memory/mydocker-cgroup","time":"2022-03-17T05:44:58+08:00"}
{"level":"info","msg":"parent process run","time":"2022-03-17T05:44:58+08:00"}
{"level":"info","msg":"init come on","time":"2022-03-17T05:44:58+08:00"}
{"level":"info","msg":"command: /bin/sh, args: [/bin/sh]","time":"2022-03-17T05:44:58+08:00"}
{"level":"info","msg":"RunContainerInitProcess command /bin/sh, args [/bin/sh]","time":"2022-03-17T05:44:58+08:00"}
{"level":"info","msg":"find path: /bin/sh","time":"2022-03-17T05:44:58+08:00"}
# pwd
/home/lw/code/go/dockerDemo
# ls -l
总用量 4668
drwxrwxr-x 2 lw lw    4096 3月  17 05:44 docs
drwxrwxr-x 3 lw lw    4096 3月   7 04:55 example
-rw-rw-r-- 1 lw lw     382 3月  12 10:18 go.mod
-rw-rw-r-- 1 lw lw    1965 3月  12 10:18 go.sum
-rw-rw-r-- 1 lw lw   11558 3月  12 10:18 LICENSE
-rwxrwxr-x 1 lw lw 4741951 3月  14 20:58 main
drwxrwxr-x 6 lw lw    4096 3月  12 10:20 mydocker
-rw-rw-r-- 1 lw lw     473 3月  12 10:18 README.md
# mount
/dev/sda2 on / type ext4 (rw,relatime,errors=remount-ro)
udev on /dev type devtmpfs (rw,nosuid,noexec,relatime,size=16103592k,nr_inodes=4025898,mode=755,inode64)
devpts on /dev/pts type devpts (rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000)
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev,inode64)
hugetlbfs on /dev/hugepages type hugetlbfs (rw,relatime,pagesize=2M)
mqueue on /dev/mqueue type mqueue (rw,nosuid,nodev,noexec,relatime)
tmpfs on /run type tmpfs (rw,nosuid,nodev,noexec,relatime,size=3227448k,mode=755,inode64)
tmpfs on /run/lock type tmpfs (rw,nosuid,nodev,noexec,relatime,size=5120k,inode64)
tmpfs on /run/user/125 type tmpfs (rw,nosuid,nodev,relatime,size=3227444k,mode=700,uid=125,gid=130,inode64)
gvfsd-fuse on /run/user/125/gvfs type fuse.gvfsd-fuse (rw,nosuid,nodev,relatime,user_id=125,group_id=130)
tmpfs on /run/user/0 type tmpfs (rw,nosuid,nodev,relatime,size=3227444k,mode=700,inode64)
gvfsd-fuse on /run/user/0/gvfs type fuse.gvfsd-fuse (rw,nosuid,nodev,relatime,user_id=0,group_id=0)
nsfs on /run/docker/netns/d503d5c5cda8 type nsfs (rw)
sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime)
securityfs on /sys/kernel/security type securityfs (rw,nosuid,nodev,noexec,relatime)
tmpfs on /sys/fs/cgroup type tmpfs (ro,nosuid,nodev,noexec,mode=755,inode64)
cgroup2 on /sys/fs/cgroup/unified type cgroup2 (rw,nosuid,nodev,noexec,relatime,nsdelegate)
cgroup on /sys/fs/cgroup/systemd type cgroup (rw,nosuid,nodev,noexec,relatime,xattr,name=systemd)
cgroup on /sys/fs/cgroup/net_cls,net_prio type cgroup (rw,nosuid,nodev,noexec,relatime,net_cls,net_prio)
cgroup on /sys/fs/cgroup/pids type cgroup (rw,nosuid,nodev,noexec,relatime,pids)
cgroup on /sys/fs/cgroup/cpuset type cgroup (rw,nosuid,nodev,noexec,relatime,cpuset)
cgroup on /sys/fs/cgroup/cpu,cpuacct type cgroup (rw,nosuid,nodev,noexec,relatime,cpu,cpuacct)
cgroup on /sys/fs/cgroup/rdma type cgroup (rw,nosuid,nodev,noexec,relatime,rdma)
cgroup on /sys/fs/cgroup/misc type cgroup (rw,nosuid,nodev,noexec,relatime,misc)
cgroup on /sys/fs/cgroup/perf_event type cgroup (rw,nosuid,nodev,noexec,relatime,perf_event)
cgroup on /sys/fs/cgroup/blkio type cgroup (rw,nosuid,nodev,noexec,relatime,blkio)
cgroup on /sys/fs/cgroup/hugetlb type cgroup (rw,nosuid,nodev,noexec,relatime,hugetlb)
cgroup on /sys/fs/cgroup/memory type cgroup (rw,nosuid,nodev,noexec,relatime,memory)
cgroup on /sys/fs/cgroup/devices type cgroup (rw,nosuid,nodev,noexec,relatime,devices)
cgroup on /sys/fs/cgroup/freezer type cgroup (rw,nosuid,nodev,noexec,relatime,freezer)
pstore on /sys/fs/pstore type pstore (rw,nosuid,nodev,noexec,relatime)
efivarfs on /sys/firmware/efi/efivars type efivarfs (rw,nosuid,nodev,noexec,relatime)
none on /sys/fs/bpf type bpf (rw,nosuid,nodev,noexec,relatime,mode=700)
debugfs on /sys/kernel/debug type debugfs (rw,nosuid,nodev,noexec,relatime)
tracefs on /sys/kernel/tracing type tracefs (rw,nosuid,nodev,noexec,relatime)
fusectl on /sys/fs/fuse/connections type fusectl (rw,nosuid,nodev,noexec,relatime)
configfs on /sys/kernel/config type configfs (rw,nosuid,nodev,noexec,relatime)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
systemd-1 on /proc/sys/fs/binfmt_misc type autofs (rw,relatime,fd=28,pgrp=0,timeout=0,minproto=5,maxproto=5,direct,pipe_ino=26120)
/var/lib/snapd/snaps/core20_1361.snap on /snap/core20/1361 type squashfs (ro,nodev,relatime,x-gdu.hide)
/var/lib/snapd/snaps/bare_5.snap on /snap/bare/5 type squashfs (ro,nodev,relatime,x-gdu.hide)
/var/lib/snapd/snaps/gnome-3-38-2004_99.snap on /snap/gnome-3-38-2004/99 type squashfs (ro,nodev,relatime,x-gdu.hide)
/var/lib/snapd/snaps/gtk-common-themes_1519.snap on /snap/gtk-common-themes/1519 type squashfs (ro,nodev,relatime,x-gdu.hide)
/var/lib/snapd/snaps/snapd_14978.snap on /snap/snapd/14978 type squashfs (ro,nodev,relatime,x-gdu.hide)
/var/lib/snapd/snaps/snap-store_558.snap on /snap/snap-store/558 type squashfs (ro,nodev,relatime,x-gdu.hide)
/var/lib/snapd/snaps/core20_1376.snap on /snap/core20/1376 type squashfs (ro,nodev,relatime,x-gdu.hide)
/dev/nvme0n1p1 on /boot/efi type vfat (rw,relatime,fmask=0077,dmask=0077,codepage=437,iocharset=iso8859-1,shortname=mixed,errors=remount-ro)
/var/lib/snapd/snaps/snapd_15177.snap on /snap/snapd/15177 type squashfs (ro,nodev,relatime,x-gdu.hide)
overlay on /var/lib/docker/overlay2/d50aa7883be1a9bfc50a2519093575713c356885fd916d5973793492bb8d2d07/merged type overlay (rw,relatime,lowerdir=/var/lib/docker/overlay2/l/6DRQTGKE2LPQHTVVITKND2RW3J:/var/lib/docker/overlay2/l/YESCAXPAOBR6LE7TQHTNL3OF4Y,upperdir=/var/lib/docker/overlay2/d50aa7883be1a9bfc50a2519093575713c356885fd916d5973793492bb8d2d07/diff,workdir=/var/lib/docker/overlay2/d50aa7883be1a9bfc50a2519093575713c356885fd916d5973793492bb8d2d07/work)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)

下面是跟着书中写的,使用busybox作为挂载点,创建容器,可以看到比较纯净了

➜  busybox git:(main) ✗ ./main run -ti /bin/sh
{"level":"info","msg":"memory cgroup path: /sys/fs/cgroup/memory/mydocker-cgroup","time":"2022-03-17T06:17:48+08:00"}
{"level":"info","msg":"memory cgroup path: /sys/fs/cgroup/memory/mydocker-cgroup","time":"2022-03-17T06:17:48+08:00"}
{"level":"info","msg":"all command is : /bin/sh","time":"2022-03-17T06:17:48+08:00"}
{"level":"info","msg":"parent process run","time":"2022-03-17T06:17:48+08:00"}
{"level":"info","msg":"init come on","time":"2022-03-17T06:17:48+08:00"}
{"level":"info","msg":"current location: /home/lw/code/go/dockerDemo/busybox","time":"2022-03-17T06:17:48+08:00"}
{"level":"info","msg":"find path: /bin/sh","time":"2022-03-17T06:17:48+08:00"}
/ # ls
bin   dev   etc   home  main  proc  root  sys   tmp   usr   var
/ # mount
/dev/sda2 on / type ext4 (rw,relatime,errors=remount-ro)
proc on /proc type proc (rw,nosuid,nodev,noexec,relatime)
/ #

环境依赖准备

使用busybox需要做一些准备工作:

  1. 安装docker
  2. 需要拉取busybox的docker 镜像,打包后解压以备使用

安装docker

需要在机器上安装docker,Ubuntu20可以参考:https://docs.docker.com/engine/install/ubuntu/

咔咔咔一顿敲命令就行了,这里就不再赘述了

拉取busybox的docker 镜像,打包后解压以备使用

操作过程的命令如下,照着运行即可

docker pull busybox

// 可以看到busybox才2M不到,真小
➜  dockerDemo git:(main) ✗ docker images
REPOSITORY    TAG       IMAGE ID       CREATED        SIZE
busybox       latest    2fb6fc2d97e1   5 days ago     1.24MB
hello-world   latest    feb5d9fea6a5   5 months ago   13.3kB

// 后台运行起来
➜  dockerDemo git:(main) ✗ docker run -d busybox top -b
29148027fac463baa870831bcbc4dcaea48d5f2253ebd95118b8c65136017021
➜  dockerDemo git:(main) ✗ docker ps
CONTAINER ID   IMAGE     COMMAND    CREATED          STATUS          PORTS     NAMES
29148027fac4   busybox   "top -b"   15 seconds ago   Up 15 seconds             loving_edison

// 打包运行的镜像,创建目录,解压到指定目录中
➜  dockerDemo git:(main) ✗ docker export -o /home/lw/Downloads/busybox.tar 29148027fac4
➜  dockerDemo git:(main) ✗ mkdir /opt/busybox
➜  dockerDemo git:(main) ✗ tar -xvf /home/lw/Downloads/busybox.tar -C /opt/busybox/

// 可以看到和系统根目录还挺像
➜  dockerDemo git:(main) ✗ ls /opt/busybox
bin  dev  etc  home  proc  root  sys  tmp  usr  var

这样,准备工作就完成了

代码编写

本篇中代码比较少,就修改一个init文件即可

pivot_root是一个重要的概念,可以参考书中描述和后面参考链接的一篇博客

照抄书中的代码跑不动,需要结合博客一起

pivot_root是一个系统调用,主要功能是去改变当前的root文件系统。
pivot_root可以将当前进程的root文件系统移动到put_old文件夹中,然后使new_root成为新的root 文件系统。
new_root 和put_old必须不能同时存在当前root 的同一个文件系统中。
pivot_root和chroot的主要区别是,pivot_root是把整个系统切换到一个新的root目录,而移除对之前root文件系统的依赖,这样你就能够umount原先的root文件系统。
而chroot是针对某个进程,系统的其他部分依旧运行于老的root目录中。

实现代码如下:

func RunContainerInitProcess() error {
	// 用setupMount代替原来的相关挂载操作
	if err := setUpMount(); err != nil {
		return err
	}

	cmdArray := readUserCommand()
	path, err := exec.LookPath(cmdArray[0])
	if err != nil {
		log.Errorf("can't find exec path: %s %v", cmdArray[0], err)
		return err
	}
	log.Infof("find path: %s", path)
	if err := syscall.Exec(path, cmdArray, os.Environ()); err != nil {
		log.Errorf("syscall exec err: %v", err.Error())
	}
	return nil
}

// 初始化挂载点
func setUpMount() error {
	// 首先设置根目录为私有模式,防止影响pivot_root,这一步是书中没有的,但没有运行不起来
	if err := syscall.Mount("/", "/", "", syscall.MS_REC|syscall.MS_PRIVATE, ""); err != nil {
		return fmt.Errorf("setUpMount Mount proc err: %v", err)
	}

	// 获取当前路径
	pwd, err := os.Getwd()
	if err != nil {
		return fmt.Errorf("get current location err: %v", err)
	}
	log.Infof("current location: %s", pwd)

	err = privotRoot(pwd)
	if err != nil {
		return err
	}

	// mount proc
	defaultMountFlags := syscall.MS_NOEXEC | syscall.MS_NOSUID | syscall.MS_NODEV
	err = syscall.Mount("proc", "/proc", "proc", uintptr(defaultMountFlags), "")
	if err != nil {
		log.Errorf("proc挂载 failed: %v", err)
		return err
	}
	syscall.Mount("tmpfs", "/dev", "tempfs", syscall.MS_NOSUID|syscall.MS_STRICTATIME, "mode=755")
	return nil
}

func privotRoot(root string) error {
	// 为了使当前root的老root和新root不在同一个文件系统下,我们把root重新mount一次
	// bind mount 是把相同的内容换了一个挂载点的挂载方法
	if err := syscall.Mount(root, root, "bind", syscall.MS_BIND|syscall.MS_REC, ""); err != nil {
		return fmt.Errorf("mount rootfs to itself error: %v", err)
	}

	// 创建 rootfs、.pivot_root 存储 old_root
	pivotDir := filepath.Join(root, ".pivot_root")
	// 判断当前目录是否已有该文件夹
	if _, err := os.Stat(pivotDir); err == nil {
		// 存在则删除
		if err := os.Remove(pivotDir); err != nil {
			return err
		}
	}
	if err := os.Mkdir(pivotDir, 0777); err != nil {
		return fmt.Errorf("mkdir of pivot_root err: %v", err)
	}

	// pivot_root 到新的rootfs,老的old_root现在挂载在rootfs/.pivot_root上
	// 挂载点目前依然可以在mount命令中看到
	if err := syscall.PivotRoot(root, pivotDir); err != nil {
		return fmt.Errorf("pivot_root err: %v", err)
	}

	// 修改当前工作目录到跟目录
	if err := syscall.Chdir("/"); err != nil {
		return fmt.Errorf("chdir root err: %v", err)
	}

	// 取消临时文件.pivot_root的挂载并删除它
	// 注意当前已经在根目录下,所以临时文件的目录也改变了
	pivotDir = filepath.Join("/", ".pivot_root")
	if err := syscall.Unmount(pivotDir, syscall.MNT_DETACH); err != nil {
		return fmt.Errorf("unmount pivot_root dir err: %v", err)
	}
	return os.Remove(pivotDir)
}

编写完成后,还有重要的一步:记得运行程序的当前目录要在busybox下

因为我们代码中需要挂载 /proc,如果在其他目录下,那是挂载不了这个的,但 busybox里面有这个目录

参考链接

Docker基础教程(157)操作系统之BusyBox(发行版):Docker迷你王国:BusyBox,小巧却强大的Linux瑞士军刀! 在这个追求轻量化的时代,Docker世界的BusyBox镜像以其不足5MB的娇小身材,却提供了百余种常用Linux工具,成为了嵌入式系统和容器化应用的理想选择。BusyBox,这个被称为“嵌入式Linux的瑞士军刀”的精简工具箱,虽然只有不到2MB的大小,却集成了一百多个最常用的Linux命令。在Docker早期,官方为了压缩容量,保证容器的快速启用,都使用BusyBox作为基础镜像。后来虽然转向Alpine,但BusyBox仍然是资源受限环境的首选。 阅读详情

相关推荐

Docker 使用全过程的教程来了,快快来一起掌握住它

Docker-compose 是用于定义和运行多容器的docker 应用程序的工具。通过compose 可以使用YAML文件 来配置应用程序的服务。使用Dockerfile 定义应用程序的环境,以便可以在任何地方复制它。2.在docker-compose.yml中定义组成应用程序的服务,以便它们可以在隔离的环境中一起运行。3.运行docker-compose up 然后Compose启动并运行你的整个应用程序。

野路子云遇见不同的自己 580

Docker 的 Busybox 操作系统镜像

BusyBox是一个遵循GPL协议、以自由软件形式发行的应用程序。Busybox在单一的可执行文件中提供了精简的Unix工具集,可运行于多款POSIX环境的操作系统,例如Linux(包括Android)、Hurd、FreeBSD等等。由于BusyBox可执行文件的文件比较小,使得它非常适合使用于嵌入式系统。作者将BusyBox称为“嵌入式Linux的瑞士军刀”。

HONEY MOOSE 4374

Obsidian笔记同步实战:基于Git的私有化部署与自动化管理

本文详细介绍了如何利用Git为Obsidian笔记构建私有化、自动化且免费的同步方案。通过安装配置Git与Obsidian-git插件,结合Gitee等远程仓库,实现笔记的版本管理、多设备同步与自动备份,打造安全可靠的知识管理体系。

y7z8a的博客 272

docker 工具 busybox

1. 获取镜像 busybox是一个聚成了一百多个最常用linux命令和工具的软件工具箱,它在单一的可执行文件中提供了精简的Unix工具集。BusyBox可运行于多款POSIX环境的操作系统中,如 Linux(包括Android),hurd,freebsa等 busybox既包含了一些简单实用工具,如cat 和 echo ,也包含了一些更大,更复杂的工具,如 grep ,find ,mount 以及telnet. 实用官方镜像 [root@ybsrv1 ~]# docker search busybox

m0_67391683的博客 4845

SVG绘制圆环进度条

在我们的大屏可视化项目中,经常会用到各种各样的图表。与传统的表格展示、枯燥的文字阐述相比,图表展示则使用户看起来更加直观、数据的展示则更加一目了然。本文基于svg绘图技术结合前端技术栈vue,以工作中常用的环形进度条为例,简单阐述一下绘制进度条的一些思路。............

qq_40289557的博客 8358

【SoloPi】SoloPi使用2-功能使用,录制回放

Soloπ是什么 Soloπ是一个无线化、非侵入式的Android自动化工具,公测版拥有录制回放、性能测试、一机多控三项主要功能,能为测试开发人员节省宝贵时间。 录制回放功能 Soloπ拥有录制操作的能力,用户只需要通过Soloπ执行用例步骤,Soloπ就能够将用户的操作记录下来,并且支持在各个设备上进行回放,这一切都能够在手机上独立完成。 ...

q_Catherine的博客 5827

自己动手写 Docker 系列文章总览

本文章系列起源于:《自己动手写 Docker》,编程实践方得真知,虽然大部分代码书中都有,但还是遇到了不少困难,下面是对于自己写的 Docker Demo 的总览

github_35735591的博客 2268

使用moveit!控制真实机械臂(5)——编写真实机械臂节点中的action服务程序

上一篇文章中,我们简要介绍了ROS中action的基本知识,为了控制真实机械臂,我们已经修改了moveit配置文件,使得moveti启动后具备一个control_msgs::FollowJointTrajectoryAction类型的action客户端,接下来,我们完成该类型action的另一半,编写C++程序来实现action的服务端。由于底层机器人控制程序一般差别都很大,这里展示的只是编程要点...

爱学习的草莓熊 1万+

docker创建busybox

1. busybox是什么 BusyBox 是一个集成了三百多个最常用Linux命令和工具的软件。BusyBox 包含了一些简单的工具,例如ls、cat和echo等等,还包含了一些更大、更复杂的工具,例grep、find、mount以及telnet。有些人将 BusyBox 称为 Linux 工具里瑞士军刀。简单的说BusyBox就好像是个大工具箱,它集成压缩了 Linux 的许多工具和命令,也...

说好的今晚不吃饭的博客 6110

MIKE21桥墩模拟实战:抠网格与构筑物法对比与选型指南

本文详细对比了MIKE21软件中抠网格法与构筑物法在桥墩模拟中的应用,包括操作步骤、适用场景及优缺点分析。通过实际案例数据展示两种方法的精度与效率差异,并提供选型决策树和常见问题解决方案,帮助工程师根据项目需求选择最优模拟方法。

weixin_42656416的博客 322

抖音私信卡片私信名片的原理分析

简单说一下它的功能吧:抖音私信卡片,解决了客户封号严重、引流效率低的痛点,所以从去年到现在,依然是热销品。"抖音快手私信名片链接跳转"是2022年抖音快手引流最新技术,可以生成卡片链接,支持标题、描述、logo以及跳转落地页的完全自定义配置.支持微信公众号和微信号复制唤起微信客户端app添加,同时也支持任意链接落地页跳转提高粉丝引流转化率,关注转化率,引流转化率,安全绿色私信卡片功能1、跳转微信用户点击卡片,自动跳转微信界面,显示好友和群聊二维码2、跳转链接用户点击卡片,自动跳转到指定链接,支持任意链接。3

m0_71385839的博客 5189

BUSYBOX Docker 容器化部署指南

BusyBox是一款集成了众多UNIX工具的嵌入式Linux实用程序集合,被誉为"嵌入式Linux的瑞士军刀"。它将常见的UNIX命令(如ls、cp、mv、sh等)整合到单个可执行文件中,体积小巧(通常在1-5MB之间,具体取决于变体),非常适合构建空间高效的容器镜像和嵌入式系统。

java_logo的专栏 1307

2025数学建模国赛A题1-4问详解(论文+完整代码)

本文介绍了数学建模国赛A题的解题思路,重点分析了三维遮蔽模型的建立和运动学代码实现。相比第一题,第二题增加了未知参数求解,需要采用遗传算法等非线性优化方法。文章强调该模型由专业团队原创开发,代码可运行,并提醒参赛者警惕市场上的保奖班现象。整体内容聚焦于竞赛解题技巧和原创性保证。

Eloveeeee的博客 2797

极速掌控Docker全链路:容器操控+Nginx主页改造+BusyBox工具实践+腾讯云仓库部署​

本文围绕Docker实操展开,介绍docker ps容器命令用法,涵盖Nginx镜像获取、运行及主页修改,阐述BusyBox工具特性、安装卸载与运行,还涉及镜像拉取推送至Hub及腾讯云仓库的创建、操作,包含丰富实践案例。

羑悻的博客. 8958

数据分析!Python爬虫爬取B站UP主数据并分析涨粉规律(附可视化图表)

爬取更多UP主:扩充列表,增加需要分析的UP主UID数量爬取更多作品:修改的参数,增加每个UP主的作品爬取页数新增分析维度:在类中添加方法,可分析发布时间(如定时发布对涨粉的影响)、内容标签(如游戏/知识区涨粉差异)优化可视化样式:调整方法中的图表类型、颜色、标题等,适配个人展示需求播放量与粉丝数强正相关:从相关性热力图可看出,总播放量与粉丝数的相关系数通常在0.8以上,说明曝光量是涨粉的核心基础作品数量存在“边际效应”

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 1225

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

自己动手写一个仿Docker虚拟容器

自己动手写一个仿Docker虚拟容器 本项目参照书籍《自己动手写Docker》 作者:陈显鹭(花名:遥鹭)-阿里云高级研发工程师等 项目地址:https://gitee.com/ShengHua666/can 项目环境:Linux 虚拟机 Ubuntu20.04 内核5.10.x,Go 1.17.1 项目运行: go mod init Bocker go mod tidy go build mydocker/main.go mv main can cp can /bin/ mv busybox.tar

huahua66123的博客 1343

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

Docker容器中使用Busybox工具箱

Busybox提供linux常用的命令 例如ping、cat、wget、telnet、nc、nslookup、traceroute等,可以满足日常工作几乎所有测试需求。 常用操作 # 拉取docker镜像 docker pull busybox # 运行busybox docker run -it --name mybusybox busybox:latest sh # 启动busybox docker start mybusybox # 进入容器内部 docker exec -it mybusyb

搬山境KL攻城狮的修炼手册 6882

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

自己动手写Docker

小编分享 《自己动手写Docker》在详细分析Docker所依赖的技术栈的基础上,一步一步地通过代码实例,让读者可以自己循序渐进地用Go语言构建出一个容器的引擎。不同于其他Docker原理介绍或代码剖析的书籍,《自己动手写Docker》旨在提供给读者一条动手路线,一步一步地实现Docker的隔离性,构建Docker的镜像、容器的生命周期及Docker的网络等。《自己动手写Docker》涉及的代码都托管在GitHub上,读者可以对照书中的步骤从代码层面学习构建流程,从而精通整个容器技术栈。《自己动手写D

fatfatearth的博客 2917

自己动手写Docker系列 -- 4.2使用AUFS包装busybox

在上篇中实现了使用宿主机busybox目录作为文件的根目录,但在容器内的对文件的操作仍会影响到宿主机的目录,本篇中实现进一步的容器和镜像隔离

github_35735591的博客 432

Docker在windows下使用教程,通过Dockerfile创建镜像/容器,以YOLO系列为例

通过可视化界面将极大的降低学习难度。

m0_57847261的博客 1万+

Docker教程小白实操入门(1)--如何创建容器

一、Docker Docker是一种管理容器的技术,可以用来创建、启动、停止和删除容器。 二、安装Docker 参考https://blog.csdn.net/jinking01/article/details/82490688 三、镜像 一个打包了运行环境的特殊文件,它包含了容器启动运行所需的所有信息,包括运行程序和配置数据等。镜像不包含任何动态数据,其内容在构建之后也不会改变。 例如,一个官方的Ubuntu14.04镜像,就包含了一套完整的Ubuntu14.04最小系统的ro..

软件工程小施同学 的专栏 3万+

Docker实战09|使用AUFS包装busybox

以上三篇主要实现了。接下来的时间会和大家一起学习Docker是如何构造镜像的。

程序员溪昂 1205

自己动手写docker-4

4.构造镜像 示例代码(更新到4.2) 4.1 使用busybox基本镜像构造容器 docker export -o busybox.tar c5a45bda498e(容器id) 可以起一个busybox的后台运行容器,通过export导出文件系统,查看下结构 pivot_root系统调用,用于改变root文件系统 int pivot_root(const char *new_root, c...

weixin_33923148的博客 255

从零开始写 Docker(四)---使用 pivotRoot 切换 rootfs 实现文件系统隔离

前面几节中,我们通过Namespace和Cgroups技术创建了一个简单的容器,实现了视图隔离和资源限制。但是大家应该可以发现,容器内的目录还是当前运行程序的宿主机目录,而且如果运行一下 mount 命令可以看到继承自父进程的所有挂载点。这貌似和平常使用的容器表现不同因为这里缺少了镜像这么一个重要的特性。Docker 镜像可以说是一项伟大的创举,它使得容器传递和迁移更加简单,那么这一节会做一个简单的镜像,让容器跑在有镜像的环境中。本章会为我们切换容器的 rootfs,以实现文件系统的隔离。

探索云原生 1321

docker 拉取镜像、创建并启动容器

获取镜像 默认情况下,使用docker pull命令,会从官方的Docker Hub库中将镜像拉取到本地。 首先介绍这条命令的格式: docker pull [OPTIONS] <仓库名>:<标签> 其中, docker pull:Docker拉取镜像的命令关键词; [OPTIONS]:命令选项; 仓库名:仓库名的格式一般为<用户名>/<软件名>。对于Docker Hub,如果不指定用户名,则默认为library,即官方镜像; 标签:标签是区分镜像不同版本的一

weixin_47271830的博客 1万+

CentOS下使用busybox

  busybox被称为嵌入式linux的瑞士军刀,这句话是在busybox自己介绍自己的时候提出的(The Swiss Army Knife of Embedded Linux)。busybox整合了很多小的unix下的通用功能到一个小的可执行文件之中,简单来说在unix或者linux下常用的那些功能在这里你都能找到,但是为了busybox的目标:嵌入式的linux,大小对于busyb...

一劍傾城 4518
上一篇: 自己动手写Docker系列 -- 3.3使用命令管道优化参数传递
下一篇: 自己动手写Docker系列 -- 4.2使用AUFS包装busybox
_萧_
博客等级 码龄10年 55粉丝 157原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值