文章目录
最全docker
文章对大家有帮助的话,还请点个赞
一、基础篇
1、docker介绍及安装
说起docker,就不的说一下现在主流的微服务框架springCloud的整体架构。从左到右开始介绍:
- PC表示客户端,请求发起方。
- PC发起请求,到Nginx上进行转发。(nginx通过Keepalived进行集群化,负载均衡)。
- ng转发请求到springcloud的gateway组件上,gateway通过配置的服务进行转发。
- 所有服务器都是注册到注册中心上的,请求都是通过注册中心来寻址的。
- 内部的负载均衡是通过ribbon进行实现的。
- 配置中心进行配置文件的管理,注册中心进行服务的管理。
- 另外,还有bus的异步处理,kafka及mq等都会实现异步。
在这架构中,咱们可以发现需要的中间件特别多,尤其是集群化的搭建,整个开发及运维成本多了好几倍。所有,出现了docker。
1.1 什么是docker
Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows操作系统的机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。【百度百科】
解释一下:docker就是一个容器服务,你可以理解为轮船上的集装箱,每一个集装箱(容器)都是一个可运行的组件或服务,只需要通过简单的命令就可以运行起来进行访问使用,节省了运维时间。
打个比方。nginx集群的搭建,除了要修改必要的配置文件外,还有安装其他的组件keepalived,如果你那边搭建的环境是不能联网的局域网,那么恭喜你的运维时间又要变长,很是累人啊。
官方文档:
Docker是基于Go语言实现的云开源项目。
Docker的主要目标是Build,Ship and Run Any App,Anywhere,也就是通过对应用组件的封装、分发、部署、运行等生命周期的管理,使用户的APP(可以是一个WEB应用或数据库应用等等)及其运行环境能够做到一次封装,到处运行。
Linux 容器技术的出现就解决了这样一个问题,而 Docker 就是在它的基础上发展过来的。将应用运行在 Docker 容器上面,而 Docker 容器在任何操作系统上都是一致的,这就实现了跨平台、跨服务器。只需要一次配置好环境,换到别的机子上就可以一键部署好,大大简化了操作
解决了运行环境和配置问题软件容器,方便做持续集成并有助于整体发布的容器虚拟化技术
1.2 docker的安装
1.2.1 docker 安装环境
- CentOS Docker 安装
- Docker支持以下的CentOS版本:
- CentOS 7 (64-bit) 8
- CentOS 6.5 (64-bit) 或更高的版本
前提条件
目前,CentOS 仅发行版本中的内核支持 Docker。
Docker 运行在 CentOS 7 上,要求系统为64位、系统内核版本为 3.10 以上。
Docker 运行在 CentOS-6.5 或更高的版本的 CentOS 上,要求系统为64位、系统内核版本为 2.6.32-431 或者更高版本。
查看自己的内核
uname命令用于打印当前系统相关信息(内核版本号、硬件架构、主机名称和操作系统类型等)。
1.2.2 dcoker安装
参考官方文档安装:官方文档
注意:省略虚拟机的搭建
卸载原有环境:
sudo yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
安装对应的依赖环境和镜像地址
sudo yum install -y yum-utils
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
安装docker CE
sudo yum install -y docker-ce docker-ce-cli containerd.io
最后出现 compelte,表示安装成功
启动docker服务
sudo systemctl start docker
查看docker的版本
sudo docker version
如果安装过慢可以设置yum源
sudo yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
yum更新下即可:
yum makecache fast
设置开机启动docker
sudo systemctl enable docker
1.3 docker 组成
-
Repository(仓库):集中存放镜像文件(iamges)的场所。
仓库分为公开仓库(Public)和私有仓库(Private)两种形式。
最大的公开仓库是 Docker Hub(https://hub.docker.com/),存放了数量庞大的镜像供用户下载。国内的公开仓库包括阿里云 、网易云 等 -
Registry:仓库注册服务器。仓库注册服务器上往往存放着多个仓库。
-
image: 镜像(Image)就是一个只读的模板。镜像可以用来创建 Docker 容器,一个镜像可以创建很多容器。
-
container:容器是独立运行的一个或一组应用。容器是用镜像创建的运行实例。
它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。可以把容器看做是一个简易版的 Linux 环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。容器的定义和镜像几乎一模一样,也是一堆层的统一视角,唯一区别在于容器的最上面那一层是可读可写的。
1.4 阿里镜像加速器
默认访问的仓库是在国外所以访问速度是没法保证的。为了更好的体验,我们可以配置阿里云的镜像加速器
控制台–>产品服务–>容器服务–>容器镜像服务—>镜像中心–>镜像加速器
[root@localhost ~]# cd /etc/docker
[root@localhost docker]# ll
total 8
-rw-r--r--. 1 root root 67 May 26 18:24 daemon.json
-rw-------. 1 root root 244 May 12 19:39 key.json
[root@localhost docker]# vim daemon.json
[root@localhost docker]# cat daemon.json
{
"registry-mirrors": ["https://lgspaf87.mirror.aliyuncs.com"]
}
[root@localhost docker]# sudo systemctl daemon-reload
[root@localhost docker]# sudo systemctl restart docker
[root@localhost docker]#
1.5 私有仓库设置
本章节只有私有仓库设置,具体的如何创建私有仓库,请看高级篇
1.5.1 设置私服仓库
#!/bin/bash
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"insecure-registries": ["domain:5000"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
注意:使用tee命令会覆盖之前的内容,建议使用vim直接文件再重新加载daemon.json文件
详细tee命令,请看菜鸟教程:tee
1.5.2 私服仓库搜索
搜索私有仓库的镜像并不能用 docker search
命令, 只能通过 http://domain:5000/v2/image_name/tags/list
查看指定镜像存在的 tag
列表。**domain
**是ip
$ curl http://domain:5000/v2/nginx/tags/list
{"name":"nginx","tags":["latest"]}
1.5.3 下载镜像
首先我们通过 docker rmi
将本地的镜像删除(取消标签)。
$ docker rmi domain:5000/nginx
Untagged: domain:5000/nginx:latest
Untagged: domain:5000/nginx@sha256:066edc156bcada86155fd80ae03667cf3811c499df73815a2b76e43755ebbc76
再使用 docker images
确认 domain:5000/nginx
这个镜像在本地不存在,接下来我们就可以从私有仓库进行下载。
$ docker pull domain:5000/nginx:latest
1.5.4 上传镜像
docker tag REPOSITORY:TAG domain:5000/images:tag
docker push domain:5000/images:tag
#上传镜像私服时,直接使用pull命令不一定能成功,因为镜像的REPOSITORY仓库源,未设置为私服仓库
#需要使用tag命令修改REPOSITORY仓库源为私服仓库源
docker tag nginx:latest domain:5000/nginx:latest
#然后才能使用 docker push 命令,记得指定
docker push domain:5000/nginx:latest
这个版本的ng我已经push到仓库了,所以显示已经存在
1.5.5 我的私服配置
registry-mirrors
为公共仓库,insecure-registries
私服仓库
{
"registry-mirrors": [
"https://registry.docker-cn.com", #docker hub 国内网站
"https://lgspaf87.mirror.aliyuncs.com", # 阿里镜像加速器
"https://docker.mirrors.ustc.edu.cn", #中科大镜像
"https://hub.docker.com" #dockerhub官网
],
"insecure-registries": [
"ip:5000" #个人私服
]
}
有一点需要提醒一下:本人不知道能不能
registry-mirrors、insecure-registries
同时配置。我同时配置后,重新加载配置文件后,docker就崩溃了。具体表现为:docker 重启报错,docker 命令无法识别。
我的解决方法:
重新修改daemon.json文件为一个地址。
删除了 /var/lib/docker文件夹,也就是docker的数据文件。但是这样的话操作,会使所有的镜像、容器,等等都会消失,请谨慎操作。
具体的,如果谁知道是咋回事,麻烦留言。
私有镜像这一章节来自:Docker 仓库
1.6 卸载docker
# 停止docker服务
systemctl stop docker
# 卸载docker,并删除docker数据文件
yum -y remov docker-ce
# 注意:/var/lib/docker 为docker镜像、容器等数据文件存储地址
rm -rf /var/lib/docker
# 重启服务
sudo systemctl restart docker
2、docker常用命令
2.1 docker 帮助命令
命令 | 说明 |
---|---|
docker version | 查看docker版本信息 |
docker info | 查看docker信息 |
docker --help | docker帮助命令 |
2.2 镜像命令
#列出本地主机上的镜像
docker images
#从 docker hub 上搜索镜像
docker search 镜像名称
#从docker hub 上下载镜像
docker pull 镜像名称
#删除本地镜像
docker rmi 镜像名称
2.2.1 查询本地镜像列表
docker images
镜像表格信息说明
选项 | 说明 |
---|---|
REPOSITORY | 表示镜像的仓库源 |
TAG | 镜像的标签 |
IMAGE ID | 镜像ID |
CREATED | 镜像创建时间 |
SIZE | 镜像大小 |
参数 | 说明 |
---|---|
-a | 列出本地所有的镜像 |
-q | 只显示镜像ID |
–digests | 显示镜像的摘要信息 |
–no-trunc | 显示完整的镜像信息 |
2.2.2 搜索服务器镜像
docker search
docker hub 官网地址:官网地址
docker hub是Docker的在线仓库,我们可以通过docker search 在上面搜索我们需要的镜像
但是注意,尽量选择可信任的镜像,还有安装docker的系统
参数名称 | 描述 |
---|---|
–no-trunc | 显示完整的描述信息 |
–limit | 分页显示 |
-f | 过滤条件 docker search -f STARS=5 tomcat STARS=5 就是点赞数大于5的tomcat |
注意:当前使用私有镜像仓库时,search命令是不起作用的,具体请看
1.5私有仓库设置
2.2.3 下载镜像
注意:当前不指定版本时,默认下载最新的版本,也就是latest
docker pull tomcat
#等价于
docker pull tomcat:latest
2.2.4 删除镜像
#删除单个镜像
docker rmi -f 镜像ID
#删除多个镜像时,需要使用镜像的 REPOSITORY:TAG 来表示当前镜像
docker rmi -f 镜像1:TAG 镜像2:TAG
#删除全部镜像(包括运行中的,停止的,失败的.....)
docker rmi -f $(docker images -qa)
#删除none镜像
docker rmi $(docker images \| grep "none" \| awk '{print $3}')
2.2.5 镜像制作
关于镜像的制作,比较麻烦,本章只讲常用命令。如有需要,请直接往下翻阅
- 【3、docker的镜像文件 】里的【3.5 将运行的容器制作为镜像】
- 【5、dockerFile】
2.3 容器命令
2.3.1 创建并启动容器
docker run [OPTIONS] IMAGE [COMMAND]
**创建:**创建容器使用的是
create
命令,但是直接使用run
运行不存在的容器时,会默认先创建在运行。**启动:**直接启动已经存在的容器,请使用
start
命令,即docker start 容器ID或者容器名称
。**重启:**重新启动正在运行的容器,请使用
restart
命令,即docker restart 容器id或者名称
。
OPTIONS中的一些参数:
options | 说明 |
---|---|
--name | “容器新名字”: 为容器指定一个名称 |
-d | 后台运行容器,并返回容器ID,也即启动守护式容器 。后台运行的容器) |
-i | 以交互模式运行容器,通常与 -t 同时使用 |
-t | 为容器重新分配一个伪输入终端,通常与 -i 同时使用 |
-P: | 随机端口映射 |
-p | 指定端口映射,有以下四种格式 ip:hostPort:containerPort ip::containerPort hostPort:containerPort containerPort 常用的是第三种 |
-v | 数据卷映射,默认:/宿主机绝对路径:/容器内目录 。具体释义详见下文4、docker数据卷 |
-e | 指定启动参数值/环境变量 |
1、本表只记录常用参数,如不满足要求,请直接翻阅到最后【7、附录OPTIONS参数说明】,查阅附录表
2、具体使用,详见【6、Docker 常用软件的安装】
交互式的容器
docker run -it centos /bin/bash
注意:使用交互模式后,会进入容器中,想退出容器,请使用
exit
命令或者使用快捷键ctrl+p+q
2.3.2 列举运行中的容器
docker ps [options]
OPTONS可用的参数
OPTIONS | 说明 |
---|---|
-a | 列出当前所有正在运行的容器+历史上运行过的 |
-l | 显示最近创建的容器。 |
-n | 显示最近n个创建的容器。 |
-q | 静默模式,只显示容器编号。 |
–no-trunc | 不截断输出。 |
2.3.3 停止及删除容器
#停止容器
docker stop 容器ID
#强制停止容器
docker kill 容器ID
#删除容器
docker rm 容器ID
#强制删除所有容器
docker rm -f $(docker ps -qa)
#删除所有的容器
docker ps -a -q | xargs docker rm
关于
xagrs
命令的解释,请看-> 菜鸟教程:xargs命令解释
2.3.4 进入运行中的容器
docker exec -it 容器ID /bin/bash
docker attach 容器ID
进入方式 | 说明 |
---|---|
exec | 在容器中打开新的终端,并且可以启动新的进程 |
attach | 直接进入容器启动命令的终端,不会启动新的进程 |
2.3.5 查看容器详情
docker inspect 容器ID
信息很多,就不展示了
2.3.6 查看容器日志
#查看日志
docker logs 容器ID
#查看实时日志
docker logs -f -t --since="2018-10-26" --tail=10 容器ID
-f:表示实时日志。
-t : 查看日志产生的日期。
–since : 此参数指定了输出日志开始日期,即只输出指定日期之后的日志。
–tail=10 : 查看最后的10条日志。
2.3.7 复制文件
有的时候文件需要从宿主机拷贝到容器中,或者是从容器拷贝到宿主机
#从容器中拷贝到宿主机
docker cp 容器ID:容器内路径 目的地路径
#从宿主机拷贝到容器中
docker cp 容器内路径:容器ID 目的地路径
2.3.8 其他命令
2.3.8.1 保存镜像到本地
有的时候咱们部署的环境,是无法联网了,只能从通过一个能联网的本地虚拟机下载镜像到本地仓库,然后保存镜像成tar格式到本地
#docker save -o "<path for generated tar file>" "<image name>"
docker save -o linux_image.tar linux_15
#或者是 docker save "<image ID>" > "<path for generated tar file>"
docker save 7df83bb6e638 > rocketmq-console-ng-latest.tar
2.3.8.2 加载镜像到本地仓库
#docker load -i "<path to image tar file>"
docker load -i rocketmq-console-ng-latest.tar
将容器保存为本地镜像又叫做容器的持久化存储,docker 镜像导入导出有两种方法:一种是使用 save 和 load 命令;一种是使用 export 和 import 命令。
Save方法,会保存该镜像的所有历史记录;Export 方法,不会保留历史记录,即没有commit历史
save保存的是镜像(image),export保存的是容器(container);load用来载入镜像包,import用来载入容器包,但两者都会恢复为镜像;
load不能对载入的镜像重命名,而 import可以为镜像指定新名称。
3、docker的镜像文件
3.1 镜像是什么
首先我们来看看镜像到底是什么?虽然前面有介绍过**镜像
和容器
**,但也不是特别的深入。
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。
3.2 UnionFS文件系统
Union 文件系统是 Docker 镜像的基础。
UnionFS(联合文件系统): Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
简单来说:镜像是分层的,每个镜像的制作都是在其他的镜像(基础镜像)基础上制作的。
特性
:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录
3.3 镜像加载原理
Docker镜像加载原理:
Docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统叫UnionFS文件系统。
UnionFS文件系统分为两层:
-
Bootfs(boot file system):Bootfs主要包含Bootloader(内核加载器)和Kernel(Linux内核)
- Bootloader主要是引导加载Kernel, Linux刚启动时会加载Bootfs文件系统,在Docker镜像的最底层是bootfs。
- 这一层与我们典型的Linux/Unix系统是一样的,包含Boot加载器和内核。
- 当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
-
Rootfs (root file system) :在Bootfs之上。包含的就是典型 Linux 系统中的 /dev, /proc, /bin, /etc 等标准目录和文件。Rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。说白了,rootfs就是一般系统的常见目录结构。
3.4 分层的镜像验证
其实这种分层的结构是很容易验证的,在【2.2.3 下载镜像】章节,咱们下载tomcat的图片中可以看到,一层层的pull。这就是镜像中的层次~~~
3.5 将运行的容器制作为镜像
注意:Docker的镜像都是只读的,但是当容器启动时,一个新的可写层被加载到镜像的顶部,这一层通常被称为容器层,容器层之下的都叫镜像层。
我们之前在上面已经学过关于镜像的基本操作,也即是常用的搜索、下载、删除等等。
本章节是讲如何将正在使用的容器制作为镜像。即:容器–>镜像
#在这之前,请先熟悉,容器制作镜像的命令commit
ocker commit -m="要提交的描述信息" -a="作者" 容器ID 要创建的目标镜像名:[标签名]
开始实操:
-
下载一个tomcat镜像,并启动。
[root@localhost ~]# docker pull tomcat #***** 省略下载过程 [root@localhost ~]# docker run -it -p 8888:8080 tomcat
浏览器访问:
-
修改容器:进入tomcat容器,创建一个新的文件html文件。访问tomcat,使其能看到网页。
浏览器访问:
-
将正在运行的容器制作为镜像
#docker commit -a='bobo' -m='add index.html' 容器ID bobo/tomcat:1.666 docker commit -a='mcs' -m='touch index to tomcat' 8d914dd9d332 mcs/tomcat:0.0.1
4、docker数据卷
4.1 数据卷
通过镜像我们可以启动多个容器,但是我们发现当我们的容器停止获取删除后,我们在容器中的应用的一些数据也丢失了,这时为了解决容器的数据持久化,我们需要通过容器数据卷来解决这个问题
4.1.1 数据卷是什么
Docker容器产生的数据,如果不通过docker commit生成新的镜像,使得数据做为镜像的一部分保存下来,那么当容器删除后,数据自然也就没有了。为了能保存数据在docker中我们使用卷。简单来说,容器卷就相当于Redis中持久化方式的RDB和AOF。
4.1.2 数据卷解决了什么问题
卷的意思其实就是文件或目录,它存在于一个或多个容器中。由docker将数据卷(文件或目录)挂载到容器中,但是请注意它不属于UnionFS文件系统。因此他能绕过文件系统,将数据文件存储到宿主机器上,从而有了持续存储或共享数据的特性。
卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷
特点:
-
数据卷可在容器之间共享或重用数据
-
卷中的更改可以直接生效
-
数据卷中的更改不会包含在镜像的更新中
-
数据卷的生命周期一直持续到没有容器使用它为止
持久化,容器间继承和共享数据
4.1.3 数据卷的使用
4.1.3.1 设置数据卷
#在运行镜像,启动容器时,挂载数据卷
docker run -it -v /宿主机绝对路径:/容器内目录 镜像名
#注意,数据卷挂载后,数据文件都在宿主机上,可以修改文件,但是在容器内修改是无法修改挂载的文件的,需要加权
docker run -it -v /宿主机绝对路径:/容器目录:ro 镜像名
4.1.3.2验证数据卷的挂载~
#先启动一下 tomcat,让其后台启动
[root@localhost opt]# docker run -v /home/tomcat/data:/usr/local/tomcat/webapps/ROOT -p 8888:8080 -d tomcat
6b29c995fb4223ae7bac7952e23c0a3ad106c6d67ef86c9c5906982984ad367f
#进入容器
[root@localhost opt]# docker exec -it 6b29c995fb bash
root@6b29c995fb42:/usr/local/tomcat# cd webapps
root@6b29c995fb42:/usr/local/tomcat/webapps# ls
ROOT
root@6b29c995fb42:/usr/local/tomcat/webapps# cd ROOT/
#查看容器下是否存在文件
root@6b29c995fb42:/usr/local/tomcat/webapps/ROOT# ls
#退出
root@6b29c995fb42:/usr/local/tomcat/webapps/ROOT# exit
exit
#往数据卷中(挂载文件夹)写入文件及内容
[root@localhost opt]# echo "hello" > /home/tomcat/data/index.html
[root@localhost opt]# cat /home/tomcat/data/index.html
hello
#重新进入容器
[root@localhost opt]# docker exec -it 6b29c995fb bash
#查看文件及内容
root@6b29c995fb42:/usr/local/tomcat# cat webapps/ROOT/index.html
hello
root@6b29c995fb42:/usr/local/tomcat#
验证是否能够访问到:(ip跟上面不一样,是因为早上的时候虚拟机的dhcp重新分配ip,给换了)
注意: 设置了卷,在容器启动后,卷会挂载到容器下,如果此时容器内的卷所在的文件夹有文件,都会被卷内的文件替换掉!如果设置文件的卷,请在启动之前,在卷内放入配置文件
此处,本人踩过坑,设置了配置文件的数据卷,但是容器启动后,容器内的配置文件都失踪了。。。。
5、DockerFile
5.1 DockerFile的介绍
DockerFile是用来构建Docker镜像的构建文件
,是由一系列命令
和参数
构成的脚本
。
学习docker,DockerFile 必须学。因为作为开发,最后开发的程序是需要打包上线的。而要想在docker上运行,必须需要将jar、war包制作成镜像,才可以在docker上运行。
5.1.1 DockerFIle编写
比如:这是从ruoyi-cloud V3.5.0 里面拷贝出来的DockerFile,这是若依团队自己书写的 DockerFile。
这是找了一个简单点的,官方的DockerFile太大,不贴了,有需要自己去找吧:docker官方镜像构建常用DockerFile地址
# 基础镜像
FROM redis
# author
MAINTAINER ruoyi
# 挂载目录
VOLUME /home/ruoyi/redis
# 创建目录
RUN mkdir -p /home/ruoyi/redis
# 指定路径
WORKDIR /home/ruoyi/redis
# 复制conf文件到路径
COPY ./conf/redis.conf /home/ruoyi/redis/redis.conf
参数解析:
指令 | 说明 |
---|---|
FROM | 基础镜像,当前新镜像是基于哪个镜像的,有继承的意味 |
MAINTAINER | 镜像维护者的姓名和邮箱地址 |
RUN | 容器构建时需要运行的命令 |
EXPOSE | 当前容器对外暴露的端口 |
WORKDIR | 指定在创建容器后,终端默认登录的进来工作目录,一个落脚点 |
ENV | 用来在构建镜像过程中设置环境变量 |
ADD | 将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar压缩包 |
COPY | 类似ADD,拷贝文件和目录到镜像中。 将从构建上下文目录中<源路径>的文件/目录复制到新的一层的镜像内的<目标路径>位置 COPY src dest COPY [“src”,“dest”] |
VOLUME | 容器数据卷,用于数据保存和持久化工作 |
CMD | 指定一个容器启动时要运行的命令 Dockerfile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run之后的参数替换 |
ENTRYPOINT | 指定一个容器启动时要运行的命令 ENTRYPOINT的目的和CMD一样,都是在指定容器启动程序及参数,追加命名 |
ONBUILD | 当构建一个被继承的Dockerfile时运行命令,父镜像在被子继承后父镜像的onbuild被触发 |
命令分组
BUILD 构架命令 | BOTH | RUN 运行命令 |
---|---|---|
FROM | WORKDIR | CMD |
MAINTAINER | USER | ENV |
COPY | EXPOSE | |
ADD | VOLUME | |
RUN | ENTRYPOINT | |
ONBUILD | ||
.dockerignore |
5.1.2 构建过程
Dockerfile中的指令需要满足如下的规则
5.1.3 执行流程
DockerFile 执行流程大体如下:
- docker从基础镜像运行一个容器
- 执行一条指令并对容器作出修改
- 执行类似docker commit的操作提交一个新的镜像层
- docker再基于刚提交的镜像运行一个新的容器
- 执行dockerfile中的下一条指令直到所有指令都执行完成
从应用软件的角度来看,Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段,
- Dockerfile是软件的原材料
- Docker镜像是软件的交付品
- Docker容器则可以认为是软件的运行态。
Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及部署与运维,三者缺一不可,合力充当Docker体系的基石。
- Dockerfile,需要定义一个Dockerfile,Dockerfile定义了进程需要的一切东西。Dockerfile涉及的内容包括执行代码或者是文件、环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、服务进程和内核进程(当应用进程需要和系统服务和内核进程打交道,这时需要考虑如何设计namespace的权限控制)等等;
- Docker镜像,在用Dockerfile定义一个文件之后,docker build时会产生一个Docker镜像,当运行 Docker镜像时,会真正开始提供服务;
- Docker容器,容器是直接提供服务的。
5.1.4 运行DockerFile构建镜像
#编写完dockerFile,那如何运行dockerFile,构建镜像
docker build -f dockerfile名称 -t 新建的镜像名:TAG .
最后面那个 点号 不是写错了,而是必须要有的
5.2 详解及实操案例
上面降了一大堆命令及理论,下面验证。
5.2.1 Base镜像
比如咱们在docker官方镜像构建常用DockerFile地址中找到 sig-cloud-instance-images
这个scratch就是base images
,也可以看成java中的Object
5.2.2 自定义镜像1[jar]
开始实操,如何制作自己的镜像
5.2.2.1 编写DockerFile
以RuoYi-Cloud-v3.5.0为例。
-
首先gateway模块先打个jar包,并上传到服务器上。
-
下载基础镜像,咱们的jar是依靠jdk来运行的,所以咱们以jdk作为基础镜像
#jdk 18 2022-03-22 版本 docker pull openjdk:8u322
-
开始编写DockerFile
#openJDK 作为基础镜像 FROM openjdk:8u322 #作者 MAINTAINER system #标签 LABEL name="ruoyi-gateway" version="2.0" auth="mcs" #数据卷 VOLUME /home/gateway/data #创建文件夹 RUN mkdir -p /home/gateway/data #工作目录,进入容器后,落点位置,即进入容器时,所在的文件位置 WOEKDIR /home/gateway #将文件拷贝到容器中 COPY ruoyi-gateway.jar /home/gateway/ruoyi-gateway.jar #执行命令 ENTRYPOINT ["java", "-jar","ruoyi-gateway.jar"]
5.2.2.2 构架镜像
# 为了方便 DockerFile ,我起名就叫DockerFile
[root@localhost gateway]# ll
total 93776
-rw-r--r--. 1 root root 481 2022-06-09 00:12:10 DockerFile
-rw-r--r--. 1 root root 96019360 2022-06-08 23:28:18 ruoyi-gateway.jar
[root@localhost gateway]#docker build -f DockerFile -t gateway:20220609 .
5.2.2.3 镜像构建历史
#不写 TAG,默认TAG为latest
docker history 镜像名称:TAG
dockerFile中每一个指令都相当于一次构建,这就是分层概念。
5.2.2.4CMD及ENTRYPOINT的区别
- Dockerfile中可以有多个CMD指令,但只有最后一个生效。
ENTRYPOINT
命令是在docker run
之后的参数会被当做参数传递给 ENTRYPOINT,之后形成新的组合命令。
5.2.3 自定义镜像2[war]
有上面的基础就不写那么详细了。直接上DockerFile:
FROM centos
MAINTAINER bobo<dengpbs@163.com>
#把宿主机当前上下文的hello.txt拷贝到容器/usr/local/路径下
COPY readme.txt /usr/local/helloincontainer.txt
#把java与tomcat添加到容器中
ADD jdk-8u73-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-8.5.71.tar.gz /usr/local/
#安装vim编辑器
RUN yum -y install vim
#设置工作访问时候的WORKDIR路径,登录落脚点
ENV MYPATH /usr/local
WORKDIR $MYPATH
#配置java与tomcat环境变量
ENV JAVA_HOME /usr/local/jdk1.8.0_73
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.71
ENV CATALINA_BASE /usr/local/apache-tomcat-8.5.71
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
#容器运行时监听的端口
EXPOSE 8080
#启动时运行tomcat
# ENTRYPOINT ["/usr/local/apache-tomcat-8.0.47/bin/startup.sh" ]
# CMD ["/usr/local/apache-tomcat-8.0.47/bin/catalina.sh","run"]
CMD /usr/local/apache-tomcat-8.5.71/bin/startup.sh && tail -F /usr/local/apache-tomcat-8.0.47/bin/logs/catalina.out
本次构建是为了尽量使用多的指令,咱们自己部署的时候,直接使用tomcat作为基础镜像就可以,而且很多tomcat的镜像自带JDk,但是直接tomcat作为镜像,会存在一个问题,或者是大多数镜像都存在的问题。那就是文件系统只能使用unix的命令,很多linux的命令是不能使用的,比如vim、yum等等,且界面奇丑无比。使用Centos作为基础镜像,咱们可以使用yum安装咱们常用的插件及命令。
6、常用软件的安装运行
鉴于咱们上写的那么多,就不放那么东西了,直接上shell脚本。
注意:所有的都是单机启动,不含集群搭建~~~,集群搭建在【高级篇】中
6.1 tomcat
#!/bin/bash
echo "开始下载tomcat镜像======="
docker pull tomcat:8.5-jdk11
echo "======================"
echo "下载结果"
docker images
echo "======================"
echo "开始准备卷=============="
#请注意如果设置了配置文件的卷,请在启动前,将修改好配置文件放到卷内。否则,容器内的配置文件会飞走消失~~~
mkdir -p /home/tomcat/data /home/tomcat/logs /home/tomcat/conf
echo "开始运行tomcat========="
# 注意端口 以及卷的位置
docker run -it -p 9080:8080 --name tomcat-8.5.71 \
-v /home/tomcat/data:/usr/local/apache-tomcat-8.5/webapps/ \
-v /home/tomcat/conf:/usr/local/apache-tomcat-8.5/conf \
-v /home/tomcat/logs/:/usr/local/apache-tomcat-8.5/logs \
--restart=always \
--privileged=true -d tomcat:8.5-jdk11
echo "====================="
echo "运行结果"
docker ps -a
echo "======================"
6.2 nginx
#!/bin/bash
echo "开始下载nginx镜像======="
docker pull nginx:latest
echo "======================"
echo "下载结果"
docker images
echo "======================"
echo "开始准备卷=============="
#请注意如果设置了配置文件的卷,请在启动前,将修改好配置文件放到卷内。否则,容器内的配置文件会飞走消失~~~
mkdir -p /home/nginx/data /home/nginx/logs /home/nginx/conf/conf.d
#======================================================================
#*****注意:nginx.conf 是配置文件
#*****另外conf.d下的配置文件default.conf也要准备
#如果从网上在下载,嫌麻烦可以,先去使用
#docker run -it -p 8010:8010 --name nginx --restart=always -e TZ=Asia/Shanghai
#--privileged=true -d nginx:latest
#启动一下nginx,然后使用cp命令拷贝到卷内。
#示例:docker cp 45f8fcc6a052:/etc/nginx/conf.d/default.conf /home/nginx/conf/conf.d
#示例:docker cp 45f8fcc6a052:/etc/nginx/nginx.conf /home/nginx/conf/
#======================================================================
echo "开始运行nginx========="
# 注意端口 以及卷的位置
docker run -it -p 8010:8010 --name nginx -m 200m \
-v /home/nginx/data:/usr/share/nginx/html/ \
-v /home/nginx/conf/nginx.conf:/etc/nginx/nginx.conf \
-v /home/nginx/conf/conf.d:/etc/etc/nginx/conf.d \
-v /home/nginx/logs/:/usr/local/apache-tomcat-8.5/logs \
--restart=always -e TZ=Asia/Shanghai \
--privileged=true -d nginx:latest
echo "====================="
echo "运行结果"
docker ps -a
echo "======================"
6.3 mysql
#!/bin/bash
echo "开始下载mysql镜像======="
docker pull mysql:5.6
echo "======================"
echo "下载结果"
docker images
echo "======================"
echo "开始准备卷=============="
#请注意如果设置了配置文件的卷,请在启动前,将修改好配置文件放到卷内。否则,容器内的配置文件会飞走消失~~~
mkdir -p /home/mysql/data /home/mysql/logs /home/mysql/conf/
#======================================================================
#*****注意:conf.d下的配置文件需要准备
#如果从网上在下载,嫌麻烦可以,先去使用
#docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.6
#启动一下mysql,然后使用cp命令拷贝到卷内。
#示例:docker cp 45f8fcc6a052:/etc/mysql/conf.d/ /home/nginx/conf/
#======================================================================
echo "开始运行nginx========="
# 注意端口 以及卷的位置
docker run --name mysql -p 3306:3306 \
-v /home/mysql/conf:/etc/mysql/conf.d/ \
-v /home/mysql/data:/var/lib/mysql \
-v /home/mysql/logs/msqld.log:/var/logs/msqld.log \
-e MYSQL_ROOT_PASSWORD=123456 \
--restart=always -d mysql:5.6
echo "====================="
echo "运行结果"
docker ps -a
echo "======================"
6.4 nacos
#!/bin/bash
echo "开始下载nacos镜像======="
#docker pull nacos/nacos-server:v2.1.0
#emmmm....上一版本,下载太鸡儿慢了,换成最新的
docker pull nacos/nacos-server:latest
echo "======================"
echo "下载结果"
docker images
echo "======================"
echo "开始准备卷=============="
#请注意如果设置了配置文件的卷,请在启动前,将修改好配置文件放到卷内。否则,容器内的配置文件会飞走消失~~~
mkdir -p /home/nacos/data /home/nacos/logs /home/nacos/conf/
#======================================================================
#*****注意:conf下的配置文件需要准备
#如果从网上在下载,嫌麻烦可以,先去使用
#docker run --name nacos -p 8848:8848 -p 9848:9848 -p 9849:9849 -e MODE=standalone -d nacos/nacos-server
#启动一下nacos,然后使用cp命令拷贝到卷内。
#示例:docker cp df33291aec0a:/home/nacos/conf /home/nacos/conf/
#示例:docker cp df33291aec0a:/home/nacos/data /home/nacos/data/
#======================================================================
echo "开始运行nacos========="
# 注意端口 以及卷的位置
docker run --name nacos -p 8848:8848 -p 9848:9848 -p 9849:9849 \
-v /home/nacos/conf:/home/nacos/conf \
-v /home/nacos/data:/home/nacos/data \
-v /home/nacos/logs:/home/logs/nacos \
-e MODE=standalone \
--restart=always -d nacos/nacos-server
echo "====================="
echo "运行结果"
docker ps -a
echo "======================"
6.5 redis
#!/bin/bash
echo "开始下载redis镜像======="
docker pull redis:6.2.7
echo "======================"
echo "下载结果"
docker images
echo "======================"
echo "开始准备卷=============="
#请注意如果设置了配置文件的卷,请在启动前,将修改好配置文件放到卷内。否则,容器内的配置文件会飞走消失~~~
mkdir -p /home/redis/data /home/redis/conf/
#======================================================================
#*****注意:conf下的配置文件redis.conf需要自己准备
#======================================================================
echo "开始运行redis========="
# 注意端口 以及卷的位置
docker run --name redis -p 6379:6379 \
-v /home/redis/conf:/usr/local/etc/redis \
-v /home/redis/data:/data \
--restart=always \
-d redis:6.2.7 redis-server /usr/local/etc/redis/redis.conf --appendonly yes
echo "====================="
echo "运行结果"
docker ps -a
echo "======================"
6.6 minio
#!/bin/bash
echo "开始下载minio镜像======="
#弄烦了,直接下载最新版本
docker pull minio/minio:latest
echo "==========下载结果============"
docker images
echo "======================"
echo "======开始准备卷========"
#请注意如果设置了配置文件的卷,请在启动前,将修改好配置文件放到卷内。否则,容器内的配置文件会飞走消失~~~
mkdir -p /home/minio/data /home/minio/conf/
echo "开始运行minio========="
# 注意端口 以及 卷的位置
# 9000 是API端口,9001是 Console的端口
# 注意: Access key length should be at least 3, and secret key length at least 8 characters
# 出现这表示用户名必须大于3个字符,密码必须大于8个字符~~
docker run --name minio -p 9000:9000 -p 9001:9001 \
-v /home/minio/conf:/root/.minio \
-v /home/minio/data:/data \
-e "MINIO_ROOT_USER=admin" \
-e "MINIO_ROOT_PASSWORD=12345678" \
--restart=always \
-d minio/minio:latest server /data --console-address ":9001"
echo "=========运行结果============"
docker ps -a
echo "==========================="
6.7 rocketmq
#!/bin/bash
#开始最麻烦的一个。。。。
#下载roketMq
echo "开始下载rocketmq、rocketmq-console......"
docker pull rocketmqinc/rocketmq:4.4.0
#下载roketmq-console
docker pull styletang/rocketmq-console-ng:latest
echo "======================"
echo "下载结果"
docker images
echo "======================"
#先启动 mqnamesrv,再启动broker,最后启动console
echo "==========开始准备mqnamesrv============"
mkdir -p /home/rocketmq/namesrv/logs /home/rockermq/namesrv/data/store
echo "开始运行mqnamesrv......."
docker run --name rmqnamesrv -p 9876:9876 \
-v /home/rocketmq/namesrv/logs:/root/logs \
-v /home/rockermq/namesrv/data/store:/root/store \
-e "MAX_POSSIBLE_HEAP=100000000" \
-e "JAVA_OPT_EXT=-server -Xms128m -Xmx128m" \
--restart=always \
-d rocketmqinc/rocketmq sh mqnamesrv
echo "=========运行结果============"
docker ps -a
echo "==========================="
echo "开始准备broker........."
mkdir -p /home/rocketmq/borker/logs /home/rockermq/borker/data/store /home/rockermq/borker/conf
touch /home/rockermq/borker/conf/broker.conf
echo "开始写入broker配置文件........"
tee /home/rockermq/borker/conf/broker.conf <<-'EOF'
# 所属集群名称,如果节点较多可以配置多个
brokerClusterName = DefaultCluster
#broker名称,master和slave使用相同的名称,表明他们的主从关系
brokerName = broker-a
#0表示Master,大于0表示不同的slave
brokerId = 0
#表示几点做消息删除动作,默认是凌晨4点
deleteWhen = 03
#在磁盘上保留消息的时长,单位是小时
fileReservedTime = 48
#有三个值:SYNC_MASTER,ASYNC_MASTER,SLAVE;同步和异步表示Master和Slave之间同步数据的机制;
brokerRole = ASYNC_MASTER
#刷盘策略,取值为:ASYNC_FLUSH,SYNC_FLUSH表示同步刷盘和异步刷盘;SYNC_FLUSH消息写入磁盘后才返回成功状态,ASYNC_FLUSH不需要;
flushDiskType = ASYNC_FLUSH
# 设置broker节点所在服务器的ip地址
brokerIP1 = 192.168.57.130
# 磁盘使用达到95%之后,生产者再写入消息会报错 CODE: 14 DESC: service not available now, maybe disk full
diskMaxUsedSpaceRatio=95
EOF
echo "broker配置文件写入完成........."
echo "开始运行broker........."
docker run --name rmqbroker --restart=always --link rmqnamesrv:namesrv \
-p 10911:10911 -p 10909:10909 \
-v /home/rocketmq/borker/logs:/root/logs \
-v /home/rockermq/borker/data/store:/root/store \
-v /home/rockermq/borker/conf/broker.conf:/opt/rocketmq-4.4.0/conf/broker.conf \
-e "NAMESRV_ADDR=namesrv:9876" \
-e "MAX_POSSIBLE_HEAP=200000000" \
-d rocketmqinc/rocketmq sh mqbroker -c /opt/rocketmq-4.4.0/conf/broker.conf
echo "=========运行结果============"
docker ps -a
echo "==========================="
echo "开始启动rocketmq-console........"
docker run --name rmqadmin -p 8090:8080 \
--link rmqnamesrv:rmqnamesrv \
-e "JAVA_OPTS=-Drocketmq.namesrv.addr=rmqnamesrv:9876 -Dcom.rocketmq.sendMessageWithVIPChannel=false" \
--restart=always \
-d styletang/rocketmq-console-ng:latest
echo "=========运行结果============"
docker ps -a
echo "==========================="
7、附录OPTIONS参数说明
OPTIONS | 说明 |
---|---|
–add-host list | 添加自定义主机到ip映射(书写格式为:主机:ip) |
-a, --attach list | 附加到STDIN、STDOUT或STDERR上 |
–blkio-weight uint16 | Block IO (相对权重),取值10到1000之间,0为禁用(默认0) |
–blkio-weight-device list | Block IO weight (相对于设备的权重) (默认为数组的形式) |
–cap-add list | 添加Linux功能 |
–cap-drop list | 删除Linux功能 |
–cgroup-parent string | 容器的可选父级对照组项 |
–cidfile string | 将容器ID写入文件 |
–cpu-period int | 限制CPU CFS(完全公平调度程序)周期 |
–cpu-quota int | 限制CPU CFS(完全公平的调度程序)上限 |
–cpu-rt-period int | 限制CPU运行时周期(以微秒为单位) |
–cpu-rt-runtime int | 限制CPU实时运行时间(以微秒为单位) |
-c, --cpu-shares int | CPU 共享 (相对权重的设定) |
–cpus decimal | 设定cpu的数量 |
–cpuset-cpus string | 允许执行的cpu (0-3,0,1) |
–cpuset-mems string | 允许执行的MEMs (0-3,0,1) |
-d, --detach | 在后台运行容器并打印容器ID |
–detach-keys string | 覆盖分离容器的键序列 |
–device list | 向容器添加主机设备 |
–device-cgroup-rule list | 向 cgroup 允许的设备列表中添加一个或多个规则 |
–device-read-bps list | 限定设备的读取速率(单位: byte/s)(默认为 []) |
–device-read-iops list | 限定设备的读取速率(单位:IO/s)(默认为 []) |
–device-write-bps list | 限定设备的写入速率(单位: byte/s)(默认为 []) |
–device-write-iops list | 限定设备的写入速率(单位:IO/s)(默认为 []) |
–disable-content-trust | 跳过镜像验证(默认为 true) |
–dns list | 设置自定义DNS服务器 |
–dns-option list | 设置DNS选项 |
–dns-search list | 设置自定义的DNS搜索域 |
–entrypoint string | 覆盖镜像的默认入口点 |
-e, --env list | 设置环境变量 |
–env-file list | 读取环境变量内容 |
–expose list | 公开一个端口或多个端口 |
–group-add list | 添加其他要加入的组 |
–health-cmd string | 命令运行以检查健康 |
–health-interval duration | 运行检查之间的时间(ms|s|m|h)(默认为 0s) |
–health-retries int | 连续的失败需要报告不健康 |
–health-start-period duration | 启动健康重试倒计时前容器初始化的启动周期(ms|s|m|h)(默认为 0s) |
–health-timeout duration | 健康检查运行情况的最大时间值 格式为:(ms|s|m|h) (默认 0s) |
–help | 打印出使用情况 |
-h, --hostname string | 定义容器主机名 |
–init | 在容器中运行初始化,以转发信号并获取进程 |
-i, --interactive | 即使没有连接,也保持STDIN开放 |
–ip string | 设定容器的 IPv4 地址 (例如,192.168.155.139) |
–ip6 string | 设定IPv6地址(例如,2001:db8::33) |
–ipc string | 使用IPC模式 |
–isolation string | 容器隔离技术 |
–kernel-memory bytes | 内核内存限制 |
-l, --label list | 在容器上设置元数据 |
–label-file list | 在以行分隔的标签文件中读取 |
–link list | 向另一个容器添加链接 |
–link-local-ip list | 容器 IPv4/IPv6 链接本地地址 |
–log-driver string | 设定容器的日志驱动 |
–log-opt list | 设定日志驱动器选项 |
–mac-address string | 配置容器MAC地址(例如,92:d0:c6:0a:29:33) |
-m, --memory bytes | 设定内存限额 |
–memory-reservation bytes | 内存软限制 |
–memory-swap bytes | 交换限制等于内存加上交换:‘-1’,以启用无限交换 |
–memory-swappiness int | 优化容器内存交换 (0 到 100) (默认为 -1) |
–mount mount | 将文件系统挂载附加到容器 |
–name string | 为容器指定一个名称 |
–network string | 将容器连接到网络 |
–network-alias list | 为容器连接的网络添加别名 |
–no-healthcheck | 禁止任何容器指定 HEALTHCHECK |
–oom-kill-disable | 禁止OOM事件被杀死 |
–oom-score-adj int | 优化主机的OOM事件 ,参数范围 (-1000 到 1000) |
–pid string | 设定PID命名 |
–pids-limit int | 优化容器pid限制(如果设置-1则为无限制) |
–privileged | 赋予容器扩展的权限 |
-p, --publish list | 将容器的端口发布到主机 |
-P, --publish-all | 将所有公开的端口发布到随机端口 |
–read-only | 将容器的根文件系统挂载为只读(后面会详细讲到) |
–restart string | 配置容器的重启策略,当容器退出时重新启动(默认为“no”) |
–rm | 当容器退出时自动移除这个容器 |
–runtime string | 使用容器的运行时 |
–security-opt list | 指定docker启动的安全项 |
–shm-size bytes | /dev/shm 的大小(这个可以使其容量进行动态的扩展) |
–sig-proxy | 设置代理接收京城信号 (默认为 true) |
–stop-signal string | 停止容器的信号 (默认为 “SIGTERM”) |
–stop-timeout int | 设置超时停止容器(以秒为单位) |
–storage-opt list | 设定容器的存储驱动程序选项 |
–sysctl map | 指定系统控制项 (默认为 map[] 的格式) |
–tmpfs list | 挂载tmpfs目录 |
-t, --tty | 为当前容器分配一个客户端 |
–ulimit ulimit | 启动需要限制的项(默认为数组的形式) |
-u, --user string | 用户名或UID(格式为: <name|uid>[:<group|gid>]) |
–userns string | 使用用户名称空间 |
–uts string | 使用UTS名称空间 |
-v, --volume list | 绑定安装卷(关于容器卷,在Docker容器数据卷中会具体的讲解) |
–volume-driver string | 容器的可选卷驱动程序 |
–volumes-from list | 指定容器装载卷 |
-w, --workdir string | 容器内的工作目录 |
–shm-size bytes | /dev/shm 的大小(这个可以使其容量进行动态的扩展) |
–sig-proxy | 设置代理接收京城信号 (默认为 true) |
–stop-signal string | 停止容器的信号 (默认为 “SIGTERM”) |
–stop-timeout int | 设置超时停止容器(以秒为单位) |
–storage-opt list | 设定容器的存储驱动程序选项 |
–sysctl map | 指定系统控制项 (默认为 map[] 的格式) |
–tmpfs list | 挂载tmpfs目录 |
-t, --tty | 为当前容器分配一个客户端 |
–ulimit ulimit | 启动需要限制的项(默认为数组的形式) |
-u, --user string | 用户名或UID(格式为: <name|uid>[:<group|gid>]) |
–userns string | 使用用户名称空间 |
–uts string | 使用UTS名称空间 |
-v, --volume list | 绑定安装卷(关于容器卷,在Docker容器数据卷中会具体的讲解) |
–volume-driver string | 容器的可选卷驱动程序 |
–volumes-from list | 指定容器装载卷 |
-w, --workdir string | 容器内的工作目录 |