此文只关注Docker基础认知和使用情况。
文章目录
什么是Docker?
官网一句话解释Docker是世界领先的软件容器化平台,可以把Docker看做是一个装应用的容器。
Docker思想
- 集装箱化:把运行程序放到新的机器上,Docker集装箱保证我们的程序不管放在哪都可以正常运行。
- 标准化
1)运输方式标准化 :如果想要把台式机上的应用部署到笔记本上,用docker就标准化了这个过程,只需要在台式机上执行一个命令,通过docker(鲸鱼)把程序发送到仓库(超级码头),再在笔记本上执行一个Docker命令,docker(鲸鱼)就把程序从仓库运输到笔记本上。
2)存储方式标准化:把程序拷贝到笔记本上的时候,得给它指定一个目录,还得记住这个目录,因为下次有改动一些东西的时候,可能还需要继续往这传,有了docker之后就不用了,因为存储方式标准化,不需要关心应用存储在什么地方,要运行它或停止它的时候,只需执行一个命令就可以了。
3)API接口标准化:Docker提供了一系列的restful API 接口,包含了对Docker应用的控制(启动、停止、查看、删除),如当你要启动程序的时候,可能需要执行tomcat startup命令,停止的时候执行shut down命令,如果不是tomcat命令,需要用别的命令来控制。有了Docker接口标准化后,只需要执行同样的命令就能控制。
4)隔离:在用虚拟机时,有自己可用内存、CPU、硬盘,完全感觉不到外面主机的存在,Docker差不多,不过它的技术
更加的轻量,可以实现快速的创建和销毁。比如你创建一个虚拟机可能要等个几分钟,而创建Docker只需要1秒。最底层的技术实际上就是Linux的一种内核的限制机制,叫做LXC(LXC是一种轻量级的容器虚拟化技术,它最大效率的隔离了进程和资源,通过CGoup、NameSpace的限制,隔离进程组所使用的物理资源,比如CPU、Memory、IO等),其实这个机制早在7、8年前就加到了Linux内核了,直到2013年Docker出世时它才火起来。云计算、敏捷开发、高频率的弹性伸缩需求、IT行业这些年的长足发展造就了Docker的火爆。
走进Docker
1、Docker里有三个核心词汇:Build、Ship、Run
镜像就是集装箱,仓库就是超级码头、容器就是运行程序的地方,用Docker运行一个程序的过程,就是去仓库把镜像拉到本地,然后用一条命令把镜像运行起来,变成容器。
-Build:构建,就是构建镜像。
- Ship:运输,运输镜像,从仓库、主机上运输。
- Run: 运行镜像,就是一个容器。
2.Docker镜像
镜像的英文名是image,前面我们讲到了集装箱,想象一下,鲸鱼驮着的所有集装箱都是一个镜像,那么本质来说,镜像到底是什么?
其实镜像就是一系列的文件,它可以包括我们运行程序的文件,也可以包括我们应用运行环境的文件,既然都是文件,Dokcer把它保存到本地了吗?答案是肯定的。但是它以什么格式保存呢?说道镜像的存储格式,就要提到Linux的存储技术,叫做联合文件系统(Union File System),它是一种分层文件系统,它可以将不同的目录挂到同一个虚拟文件系统下。
比如test1,目录下有三个文件夹,test2目录下有一个文件README、两个文件,联合文件系统就是可以在同一个文件夹下看到这里的五个文件夹和一个文件Readme,也就是这两个文件夹的集合。
通过这样一种方式呢,联合文件系统就可以实现文件的分层,比如test1可以看做第一层,test2可以看做第二层,每一层有每一层的文件,Docker就是利用了这种分层的概念来实现镜像存储,下面就是镜像的存储格式图。
很明显地可以看到这张图是分层的,下面有一层,上面也是一层一层的,一个个集装箱在一起,这就是镜像最直观的存储形式,这个例子它的最底层是操作系统的引导,上面是Linux操作系统,再上面是相关软件(如果是我们的程序,那可能就是JDK、Tomcat),最上面是在容器中可以进行写的操作。
Docker镜像每一层文件系统都是只读的,把每一层加载完成之后呢,这些文件都会被看做同一个目录,相当只有一个文件系统,Docker的这种文件系统被称作镜像。
3、Docker容器
容器的本质就是一个进程,为了便于理解,可以想象成一个 虚拟机,每个虚拟机都有都有自己的文件系统,可以把整个这一备份看作是容器的文件系统,相当于虚拟机里面所有的文件系统,它和虚拟机的区别是它这里的文件系统是一层一层的,并且这下面的N层都收只读的,只有上面一层是可写的。为什么要有可写的这一层呢?想一想如果大家的程序运行起来,势必会要写一些日志,写一些文件,或者对系统的某一些文件做一些修改,这是大部分程序都有的需求,所以容器在最上面一层创建了一个可读可写的文件系统。
如果程序在运行过程中要写一个镜像里面的一个文件,这种情况将发生什么呢?因为镜像的每一层都是只读的,所以它在写这个文件之前会把这个文件这一层拷到文件的最上一层,然后再对它进行修改,修改了之后,当我们的应用读一个文件的时候会从顶层开始查找,如果没有才会找下一层,因为我们这个文件已被拷到最上一层了,所以会在最上一层找到它最新的内容。由于容器的最上一层是可以修改的,而镜像是不可以修改的,这样就可以保证同一个镜像可以生成多个容器独立运行,而它们之间没有任何的干扰。
4、Docker仓库
构建镜像的目的就是为了在其它的机器或环境运行我的程序,那我就需要把我的镜像传到目的地去,我该如何完成传输过程?这就用到了Docker仓库,我需要先把我的镜像传到Docker仓库里去,目的地再从仓库把我的镜像拉过去,这就完成了这样的一个传输过程。谁提供Dockder仓库呢?肯定有一个中央服务器提供给我地址去访问它,是谁提供了这样的服务呢?Docker自已就提供了,提供服务的地址就是:hub.docker.com。但这这个网站在开始的时候在国内访问不了,现在虽然可以访问了,但是下载镜像的速度非常的慢。为了解决这个问题,国内很多的公司做自已的仓库,比较知名的仓库有163yun.com/product/repo (网易蜂巢的一个镜像中心),这里有一些我们常用的镜像,这些仓库都是其它公司给我们提供好的中心,我们可以把镜像传过去,如果我的镜像比较私密,不想让别人看到,只是内部的人使用的话,Docker也支持我们自已搭建一个镜像中心,比如我们是一个内网的环境,可以把我们的镜像中心在内网搭建起来,最后我们在镜像的传输过程放到内网的Docker仓库里就行了。
Docker安装
1、windows 安装
Win10之外:
下载地址:https://www.docker.com/products/docker-toolbox
Win10:
下载地址:https://www.docker.com/products/docker#/windwos
Docker对Win10做了原生的支持。
附:boot2docker.iso下载地址:http://pan.baidu.com/s/1qYyc0ag
运行docker version,输出Client和Server信息,则说明已安装OK,如下所示:
2、MaxOS安装
3、Linux安装
Docker是在Ubuntu上开发的,对Ubuntu支持是最好的,下面以Ubuntu为例演示安装过程。
a、uname -r
检查内核版本,检查其值是否大于3.10
su
切入到root用户,将apt-get更新到最新版本
b、apt-get install -y docker.io
安装Docker
这种安装方式是系统自带的安装包,可能不是Docker的最新版本,如果要安装Docker最新版本,可以使用curl -s https://get.docker.com|sh
这句话的意思就是get.docker.com网页内容拿过来,执行sh,这是Docker提供的一种安装方式。
c、service docker start
启动Docker
d、执行docker version
查看docker是否安装ok
Docker初体验
1、第一个Docker镜像:Hello-wrold
1)从Docker 远程仓库拉取镜像到本地。
docker pull [OPTINS] NAME 【:TAG】
- name :表示要拉取镜像的名称。
- TAG:可选的,如果不加默认是:latest,表示镜像的最新版本,用TAG就会下载TAG 指定的版本。
- OPTIONS: 可选的,表示一些参数
2)在此设置使用docker国内镜像DaoCloud,右键点击桌面右下角的docker图标,选择Settings。
在Daemon标签下的Registry mirrors列表中加入下面的镜像地址:http://141e5461.m.daocloud.io,点击 Apply,Docker服务将会自动重启生效。
-docker images
查看镜像
- REPOSITORY: 镜像的名字
- TAG: latest, 最新版本
- IMAGE_ID: 是一个64位的字符串,它可以唯一的标识我们的镜像,这里只显示16位,后面在显示时自动被截掉了
- CREATE: 创建时间,说明这个hello-world在4个月前被修改过。
- SIZE: 大小,只有1.8KB
3) 如果是Linux系统,则按如下操作设置国内镜像。
修改或创建daemon.json文件:vi /etc/docker/daemon.json
将以下配置写入到文件中,保存并退出:
{
"registry-mirrors": ["https://registry.docker-cn.com"]
}
重启docker: systemctl restart docker.service
2、运行第一个docker容器
docker run [OPTIONS] IMAGE [:TAG] [COMMAND] [ARG:]
- IMAGE: 表示镜像的名字
- COMMAND: 表示这个镜像在运行起来的时候要执行什么命令
- ARG: 表示这表命令所依赖的参数。
docker命令运行过程如下:
最左边Client是我们在本机的Docker Client,就是我们执行命令的时候Docker Client的部分,中间这部分DOCKER_HOST也是在我们本机的Docker服务(Docker Daemon),最右边是Docker的远程仓库。
Docker Client输入docker pull,将会向Docker Daemon发起pull命令,告诉Docker Daemon要拉取某一个镜像,Docker Daemon会先在本机Images去检查镜像是否存在,如果存在且版本就是你所要拉取的版本,就不会做任何的操作,如果不存在将会去Docker仓库找我们需要拉取的镜像名字,如果找到了就会从Docker仓库传到我们本地,把我们要的镜像拉到本地来。
Docker Client输入docker run,第一步也是把我们的命令发到本地的Docker Daemon,Docker Daemon会检查这个镜像是否在本机已经存在,如果不存在,将会执行一个相当于Docker pull的过程去远端Docker仓库把镜像下载回来,然后通过一定的方式把这个镜像运行起来,变成Docker容器。
Docker 运行Nginx
Nginx是一个Web服务器,是一个持久运行的容器,上面我们的hello-world是前台运行的(因为我们能看到它打印出的运行结果),运行Nginx可以选择前台运行,也可以选择后台运行,如果一个前台运行的镜像,可以用Ctrl+C结束进程,进程结束了,镜像也就结束了,所以说Nginx最好的运行方式是后台运行。成功运行Nginx后,可以进入容器内部看看Nginx容器到底是什么样的。
docker run -d library/nginx
: 命令的返回字符串代表容器的ID,
docker ps
:查看运行的容器,看到的CONTAINER ID是一样的。
-d
:表示后台运行,如果想了解更到docker run参数,可以运行docker run --help
查看。
docker exec
进入一个容器内部,相当于一个Linux虚拟机。
docker网络
a、网络类型
bridge模式
docker的隔离性,网络也是隔离性的一部分,Linux用了namespace来进行资源的隔离,比如PIDNameSpace就是用来隔离进程的,Mount NameSpace用来隔离文件系统的,Network NameSpace是用来隔离网络的,每一个Network NameSpace都提供了一份独立的网络环境,包括网卡、路由、iptable规则等等,都是与其它的Network NameSpace隔离的,Docker容器在默认情况下都是分配一个独立的Network NameSpace,也就是网络类型中的bridge模式。
Host模式
如果启动容器的时候,指定使用Host模式,那么这个容器将不会获得一个独立的Network NameSpace,而是和主机共同使用一个,这个时候,容器将不会虚拟出自已的网卡,配置自已的IP等等,而是会使用宿主机上的IP和端口,也就是在Docker里使用网络的时候和在主机上使用网络是一样的。
None模式
Docker将不会和外界的任何东西进行通信。
b、端口映射
在使用bridge模式的时候,就涉及到了一个问题,既然它使用了网络有独立的NameSpace,这就需要一种技术使容器内的端口可以在主机上访问到,这种技术就是端口映射。Docker可以指定你想把容器内的某一个端口可以在容器所在主机上的某一个端口做一个映射,当你在访问主机上的这个端口的时候,其实就是访问容器里面的那个端口。
第一种方式: 指定端口映射
docker run -d -p 8080:80 hub.c.163.com/library/nginx
-p
:开放一个容器的端口到主机上。- 8080:表示主机端口
- 80:表示容器端口
Windows系统使用netstat -aon|findstr “8080”
,查看端口是否开放
在浏览器中访问 localhost:8080,出现如下页面
第二种方式:端口随机映射
Docker run -d -P hub.c.163.com/library/nginx
-P
:将容器的所有端口,随机的映射到主机
浏览器访问localhost:32678 成功
Docker化第一Java Web应用
1、制作自己的镜像
- Dockerfile:告诉Docker,我要怎么制作我的镜像,以及执行镜像的每一步操作是什么。
- docker build : 用来执行Dockerfile 里面所描述的每一件事情,最终把项目镜像构建出来。
- Jpress : http://jpress.io/ ,这里以jpress开源的博客平台为例。
2、将自己的项目打包成war包,这里直接下载 jpress.war 包
3、编写Dokcerfile文件
from hub.c.163.com/library/tomcat
MAINTAINER zhaojj XXXX@163.com
copy jpress.war /usr/local/tomcat/webapps
这里需要将Dockerfile文件和war包放在同一个目录下面。
- from 表示引入的基础镜像,这里需要引入Tomcat
- Maintainer 表示构建人和联系方式
- copy : 表示将war包,复制到tomcat容器里的目录下。
4、下载Tomcat镜像
5、构建web项目镜像
docker build -t jpress:latest E:\jpress
-t
: 表示镜像的名称和版本。
运行镜像
浏览器访问 :localhost:8888/jpress
项目运行成功,Jpress项目还依赖mysql数据库,我们可以通过docker运行mysql
拉取镜像
docker pull hub.c.163.com/library/mysql:latest
运行镜像
docker run -d -p 3377:3306 -e MYSQL_ROOT_PASSWORD=111111 -e MYSQL_DATABASE=jpress hub.c.163.com/library/mysql
这里进行数据配置时,因为mysql是运行在容器内,在主机上访问设置为主机ip。
配置好之后docker restart
c重启,页面如下,不知道Jpress就是这样,还是我哪里出现了问题。