首页 存档 技术 查看内容

聊聊代码 | Docker Swarm模式下,Docker应用如何实现服务发现

2018-3-30 13:00 |来自: 互联网 536 0

摘要: 活动预告全球云计算开源产业峰会 BoCloud博云 高级解决方案架构师 赵安全 将在4月19日14:30-14:50 容器论坛中分享 《容器在传统行业落地的再思考》 相约现场 不见不散~原文:How Service Discovery Works in Contain ...

活动预告

全球云计算开源产业峰会

BoCloud博云

高级解决方案架构师

赵安全

将在4月19日14:30-14:50

容器论坛中分享

《容器在传统行业落地的再思考》

相约现场 不见不散~


原文:How Service Discovery Works in Containerized Applications Using Docker Swarm Mode

作者:JOHN KINSELLA

翻译:岳俊凯

来源:DockOne.io

原文链接:http://www.dockone.io/article/2219


当我们第一次考虑在生产环境中使用容器时,常常会面对一个问题:当容器运行在一组服务器集群上时,无论它在哪个服务器上,如何让其他实体(人或应用程序)可靠地连接到它。

一定程度上,这个问题也存在于之前的虚拟化时代。在常见的三层web应用堆栈中,这可以用以下方式处理:

  • 负载均衡器具有后端Web服务器的IP地址

  • Web服务器具有实现业务逻辑的应用服务器的IP地址

  • 编写应用服务器查询数据库的sql语句,用于返回数据


只要Web服务器,应用服务器或数据库服务器没有被替换,上述的解决方案就会很简单。如果它们被替换了,Devops工程师将确保新系统使用之前的IP地址。

而现在,新的替代方案出现了,如Zookeeper,但并非唯一。随着架构复杂度的增加,服务发现越来越受到重视:以前可能只有10台虚拟机,但现在可能会有200至300个容器,而且容器的生命周期明显短于虚拟机的。

在Docker的“内置电池,但可以被替代”的理念之后,Docker Swarm模式配备了内置的DNS服务器。它为用户提供简单的服务发现。如果某时,用户的需求超出了DNS服务器的设计参数,那么他们可以使用第三方的服务发现。


开始


关于如何安装Docker Swarm集群,互联网上有大量的资源,这里不再赘述。对于这篇文章,我们将使用在GitHub上的Vagrant配置,并为此发布一些端口转发。如果你已经安装了Vagrant和Virtualbox,可用以下方式来启动一个Docker Swarm集群:

$gitclonehttps://github.com/jlk/docker-swarm-mode-vagrant.git

Cloninginto'docker-swarm-mode-vagrant'...

remote:Countingobjects:23,done.

remote:Total23(delta0),reused0(delta0),pack-reused23

Unpackingobjects:100%(23/23),done.

$cddocker-swarm-mode-vagrant/

$vagrantup


在最后一个命令之后,Vagrant大约需要5至10分钟去下载Ubuntu虚拟机镜像,启动3个虚拟机,更新软件包,安装Docker引擎并将虚拟机节点(以下简称节点)加入一个Swarm集群。通过SSH协议,你可以使用以下命令进入主节点,并列出Swarm集群的成员:

$vagrantsshnode-1

vagrant@node-1:~$dockernodels

IDHOSTNAMESTATUSAVAILABILITYMANAGERSTATUS

9f22lo0cthxn64w79arje5rqgnode-2ReadyActive

p2yg78i4fmzwglu8lp4j1cebc*node-1ReadyActiveLeader

tp9h7cpef13fzeztje38igs4snode-3ReadyActive

(ID将是不同的,因为节点是不同的)


启动一个WordPress应用


接下来,让我们启动一个包含MariaDB数据库服务(以下简称dbcluster服务)和wordpress服务的应用程序。为了方便起见,我们使用另一个包含docker-compose文件的GitHub项目来构建集群。让我们克隆这个项目并启动容器:

vagrant@node-1:~$gitclonehttp://github.com/jlk/wordpress-swarm.git

Cloninginto'wordpress-swarm'...

remote:Countingobjects:7,done.

remote:Compressingobjects:100%(6/6),done.

remote:Total7(delta0),reused4(delta0),pack-reused0

Unpackingobjects:100%(7/7),done.

Checkingconnectivity...done.

vagrant@node-1:~$cdwordpress-swarm

vagrant@node-1:~/wordpress-swarm$dockerstackdeploy--compose-filedocker-stack.ymlwordpress

Creatingnetworkwordpress_common

Creatingservicewordpress_wordpress

Creatingservicewordpress_dbcluster

vagrant@node-1:~/wordpress-swarm$


在后台,Docker正在调度这些容器用以跨节点运行,下载镜像和旋转容器。根据你的服务器运算速度和网络速度,大约一分钟后,你可以看到运行的服务:

vagrant@node-1:~/wordpress-swarm$dockerservicels

IDNAMEMODEREPLICASIMAGE

fyhqrei7hz75wordpress_dbclusterreplicated1/1toughiq/mariadb-cluster:latest

ojbyktsyrmlawordpress_wordpressreplicated2/2wordpress:php7.1-apache

vagrant@node-1:~/wordpress-swarm$


此时,你可以在浏览器中输入http://localhost:8080,并查看WordPress应用的初始配置。

查看docker-stack.yml文件,你将看到传递到wordpress容器的环境变量,这些指示容器连接到dbcluster服务。这只是一个传入容器的字符串,两个服务之间没有定义的链接。在旧版本的演示中,我们不得不在docker-stack.yml文件中的wordpress服务和dbcluster服务之间创建一个“link”,以便wordpress容器能够识别和使用dbcluster服务名。具体操作如下:

services:

wordpress:

...

links:

-dbcluster


而在新版本的演示中,Docker创建dbcluster容器之后,dbcluster服务会自动在其DNS中发布一个A记录,以允许其他容器在查找DNS名称时找到它。如果查看其中一个wordpress容器的初始日志,你可能会看到它无法找到dbcluster服务,接着在几次尝试后,最终找到。在dbcluster容器启动时,wordpress容器一直尝试建立一个数据库连接,一旦数据库容器启动,它将连接起来,具体细节如下:

Warning:mysqli::__construct():php_network_getaddresses:getaddrinfofailed:Nameorservicenotknownin-online22

Warning:mysqli::__construct():(HY000/2002):php_network_getaddresses:getaddrinfofailed:Nameorservicenotknownin-online22

MySQLConnectionError:(2002)php_network_getaddresses:getaddrinfofailed:Nameorservicenotknown

Warning:mysqli::__construct():(HY000/2002):Connectionrefusedin-online22

MySQLConnectionError:(2002)Connectionrefused



AH00558:apache2:Couldnotreliablydeterminetheserver'sfullyqualifieddomainname,using10.0.0.3.Setthe'ServerName'directivegloballytosuppressthismessage

AH00558:apache2:Couldnotreliablydeterminetheserver'sfullyqualifieddomainname,using10.0.0.3.Setthe'ServerName'directivegloballytosuppressthismessage

[MonFeb2716:16:43.0867612017][mpm_prefork:notice][pid1]AH00163:Apache/2.4.10(Debian)PHP/7.1.2configured--resumingnormaloperations

[MonFeb2716:16:43.0868362017][core:notice][pid1]AH00094:Commandline:'apache2-DFOREGROUND'


扩展数据库


接下来,我们尝试扩展数据库服务。选择的MariaDB镜像已经启用了Galera集群功能,并且配置为通过组播方式发现集群成员。虽然基于DNS的服务发现内置于Docker Swarm模式中,但仍然需要更复杂的多主复制过程,以便应用程序能够确定,因此我们需要开启Galera集群功能。现在将dbcluster服务扩展到三个副本:

vagrant@node-1:~/wordpress-swarm$dockerservicescalewordpress_dbcluster=3
wordpress_dbclusterscaledto3


再增加两个dbcluster容器,并将它们添加到dbcluster服务之后的数据库池中。容器通过多播方式互相发现,同步。一旦你在容器日志中看到如下信息,就说明我们成功创建了一个三容器的dbcluster服务:

2017-02-2716:49:42139688903960320[Note]WSREP:
Member2.0(84e5bc4c66b9)syncedwithgroup.


在浏览器中,我们重新加载WordPress应用,它仍然可以正常工作。此时,当wordpress服务尝试连接到dbcluster服务时,该请求由Docker在三个dbcluster容器之间进行负载均衡。在内置于Docker的DNS服务器中,dbcluster服务的IP地址是“虚拟IP”,在后台,Docker使用IPVS将流量均摊到各个dbcluster容器。如果多主复制未同步,则会导致严重的混乱。

最后,我们将dbcluster服务收缩回单个容器。在传统的生产环境中,我们必须非常谨慎地操作,但是在Docker中可以很轻松:

vagrant@node-1:~/wordpress-swarm$dockerservicescalewordpress_dbcluster=1

wordpress_dbclusterscaledto1

vagrant@node-1:~/wordpress-swarm$


因此,两个dbcluster容器将被关闭,dbcluster服务将返回到一个容器大小,WordPress应用仍然正常运行。

Docker Swarm模式的服务发现真的很好,它帮助我们松散地定义应用程序各个部分之间的关系。


上期回顾


路过

雷人

握手

鲜花

鸡蛋

相关分类

返回顶部