这是关于docker虚拟化技术的文档。旨在用于给初学者快速搭建docker环境以及学习相关知识。
虚拟化技术是一个通用的概念。在计算领域,一般指的是计算虚拟化,或者通常说的服务器虚拟化。
维基百科的定义如下:
在计算机技术中,虚拟化(Virtualization)是一种资源管理技术,是将计算机的各种实体资源,如服务器、网络、内存以及存储等,予以抽象、转换后呈现出来,打破实体结构间的不可切割的障碍,使用户可以用比原来的组态更好的方式来应用这些资源。
从大类上分,虚拟化技术可分为基于硬件的虚拟化和基于软件的虚拟化。我们常用的是基于软件的虚拟化。
基于软件的虚拟化从对象所在层次,又可以分为应用虚拟化和平台虚拟化。其中前者是指一些模拟器设备软件。后者又可以细分为如下几个子类:
本文档所指的Docker虚拟化,就是属于操作系统级虚拟化的技术范畴。
Docker是基于GO语言实现的云开源项目,诞生于2013年初,最初的发起者是dotCloud公司。
现在主流的Linux操作系统都已经支持Docker。例如,RedHat RHEL、CentOS,Ubuntu等操作系统,都已经默认带有Docker软件包。(受版本问题,可能有些低版本的操作系统,需要自行安装)。
Docker的主要目标是“Build Ship and Run Any App,Anywhere”,即通过对应用组件的封装(Packaging)、分支(Distribution)、部署(Deployment)、运行(Runtime)等生命周期的管理,达到应用组件级别的“一次封装,到处运行”。
Docker引擎的基础是Linxu容器技术。IBM给出关于容器技术的准确描述:
容器有效地将由单个操作系统管理的资源划分到孤立的组中,以便更好地在孤立的组之间平衡有冲突的资源使用需求。与虚拟化相比,这样既不需要指令级模拟,也不需要即时编译。容器可以在核心CPU本地运行指令,而不需要任何专门的解释机制。此外,也避免了准虚拟化和系统调用替换中的复杂性。
我们可以简单地将Docker容器理解为一种沙盒(SandBox)。每个容器内运行一个应用。不同的容器相互隔离,容器之间也可以建立通信机制。容器的创建和停止都十分快速,容器自身对资源的需求也十分有限,远低于虚拟机。
对开发和运维(DevOps)过程中,具有如下几个优势:
Docker是面向应用的,其终极目标是构建PAAS平台,而现有虚拟机主要目的是提供一个灵活的计算资源池,是面向架构的,其终极目标是构建一个IAAS平台,所以它不能替代传统虚拟化解决方案。目前在容器可管理性方面,对于方便运维,提供UI来管理监控各个containers的功能还不足,还都是第三方实现如DockerUI、Dockland、Shipyard等。
Docker镜像(Image)类似于虚拟机镜像,可以将它理解为一个面向Docker引擎的只读模板,包含了文件系统。
镜像是创建Docker容器的基础。通过版本管理和增量文件的文件系统,Docker提供了一套十分简单的机制来创建和更新现有的镜像,用户甚至可以从网上下载一个已经做好的应用镜像,并通过简单的命令就可以直接使用。
Docker容器(Container)类似于一个轻量级的沙箱,Docker利用容器来运行和隔离应用。
容器是从镜像创建的应用运行实例,可以将其启动、开始、停止、删除,而这些是相互隔离、互不可见。
镜像自身是只读的。容器从镜像启动的时候,Docker会在镜像的最上层创建一个可读写层,镜像本身将保持不变。
Docker仓库(Repository)类似于代码仓库,是Docker集中存放镜像文件的场所。
注册服务器是存放仓库的地方,其上往往存放着多个仓库。每个仓库集中存放某一类镜像,往往包括多个镜像文件,通过不同的标签(tag)来进行区分。
如下图:
根据所存储的镜像公开分享与否,Docker仓库可以分为公开仓库(Public)和私有仓库(Private)两种形式。
目前,最大的公开仓库是Docker Hub,存放了数量庞大的镜像供用户下载。
在国内比较稳定的是阿里云仓库。
当用户创建了自己的镜像之后就可以使用push命令将它上传到指定的公有或私有仓库。这样用户下次在另外一台机器上使用该镜像时,只需将其从仓库上pull下拉就可以使用了。
注意:Docker利用仓库管理镜像的设计理念与Git非常相似。
Docker引擎是一个客户端–服务器应用,由如下主要组件组成:
如下图:
CLI使用Docker的REST API 来和Docker的守护进程交互,通过脚本或直接的CLI命令。
守护进程(daemon process)创建和管理Docker对象(objects).Docker对象包括镜像(images)、容器(containers)、网络(networks)、数据卷(data volumes)等等.
Docker使用客户端-服务器(client-server)架构. Docker client 告诉Docker daemon 建立、运行、和分发你你的Docker容器. Docker client和daemon可以运行在同一个系统中,或者可以使用Docker client 和远程的Docker daemon 取得联系。docker客服端和docker守护进程之间通过sockets 或者REST API 交互。
如下图:
Docker支持在主流的操作系统平台上使用,包括Ubuntu、CentOS、Windows以及MacOS系统等。本文档主要讲解三个平台的安装,包括:CentOS,Windows以及MacOS系统。
docker容器最早受到RHEL完善的支持是从最近的CentOS 7.0开始的,官方说明是只能运行于64位架构平台,内核版本为2.6.32-431及以上(即>=CentOS 6.5,运行docker时实际提示3.8.0及以上)。
需要注意的是CentOS 6.5与7.0的安装是有一点点不同的,CentOS-6上docker的安装包叫docker-io,并且来源于Fedora epel库,这个仓库维护了大量的没有包含在发行版中的软件,所以先要安装EPEL,而CentOS-7的docker直接包含在官方镜像源的Extras仓库(CentOS-Base.repo下的[extras]节enable=1启用)。前提是都需要联网,具体安装过程如下。
# uname -r
2.6.32-431.el6.x86_64
注意:必须要大于等于这个版本号
yum -y install http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm
# yum install docker-io
Dependencies Resolved
===========================================================================================
Package Arch Version Repository Size
===========================================================================================
Installing:
docker-io x86_64 1.1.2-1.el6 epel 4.5 M
Installing for dependencies:
lua-alt-getopt noarch 0.7.0-1.el6 epel 6.9 k
lua-filesystem x86_64 1.4.2-1.el6 epel 24 k
lua-lxc x86_64 1.0.6-1.el6 epel 15 k
lxc x86_64 1.0.6-1.el6 epel 120 k
lxc-libs x86_64 1.0.6-1.el6 epel 248 k
Transaction Summary
===========================================================================================
Install 6 Package(s)
# service docker start
# yum -y update
# cat >/etc/yum.repos.d/docker.repo <<-EOF
[dockerrepo]
name=Docker Repository
baseurl=https://yum.dockerproject.org/repo/main/centos/7
enabled=1
gpgcheck=1
gpgkey=https://yum.dockerproject.org/gpg
EOF
yum install -y docker-engine
yum install -y docker-selinux
# systemctl start docker.service
# systemctl enable docker.service
略
镜像是Docker的三大核心概念之一。
Docker运行容器前需要本地存在对应的镜像,如果镜像不存在本地,Docker会尝试从默认仓库下载(默认使用Docker Hub公共注册服务器中的仓库),用户也可以通过配置,使用自定义的镜像仓库。
本节内容将围绕着镜像这一核心概念的具体操作,包括如何使用pull命令从Docker仓库中下载镜像到本地;如何查看本地已有的镜像信息;如何在远端仓库使用search命令进行搜索和过滤;如何删除镜像标签和镜像文件;如何创建用户定制的镜像并且保存为外部文件等等。
Docker默认下载镜像是通过默认仓库下载,其默认仓库是在国外的站点,在访问速度上比较慢,不稳定。为了改变这一情况,国内一些大的容器服务站点,例如:阿里云,daocloud等,提供了访问加速器。我们可以通过配置访问加速器,提高稳定性和下载速度。
镜像是Docker运行容器的前提。
可以使用docker pull命令从网络中下载镜像。该命令的格式为:
docker pull Name[:TAG]
如果不显示地指定TAG,则默认下载latest标签,即下载仓库中最新版本的镜像。
例如:
docker pull centos
该命令相当于从默认注册服务器(Registry.hub.docker.com)中的centOS仓库下载标记为latest的镜像。
docker pull registry.cn-hangzhou.aliyuncs.com/acs-sample/centos
该命令相当于从阿里云注册服务器(registry.cn-hangzhou.aliyuncs.com/acs-sample)中的centOS仓库下载标记为latest的镜像。
我们来看一下,下载过程,如下图:
下载过程中可以看出,镜像文件一般是由若干层组成,首行a3ed95caeb92这样的字符串代表了各层的ID。下载过程中会获取并输出镜像的各层信息。层(Layer)其实是AUFS(高级联合文件系统)中的重要概念,是现实增量保存与更新的基础。
下载完成后,既可以使用该镜像了。例如:
docker run -ti centos /bin/bash
使用docker images命令可以列出本地主机上已有的镜像。
例如:
docker images
如下图:
列出信息依次为:
其中镜像的ID信息十分重要,它唯一标识了镜像。
为了方便使用某个镜像,我们可以修改标签值,例如:
docker tag mysql mysql2
修改后,如下图:
如上图,我们已经将mysql改为mysql2并创建了一个新的image,但是,这里要注意,mysql和mysql2其实实际上是一个镜像,只不过是同时指向了同一个镜像ID。
我们也可以使用,
docker rmi mysql2
删除它。如图:
使用docker inspect [镜像名]命令可以获得该镜像的详细信息。
例如:
docker inspect mysql
如下图:
使用docker search命令可以搜索远端仓库中共享的镜像,默认搜索Docker Hub官方仓库的镜像。
例如:
docker search centos
如下图:
其实,我们还可以在阿里云容器服务站点中搜索
地址如下:https://dev.aliyun.com
命令格式如下:
docker rmi [IMAGE]
其中IMAGE可以是标签或ID
例如:
docker rmi mysql2
这条命令删除了该镜像多个标签中的一个指定标签而已,并不影响镜像文件。但是,当镜像只剩下一个标签的时候,就会彻底删除该镜像。
当使用docker rmi命令后面跟上镜像的ID时,会先尝试删除所有指向该镜像的标签,然后删除该镜像文件本身。
如下图:
案例:
首先先运行镜像,创建一个简单的容器:
docker run -ti centos2 /bin/bash
使用docker ps -a命令查看本机上存在的所有容器
docker ps -a
删除镜像
docker rmi centos2
如下图,显示错误:
Docker会提示有容器正在运行,无法删除。
如果要强制删除,可以使用-f参数:
docker rmi -f centos2
但不建议强制删除的方式删除容器依赖的镜像。正确的方式是,先删除依赖该镜像的所有容器,再删除镜像。
可以使用如下命令,删除容器:
docker rm [CONTAINER ID]
如果要存出镜像到本地文件,可以使用docker save命令。
例如:
docker save -o centos.tar centos
如果要导入镜像到Docker中,可以使用docker load
例如:
docker load --input centos.tar
使用docker push命令上传镜像到仓库。默认上传到DockerHub,命令格式如下:
docker push NAME[:TAG]
第一次使用时,会提示输入登录信息或进行注册。
容器是Docker的另外一个核心概念。
简单地说,容器是镜像的一个运行实例,所不同的是,它带有额外的可写文件层。
本节将具体介绍容器的重要操作,包括创建一个容器、启动容器、终止一个容器、进入容器内执行操作、删除容器和导入导出容器来实现容器迁移等。
Docker的容器十分轻量级,用户可以随时创建或删除容器。
可以使用docker create 命令新建一个容器,例如:
docker create -ti centos
使用docker create 命令新建的容器处于停止状态,可以使用docker start命令启动它。
启动容器有两种方式:
例如:
docker run centos /bin/echo "hello world"
如图结果:
当利用docker run 来创建并启动容器时,Docker后台要进行如下过程:
通过docker ps 命令可以查看所有运行的容器信息。
docker ps
结果如图:
我们可以看出,当执行完“hello world“后,容器着被终止,通过docker ps 命令看不到任何运行的容器信息。
通过-a 可以查看存在的容器,包括运行的和终止的容器信息。
docker ps -a
结果如图:
结果信息列如下:
通过结果截图,我们看到了刚刚我们执行的“hello world”容器的信息。目前它的状态是终止。
docker run -t -i centos /bin/bash
其中,-t选项让Docker分配一个伪终端并绑定到容器的标准输入上,-i则让容器的标准输入保持打开。
结果如图:
docker run -d centos /bin/sh -c "while true; do echo hello world; sleep 1; done"
结果如图:
我们可以通过docker logs [容器ID]查看容器日志。
docker logs 3a
在使用-d 参数时,容器启动后进入后台,用户无法看到容器中的信息。某些时候如果需要进入容器进行操作,我们可以使用docker attach命令,docker exec命令,以及nesenter工具等,比较常用的还是docker exec命令。
下面我们来介绍一下使用:
docker exec -ti 3adb27e44229 /bin/bash
其中,“3adb27e44229”为容器ID。
这样我们就可以进入一个后台运行的容器内部操作了。
可以使用docker stop命令来终止一个运行的容器。
docker stop 3adb27e44229
同时,也可以使用docker restart命令来重启一个容器。
docker restart 3adb27e44229
使用docker rm命令删除处于终止状态的容器。例如:
docker rm 3adb27e44229
如果该容器在运行中强制删除,需要使用-f参数。
使用docker export命令导出容器。例如:
docker export 3adb27e44229 >testexport.tar
使用docker import命令导入,成为镜像。例如:
cat testexport.tar | docker import - test
仓库(Respository)是集中存放镜像的地方。
仓库又分为公共仓库和私有仓库。本部分的内容主要是讲解,如何在注册服务器(Registry)中下载某个仓库的某个版本的镜像。
注册地址:https://dev.aliyun.com
执行复制命令:
以上完成了从公有仓库下载镜像的步骤。对于创建私有仓库的方式,暂略。
在使用Docker的过程中,往往需要能查看容器内应用产生的数据,或者需要把容器内的数据进行备份,甚至多个容器之间进行数据的共享,这必然涉及容器的数据管理操作。
容器中管理数据主要有两种方式:
本节将首先讲解如何在容器内创建数据卷,并且把本地的目录或文件挂载到容器内的数据卷。而后,会讲解如何使用数据卷容器在容器和主机、容器和容器之间共享数据。
数据卷是一个可供容器使用的特殊目录,它绕过文件系统,可以提供很多有用的特性。
数据卷的使用,类似于Linux下对目录或文件进行mount(挂载)操作。
在用docker run命令的时候,使用- v标记可以在容器内创建一个数据卷。多次使用-v标记可以创建多个数据卷。
使用-v标记也可以制定挂载一个本地的已有目录到容器中去作为数据卷。
docker run -d -P --name web -v /yundata/webapps:/opt/webapp mycentos
解释命令:该命令是将mycentos镜像运行,并将其后台运行,同时暴露所有容器需要暴露的端口,同时将容器的别名设置为“web“,最后将本地(宿主)主机的_yundata_webapps目录挂载到容器内_opt_webapp目录上。
-P暴露所有容器需要暴露的端口(比如:8080,80等)
—name将容器设置别名
-v挂载数据卷,:冒号前为本地(宿主)主机的目录,冒号后为容器内目录
这个命令演示测试的时候十分方便,比如:用户可以放置一些程序或数据到本地目录中,然后在容器内运行、访问使用。
注意:本地目录的路径必须要是绝对路径,如果目录不存在Docker会自动创建。
Docker挂载的数据卷默认权限是读写(rw),用户也可以,ro指定为只读。
docker run -d -P --name web -v /yundata/webapps:/opt/webapp:ro mycentos
加入了:ro之后,容器内挂载的数据卷的数据就无法修改了。
这种方式目前已经不建议使用了,从Docker1.1.0起,推荐的方式是直接挂载文件所在的目录。
如果用户需要在容器之间共享一些持续更新的数据,最简单的方式是使用数据卷容器,数据卷容器其实就是一个普通的容器,专门用它提供数据卷供其他容器挂载使用。
案例:创建一个数据卷容器,并将其挂载到两个容器中,共享。
第一步:创建数据卷容器,并创建数据卷dbdata目录,同时,将数据卷容器命名为dbdata
docker run -d -v /dbdata --name dbdata mycentos
第二步:将数据卷容器,挂载到两个容器中,使用—volumes-from来挂载dbdata容器中的数据卷
docker run -d --volumes-from dbdata --name db1 mycentos
docker run -d --volumes-from dbdata --name db2 mycentos
此时,容器db1和db2都挂载同一个数据卷到相同的/dbdata目录。三个容器任何一方在该目录下的写入,其他容器都可以看到。
多次使用—volumes-from参数来从多个容器挂载多个数据卷。还可以从其他已经挂载了容器卷的容器来挂载数据卷。例如:
docker run -d --name db3 --volumes-from db1 mycentos
注意:使用—volumes-from参数所挂载数据卷的容器自身并不需要保持在运行状态。
如果删除了挂载的容器(包括dbdata、db1和db2),数据卷并不会自动删除。如果要删除一个数据卷,必须在删除最后一个还挂载着它的容器时显示使用docker rm -v命令来指定同时删除关联的容器。
大量的互联网应用服务包括多个服务组件,这往往需要更多个容器之间通过网络通信进行相互配合。
Docker目前提供了映射容器端口到宿主主机和容器互联机制来为容器提供网络服务。
本节将讲解如何使用Docker的网络功能。包括使用端口映射机制来将容器内应用服务提供给外部网络,以及通过容器互联系统让多个容器之间进行快捷的网络通信。
在启动容器的时候,如果不指定对应参数,在容器外部是无法通过网络来访问容器内的网络应用和服务的。
当容器中运行一些网络应用,例如:tomcat,nginx等,要让外部访问这些应用时,可以通过-P或-p参数来指定端口映射。当使用-P标记时,Docker会随机映射一个30000-49900的端口至容器内部开发的网络端口.
例如:
docker run -d -P mytomcat
结果如图:
可以看出,容器的8080端口映射到了本地32772端口,我们可以通过这个端口访问到容器中的tomcat服务。
例如:
http://127.0.0.1:32772
如图:
-p(小写的)则可以指定要映射的端口,并且,在一个指定端口上只可以绑定一个容器。支持的格式如下:
ip:hostPost:containerPort
ip::containerPort
hostPost:containerPort
docker run -d -p 8080:8080 mytomcat
docker run -d -p 127.0.0.1:8080:8080 mytomcat
docker run -d -p 127.0.0.1::8080 mytomcat
docker port (容器ID/容器别名) 5000
docker inspect (容器ID/容器别名)
结果截图:
容器的连接(linking)系统是除了端口映射外另外一种可以与容器中应用进行交互的方式。它会在源和接收容器之间创建一个隧道。接收容器可以看到源容器指定的信息。
使用—name标记可以为容器自定义命名:
docker run -d -P --name tomcat mytomcat
注意:容器的名称是唯一的。如果已经命名了一个叫tomcat的容器,当你要再次使用tomcat这个名称的时候,需要先用docker rm来删除之前创建的同名容器。
使用—link参数可以让容器之间安全的进行交互。
格式:
—link name:alias,其中name是要链接的容器的名称,alias是这个连接的别名。
案例:
1.先创建一个数据库容器(db)
docker run -d --name db -e MYSQL_ROOT_PASSWORD=qaz123 mysql
2.创建一个web容器(tomcat),并将它连接到db容器
docker run -d -P --name web --link db:db mytomcat
docker常用命令
# 查看docker的版本信息
$ docker version
# 查看安装docker的信息
$ docker info
# 查看本机Docker中存在哪些镜像
$ docker images
# 检索image
$ docker search ubuntu:14.04
# 在docker中获取ubuntu镜像
$ docker pull ubuntu:14.04
# 显示一个镜像的历史
$ docker history birdben/ubuntu:v1
# 列出一个容器里面被改变的文件或者目
$ docker diff birdben/ubuntu:v1
# 从一个容器中取日志
$ docker logs birdben/ubuntu:v1
# 显示一个运行的容器里面的进程信息
$ docker top birdben/ubuntu:v1
# 从容器里面拷贝文件/目录到本地一个路径
$ docker cp ID:/container_path to_path
# 列出当前所有正在运行的容器
$ docker ps
# 列出所有的容器
$ docker ps -a
# 列出最近一次启动的容器
$ docker ps -l
# 查看容器的相关信息
$ docker inspect $CONTAINER_ID
# 显示容器IP地址和端口号,如果输出是空的说明没有配置IP地址(不同的Docker容器可以通过此IP地址互相访问)
$ docker inspect --format='{{.NetworkSettings.IPAddress}}' $CONTAINER_ID
# 保存对容器的修改
$ docker commit -m "Added ssh from ubuntu14.04" -a "birdben" 6s56d43f627f3 birdben/ubuntu:v1
# 参数:
# -m参数用来来指定提交的说明信息;
# -a可以指定用户信息的;
# 6s56d43f627f3代表的时容器的id;
# birdben/ubuntu:v1指定目标镜像的用户名、仓库名和 tag 信息。
# 构建一个容器
$ docker build -t="birdben/ubuntu:v1" .
# 参数:
# -t为构建的镜像制定一个标签,便于记忆/索引等
# . 指定Dockerfile文件在当前目录下,也可以替换为一个具体的 Dockerfile 的路径。
# 在docker中运行ubuntu镜像
$ docker run <相关参数> <镜像 ID> <初始命令>
# 守护模式启动
$ docker run -it ubuntu:14.04
# 交互模式启动
$ docker run -it ubuntu:14.04 /bin/bash
# 指定端口号启动
$ docker run -p 80:80 birdben/ubuntu:v1
# 指定配置启动
$ sudo docker run -d -p 10.211.55.4:9999:22 birdben/ubuntu:v1 '/usr/sbin/sshd' -D
# 参数:
# -d:表示以“守护模式”执行,日志不会出现在输出终端上。
# -i:表示以“交互模式”运行容器,-i 则让容器的标准输入保持打开
# -t:表示容器启动后会进入其命令行,-t 选项让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上
# -v:表示需要将本地哪个目录挂载到容器中,格式:-v <宿主机目录>:<容器目录>,-v 标记来创建一个数据卷并挂载到容器里。在一次 run 中多次使用可以挂载多个数据卷。
# -p:表示宿主机与容器的端口映射,此时将容器内部的 22 端口映射为宿主机的 9999 端口,这样就向外界暴露了 9999 端口,可通过 Docker 网桥来访问容器内部的 22 端口了。
# 注意:这里使用的是宿主机的 IP 地址:10.211.55.4,与对外暴露的端口号 9999,它映射容器内部的端口号 22。ssh外部需要访问:ssh [email protected] -p 9999
# 不一定要使用“镜像 ID”,也可以使用“仓库名:标签名”
# start 启动容器
$ docker start 117843ade696117843ade696
# stop 停止正在运行的容器
$ docker stop 117843ade696117843ade696
# restart 重启容器
$ docker restart 117843ade696117843ade696
# rm 删除容器
$ docker rm 117843ade696117843ade696
# rmi 删除镜像
$ docker rmi ed9c93747fe1Deleted
# 登录Docker Hub中心
$ docker login
# 发布上传image(push)
$ docker push birdben/ubuntu:v1
修改密码:
echo 'newpassword' |passwd root --stdin
映射端口和服务
docker run -d -p 8888:22 myssh4:latest /usr/sbin/sshd -D
提交修改:
docker commit 81041ab6b5f6 myssh4
运行:
docker run -it 3b5e50532f20 /bin/bash
执行容器某个应用:
docker exec 81041ab6b5f6 /bin/bash
查看当前运行容器列表:
docker ps
查看所有镜像列表:
docker images
停止某个容器:
docker stop [name/容器id]
ssh登录:
ssh root@192.168.203.134 -p 8888
阿里docker仓库以及加速器:
https://cr.console.aliyun.com/
删除容器:
docker rm [CONTAINER ID(容器id)]
删除镜像:
docker rmi [IMAGE ID(镜像id)]
centos7下安装docker:
curl -sSL http://acs-public-mirror.oss-cn-hangzhou.aliyuncs.com/docker-engine/internet | sh -
获得镜像:
docker pull NAME[:TAG]
在aliyun仓库获得镜像:https://dev.aliyun.com
DOCKER容器时区问题解决
[root@ab374724d6b0 ~]# rm -rf /etc/localtime
[root@ab374724d6b0 ~]# ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
Dockerfile中,ADD和COPY都是拷贝本机文件到container制作image。
那么ADD和COPY有什么区别呢?
ADD比COPY多了2个功能:
① ADD 的可以为URL
② ADD 到container的tar文件会被自动解压,并删除原tar文件。
V 1.0.0
以下是在编写文档中收集的资源,对深入理解与运用有帮助