1.什么是 Docker
Docker 是 Docker 公司的开源项目,使用 Google 公司推出的 Go 语言开发的,并于 2013 年 3 月以 Apache 2.0 授权协议开源,主要项目代码在 GitHub 上进行维护。
下面的图片比较了 Docker 和传统虚拟化方式的不同之处。传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。
2.为什么要使用 Docker?
2.1 更高效的利用系统资源
由于容器不需要进行硬件虚拟以及运行完整操作系统等额外开销,Docker 对系统资源的利用率更高。无论是应用执行速度、内存损耗或者文件存储速度,都要比传统虚拟机技术更高效。因此,相比虚拟机技术,一个相同配置的主机,往往可以运行更多数量的应用。
2.2 更快速的启动时间
传统的虚拟机技术启动应用服务往往需要数分钟,而 Docker 容器应用,由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间。
2.3 一致的运行环境
开发过程中一个常见的问题是环境一致性问题。由于开发环境、测试环境、生产环境不一致,导致有些 bug 并未在开发过程中被发现。而 Docker 的镜像提供了除内核外完整的运行时环境,确保了应用运行环境一致性,从而不会再出现 “这段代码在我机器上没问题啊” 这类问题。
2.4 持续交付和部署
对开发和运维人员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。
使用 Docker 可以通过定制应用镜像来实现持续集成、持续交付、部署。开发人员可以通过 Dockerfile 来进行镜像构建,并结合 持续集成系统进行集成测试,而运维人员则可以直接在生产环境中快速部署该镜像,甚至结合持续部署系统进行自动部署。
而且使用 Dockerfile 使镜像构建透明化,不仅仅开发团队可以理解应用运行环境,也方便运维团队理解应用运行所需条件,帮助更好的生产环境中部署该镜像。
2.5 更轻松的迁移
由于 Docker 确保了执行环境的一致性,使得应用的迁移更加容易。Docker 可以在很多平台上运行,无论是物理机、虚拟机、公有云、私有云,甚至是笔记本,其运行结果是一致的。因此用户可以很轻易的将在一个平台上运行的应用,迁移到另一个平台上,而不用担心运行环境的变化导致应用无法正常运行的情况。
2.6 更轻松的维护和扩展
Docker 使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。此外,Docker 团队同各个开源项目团队一起维护了一大批高质量的官方镜像,既可以直接在生产环境使用,又可以作为基础进一步定制,大大的降低了应用服务的镜像制作成本。
2.7 对比传统虚拟机总结
3 基本概念
Docker 包括三个基本概念
- 镜像(Image)
- 容器(Container)
- 仓库(Repository)
理解了这三个概念,就理解了 Docker 的整个生命周期。
3.1 Docker 镜像
我们都知道,操作系统分为内核和用户空间。对于 Linux 而言,内核启动后,会挂载 root 文件系统为其提供用户空间支持。而 Docker 镜像,就相当于是一个 root 文件系统。比如 Docker 官方镜像 ubuntu:14.04 就包含了完整的一套 Ubuntu 14.04 最小系统的 root 文件系统。
Docker 镜像是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。镜像不包含任何动态数据,其内容在构建之后也不会被改变。
3.2 Docker 容器
镜像和容器的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。
每一个容器运行时,是以镜像为基础层,在其上创建一个当前容器的存储层,我们可以称这个为容器运行时读写而准备的存储层为容器存储层。
容器存储层的生存周期和容器一样,容器消亡时,容器存储层也随之消亡。因此,任何保存于容器存储层的信息都会随容器删除而丢失。
按照 Docker 最佳实践的要求,容器不应该向其存储层内写入任何数据,容器存储层要保持无状态化。所有的文件写入操作,都应该使用 数据卷(Volume)、或者绑定宿主目录,在这些位置的读写会跳过容器存储层,直接对宿主(或网络存储)发生读写,其性能和稳定性更高。
数据卷的生存周期独立于容器,容器消亡,数据卷不会消亡。因此,使用数据卷后,容器可以随意删除、重新 run,数据却不会丢失。
3.3 Docker 仓库
镜像构建完成后,可以很容易的在当前宿主上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry 就是这样的服务。
3.4 安装 Docker
官方网站上有各种环境下的 安装指南,这里主要介绍下 CentOS 的安装。
4 CentOS 操作系统安装 Docker
4.1 系统要求
Docker 需要安装在 CentOS 7 64 位的平台,并且内核版本不低于 3.10. CentOS 7.× 满足要求的最低内核版本要求,但由于 CentOS 7 内核版本比较低,部分功能(如 overlay2 存储层驱动)无法使用,并且部分功能可能不太稳定。所以建议大家升级到最新的 CentOS 版本,并且内核也更新到最新的稳定版本。
4.2 使用阿里云的安装脚本自动安装
为了简化 Docker 安装流程,我们可以使用阿里云提供的一套安装脚本,CentOS 系统上可以使用这套脚本安装 Docker :
首先,查看阿里云ECS Linux服务器系统内核版本:
1 | uname -r |
安装epel
1 | yum install epel-release -y |
1 | yum clean all |
1 | yum list |
会出现非常多的包
yum安装docker-io
1 | sudo yum -y install docker-io |
安装成功,最终会出现Complete字样
启动Docker
1 | systemctl start docker |
检查Docker服务,一般出现下图的信息说明Docker初步是安装成功的
1 | docker info |
执行这个命令后,脚本就会自动的将一切准备工作做好,并且把 Docker 安装在系统中。
Docker 通过运行 hello-world 映像验证是否正确安装。
1 | $ docker run hello-world |
此命令下载测试镜像并在容器中运行它。当容器运行时,它打印一条信息消息并退出。如果你没有配置镜像加速器的话,运行 hello-world 映像验证也是不会成功的.因为国内网络的原因,无法下载测试镜像,更别说运行测试镜像了,所以这一步可以先跳过,继续往下看,等一下配置完镜像加速器再来验证.
查看当前 Docker 的版本
1 | $ docker -v |
可以看出当前的 Docker 为 Docker CE 17.05.0 版本,CE 代表 Docker 社区版,EE 代表 Docker 企业版.
卸载 Docker CE
卸载Docker软件包:
1 | $ yum remove docker-ce |
卸载旧版本 Docker
较老版本的 Docker 被称为 docker 或 docker-engine。如果这些已安装,请卸载它们以及关联的依赖关系。
1 | $ yum remove docker docker-common docker-selinux docker-engine |
主机上的图像,容器,卷或自定义配置文件不会自动删除。必须手动删除任何已编辑的配置文件。删除所有图像,容器和卷:
1 | $ rm -rf /var/lib/docker |
给镜像打标签
1 | docker tag ubuntu ubuntu1 |
改变tag值,区分标签
1 | docker tag ubuntu ubuntu2:123 |
1 | docker run -itd centos //把镜像启动为容器,-i表示让容器的标准输入打开,-t表示分配一个伪终端,-d表示后台启动 |
检查加速器是否生效
Linux系统下配置完加速器需要检查是否生效,在命令行执行 ps -ef | grep dockerd,如果从结果中看到了配置的 –registry-mirror 参数说明配置成功。
1 | $ sudo ps -ef | grep dockerd |
使用 Docker 镜像
Docker 运行容器前需要本地存在对应的镜像,如果镜像不存在本地,Docker 会从镜像仓库下载(默认是 Docker Hub 公共注册服务器中的仓库)。
获取镜像
阿里云镜像库 上有大量的高质量的镜像可以用,这里我们就说一下怎么获取这些镜像并运行。
获取镜像的命令是 docker pull。其命令格式为:
docker pull [选项] [Docker Registry地址]<仓库名>:<标签>
具体的选项可以通过 docker pull –help 命令看到,这里我们说一下镜像名称的格式。
Docker Registry地址:地址的格式一般是 <域名/IP>[:端口号]。默认地址是 Docker Hub。
仓库名:如之前所说,这里的仓库名是两段式名称,既 <用户名>/<软件名>。对于 Docker Hub,如果不给出用户名,则默认为 library,也就是官方镜像.一定要配置镜像加速器,不然下载速度很慢。
比如:
1 | $ docker pull ubuntu:14.04 |
上面的命令中没有给出 Docker Registry 地址,因此将会从 Docker Hub 获取镜像。而镜像名称是 ubuntu:14.04,因此将会获取官方镜像 library/ubuntu 仓库中标签为 14.04 的镜像。
查看已下载的镜像
要想列出已经下载下来的镜像,可以使用 docker images 命令。
1 | $ docker images |
列表包含了仓库名、标签、镜像 ID、创建时间以及所占用的空间。
运行
有了镜像后,我们就可以以这个镜像为基础启动一个容器来运行。以上面的 ubuntu:14.04 为例,如果我们打算启动里面的 bash 并且进行交互式操作的话,可以执行下面的命令。
1 | $ docker run -it --rm ubuntu:14.04 bash |
docker run 就是运行容器的命令,具体格式我们会在后面的章节讲解,我们这里简要的说明一下上面用到的参数。
-it:这是两个参数,一个是 -i:交互式操作,一个是 -t 终端。我们这里打算进入 bash 执行一些命令并查看返回结果,因此我们需要交互式终端。
–rm:这个参数是说容器退出后随之将其删除。默认情况下,为了排障需求,退出的容器并不会立即删除,除非手动 docker rm。我们这里只是随便执行个命令,看看结果,不需要排障和保留结果,因此使用 –rm 可以避免浪费空间。
ubuntu:14.04:这是指用 ubuntu:14.04 镜像为基础来启动容器。
bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 bash。
进入容器后,我们可以在 Shell 下操作,执行任何所需的命令。这里,我们执行了 cat /etc/os-release,这是 Linux 常用的查看当前系统版本的命令,从返回的结果可以看到容器内是 Ubuntu 14.04.5 LTS 系统。
最后我们通过 exit 退出了这个容器。
定制镜像
现在让我们以定制一个 Web 服务器为例子,来讲解镜像是如何构建的。
安装nginx
1 | docker run -it --name my-nginx -d -p 80:80 nginx |
这条命令会用 nginx 镜像启动一个容器,命名为 webserver,并且映射了 80 端口,这样我们可以用浏览器去访问这个 nginx 服务器。
如果是在 Linux 本机运行的 Docker,或者如果使用的是 Docker for Mac、Docker for Windows,那么可以直接访问:http://localhost;如果使用的是 Docker Toolbox,或者是在虚拟机、云服务器上安装的 Docker,则需要将 localhost 换为虚拟机地址或者实际云服务器地址,还要配置安全组放通对应的端口。
直接用浏览器访问的话,我们会看到默认的 Nginx 欢迎页面。
5 Docker的使用
5.1 Docker通过容器创建镜像
通过docker run -it –rm centos bash启动容器后,bash为进入容器后我们要执行的命令,这样就可以打开一个终端
进入到改容器中,我们做一些变更,比如安装一些东西,然后针对这个容器进行创建新的镜像
想要查看net信息,ifcongif出现command not found,在容器中执行yum install -y net-tools
1 | docker commit -m "change somth" -a "somebody info" container_id new_image_name //container_id通过docker ps -a 获取,后面的new_image_name为新镜像的名字 |
例如:docker commit -m “install net-tools” -a “amingLinux” ea4d8441675e centos_nettools
这个命名有点像svn的提交,-m 加一些改动信息,-a 指定作者相关信息,ea4d8441675e这一串为容器Id,再后面为新镜像的名字。
5.2 Docker使用模板创建镜像
首先去下载一个模板 https://openvz.org/Download/templates/precreated
导入改镜像的命令为:cat centos-6-x86-minimal.tar.gz|docker import - centos6
docker images查看导入的镜像
把现有镜像导出为一个文件:docker save -o aming-centos.tar
我们还可以用该文件恢复本地镜像:docker load –input aming-centos.tar 或者 docker load < aming-centos.tar
docker push image_name //可以把自己的镜像传到dockerhub官方网站上去,但前提是需要先注册一个用户,后续如果有需求在间就吧
5.3 Docker容器管理
docker create -it centos6 bash //这样就可以创建一个容器,但该容器并没有启动
docker start container_id //启动容器后,可以使用docker ps 查看到,有start就有stop和restart
之前我们使用的docker run 相当于先create再start
docker run -it centos bash
这样就进入到了一个虚拟终端里面,我们可以运行一些命令,使用命令exit或ctrl d 退出该bash,当退出后这个容器也会停止
docker run -d 可以让容器在后台运行
比如:docker run -d centos bash -c “while :;do echo “123”;sleep 2;done”
docker run –name web -itd centos bash //–name给容器自定义名字
docker run –rm -it centos bash -c “sleep 30” //–rm可以让容器退出后直接删除,在这里命令执行完容器就会退出
docker logs 可以获取容器运行历史信息,用法如下
1 | docker logs container_id |
docker attach 可以进入一个后台运行的容器,比如
docker attach container_id //但是attach命令不算好用,比如我们想退出终端,就得exit了,这样容器也就退出了,还有一种方法
docker exec -it container_id bash //可以临时打开一个虚拟终端,但exit后容器依然运行着
docker rm container_id //container_id是ps的时候查看到的,这样就可以把container删除,如果是运行的容器可以加-f
docker export container_id > file.tar //导出容器,可以迁移到其他机器上,需要导入
cat file.tar |docker import -aming_test //这样会生成aming_test的镜像
5.4 Docker仓库管理
配置私有仓库
docker pull registry //下载registry镜像,registry为Docker官方提供的一个镜像,我们可以用它来创建本地的Docker私有仓库
docker run -d -p 5000:5000 registry //以registry镜像启动容器,-p会把容器的端口映射到宿主机上,:左边为宿主机监听端口,:右边为容器监听端口
curl 127.0.0.1:5000/v2/_catalog //可以访问它
下面我们来把其中一个镜像上传到私有仓库
第一步打tag
1 | docker tag aming_test 172.7.15.113:5000/centos //标记一下tag,必须要带有私有仓库的ip:port |
第二步push
docker push 172.7.15.113:5000/centos //把标记的镜像给推送到私有的仓库
出现:The push refers to a repository [47.95.112.137:5000/centos6]
An image does not exist locally with the tag: 47.95.112.137:5000/centos6
此时并不会成功需指定私有仓库地址,更改配置文件,vi /etc/docker/daemon.json,添加{“insecure-registries”:[“172.7.15.113:5000”]}
重启systemctl restart docker , docker ps -a 查看容器已经关闭,还需要重启
docker start id //这里的id为registry容器id
再次push
docker push 172.7.15.113:5000/centos
curl 127.0.0.1:5000/v2/_catalog //可以查看到推送上来的镜像
从私有仓库下载镜像
docker pull 172.7.15.113:5000/centos
5.5 Docker数据管理
1 挂载本地的目录到容器里
docker run -tid -v /data/:/data centos bash //-v用来指定挂载目录,:前面的/data/为宿主机本地目录,:后面的/data/为容器里的目录,会在容器中自动创建
2 挂载数据卷
其实我们挂载目录的时候,可以指定容器name,如果不指定就随机定义了。比如上面我们没有指定,它就生成了一个名字为relaxed_franklin,这个名字可以使用命令docker ps 看最右侧一列
docker run -itd –volumes-from relaxed_franklin aming123 bash //relaxed_franklin为容器名,docker ps可知
这样,我们使用aming123镜像创建了新的容器,并且使用了relaxed_franklin容器的数据卷
3 定义数据卷容器
有时候,我们需要多个容器之间相互共享数据,类似于linux里的NFS,所以就可以搭建一个专门的数据卷容器,然后其他容器直接挂在改数据卷
首先建立数据卷容器
docker run -itd -v /data/ –name testvol centos bash //注意这里的/data/是容器的/data目录,并非本地的/data/目录
然后让其他容器挂载改数据卷
docker run -itd –volumes-from testvol aming123 bash //testvol为数据卷容器名,aming123为镜像
如果想home目录也共享 mv /home/ /home.1; ln -s /data/ home //软链接
4 数据卷管理 - 数据卷的备份与恢复
备份
1 | mkdir /vol_data_backup |
说明:首先我们需要使用testvol数据卷新开一个容器,同时我们还需要把本地的/vol_data_backup/目录挂载到改容器的/backup下,这样在容器中/backup目录里面新建的文件
我们就可以直接在/vol_data_backup/目录中看到了。然后再把/data/目录下面的文件打包成data.tar文件放到/backup目录下面
恢复
思路:先新建一个数据卷容器,在建一个新的容器并挂载该数据卷容器,然后再把tar包解压。
新建数据卷容器:docker run -itd -v /data/ –name testvol2 aming/centos bash
挂载数据卷新容器,并解包:docker run –volumes-from testvol2 -v /vol_data_backup/:/backup aming/centos tar xvf /backup/data.tar
5 Docker网络模式
- host模式,使用docker run 时使用–net=host指定
docker使用的网络实际上和宿主机一样,在容器内看到的网卡ip是宿主机ip
- container模式,使用–net=container:container_id/container_name
多个容器使用共同的网络,看到的ip是一样的
none模式,使用–net=none指定,这种模式下,不会配置任何网络
bridge模式,使用–net=bridge指定默认模式,不用指定默认就是这种网络模式
这种模式会为每个容器分配一个独立的Network Namespace。 类似于vmware的nat网络模式。同一个宿主机上的所有容器会在同一个网段下,相互之间是可以通信的。
6 Docker网络管理 - 外部访问容器
首先使用centos镜像新建一个容器,然后在该容器中安装httpd服务并启动
再把该容器导成一个新的镜像(centos-httpd),然后再使用新镜像创建容器并指定端口映射
docker run -itd -p 5123:80 centos-httpd bash //-p 可以指定端口映射,本例中将容器的80端口映射为本地的5123端口
docker exec -it container_id bash
启动httpd:httpd -k start
编辑1.html:vi/var/www/html/1.html 随便写点东西
退出该容器:exit
测试:curl 127.0.0.1:5123/1.html
-p后面也支持IP:port:ip:port的格式,比如:-p 127.0.0.1:8080:80
也可以不写本地的端口,只写ip,这样会随意分配一个端口
-p 127.0.0.1::80 //注意这里是两个冒号
***例如:
进入容器里下载nginx
yum install -y epel-release
yum install -y nginx
此时启动nginx会报错systemctl start nginx Failed to get D-Bus connection: Operation not permitted
安装完成nginx,将容器打包成镜像,
运行镜像映射端口:
内网curl localhost和外网curl 宿主机ip:8088均可访问
Operation not permitted
新建的容器,启动nginx或者httpd服务的时候会报错
Failed to get D-Bus connection:Operation not permitted,这是因为dbus-daemon没有启动,解决该问题可以这样做
启动容器时,要加上–privileged -e “container=docker” , 并且最后面的命令改为/usr/sbin/init
docker run run -itd –privileged -e “container=docker” -p 8088:80 centos_with_nginx /usr/sbin/init
7 Docker网络管理 - 容器互联
下载一个mysql镜像 docker pull mysql
新建一个容器命名为db , docker run -it -d -p 13306:3306 –name db mysql bash
在新建一个web容器,并和db互联
docker run -it -d -p 12308:80 –name web –link db:db centos-httpd bash //db:db意思为db容器在web容器里的别名为db
在web上运行env命令可以查看到关于db环境变量
8 Docker网络管理 - 配置桥接网络
为了使本地网络中的机器和Docker容器更方便的通信,我们经常会有将Docker容器配置到和主机同一网段的需求。这个需求其实很容易实现,我们只要将Docker容器和宿主机的网卡桥接起来,再给Docker容器配上ip就可以了。
cd /etc/sysconfig/network-scripts/; cp ifcfg-eth0 ifcfg-br0
vi ifcfg-eth0 //增加BRIDGE=br0, 删除IPADDR,NETMASK,GATEWAY, DNS1
vi ifcfg-br0 //修改DEVICE为br0, Type为bridge,把eth0的网络设置到这里来
systemctl restart network
安装pipwork
git clone https://github.com/jpetazzo/pipwork
cp pipework/pipework /usr/local/bin/
开启一个容器
docker run -itd –net=none –name aming123 centos_with_nettool bash
pipework br0 aming123 172.7.15.201/24@172.7.15.3 // #201为容器的ip,@后面的ip为网关ip
docker exec -it aming123 bash //#进去后ifconfig查看就可以看到新添加的ip
9 Dockerfile创建镜像 - dockerfile格式
- FROM //指定基于哪个基础镜像
格式 FROM
- MAINTAINER //指定作者信息
格式:MAINTAIN
- RUN //镜像操作指令
格式为 RUN
比如:RUN yum install httpd , RUN [“/bin/bash”,”-c”,”echo hello”]
- CMD //三种格式
CMD [“executable”,”param1”,”param2”]
CMD command param1 param2
CMD [“param1”,”param2”]
RUN和CMD看起来挺像,但是CMD用来指定容器启动时用到的命令,只能有一条。比如:
CMD [“/bin/bash”,”/usr/local/nginx/sbin/nginx”,”-c”,”/usr/local/nginx/conf/nginx.conf”]
- EXPOSE
格式为 EXPOSE
这个用来指定要映射出去的端口,比如容器内部我们启动了sshd和nginx,所以我们需要把22和80端口暴露出去。这个需要配合-P(大写)来工作,也就是说在启动容器时,需要加上-P,让它自动分配。如果想指定具体的端口,也可以使用-p(小写)来指定。
- ENV
格式 ENV
ENV PATH /usr/local/mysql/bin:$PATH
它主要是为后续的RUN指令提供一个环境变量,我们也可以定义一些自定义的变量
ENV MYSQL_version 5.6
- ADD 格式add
将本地的一个文件或目录拷贝到容器的某个目录里。其实src为Dockerfile所在目录的相对路径,它也可以是一个url。比如: ADD <conf/vhosts> </usr/local/nginx/conf>
- COPY
格式同add,使用方法和add一样,不同的是,它不支持url
- ENTRYPOINT 格式类似CMD
容器启动时要执行的命令,它和CMD很像,也是只有一条生效,如果写多个只有最后一条生效。和CMD不同是:
CMD是可以被docker run 指令覆盖的,而ENTRYPOINT不能覆盖。比如,容器名字为aming,我们在Dockerfile中指定如下CMD:
CMD [“/bin/echo”,”test”]
启动容器的命令是docker run aming 这样会输出test, 假如启动容器的命令是docker run -it aming /bin/bash 什么都不会输出
ENTRYPOINT不会被覆盖,而且会比CMD或者docker run指定的命令要靠前执行
ENTRYPOINT [“echo”,”test”]
docker run -it aming 123
则会输出test 123 ,这相当于要执行命令echo test 123
- VOLUME
格式 VOLUME [“/data”]
创建一个可以从本地主机或其他容器挂载的挂载点
- USER
格式 USER daemon
指定运行容器的用户
- WORKDIR /path/to/workdir
为后续的RUN、CMD或者ENTRYPOINT指定工作目录
- Dockerfile创建镜像 - Dockerfile示例
先下载nginx的配置文件
wget http://www.apelearn.com/study_v2/nginx_conf
vim Dockerfile //内容如下
##Set the base image to CentOS
FROM centos
#File Author / Maintainer
MAINTAINER aming aming@aminglinux.com
#Install necessary tools
RUN yum install -y pcre-devel wget net-tools gcc zlib-devel make openssl-devel
#Install Nginx
ADD http://nginx.org/download/nginx-1.8.0.tar.gz .
RUN tar zxvf nginx-1.8.0.tar.gz
RUN mkdir -p /usr/local/nginx
RUN cd nginx-1.8.0 && ./configure –prefix=/usr/local/nginx && make && make install
RUN rm -fv /usr/local/nginx/conf/nginx.conf
ADD http://www.apelearn.com/study_v2/ .nginx_conf /usr/local/nginx/conf/nginx.conf
Expose ports
EXPOSE 80
Set the default command to execute when creating a new container
ENTRYPOINT /usr/local/nginx/sbin/nginx && tall -f /etc/passwd
创建镜像
docker build -t centos_nginx . //.表示在哪个路径下
docker images //可以看到我们新建的镜像
docker run -itd -p 8088:80 centos_nginx bash