第一:什么是Docker?
在Docker之前,我们肯定要先了解Docker是什么。官网的介绍是“Docker is the world’s leading software container platform.”官方给Docker的定位是一个应用容器平台。至于为什么要做这个Docker,官网上还有这么一句话"Docker is an open platform for developers and sysadmins to build, ship, and run distributed applications, whether on laptops, data center VMs, or the cloud."这句话用一句非常简单的话去概括就是"Build once,Run anyWhere".这一点跟Java很像。
那么它这样做是要解决现实中什么问题,我列举 3 个情况。
1、合作开发的时候,在本机可以跑,别人的电脑跑不起来。
这里我们拿java Web应用程序举例,我们一个java Web应用程序涉及很多东西,比如jdk、tomcat、spring等等。当这些其中某一项版本不一致的时候,可能就会导致应用程序跑不起来这种情况。Docker则将程序直接打包成镜像,直接运行在容器中即可。
2、服务器自己的程序挂了,结果发现是别人程序出了问题把内存吃完了,自己程序因为内存不够就挂了。
这种也是一种比较常见的情况,如果你的程序重要性不是特别高的话,公司基本上不可能让你的程序独享一台服务器的,这时候你的服务器就会跟公司其他人的程序共享一台服务器,所以不可避免地就会受到其他程序的干扰,导致自己的程序出现问题。Docker就很好解决了环境隔离的问题,别人程序不会影响到自己的程序。
3、公司要弄一个活动,可能会有大量的流量进来,公司需要再多部署几十台服务器。
在没有Docker的情况下,要在几天内部署几十台服务器,这对运维来说是一件非常折磨人的事,而且每台服务器的环境还不一定一样,就会出现各种问题,最后部署地头皮发麻。用Docker的话,我只需要将程序打包到镜像,你要多少台服务,我就给力地跑多少容器,极大地提高了部署效率。
第二:Docker与虚拟机的区别
关于Docker与虚拟机的区别,我在网上找到的一张图,非常直观形象地展示出来,话不多说,直接上图。
比较上面两张图,我们发现虚拟机是携带操作系统,本身很小的应用程序却因为携带了操作系统而变得 非常大,很笨重。Docker是不携带操作系统的,所以Docker的应用就非常的轻巧。另外在调用宿主机的 CPU、磁盘等等这些资源的时候,拿内存举例,虚拟机是利用Hypervisor去虚拟化内存,整个调用过程是 虚拟内存->虚拟物理内存->真正物理内存,但是Docker是利用Docker Engine去调用宿主的的资源,这时 候过程是虚拟内存->真正物理内存。
第三:Docker安装
Docker的安装非常简单,官网上都给出了具体的安装步骤,都是可视化的安装,三步就搞定了。这里我就不细说了,附上Docker的官网安装教程地址。
Mac:https://docs.docker.com/docker-for-mac/install/#install-and-run-docker-for-macWindows:https://docs.docker.com/docker-for-windows/install/#install-docker-for-windowslinux的话,官网有不同版本的安装的教程,这里放上ubuntu的安装教程,其他小伙们自行查看。ubuntu:https://docs.docker.com/engine/installation/linux/ubuntu/#install-docker
第四:Docker三个基本概念
下面这张图非常的经典,很形象地展示了,什么是容器,什么是镜像,什么是仓库,以及三者之间的联系。
接下来我们来解释一下这张图。现在我们要造一间厨房,在造之前我们首先要干的一件事,就是先列举出我们造厨房需要的东西。我们可能需要一个通了水电煤的房子以及一些必需的厨房用具诸如锅碗瓢勺、煤气灶、冰箱、水槽等等这些东西。现在我们知道需要了什么东西之后,我们就去找这些东西。首先我们先去京东购买一些厨房用具,这些用具就好比我们的Docker镜像,我们厨房的用具到了之后得找个地方把它们放在,不可能随处丢吧,不然后面用的时候就找不到它了,那么我们Docker镜像也是这样,需要一个Docker仓库去存储这些镜像。现在我们有了这些厨房用具之后就可以做饭了吗?答案当然是不能,没水没电没火啊!这时候我们得把厨房用具给装到一个通了水电煤的房子才行,那么Docker镜像也是这样,单纯的Docker镜像是不能用的,它得装到Docker容器中通了水电煤才能使用。等我们装好了厨房用具之后我们就可以开始做饭,那么我们的Docker镜像装到Docker容器之后,我们应用就可以跑起来了。
第五:我的第一个Docker镜像
上面的文章中,我们了解了一下Docker,接下来我们学着做一个属于自己的Docker镜像
第一步:从镜像中心下载一个Node镜像
去http://hub.daocloud.io/上找到Node镜像地址并执行如下命令:docker pull daocloud.io/library/node:标签查看本地库的Docker镜像,是否下载完成:docker images
结果如下
第二步:写一个app.js
app.js的内容如下,内容很简单,作用也很简单,起一个80端口的服务,页面显示“Hello Docker”。
var http = require('http');http.createServer(function (request, response) {// 发送 HTTP 头部HTTP 状态值: 200 : OK内容类型: text/plainresponse.writeHead(200, {'Content-Type': 'text/plain'});// 发送响应数据 "Hello World"response.end('Hello Docker\n');}).listen(3000);// 终端打印如下信息console.log('Server running at http://127.0.0.1:3000/');
第三步:写一个Dockerfile,用于构建镜像
如下
#依赖的镜像FROM daocloud.io/library/node:latest#镜像创建者的信息MAINTAINER wuming "wuming@maihaoche.com"#执行mkdir helloDocker创建一个helloDocker文件夹RUN mkdir helloDocker#将app.js添加到helloDocker文件夹中ADD app.js helloDocker#容器运行时启动的命令,下面命令等价于 CMD node /helloDocker/app.jsCMD ["node","/helloDocker/app.js"]
第四步:执行命令,构建对象
如下
docker build -t hello-docker .//-t 用于指定镜像的name:tag,没有指定tag则是latest。//. 代表Dockerfile 所在的路径,这里是当前目录
结果如下:
如果镜像仓库或者标签错了的话,可以使用如下命令进行修改
docker tag IMAGE ID name:tag//例: docker tag 1786dad83d25 hello-docker:1.0.0
结果如下:
-
-
这里需要注意的是“docker tag”是新建一个标签用于目标镜像指向源镜像,所以我们记得删除原来的标签
docker rmi name:tag//例:docker rmi hello-docker:latest
-
温馨提示:当前目录应该有Dockerfile和app.js才可用上面命令构建成功
第六:我的第一个Docker容器
docker run -d -p 8003:3000 IMAGE ID
注意事项:
1. -p IP:hostport:containerport 或 -p IP::port 来指定允许访问容器的主机上的 IP、接口等,我这里只允许外部8080端口来访问3000端口
2. -d 就是在后台运行容器,并返回容器ID。有兴趣的小伙伴可以体验一下有-d和没-d的区别这时我们输入http://localhost:8003/就可以访问了我们刚刚启的服务了。
另外我们可以通过*docker ps *来查看当前所有启动的容器。
接下来我们进入容器中看看这个容器到底有什么东西!
docker exec -it /bin/bash
进入容器中我们就看到了刚刚我们之前在Dockerfile建的helloDocker文件夹,进去之后发现了我们的app.js.执行exit命令就可以退出容器。