什么是?
- 书面解释
Docker是一个开源项目,诞生于2013年初,最初是dotCloud公司内部的一个业余项目。它基于Google公司推出的Go语言实现。项目后来加入了Linux基金会,遵从了Apache2.0协议,项目代码在GitHub上进行维护。Docker自开源后受到广范的关注和讨论,以至于dotCloud公司后来都改名为Docker Inc。RedHat已经在其RHEL6.5中集中支持Docker;Google也在其PaaS产品中广泛应用。Docker的目标是实现经量级的操作系统虚拟化解决方案。Docker的基础是Linux容器(LXC)等技术。在LXC的基础上Docker进行了进一步的封装,让用户不需要关心容器的管理,使得操作更加简单。用户操作Docker的容器就像操作一个快速轻量级的虚拟机一样简单。
- 本人理解
Docker其实相当于一个运行在我们操作系统之上的一个程序,在这个程序内部可以搭建我们程序运行的环境,以往我们在部署项目时,通常把一个服务器作为一个整体,在此基础上部署和运行我们开发的程序,而Docker相当于在的服务器上装上一个一个独立的箱子,箱子可以互不受影响[参照如Docker官方Logo,如上图],如果还不理解的话,可以暂且往下看
- docker的设计思想
Docker的思想来自于集装箱,集装箱解决了什么问题?在一艘大船上,可以把货物规整的摆放起来。并且各种各样的货物被集装箱标准化了,集装箱和集装箱之间不会互相影响。那么我就不需要专门运送水果的船和专门运送化学品的船了。只要这些货物在集装箱里封装的好好的,那我就可以用一艘大船把他们都运走。docker就是类似的理念。
为什么?
- 传统部署思路带来的问题
1.[不同的应用程序可能会有不同的应用环境],比如.net开发的网站和java开发的网站依赖的软件就不一样,如果把他们依赖的软件都安装在一个服务器上就要调试很久,而且很麻烦,还会造成一些冲突。常规来讲,我们可以在服务器上创建不同的虚拟机在不同的虚拟机上放置不同的应用,但是虚拟机开销比较高。docker可以实现虚拟机隔离应用环境的功能,并且开销比虚拟机小
2.[开发环境和测试环境以及生产环境的冲突],你开发软件的时候用的是Ubuntu,但是运维管理的都是centos,运维在把你的软件从开发环境转移到生产环境的时候就会遇到一些Ubuntu转centos的问题,比如:有个特殊版本的数据库,只有Ubuntu支持,centos不支持,在转移的过程当中运维就得想办法解决这样的问题。这时候要是有docker你就可以把开发环境直接封装转移给运维,运维直接部署你给他的docker就可以了。而且部署速度快。
3.[资源占用方面]在服务器负载方面,如果你单独开一个虚拟机,那么虚拟机会占用空闲内存的,docker部署的话,这些内存就会利用起来。
- Docker的优势
作为一种新兴的虚拟化方式,Docker 跟传统的虚拟化方式相比具有众多的优势。首先,Docker 容器的启动可以在秒级实现,这相比传统的虚拟机方式要快得多。其次,Docker 对系统资源的利用率很高,一台主机上可以同时运行数千个Docker 容器。
容器除了运行其中应用外,基本不消耗额外的系统资源,使得应用的性能很高,同时系统的开销尽量小。
传统虚拟机方式运行10 个不同的应用就要起10 个虚拟机,而Docker 只需要启动10 个隔离的应用即可。具体说来,Docker 在如下几个方面具有较大的优势。
1,更快速的交付和部署
对开发和运维(devop)人员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。开发者可以使用一个标准的镜像来构建一套开发容器,开发完成之后,运维人员可以直接使用这个容器来部署代码。Docker 可以快速创建容器,快速迭代应用程序,并让整个过程全程可见,使团队中的其他成员更容易理解应用程序是如何创建和工作的。Docker 容器很轻很快!容器的启动时间是秒级的,大量地节约开发、测试、部署的时间.
2,更轻松的迁移和扩展
Docker 容器几乎可以在任意的平台上运行,包括物理机、虚拟机、公有云、私有云、个人电脑、服务器
等。这种兼容性可以让用户把一个应用程序从一个平台直接迁移到另外一个。
3,更简单的管理
使用Docker,只需要小小的修改,就可以替代以往大量的更新工作。所有的修改都以增量的方式被分发和更新,从而实现自动化并且高效的管理。对比虚拟机
- Docker的劣势
Docker是基于Linux 64bit的,无法在32bit的linux/Windows/unix环境下使用
LXC是基于cgroup等linux kernel功能的,因此container的guest系统只能是linux base的
隔离性相比KVM之类的虚拟化方案还是有些欠缺,所有container公用一部分的运行库
网络管理相对简单,主要是基于namespace隔离
cgroup的cpu和cpuset提供的cpu功能相比KVM的等虚拟化方案相比难以度量(所以dotcloud主要是按内存收费)
Docker对disk的管理比较有限
container随着用户进程的停止而销毁,container中的log等用户数据不便收集
怎么用?
-
Docker下载安装
1.1 前提条件目前,CentOS 仅发行版本中的内核支持 Docker。
Docker 运行在 CentOS 7 上,要求系统为64位、系统内核版本为 3.10 以上。[username -r 查看内核]
Docker 运行在 CentOS-6.5 或更高的版本的 CentOS 上,要求系统为64位、系统内核版本为 2.6.32-431 或者更高版本1.2 yum安装gcc相关[运行所需依赖]
yum -y install gcc yum -y install gcc-c++
1.3 卸载旧版本[可选]
yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine
1.4 安装
yum install docker
1.5 查看版本
docker version
1.6 运行HelloWorld
docker run hello-world #由于本地没有hello-world这个镜像,所以会下载一个hello-world的镜像,并在容器内运行
1.7 卸载Docker
systemctl stop docker yum -y remover docker rm -rf /var/lib/docker
1.8 配置阿里云加速服务
-
docker命令[帮助+镜像]
2.1 什么是Docker镜像?Docker的镜像有点类似于面向对象思想中的类,在类中我们可以定义好类的属性和方法,Docker的镜像是帮助我们把各种环境进行一个封装,在Docker的线上仓库中可以通过搜索查找各种官方以及第三方为我们提供好的Dokcer镜像
2.2 帮助命令
docker version #查看docker版本 docker info #显示全系统信息 docker --help #显示docker相关的所有命令及功能说明
2.3 镜像命令
#列表本机上的镜像 docker images #可选项 -a #列表本地的所有镜像及子镜像 -q #只显示镜像ID --digests #显示镜像的摘要信息 --no-trunc #显示完整的镜像信息 #镜像搜索命令,搜索远程仓库 docker search 镜像名称 #可选项 -s #列出收藏数不少于指定值的镜像 #镜像下载命令 docker pull 镜像名称:[TAG] #例如:docker pull tomcat:8.5 下载8.5的镜像版本,不指定TAG默认下载latest最新版本 #镜像删除命令 docker rim 镜像ID #通过docker images列出本机镜像信息,内包含镜像ID #全部删除镜像 docker rim -f (docker images -q)
-
docker命令[容器]
3.1 什么是容器上文讲到了什么是镜像,提到了镜像类似于一个类,那个容器就相当于类生成的对象,一个类可以有多个对象,对象之间互不打扰,Docker镜像和容器的关系就是这样
3.2 创建并启动容器
docker run [options] images [command][args] /镜像ID #--name="容器新名字": 为容器指定一个名称; #-d: 后台运行容器,并返回容器ID,也即启动守护式容器; #-i:以交互模式运行容器,通常与 -t 同时使用; #-t:为容器重新分配一个伪输入终端,通常与 -i 同时使用; #-P: 随机端口映射; #-p: 指定端口映射,有以下四种格式 #ip:hostPort:containerPort #ip::containerPort #hostPort:containerPort #containerPort docker run -d centos #问题:docker ps -a 进行查看, 会发现容器已经退出 #Docker容器后台运行,就必须有一个前台进程.
3.3 退出容器
exit 退出容器并关闭容器 ctrl+p+q 退出不关闭容器
3.4 列出当前所有容器
docker ps [options ] #默认列出当前正在运行的容器 #-a 显示所有运行和没有运行的容器 #-l :显示最近创建的容器。 #-n:显示最近n个创建的容器。 #-q :静默模式,只显示容器编号。 #--no-trunc :不截断输出。
3.5 查看容器日志
docker logs 容器ID [options] # -t 是加入时间戳 # -f 跟随最新的日志打印 # --tail 数字 显示最后多少条
3.6 查看容器运行进程
docker top 容器ID
3.7 查看容器内部细节
docker inspect 容器ID #通过以上命令可查看容器的详情信息
3.8 进入正在进行的容器并以命令行交互
#刚才我提到了Docker容器如果想到在后台运行就必须有一个前台终端,那么我们应该怎么进入正在运行的容器呢,是打开我们的伪终端,还是重新打开一个新的终端呢 docker exec -it 容器ID /bin/bash #重新打开一个新的终端 如果以这种方式进入容器,可以使用exit退出。而不会关闭容器 docker attach 容器ID #attach 直接进行容器终端,不会启动新的进程 #这种方式里面使用exit退出会关闭容器 如果不想关闭容器必须使用ctrl+p+q
-
docker容器数据卷[重点]
4.1 什么是容器数据卷1.将应用与运行的环境打包形成容器运行 ,运行可以伴随着容器,但是我们对数据的要求希望是持久化的
2.容器之间希望有可能共享数据
[作者解释] 我们可以这样去思考,如果一个Docker容器依靠镜像运行起来,那么我们的项目运行在一个虚拟出来的环境中,如果容器关闭,那我们的数据是不是也随之消失,所以我们应该让容器的数据与我们的宿主机关联起来,及时容器关闭宿主机的数据也不会消失,相当于在宿主机指定一个文件夹进行数据同步备份,另一种情况我们可能希望两个容器之间进行通信,那我是不是可以将两个容器的数据卷指定到宿主机同一个目录,那么容器之间是不是就达成了数据共享,注意容器与宿主机的数据同步是双向绑定的,即不管是在宿主机目录还是容器目录修改数据卷内容都会被同步4.2 添加数据卷的方式
#1.直接使用命令添加 docker run -it -v /宿主机目录:/容器内目录 镜像ID /bin/bash #--privileged=true #开启root权限,可以设置容器里的内核参数。 #2.使用DockerFile添加 # 关于DockerFile方式添加将在下方讲解,这里可以理解Docker相当于我们编写Docker镜像的文件
-
DockerFile [重要]
5.1 什么是Dockerfile1,Dockerfile是用来构建Docker镜像的构建文件,是由一系列的命令和参数构成的脚本
2,Dokcerfile的构建步骤 编写Dokcerfile文件->docker build 生成新的镜像->docker run 运行镜像5.2 DockerFile体系结构[文件内关键词]
FROM #基础镜像,当前新镜像是基于哪个镜像的 MAINTAINER #镜像维护者的姓名和邮箱地址 RUN #容器构建时需要运行的命令 EXPOSE #当前容器对外暴露的端口 WORKDIR #指定在创建容器后,终端默认登陆进来的工作目录 ENV #用来在构建镜像过程中设置环境变量 ADD #将宿主机目录下的文件拷贝进镜像并且ADD命令会自动处理URL和解压tar包 COPY #类似ADD,拷贝文件和目录到镜像中 ,语法COPY src dest COPY [''src","dest"] VOLUME #容器数据卷,用于数据保存和持久化工作 CMD #指定一个容器启动时要运行的命令格式 #shell: CMD <命令> #exec CMD ['可执行文件',"参数1","参数2"] #DockerFile中可以有多个CMD指令,但只有最后一个生效,CMD会被 docker run之后的参数替换 ENTEYPONT #指定一个容器启动时要运行的命令 #ENTRYPOINT的目地和CMD一样,都是在指定容器启动程序及参数 OBBUILD #当构建一个被继承的Dockerfile时运行命令,父镜像在被子镜像继承后触发父镜像的onbuild
-
Dockerfile 通过Dockerfile文件自定义一个tomcat镜像
6.1 官方仓库pull一个centOS镜像
6.2 准备jdk和tomcat源文件
6.3 创建并编写Dockerfile文件[在jdk和tomcat同级目录创建名为Dockerfile的文件]#基于centos镜像 FROM centos #设置作者和邮箱 MAINTAINER docker@email.com #声明变量 ENV MYPATH /usr/local/tomcat #创建tomcat的目录 RUN mkdir -p /usr/local/java #把tomcat和JDKcopy到/root/ ADD jdk-8u181-linux-x64.tar.gz /root/ ADD apache-tomcat-8.5.43.tar.gz /root/ #列出root目录下的所有内容 RUN ls -lh /root/ #把apache-tomcat-8.5.43修改成tomcat RUN mv /root/apache-tomcat-8.5.43 /root/tomcat #把tomcat 放到/usr/local/ RUN mv /root/tomcat /usr/local/ #把jdk1.8.0_181移动到/usr/local/java RUN mv /root/jdk1.8.0_181 /usr/local/java #设置工作目录 WORKDIR $MYPATH #配置JAVA和tomcat环境变量 ENV JAVA_HOME /usr/local/java/jdk1.8.0_181 ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ENV CATALINA_HOME /usr/local/tomcat ENV CATALINA_BASE /usr/local/tomcat ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin #安装VIM -y代表所有的确认的地方全部yes #RUN yum -y install vim #设置对名暴露的端口 纯提示作用 EXPOSE 8080 #打开一个终端 CMD bin/startup.sh && tail -F logs/catalina.out
6.4 构建镜像
docker build -t 自定义镜像名:镜像版本 . #在DockerFile文件同级目录运行命令,docker会自动寻找名为Dockerfile的文件
6.5 运行镜像测试
docker run -d -p 8080:8080 自定义镜像名:镜像版本
-
Docker的四种网络模式[可选]
7.1 概述docker run创建Docker容器时,可以用–net选项指定容器的网络模式,Docker有以下4种网络模式:
bridge模式:使–net =bridge指定,默认设置;
host模式:使–net =host指定;
none模式:使–net =none指定;
container模式:使–net =container:NAMEorID指定。
可以使用docker network ls来查看7.2 bridge模式
bridge模式是Docker默认的网络设置,此模式会为每一个容器分配Network Namespace、设置IP等,并将并将一个主机上的Docker容器连接到一个虚拟网桥上。当Docker server启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。接下来就要为容器分配IP了,Docker会从RFC1918所定义的私有IP网段中,选择一个和宿主机不同的IP地址和子网分配给docker0,连接到docker0的容器就从这个子网中选择一个未占用的IP使用。如一般Docker会使用172.17.0.0/16这个网段,并将172.17.42.1/16分配给docker0网桥(在主机上使用ip addr命令是可以看到docker0的,可以认为它是网桥的管理端口,在宿主机上作为一块虚拟网卡使用)。
7.3 host模式
如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。
7.4 none模式
在none模式下,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。
7.5 container模式
这个模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的IP,而是和一个指定的容器共享IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过lo网卡设备通信。