您的位置:首页 > 运维架构 > Docker

Docker1(简介与Dockerfile)

2017-11-16 23:17 387 查看

一.Docker简介

1.传统的虚拟机是通过中间层将一台或多台独立的机器,虚拟运行在物理机上,而容器则是直接运行在操作系统之上的用户空间。因此,容器虚拟化也被称为操作系统虚拟化,与虚拟机相比,最大的优点是磁盘占用空间少,两者均需要应用和库,虚拟机需要多出几个G的操作系统来支撑,容器依赖于linux内核。



Docker是一种将应用程序自动部署到容器的开源引擎。Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化

2.基本组成

(1)客户端与守护进程

通过客户端执行各种命令,客户端向守护进程发起请求,守护进程处理完之后,将结果返回给客户端。



(2)docker镜像

层叠的只读文件系统,最底端是引导文件系统bootfs,第二层root文件系统(可以是一种操作系统,如Ubuntu),在其之上,又通过联合加载,加载了几种文件系统(联合加载的意思是,对外表现为一种,包括所有的底层文件和目录),docker将这些称为镜像。



(3)docker容器

docker的启动执行阶段,在镜像最顶层加载一个读写层,比如想修改一个文件,从最下面的只读层复制到读写层,该文件的只读版本仍存在,只是被读写层的该文件副本所隐藏,这就是docker中的一个重要机制,写时复制。



(4)结构框架





二.Docker安装使用

1.安装启动

yum install -y docker-engine-1.12.6-1.el7.centos.x86_64  docker-engine-selinux-1.12.6-1.el7.centos.noarch




2.基本命令

(1) docker load ###镜像加载,导入镜像

docekr save ubuntu > ubuntu.tar ###导出镜像为tar包

docekr rmi ###删除镜像

docker images ###查看已加载的镜像









(2)docker run ###利用镜像生成容器,名字为vm1,直接进入容器内,容器ip 是在docker0的ip上递增





(3)docker ps ###默认为查看在线的容器

docker ps -a ###查看所有容器

docker ps -aq ###显示所有容器的ID



(4)docker commit ###利用已有的容器vm1,添加新的东西,来生成新的镜像ubuntu:v1,并利用新镜像生成新的容器vm2,vm2中直接存在新添的文件

ctrl +p+q ###退出容器,但容器没关,可docker attach vm1 ###连接容器

ctrl +d ###直接关闭容器,此时若想进入容器,需要先docker start vm1 ###启动容器 然后docekr attach vm1 ###连接容器







(5)docker cp ###往容器中直接复制文件



(6)docker diff ###查看容器修改



(7)docker exec ###在容器外对容器执行操作,比如ls ,rm





(8)docekr stop vm1 ###停止容器

docker rm ###删除容器,后可跟ID,或者容器明(此例中是ID)



(9)docker top ###查看容器进程



(10)docker search ##寻找镜像(前提是本机能上网,这是去docekr官方仓库寻找)

docker pull ###从仓库中拉取镜像(可理解为下载镜像)

docekr push ###将镜像推送到仓库







(11)docker inspect ##容器具体信息,包括Pid,ip等,可直接访问该ip









(12)docekr history ###查看镜像分层情况,可以看出ubuntu:v1镜像与ubuntu镜像相比,多了一层,即存放的file{1..5},当删除镜像ubuntu:v1后,也只是将多出的最顶层删掉,底层仍保持,这也进一步说明,在docker中,镜像相同的部分是只存一份的,极大的减少了占用空间





(13)docker run 在创建容器时使用 -v 参数可以挂载一个或多个数据卷到当前运行的容器中,-v

的作用是将宿主机上的目录作为容器的数据卷挂载到容器中,使宿主机和容器之间可以共享一个目录,冒号前面的是宿主机的目录(本地目录不存在 docker 会自动创建),冒号后面的是容器中的挂载目录

默认挂载可以读写数据卷,也可以只读挂载(如此例中的/data2)







(14)docekr create ###生成数据卷,这样之后可直接利用该数据卷生成容器,不必像(12)一样,每次生成要用到数据卷共享时,都要写明宿主机目录与容器目录的对应关系(此例中因为宿主机中/tmp/data1中存在file1-5,所以生成的新容器vm1中,直接共享了该文件)





(15)宿主机目录挂载到容器的例子









(16)docekr run –rm ###备份,将容器中/data1中的文件压缩后保存到容器中的/backup/data.tgz,因为共享,所以在宿主机/tmp/backup中也可以看到





三.网络模式

1.修改默认docker0的ip值

Docker 在启动时会创建一个虚拟网桥 docker0,容器启动后都会被桥接到 docker0 上,并自动分配到一个 IP 地址(在docker0上递增)。

cp /lib/systemd/system/docker.service /etc/systemd/system/docker.service


vim /etc/systemd/system/docker.service


[Service]
Type=notify
ExecStart=/usr/bin/docker daemon -H fd:// --bip="172.18.0.1/24"
。。。


重新加载

systemctl daemon-reload
# systemctl start docker


2.四中网络模式:bridge 桥接模式、host 模式、container 模式和 none 模式

Bridge 桥接模式的实现步骤主要如下:

(1) Docker Daemon 利用 veth pair 技术,在宿主机上创建两个虚拟网络接口设备,假设为

veth0 和 veth1。而 veth pair 技术的特性可以保证无论哪一个 veth 接收到网络报文,都会将

报文传输给另一方。

(2) Docker Daemon 将 veth0 附加到 Docker Daemon 创建的 docker0 网桥上。保证宿主机的网

络报文可以发往 veth0;

(3) Docker Daemon将veth1添加到Docker Container所属的namespace下,并被改名为eth0。

如此一来,保证宿主机的网络报文若发往 veth0,则立即会被 eth0 接收,实现宿主机到

Docker Container网络的联通性;同时,也保证Docker Container单独使用eth0,实现容器网

络环境的隔离性。

bridge 桥接模式下的 Docker Container 在使用时,并非为开发者包办了一切。最明显的是,

该模式下Docker Container不具有一个公有IP,即和宿主机的eth0不处于同一个网段。导致

的结果是宿主机以外的世界不能直接和容器进行通信。虽然 NAT 模式经过中间处理实现了

这一点,但是 NAT 模式仍然存在问题与不便,如:容器均需要在宿主机上竞争端口,容器

内部服务的访问者需要使用服务发现获知服务的外部端口等。另外 NAT 模式由于是在三层

网络上的实现手段,故肯定会影响网络的传输效率。

host 模式:

host 模式是 bridge 桥接模式很好的补充。采用 host 模式的 Docker Container,可以直接使用

宿主机的 IP 地址与外界进行通信,若宿主机的 eth0 是一个公有 IP,那么容器也拥有这个公

有 IP。同时容器内服务的端口也可以使用宿主机的端口,无需额外进行 NAT 转换。当然,

有这样的方便,肯定会损失部分其他的特性,最明显的是 Docker Container 网络环境隔离性

的弱化,即容器不再拥有隔离、独立的网络栈。另外,使用host模式的Docker Container虽

然可以让容器内部的服务和传统情况无差别、无改造的使用,但是由于网络隔离性的弱

化,该容器会与宿主机共享竞争网络栈的使用;另外,容器内部将不再拥有所有的端口资

源,原因是部分端口资源已经被宿主机本身的服务占用,还有部分端口已经用以 bridge 网

络模式容器的端口映射。



Container 网络模式:

(1) 查找 other container(即需要被共享网络环境的容器)的网络 namespace;

(2) 将新创建的 Docker Container(也是需要共享其他网络的容器)的 namespace,使用

other container 的 namespace。

Docker Container 的 other container 网络模式,可以用来更好的服务于容器间的通信。

在这种模式下的 Docker Container 可以通过 localhost 来访问 namespace 下的其他容器,传输

效率较高。虽然多个容器共享网络环境,但是多个容器形成的整体依然与宿主机以及其他

容器形成网络隔离。另外,这种模式还节约了一定数量的网络资源。但是需要注意的是,

它并没有改善容器与宿主机以外世界通信的情况。

None 网络模式:

网络环境为 none,即不为 Docker Container 任何的网络环境。一旦 Docker Container 采用了

none 网络模式,那么容器内部就只能使用 loopback 网络设备,不会再有其他的网络资源。

可以说none模式为Docker Container做了极少的网络设定,但是俗话说得好“少即是多”,在

没有网络配置的情况下,作为 Docker 开发者,才能在这基础做其他无限多可能的网络定制

开发。这也恰巧体现了 Docker 设计理念的开放。

3.None模式

(1)netns 是在 linux 中提供网络虚拟化的一个项目,使用 netns 网络空间虚拟化可以在本地虚拟

化出多个网络环境,目前 netns 在 lxc 容器中被用来为容器提供网络。

使用 netns 创建的网络空间独立于当前系统的网络空间,其中的网络设备以及 iptables 规则

等都是独立的,就好像进入了另外一个网络一样。

(2)容器没有ip,docker0也没有桥接上





(3)创建两个网络接口veth0 veth1





(4)将接口打开,可看到由down状态转为up状态





(5)将docker0与veth0连接



(6)寻找容器的pid,链接到网络命名空间,ip nets list 查看所有 network namespace







(7)在 namespace 中新加一个设备,状态为down





(8)在 namespace 中启用设备veth1 ,即eth0,状态转为up



(9)添加ip



(10)添加网关







四.Dockerfile

1.基于rhel7 创建容器,需要我们手动写yum仓库(dvd.repo),才能yum安装







2.利用dockerfile文件直接在镜像中产生yum仓库

(1)Dockerfile必须写在docker的干净目录中,为了方便,将之前的dvd.repo文件直接拷贝过来,当然也可以手写





(2).编写Dockerfile文件,最后进行创建镜像和容器,容器内可直接yum安装

vim Dockerfile

FROM rhel7 指定基础镜像

MAINTAINER yakexi007@westos.org 作者信息

ENV HOSTNAME server1 设置容器主机名

COPY 命令可以复制本地文件夹到镜像中



(3)创建新镜像rhel7:v1(. 的意思是读取当前目录中的文件)





3.在rhel7:v1的基础上,希望可以直接进行安装http,并写入默认发布文件

(1)EXPOSE 80 暴露容器端口,由于内部服务会启动Web服务,我们需要把对应的80端口暴露出来,可以提供给容器间互联使用,可以使用 EXPOSE 命令。

RUN yum install -y httpd && yum clean all 镜像操作命令

ADD 命令支持添加本地的 tar 压缩包到容器中指定目录,压缩包会被自动解压为目录,也

可以自动下载 URL 并拷贝到镜像,例如:

ADD html.tar /var/www

ADD http://www.westos.org/html.tar /var/www

CMD [“/usr/sbin/httpd”, “-D”, “FOREGROUND”] 镜像启动命令,默认只能启动一条,此命令可在随意一台开启了http服务的机器上,ps ax 查看到,如下图



(2)Dockerfile文件



(3)Dockerfile文件中的index.html文件,放在/tmp/docker/目录下(即Dockerfile文件所在之处)



(4)创建镜像rhel7:v2



(5)创建容器vm2,端口映射,将80端口映射到本机8000端口





4.在rhel7:v1上进行新的镜像生成,使ssh互联服务安装开启

(1)可以现在之前的容器中做实验,看需要什么步骤,首先安装openssh包,之后进行密码连接认证,此处设置密码为westos,启动命令CMD包含在配置文件sshd.service中,在实验中发现,当输入/usr/sbin/sshd 时,发现提示缺少三个文件,需要ssh-keygen添加上去



(2)Dockerfile文件







五.Supervisord

1.CMD 如果只有一个命令,那如果我们需要运行多个服务怎么办呢?如果一定要在一个容器中运行多个服务可以考虑用 Supervisord 来进行进程管理,方式就是将多个启动命令放入到一个启动脚本中。

在docker目录中,较之前的yum源,增添新的yum仓库,里面内含supervisor安装包。


2.编写supervisor脚本文件(此例中是包含http以及ssh服务)



3.Dockerfile文件



4.创建新的镜像rhel7:v4

docker build -t rhel7:v4 .


5.生成容器vm4,并有端口映射





6.测试



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: