Docker开发实践笔记三


声明:本文转载自https://my.oschina.net/u/915967/blog/1612637,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

1、容器网络基础

作为一个寄宿在宿主主机上的容器,我们要想办法让外部网络能够访问到它,这样才能够使用其提供的服务。当docker启动时,它会在宿主主机上创建一个名为docker0的虚拟网络接口。linux下可以通过:ifconfig命令查看,windods下使用ipconfig查看。

1.1 暴露网络端口

Docker中运行网络应时,要让外部能访问这里需要通过-P或-p参数来指定端口映射。通过端口映射来实现端口暴露是容器对外提供服务的基础方法。

-P(大写):Docker会在宿主主机上随机为应用分配一个49000~49900内的未被使用的端口,并将其映射到容器开放的网络端口(即通过EXPOSE配置的端口)。

这里以官方的一个培训项目示例:

docker run -d -P training/webapp python app.py  使用下面的命令可以查看到运行分配的端口号。 docker ps

上面的32768就是随机分配的端口,每次运行时分配的可能都不一样,5000是容器暴露出来的端口。这样通过http://localhost:32768 就能访问服务了。

-p(小写):它可以指定宿主主机上的端口映射到容器内部指定的开放端口,格式有如下3种:

ip:hostPort:containerPort //指定ip和端口与容器开放的端口绑定

docker run -d -p 192.168.0.1:8000:5000 training/webapp python app.py

ip::containerPort //指定ip的随机端口与容器开放的端口绑定

docker run -d -p 192.168.0.1::5000 training/webapp python app.py //相当于省略了端口号所有两个冒号连在一起了

hostPort:containerPort  //宿主主机上所有的网络接口的指定的端口都会绑定(比如你可以使用localhost、局域网ip、主机名等加端口访问服务)。

docker run -d -p 8000:5000 training/webapp python app.py

容器的所有配置信息可以通过下面的命令查看:

docker inspect 容器ID或名称

 

2、数据卷

Docker中的数据可以存储在类似于虚拟机磁盘的介质中,在Docker中称为数据卷(Data Volume)。数据卷可以用来存储Docker应用的数据,也可以用来在Docker容器间进行数据共享。
数据卷呈现给Docker容器的形式就是一个目录,支持多个容器间共享,修改也不会影响镜像。使用Docker的数据卷,类似在系统中使用 mount 挂载一个文件系统。

数据卷是一个可供一个或多个容器使用的特殊目录,使用它可以达到如下目的。

1)绕过“拷贝写”系统,以达到本地磁盘IO的性能,(比如运行一个容器,在容器中对数据卷修改内容,会直接改变宿主机上的数据卷中的内容,所以是本地磁盘IO的性能,而不是先在容器中写一份,最后还要将容器中的修改的内容拷贝出来进行同步。)
2)绕过“拷贝写”系统,有些文件不需要在docker commit打包进镜像文件。
3)数据卷可以在容器间共享和重用数据
4)数据卷可以在宿主和容器间共享数据(共享单个文件,也可以是socket)
5)数据卷数据改变是直接修改的
6)数据卷是持续性的,直到没有容器使用它们。即便是初始的数据卷容器或中间层的数据卷容器删除了,只要还有其他的容器使用数据卷,那么里面的数据都不会丢失。
 

2.1 创建、挂载数据卷

有两种方式创建数据卷,具体如下:

1.在Dockerfile中,使用VOLUMN指令,如:VOLUME /var/lib/mysql

2.在命令行中使用docker run时,使用-v参数创建数据卷并将其挂载到容器中

docker run -d -P -v /webapp /training/webapp python app.pyp 

上面只是定义了一个/webapp的数据卷,并没有指定宿主机上的目录,docker会自动分配一个具有唯一名字的目录给该数据卷。


1)一个数据卷是一个特别指定的目录,该目录利用容器的UFS文件系统可以为容器提供一些稳定的特性或者数据共享。数据卷可以在多个容器之间共享
2)创建数据卷,只要在docker run命令后面跟上-v参数即可创建一个数据卷,当然也可以跟多个-v参数来创建多个数据卷,当创建好带有数据卷的容器后,
   就可以在其他容器中通过--volumes-froms参数来挂载该数据卷了,而不管该容器是否运行。也可以在Dockerfile中通过VOLUME指令来增加一个或者多个数据卷。
3)如果有一些数据想在多个容器间共享,或者想在一些临时性的容器中使用该数据,那么最好的方案就是你创建一个数据卷容器,然后从该临时性的容器中挂载该数据卷容器的数据。
   这样,即使删除了刚开始的第一个数据卷容器或者中间层的数据卷容器,只要有其他容器使用数据卷,数据卷都不会被删除的。
4)不能使用docker export、save、cp等命令来备份数据卷的内容,因为数据卷是存在于镜像之外的。备份的方法可以是创建一个新容器,挂载数据卷容器,同时挂载一个本地目录,
   然后把远程数据卷容器的数据卷通过备份命令备份到映射的本地目录里面。如下:
   # docker run -rm --volumes-from DATA -v $(pwd):/backup busybox tar cvf /backup/backup.tar /data
5)也可以把一个本地主机的目录当做数据卷挂载在容器上,同样是在docker run后面跟-v参数,不过-v后面跟的不再是单独的目录了,它是[host-dir]:[container-dir]:[rw|ro]这样格式的,
   host-dir是一个绝对路径的地址,如果host-dir不存在,则docker会创建一个新的数据卷,如果host-dir存在,但是指向的是一个不存在的目录,则docker也会创建该目录,然后使用该目录做数据源。

docker run -d -P --name webapp -v `pwd`:/webapp training/webapp python app.py  //用pwd获取当前绝对路径

注意事项:如果容器内部已经存在/webapp目录,那么挂载宿主目录之后,它的内容将会被覆盖。(不过一般不会直接在容器中写重要的数据,是吧!)

需要注意的是,Dockerfile并不支持挂载本地目录到数据卷,也就是说不能在Dockerfile文件中使用VOLUME指令挂载本地目录到数据卷,主要是因为不同操作系统 的目录格式不尽相同。为了保证Dockerfile的可移植性,所以不支持这种方式,只能通过-v参数的形式挂载。

挂载目录后面可以跟上目录的操作权限,默认是RW权限。使用格式如下:

docker run -d -P -v `pwd`:/webapp:ro training/webapp python app.py docker run -d -P -v `pwd`:/webapp:rw training/webapp python app.py

除了挂载主机目录外,也可以挂载主机的文件作为数据卷:

docker run --rm -it -v d:/test.txt:/test.txt ubuntu:latest /bin/bash   //挂载的这个文件必须要存在,否则docker会创建同名的目录,比如上面的test.txt文件不存在时会创建一个test.txt的目录。

 

2.1 数据卷容器

数据卷容器故名思义是指一个专门用于挂载数据卷的容器,以供其他容器引用和使用。它主要是用在多个容器需要从一处获得数据时。在实际操作时,需要将数据容器命名,有了确定的容器名之后,对它有依赖关系的其它容器就可以通过--volumes-from引用它的数据卷。

首先,建立一个数据卷容器,名为test_dbdata,并为该容器新建一个数据卷/dbdata。具体操作为:

docker run -d -v /dbdata --name test_dbdata training/postgres

接着创建一个容器db1,它引用test_dbdata的数据卷,具体操作为:

docker run -d --volumes-from=test_dbdata --name db1 training/postgres

可以通过docker inspect test_dbdata/db1 来查看容器挂载信息。

从inspect信息中可以看到他们的数据卷是一样的。需要说明的是,数据卷一旦声明,它的生命周期和声明它的那个容器就无关了。当声明它的容器停止了,数据卷依赖存在,除非所有引用它的容器都被删除了并且显式地删除了该数据卷。此外,一个容器引用一个数据卷容器时,并不要求数据卷容器是运行的。一个数据卷容器可以被多个容器引用。

docker run -d --volumes-from=test_dbdata --name db2 training/postgres

此外,数据卷容器还可以级联经引用。例如,新建一个容器db3,它可以引用db1的数据卷。

docker run -d --volumes-from=db1 --name db3 training/postgres

无论是声明数据卷的容器还是后续引用该数据卷的容器,容器的停止和删除都不会导致数据卷本身删除。如果需要删除数据卷,那么需要删除所有依赖它的容器,并且在删除最后一个依赖容器时加入-v标志。这里,假如test_dbdata、db1、db2都已经邮件了,那么删除db3时加上-v参数就可以删除数据卷。

docker rm -v db3

2.2 数据的备份与恢复

利用数据卷容器,还可以进行数据的备份和恢复等。

1、备份、恢复

利用数据卷容器,我们可以备份一个数据卷容器的数据。

首先,建立一个数据卷容器,相关操作为:

docker run -d -v /dbdata --name dbdata training/postgress

这样,数据都保存到了容器的/dbdata目录,这里要备份/dbdata目录到本地,相关操作为:

docker run --volumes-from dbdata -v ${pwd}:/backup ubuntu tar cvf /backup/backup.tar /dbdata

这里创建了一个新的数据卷容器,并引用了dbdata数据卷容器,当前目录挂载到新的数据卷容器/backup目录,这样当前目录就和/backup目录是同一个目录了,容器中的数据写到/backup目录亦即写到了宿主机的当前目录。

恢复的过程其实就是将原来tar cvf打包的数据,使用tar xvf解压到数据卷。

注意:在windows中如果使用git-bash的命令行来运行命令,pwd得到的路径不认,可以直接写绝对路径,格式是:/d/docker_data d表示d盘。就是原来的 d:/ 换成了/d。

很详细的讲解数据卷、及备份恢复的文章:

Docker容器学习梳理--Volume数据卷使用

2.3 容器连接

前面我们使用了-P或-p来暴露容器端口,以供外界使用该容器。还有另一种容器对外提供服务的方法——容器连接。容器连接包含源容器和目标容器:源容器是提供服务的一方,对外提供指定服务;目标容器连接到源容器后,就可以使用其所提供的服务。容器连接依赖于容器名,所以当需要使用容器连接时,首先需要命名容器,然后使用--link参数进行连接。

连接的格式为:--link name:alias,其中name是源容器的名称,alias是这个连接的别名。下面是一个连接的示例:

docker run -d --name dbdata training/postgres 上面的命令先建立了一个数据库的容器,使用下面的命令连接它。 docker run -d -P --name web --link dbdata:db training/webapp python app.py

通过docker inspect web可以查看到连接信息。

通过这种方法,dbdata容器为web容器提供了服务,但并没有使用-P或-p对外暴露端口,这使得源容器dbdata更安全。那web容器是如何使用dbdata的服务呢?

Docker给目标容器提供了如下两种方式来暴露连接提供的服务:

  • 环境变量
  • /etc/hosts文件

下面分别说明它们。

1 环境变量

当两个容器连接互联之后,Docker将会在目标容器中设置相关的环境变量,以便在目标容器中使用源容器提供的服务。连接环境变量的命令格式为<alias>_NAME,其中alias是--link参数中的别名。例如web容器连接dbdata容器,参数为--link dbdata:webdb,那么在容器中则有环境变量WEBDB_NAME=/web/webdb。

一般情况下,可以使用evn命令来查看一个容器的环境变量,相关代码为:

docker run --rm --name web --link dbdata:webdb training/webapp env

下面是显示结果:

2 /etc/hosts文件

查看目标容器的/etc/hosts配置文件,具体操作如下:

docker run -i -t --rm --name web2 --link dbdata:webdb training/webapp /bin/bash

可以看到,容器连接webdb对应的ip地址,该ip地址即为dbdata容器的地址,容器对webdb连接的操作将映射到该地址上。

2.4 代理连接

上面说的容器连接都是在同一个宿主主机上的连接,要实现跨主机的容器连接,目前可以使用ambassador模式来实现跨主机连接,这种模式叫代理连接。

现阶段代理的实现方法有多种,下面收集了一些方案(如有最好的方便欢迎留言)

http://blog.csdn.net/shanyongxu/article/details/51398574

http://blog.csdn.net/magerguo/article/details/72123515

http://www.bijishequ.com/detail/445655?p=

http://blog.51cto.com/renyongfan/1812825

 

本文发表于2018年01月25日 08:32
(c)注:本文转载自https://my.oschina.net/u/915967/blog/1612637,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 664 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

行业标准总是平庸的

一直到现在我才突然明白,我梦寐以求,是真爱和自由。

把爱情留给我身边最真心的姑娘,你陪我歌唱陪我流浪,陪我两败俱伤。

把青春献给身后那座辉煌的都市,为了这个美梦,我们付出着代价。

又是一年五一,祝我们工人阶级劳动节快乐! 今年被困在北京了,离境再入境需要隔离十五天。只能京津冀周边走一走了,想出去玩啊啊啊啊啊~

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1