栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

容器 export和import tar rootfs 自己做跟rootfs作为容器base

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

容器 export和import tar rootfs 自己做跟rootfs作为容器base

Docker容器运行已经不是简单的通过Docker daemon来启动,而是集成了containerd、runC等多个组件。Docker服务启动之后,我们也可以看见系统上启动了dockerd、docker-containerd等进程,本文主要介绍新版Docker(1.11以后)每个部分的功能和作用。

 

下面就来介绍下独立分拆出来的其他几个模块。

Containerd  
containerd是容器技术标准化之后的产物,为了能够兼容OCI标准,将容器运行时及其管理功能从Docker Daemon剥离。理论上,即使不运行dockerd,也能够直接通过containerd来管理容器。(当然,containerd本身也只是一个守护进程,容器的实际运行时由后面介绍的runC控制。)

最近,Docker刚刚宣布开源containerd。从其项目介绍页面可以看出,containerd主要职责是镜像管理(镜像、元信息等)、容器执行(调用最终运行时组件执行)。

 

containerd向上为Docker Daemon提供了gRPC接口,使得Docker Daemon屏蔽下面的结构变化,确保原有接口向下兼容。向下通过containerd-shim结合runC,使得引擎可以独立升级,避免之前Docker Daemon升级会导致所有容器不可用的问题。

Docker、containerd和containerd-shim之间的关系,可以通过启动一个Docker容器,观察进程之间的关联。首先启动一个容器,
 

[root@jettoloader k3s-ansible-master]# yum install psmisc
[root@jettoloader k3s-ansible-master]# ps -ef | grep docker
root     30589     1  0  2021 ?        02:30:19 /usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock --cluster-store consul://172.16.10.21:8500 --cluster-advertise 172.16.10.21:2375

pid=30589

[root@jettoloader k3s-ansible-master]# pstree -l -a -A 30589
dockerd -H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock --cluster-store consul://172.16.10.21:8500 --cluster-advertise 172.16.10.21:2375
  |-containerd --config /var/run/docker/containerd/containerd.toml --log-level info
  |   |-containerd-shim -namespace moby -workdir /var/lib/docker/containerd/daemon/io.containerd.runtime.v1.linux/moby/304fdae4c7094db09a646a95b85917ae05582491d762d6edd29f986e7b6c324a -address /var/run/docker/containerd/containerd.sock -containerd-binary /usr/bin/containerd -runtime-root /var/run/docker/runtime-runc
  |   |   |-tini -- /entrypoint.sh
  |   |   |   `-entrypoint.sh /entrypoint.sh
  |   |   |       |-sleep 1
  |   |   |       |-start_hbase.sh /opt/bin/start_hbase.sh
  |   |   |       |   `-java -Dproc_master -XX:onOutOfMemoryError=kill -9 %p -XX:+UseConcMarkSweepGC -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:PermSize=128m -XX:MaxPermSize=128m -XX:ReservedCodeCacheSize=256m -Dhbase.log.dir=/opt/hbase/bin/../logs -Dhbase.log.file=hbase.log -Dhbase.home.dir=/opt/hbase/bin/.. -Dhbase.id.str= -Dhbase.root.logger=INFO,console -Dhbase.security.logger=INFO,RFAS org.apache.hadoop.hbase.master.HMaster start
  |   |   |       |       `-235*[{java}]
  |   |   |       `-start_opentsdb. /opt/bin/start_opentsdb.sh
  |   |   |           `-java -XX:+UseConcMarkSweepGC -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -enableassertions -enablesystemassertions -classpath /usr/local/share/opentsdb/*.jar:/usr/local/share/opentsdb:/usr/local/share/opentsdb/bin:/usr/local/share/opentsdb/lib/asm-4.0.jar:/usr/local/share/opentsdb/lib/async-1.4.0.jar:/usr/local/share/opentsdb/lib/asynchbase-1.8.2.jar:/usr/local/share/opentsdb/lib/commons-jexl-2.1.1.jar:/usr/local/share/opentsdb/lib/commons-logging-1.1.1.jar:/usr/local/share/opentsdb/lib/commons-math3-3.4.1.jar:/usr/local/share/opentsdb/lib/guava-18.0.jar:/usr/local/share/opentsdb/lib/jackson-annotations-2.9.5.jar:/usr/local/share/opentsdb/lib/jackson-core-2.9.5.jar:/usr/local/share/opentsdb/lib/jackson-databind-2.9.5.jar:/usr/local/share/opentsdb/lib/javacc-6.1.2.jar:/usr/local/share/opentsdb/lib/jgrapht-core-0.9.1.jar:/usr/local/share/opentsdb/lib/kryo-2.21.1.jar:/usr/local/share/opentsdb/lib/log4j-over-slf4j-1.7.7.jar:/usr/local/share/opentsdb/lib/logback-classic-1.0.13.jar:/usr/local/share/opentsdb/lib/logback-core-1.0.13.jar:/usr/local/share/opentsdb/lib/minlog-1.2.jar:/usr/local/share/opentsdb/lib/netty-3.10.6.Final.jar:/usr/local/share/opentsdb/lib/protobuf-java-2.5.0.jar:/usr/local/share/opentsdb/lib/reflectasm-1.07-shaded.jar:/usr/local/share/opentsdb/lib/slf4j-api-1.7.7.jar:/usr/local/share/opentsdb/lib/tsdb-2.4.0.jar:/usr/local/share/opentsdb/lib/zookeeper-3.4.6.jar:/etc/opentsdb net.opentsdb.tools.TSDMain --port=4242 --staticroot=/usr/local/share/opentsdb/static --cachedir=/tmp --auto-metric
  |   |   |               `-41*[{java}]
  |   |   `-9*[{containerd-shim}]
  |   `-15*[{containerd}]
  |-docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 4242 -container-ip 172.17.0.2 -container-port 4242
  |   `-7*[{docker-proxy}]
  `-15*[{dockerd}]

虽然pstree命令截断了命令,但我们还是能够看出,当Docker daemon启动之后,dockerd和docker-containerd进程一直存在。当启动容器之后,docker-containerd进程(也是这里介绍的containerd组件)会创建docker-containerd-shim进程,其中的参数304fdae4c7094db09a646a95b85917ae05582491d762d6edd29f986e7b6c324a就是要启动容器的id。最后docker-containerd-shim子进程,已经是实际在容器中运行的进程(既sleep 1000)。

docker-containerd-shim另一个参数,是一个和容器相关的目录[root@jettoloader k3s-ansible-master]# ls -al /var/run/docker/containerd/304fdae4c7094db09a646a95b85917ae05582491d762d6edd29f986e7b6c324a/,里面的内容有:

[root@jettoloader k3s-ansible-master]# ls -al /var/run/docker/containerd/304fdae4c7094db09a646a95b85917ae05582491d762d6edd29f986e7b6c324a/
total 4
drwxr-xr-x 2 root root  100 Jan 17 15:15 .
drwx------ 4 root root  160 Nov 15 17:09 ..
prwx------ 1 root root    0 Jan 17 15:54 init-stderr
prwx------ 1 root root    0 Nov 15 17:10 init-stdout
-rw------- 1 root root 4096 Jan 17 15:15 .init-stdout.sw

其中包括了容器配置和标准输入、标准输出、标准错误三个管道文件。

RunC  
OCI定义了容器运行时标准,runC是Docker按照开放容器格式标准(OCF, Open Container Format)制定的一种具体实现。

runC是从Docker的libcontainer中迁移而来的,实现了容器启停、资源隔离等功能。Docker默认提供了docker-runc实现,事实上,通过containerd的封装,可以在Docker Daemon启动的时候指定runc的实现。

我们可以通过启动Docker Daemon时增加--add-runtime参数来选择其他的runC现。下面就让我们看下这几个模块如何工作。

容器导出到rootfs, 此时,标准包所需的容器数据已经准备完毕,接下来我们需要创建配置文件:

[root@jettoloader aaa]# mkdir rootfs 
[root@jettoloader aaa]# docker export $(docker create petergrace/opentsdb-docker:latest) | tar -C rootfs -xvf -

[root@jettoloader aaa]# ls rootfs/
bin  data  dev  entrypoint.sh  etc  home  lib  media  mnt  opentsdb-plugins  opt  proc  root  run  sbin  srv  sys  tini  tmp  usr  var

此时会生成一个名为config.json的配置文件,该文件和Docker容器的配置文件类似,主要包含容器挂载信息、平台信息、进程信息等容器启动依赖的所有数据。

最后,可以通过runc命令来启动容器:

[root@jettoloader aaa]# runc spec

[root@jettoloader aaa]# ls
config.json  rootfs

最后,可以通过runc命令来启动容器,执行之后,我们可以看见容器已经启动:

[root@jettoloader aaa]# runc run busybox
/ # ps aux
PID   USER     TIME  COMMAND
    1 root      0:00 sh
    8 root      0:00 ps aux


[root@jettoloader k3s-ansible-master]# runc list
ID          PID         STATUS      BUNDLE           CREATED                          OWNER
busybox     26539       running     /root/work/aaa   2022-01-17T07:50:18.917471987Z   root

注意,runc必须使用root权限启动。

此时,事实上已经可以不依赖Docker本身,如果系统上安装了runc包,即可运行容器。

当然,也可以使用docker-runc命令来启动容器:

从这里可以看到标准化的重要性。

总结  

从Docker 1.11之后,Docker Daemon被分成了多个模块以适应OCI标准。拆分之后,结构分成了以下几个部分。

 

其中,containerd独立负责容器运行时和生命周期(如创建、启动、停止、中止、信号处理、删除等),其他一些如镜像构建、卷管理、日志等由Docker Daemon的其他模块处理。

Docker的模块块拥抱了开放标准,希望通过OCI的标准化,容器技术能够有很快的发展。

导入

从网络地址导入

docker import https://example.com/container.tar

从本地导入

docker import /path/to/exampleContainer.tgz

基于当前系统制作docker镜像

1:通过tar 备份目录
tar -cvpf /home/exampleContainer.tar --directory=/ --exclude=proc --exclude=sys --exclude=dev --exclude=run /


2:导入镜像
cat exampleContainer.tar | docker import - exampleContainer

1.export命令导出的tar文件略小于save命令导出的

2.export命令是从容器(container)中导出tar文件,而save命令则是从镜像(images)中导出
3.基于第二点,export导出的文件再import回去时,无法保留镜像所有历史(即每一层layer信息,不熟悉的可以去看Dockerfile),不能进行回滚操作;而save是依据镜像来的,所以导入时可以完整保留下每一层layer信息。如下图所示,nginx:latest是save导出load导入的,nginx:imp是export导出import导入的。

建议

可以依据具体使用场景来选择命令

若是只想备份images,使用save、load即可若是在启动容器后,容器内容有变化,需要备份,则使用export、import

Docker、Containerd、RunC...:你应该知道的所有_高效开发运维的博客-CSDN博客

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/705806.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号