[TOC]
什么是docker?
来至知乎高赞回答:Docker的思想来自于集装箱,集装箱解决了什么问题?在一艘大船上,可以把货物规整的摆放起来。并且各种各样的货物被集装箱标准化了,集装箱和集装箱之间不会互相影响。那么我就不需要专门运送水果的船和专门运送化学品的船了。只要这些货物在集装箱里封装的好好的,那我就可以用一艘大船把他们都运走。
docker就是类似的理念。现在都流行云计算了,云计算就好比大货轮。docker就是集装箱。
1.不同的应用程序可能会有不同的应用环境,比如.net开发的网站和php开发的网站依赖的软件就不一样,如果把他们依赖的软件都安装在一个服务器上就要调试很久,而且很麻烦,还会造成一些冲突。比如IIS和Apache访问端口冲突。这个时候你就要隔离.net开发的网站和php开发的网站。常规来讲,我们可以在服务器上创建不同的虚拟机在不同的虚拟机上放置不同的应用,但是虚拟机开销比较高。docker可以实现虚拟机隔离应用环境的功能,并且开销比虚拟机小,小就意味着省钱了。
2.你开发软件的时候用的是Ubuntu,但是运维管理的都是centos,运维在把你的软件从开发环境转移到生产环境的时候就会遇到一些Ubuntu转centos的问题,比如:有个特殊版本的数据库,只有Ubuntu支持,centos不支持,在转移的过程当中运维就得想办法解决这样的问题。这时候要是有docker你就可以把开发环境直接封装转移给运维,运维直接部署你给他的docker就可以了。而且部署速度快。
3.在服务器负载方面,如果你单独开一个虚拟机,那么虚拟机会占用空闲内存的,docker部署的话,这些内存就会利用起来。
4.实现标准化
一、docker介绍
docker是一个开源的引擎,可以轻松的为任何应用创建一个轻量级的、可移植的、自给自足的容器。开发者在笔记本上编译测试通过的容器可以批量地在生产环境中部署,包括VMs(虚拟机)、bare metal、OpenStack 集群和其他的基础应用平台。 简单说,docker最大的优势是能给让运维人员或者开发人员快速部署和交付资源,大大提高了工作效率。
- 容器虚拟化,比传统的虚拟化轻量。
- 2013年出现,发展非常迅猛。
- Redhat在6.5版本开始支持docker。
- 使用go语言开发,基于apache2.0协议。
- 开源软件,项目代码在github维护。
- docker从1.13x开始,版本分为社区版ce和企业版ee,并且基于年月的时间线形式。
1.1、容器虚拟化和传统虚拟化比较:
容器虚拟化:
传统虚拟化:
我们创建一个新的虚拟机的时候,如果使用Vmware,首先我们需要分配一定的硬件资源去运行虚拟出来的系统,如果一台电脑例如我的win7 配置一般,也就顶多可以跑10个centos,但是如果使用Docker就可以创建成千上百个centos系统,且每个系统都是独立的,隔离开来的,硬件资源也是隔离开来的。
1.2、docker的优势
- 启动非常快,秒级实现。
- 资源利用率很高,一台机器可以跑上千个docker容器。
- 更快的交付和部署,一次创建和配置后,可以在任意地方运行。
- 内核级别的虚拟化,不需要额外的hypevisor- – 支持,会有更高的性能和效率。
- 易迁移,平台依赖性不强。
1.3、docker的核心概念
镜像,是一个只读的模板,类似于安装系统用到的那个iso文件,我们通过镜像来完成各种应用的部署。
容器,镜像类似于操作系统,而容器类似于虚拟机本身。它可以被启动、开始、停止、删除等操作,每个容器都是相互隔离的。
仓库,存放镜像的一个场所,仓库分为公开仓库和私有仓库。 最大的公开仓库是Docker hub(hub.docker.com),国内公开仓库(dockerpool.com)
二、docker的安装和配置
2.1、安装
|
|
- 当我们安装完毕后启动,docker会自动帮我们创建一些iptables规则,尽量不要去修改这些规则。而且每次启动docker时都会重新生成,所以不用担心误删
2.2、镜像管理
由于docker的服务器再国外,所以下载镜像是会比较慢,所以我们可以使用阿里云的镜像。并且阿里云还可以配置加速
|
|
- 这个url为加速器地址,有需要可以自行到阿里云申请
- 配置完加速器后,需要重启docker服务,再次pull镜像会快很多
(1)获取镜像
|
|
(2)查看本地镜像
|
|
(3)搜索仓库中的镜像
|
|
(4)创建镜像TAG
|
|
- 类似于更换一个新名字再次展现出来。格式为REPOSITORY:TAG
(5)启动镜像
|
|
- 执行后,会创建并启动一个容器使用镜像,容器编号为输出内容
- -i表示让容器的标准输入打开,-t表示分配一个伪终端,-d表示后台启动,要把-i -t -d 放到镜像名字前面
(6)进入容器
|
|
(7)停止镜像
|
|
(8)查看运行的容器
|
|
- -a可以显示所有
(9)删除镜像
|
|
- 用来删除指定镜像, 其中后面的参数可以是tag,如果是tag时,实际上是删除该tag。当后面的参数为镜像ID时,则会彻底删除整个镜像,所有标签也会一同删除
2.3、通过容器创建镜像
启动容器后,我们可以使用以下命令进入容器
|
|
- 其中xxxxx为容器id,这个id可以用docker ps查看,最后面的bash为进入容器后我们要执行的命令,这样就可以打开一个终端
进入到容器中后,我们可以查看以下基础的设备信息,都是基于宿主机建立起来的。我们可以做一些变更,比如安装一些东西,然后针对这个容器进行创建新的镜像:
在容器中执行:
|
|
现在,我们可以把刚刚安装net-tools的镜像保存成一个新的镜像,下次我们再次需要的时候就可以直接使用(不需要再次安装我们已经安装过的服务)
|
|
- container_id通过docker ps -a获取
- new_image_name表示新镜像名字
- -m表示改动信息
- -a表示添加作者相关信息
|
|
2.4、通过模板创建镜像
(1)首先我们先在openvz下载一个模板,本次实验下载一个centos-6-x86-minimal
|
|
(2)导入镜像
|
|
- 最后面的centos为导入后镜像的名称
(3)将现有镜像导出为一个文件
|
|
- -o后面指定导出后文件的名称。
(4)使用导出的文件恢复镜像
首先我们先删除原有镜像
|
|
然后再使用我们刚刚导出的文件恢复
|
|
(5)将自己的镜像传到docker官方网站上
|
|
- 需要我们先注册一个用户
2.5、容器管理
(1)创建容器
|
|
- 这样就可以创建一个容器,但该容器并没有启动
(2)启动容器
|
|
- 启动容器后,可以使用docker ps查看到,有start,stop和restart
- 之前我们使用的docker run相当于先create再start
(3)直接进入容器
|
|
- 这样就可以进入一个虚拟终端里面。我们可以运行一些命令,使用exit或Ctrl+d退出该bash,当退出后这个容器也会停止。
(4)后台运行容器
|
|
使用-c,后面跟命令。可以让容器运行时执行命令
1docker run -d centos bash -c "while :; do echo "123"; sleep 2; done"
(5)自定义容器名字
为自定义名字前,容器的名字都是随机的。我们进入容器需要指定CONTAINER ID,自定义名称后我们就可以指定名称登录。
|
|
- 实际为创建一个名字为web的容器
(6)执行命令后删除容器
|
|
(7)获取容器运行历史信息
|
|
(8)进入后台运行的容器
|
|
- 进入后,如果退出的话,容器也会退出停止
(9)删除容器
|
|
- container_id,是ps的时候查看到的,这样就可以把container删除,如果是运行的容器,可以加-f
(10)导出导入容器
|
|
2.6、docker仓库管理
我们可以自己创建一个私有仓库,来管理我们的镜像
(1)首先,下载registry,registry官方提供的一个镜像,我们可以用它来常见本地的docker私有仓库
|
|
(2)以镜像registry镜像启动容器
|
|
- -p表示会把容器的端口映射到宿主机上,宿主机端口:容器监听端口
(3)查看私有仓库的镜像
|
|
(4)推送镜像到私有仓库
首先,我们需要给要推送的镜像编辑一下tag
|
|
- tag必须带私有仓库的ip:port
接下来,我们需要修改配置文件
|
|
修改之后,需要重新启动docker
|
|
重启之后,docker的容器就都关闭了,所以我们还需要重新启动registry容器
|
|
- 这里的id为registry容器id,可以使用docker ps -a查看
现在,我们就可以将本地的镜像推送到我们的私有仓库了
|
|
步骤,启动registry容器,给需要推送的镜像打标签,再推送到私有云
当然,我们也可以下载私有仓库的镜像
|
|
- 上面提示我们本地已经有该镜像了
- 如果我们需要在其他机器上pull该镜像,需要修改配置文件/etc/docker/daemon.json,添加私有仓库的ip:port相关配置
2.7、docker数据管理
容器产生的数据,再容器关闭或者删除时,会一并消除。所以我们可以挂载本地的目录到容器里。
(1)挂载本地的目录到容器里
|
|
- -v后面指定目录,共享目录,并且可关联宿主机的目录,宿主机目录:容器目录
- –name后面跟名字,指定容器名字
- 在容器中创建的目录,宿主机上也会创建
(2)我们也可以单纯的将容器的目录共享
有时候,我们需要多个容器之间相互共享数据,类似于linux里面的NFS,所以就可以搭建一个专门的数据卷容器,然后其他容器直接挂载该数据卷。
首先,建立数据卷容器
|
|
- 这里的/data/是容器自己的目录,表示将/data/共享出来
(3)挂载数据卷
当我们有数据卷容器时,我们可以挂载这些数据卷
|
|
- –volumes-from后面跟的是数据卷容器的名字,如果之前没有指定,需要我们使用docker ps -a查看最后一列
- 这样,我们使用centos镜像创建了新的容器,并且使用了data_test容器的数据卷
2.8、docker数据卷的备份和恢复
如果数据卷容器在共享目录时,直接跟宿主机关联了目录,那么数据都会存在关联目录里。如果没有关联目录,那么我们需要进行以下操作
- 我们在新建的容器中使用一个目录/backup/与宿主机关联目录/data/backup,然后挂载数据卷容器共享的目录/data/。
- 备份的时候,打包新建容器/data/中的数据到/backup中即可完成备份
- 恢复的时候,将之前打包的数据包直接恢复到新建容器的/data/即可
(1)备份
|
|
(2)恢复
将数据恢复到其他容器
新建一个数据卷容器,将新的容器挂载数据卷容器目录
|
|
新建容器挂载数据卷目录,并解包
|
|
三、docker网络模式
3.1、网络模式
模式 | 使用 | 作用 |
---|---|---|
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网络模式。同一个宿主机上的所有容器会在同一个网段下,可以通信 |
桥接 | 使用第三方工具pipwork | 容器与宿主机在同一网段,类似VMware的桥接网络 |
3.2、外部访问容器
默认使用的是bridge网络模式,容器的网段与宿主机的网段是不同的,其他主机是无法访问到容器的端口的。我们可以使用端口映射,使其他主机可以访问到容器的服务
(1)首先使用centos镜像新建一个容器,然后在该容器中安装httpd服务,并启动
|
|
(2)再把该镜像导出为一个新的镜像(centos_http),然后再使用新的镜像创建容器并指定端口映射
|
|
- -p用来映射端口,也支持ip:port:ip:port 的格式,比如-p 127.0.0.1:8080:80,也可以不写本地的端口,只写ip,这样会随意分配一个端口,比如-p 127.0.0.1::80,有两个冒号
(3)启动httpd服务
|
|
启动时,出现错误:”Failed to get D-Bus connection: Operation not permitted”
解决办法
|
|
(4)测试端口映射
添加测试文件
|
|
3.3、配置桥接网络
为了使本地网络中的机器和Docker容器更方便的通信,我们经常会有将Docker容器配置到和主机同一网段的需求。这个需求其实很容易实现,我们只要将Docker容器和宿主机的网卡桥接起来,再给Docker容器配上IP就可以了。配ip时需要借助第三方工具,该模式类似VMware的桥接模式,容器和宿主机在同一网段。
(1)修改宿主机网卡配置文件
|
|
修改ens33网卡
|
|
修改br网卡
|
|
重启网络服务
|
|
- 配置成功应该是这样的,而且使用xshell连接的终端不会断开
(2)安装pipwork
|
|
(3)设置容器ip
开启一个容器
|
|
- 需要使用–net=none,该容器只会有一个lo网卡
设置容器ip
|
|
四、docker的Dockerfile
我们之前介绍了使用模板导入导出创建镜像和使用容器创建镜像,我们还可以使用Dockerfile创建镜像,可以在创建之前-配置Dockerfile实现自动化构建
4.1、dockerfile的格式
(1)FROM
指定基于那个基础镜像
|
|
(2)MAINTAINER
指定作者信息
|
|
(3)RUN
镜像操作命令
|
|
(4)CMD
指定容器启动时用到的命令,只能有一条
|
|
(5)EXPOSE
指定要映射出去的端口,例如容器内部我们启动了sshd和nginx,所以我们需要把22和80端口暴露哦出去。
|
|
- 这个需要配合-P来工作,也就是说在前启动容器时需要加上-P,让它自动分配。如果想指定具体的端口,也可以使用-p来指定
(6)ENV
主要是为了后续RUN指令提供一个环境变量,我们也可以定义一些自定义的变量
|
|
(7)ADD
将本地的一个文件或目录拷贝到容器的某个目录里。其中src为dockerfile所在目录的相对路径,它也可以是一个url
|
|
(8)COPY
使用方法与ADD一样,只是不支持url
|
|
(9)ENTRYPOINT
容器启动时要执行的命令,跟CMD很像,也是只用一条生效,如果写多个只有最后一条生效。和CMD不同的是:
|
|
(10)VOLUME
创建一个可以从本地主机或者其他容器挂载的挂载点
|
|
(11)USER
指定运行容器的用户
|
|
(12)WORKDIR
为后续的RUN、CMD或者ENTRYPOINT指定工作目录
|
|
4.2、Dockerfile示例
(1)创建Dockerfile文件
|
|
(2)创建镜像
|
|
- centos_nginx为新的镜像名称
查看新建的镜像
|
|
映射端口,我们需要使用容器的80端口
|
|
五、使用docker compose部署服务
docker compose可以方便我们快捷高效地管理容器的启动,停止,重启等操作,它类似Linux下的shell脚本,基于yaml语法,在该文件里我们可以描述应用的架构,比如用什么景象,数据卷,网络模式,监听端口等信息。我们可以在一个compose文件中定义一个多容器的应用(比如jumpserver),然后通过该compose来启动这个应用。
(1)安装compose
|
|
- Compose区分Version 1和Version 2(Compose 1.6.0+,Docker Engine 1.10.0+)。Version 2支持更多的指令。Version 1没有声明版本默认是”version 1”。Version 1将来会被弃用。
(2)docker compose示例
创建示例文件,并写入内容
|
|
启动容器
|
|
常用参数
|
|
查看语法
|
|