在Docker Swarm模式下,Docker应用如何实现服务发现

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 本文讲的是在Docker Swarm模式下,Docker应用如何实现服务发现【编者的话】无论容器是否存在于集群之中,本文将告诉我们如何可靠地连接到它。
本文讲的是在Docker Swarm模式下,Docker应用如何实现服务发现【编者的话】无论容器是否存在于集群之中,本文将告诉我们如何可靠地连接到它。 

【深圳站|3天烧脑式Kubernetes训练营】培训内容包括:Kubernetes概述和架构、部署和核心机制分析、进阶篇——Kubernetes调工作原理及源码分析等。

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

一定程度上,这个问题也存在于之前的虚拟化时代。在常见的三层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集群:
$ git clone https://github.com/jlk/docker-swarm-mode-vagrant.git

Cloning into 'docker-swarm-mode-vagrant'...

remote: Counting objects: 23, done.

remote: Total 23 (delta 0), reused 0 (delta 0), pack-reused 23

Unpacking objects: 100% (23/23), done.

$ cd docker-swarm-mode-vagrant/

$ vagrant up

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

vagrant@node-1:~$ docker node ls

ID                           HOSTNAME  STATUS  AVAILABILITY  MANAGER STATUS

9f22lo0cthxn64w79arje5rqg    node-2    Ready   Active

p2yg78i4fmzwglu8lp4j1cebc *  node-1    Ready   Active        Leader

tp9h7cpef13fzeztje38igs4s    node-3    Ready   Active

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

启动一个WordPress应用

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

Cloning into 'wordpress-swarm'...

remote: Counting objects: 7, done.

remote: Compressing objects: 100% (6/6), done.

remote: Total 7 (delta 0), reused 4 (delta 0), pack-reused 0

Unpacking objects: 100% (7/7), done.

Checking connectivity... done.

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

vagrant@node-1:~/wordpress-swarm$ docker stack deploy --compose-file docker-stack.yml wordpress

Creating network wordpress_common

Creating service wordpress_wordpress

Creating service wordpress_dbcluster

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

在后台,Docker开始下载镜像,启动容器,调度容器以实现跨节点运行。根据你的服务器运算速度和网络速度,大约一分钟后,你可以看到运行的服务:
vagrant@node-1:~/wordpress-swarm$ docker service ls

ID            NAME                 MODE        REPLICAS  IMAGE

fyhqrei7hz75  wordpress_dbcluster  replicated  1/1       toughiq/mariadb-cluster:latest

ojbyktsyrmla  wordpress_wordpress  replicated  2/2       wordpress: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: getaddrinfo failed: Name or service not known in - on line 22

Warning: mysqli::__construct(): (HY000/2002): php_network_getaddresses: getaddrinfo failed: Name or service not known in - on line 22

MySQL Connection Error: (2002) php_network_getaddresses: getaddrinfo failed: Name or service not known

Warning: mysqli::__construct(): (HY000/2002): Connection refused in - on line 22

MySQL Connection Error: (2002) Connection refused

…

AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 10.0.0.3. Set the 'ServerName' directive globally to suppress this message

AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 10.0.0.3. Set the 'ServerName' directive globally to suppress this message

[Mon Feb 27 16:16:43.086761 2017] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.10 (Debian) PHP/7.1.2 configured -- resuming normal operations

[Mon Feb 27 16:16:43.086836 2017] [core:notice] [pid 1] AH00094: Command line: 'apache2 -D FOREGROUND' 

扩展数据库

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

再增加两个dbcluster容器,并将它们添加到dbcluster服务之后的数据库池中。容器通过多播方式互相发现,同步。一旦你在容器日志中看到如下信息,就说明我们成功创建了一个三容器的dbcluster服务:
2017-02-27 16:49:42 139688903960320 [Note] WSREP: 
Member 2.0 (84e5bc4c66b9) synced with group.

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

最后,我们将dbcluster服务收缩回单个容器。在传统的生产环境中,我们必须非常谨慎地操作,但是在Docker中可以很轻松:
vagrant@node-1:~/wordpress-swarm$ docker service scale wordpress_dbcluster=1

wordpress_dbcluster scaled to 1

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

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

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

原文链接:How Service Discovery Works in Containerized Applications Using Docker Swarm Mode(翻译:岳俊凯)

===========================================
译者介绍 

岳俊凯,开源软件爱好者,研究方向是Devops和计算机视觉,乐于实现一些新奇的想法。

原文发布时间为:2017-04-03

本文作者:岳俊凯

本文来自云栖社区合作伙伴Dockerone.io,了解相关信息可以关注Dockerone.io。

原文标题:在Docker Swarm模式下,Docker应用如何实现服务发现

相关文章
|
10天前
|
NoSQL 关系型数据库 MySQL
《docker高级篇(大厂进阶):4.Docker网络》包括:是什么、常用基本命令、能干嘛、网络模式、docker平台架构图解
《docker高级篇(大厂进阶):4.Docker网络》包括:是什么、常用基本命令、能干嘛、网络模式、docker平台架构图解
109 56
《docker高级篇(大厂进阶):4.Docker网络》包括:是什么、常用基本命令、能干嘛、网络模式、docker平台架构图解
|
22天前
|
安全 Docker 容器
docker的默认网络模式有哪些
Docker 默认网络模式包括:1) bridge:默认模式,各容器分配独立IP,可通过名称或IP通信;2) host:容器与宿主机共享网络命名空间,性能最优但有安全风险;3) none:容器隔离无网络配置,适用于仅需本地通信的场景。
35 6
|
25天前
|
Prometheus 监控 Cloud Native
如何使用Prometheus监控Docker Swarm集群的资源使用情况?
还可以根据实际需求进行进一步的配置和优化,如设置告警规则,当资源使用超出阈值时及时发出警报。通过这些步骤,能够有效地使用 Prometheus 对 Docker Swarm 集群的资源进行监控和管理。
43 8
|
25天前
|
Prometheus 监控 Cloud Native
如何监控Docker Swarm集群的性能?
如何监控Docker Swarm集群的性能?
82 8
|
25天前
|
调度 开发者 Docker
Docker Swarm
Docker Swarm 为容器化应用的部署和管理提供了一种高效、可靠的方式,使开发者能够更轻松地构建和运行分布式应用。随着容器技术的不断发展,Docker Swarm 在企业级应用中的应用也将越来越广泛。
48 8
|
25天前
|
监控 Docker 容器
Docker Swarm集群的扩展与缩容策略,涵盖其意义、方法、步骤及注意事项
本文深入探讨了Docker Swarm集群的扩展与缩容策略,涵盖其意义、方法、步骤及注意事项,旨在帮助用户高效管理集群资源,适应业务变化,确保服务稳定性和资源优化。
47 6
|
25天前
|
存储 Prometheus 监控
Docker容器内进行应用调试与故障排除的方法与技巧,包括使用日志、进入容器检查、利用监控工具及检查配置等,旨在帮助用户有效应对应用部署中的挑战,确保应用稳定运行
本文深入探讨了在Docker容器内进行应用调试与故障排除的方法与技巧,包括使用日志、进入容器检查、利用监控工具及检查配置等,旨在帮助用户有效应对应用部署中的挑战,确保应用稳定运行。
32 5
|
25天前
|
开发框架 安全 开发者
Docker 是一种容器化技术,支持开发者将应用及其依赖打包成容器,在不同平台运行而无需修改。
Docker 是一种容器化技术,支持开发者将应用及其依赖打包成容器,在不同平台运行而无需修改。本文探讨了 Docker 在多平台应用构建与部署中的作用,包括环境一致性、依赖管理、快速构建等优势,以及部署流程和注意事项,展示了 Docker 如何简化开发与部署过程,提高效率和可移植性。
55 4
|
25天前
|
存储 缓存 运维
Docker镜像采用分层存储,每层代表镜像的一部分,如基础组件或应用依赖,多层叠加构成完整镜像
Docker镜像采用分层存储,每层代表镜像的一部分,如基础组件或应用依赖,多层叠加构成完整镜像。此机制减少存储占用,提高构建和传输效率。Docker还通过缓存机制提升构建和运行效率,减少重复工作。文章深入解析了Docker镜像分层存储与缓存机制,包括具体实现、管理优化及实际应用案例,帮助读者全面理解其优势与挑战。
43 4
|
25天前
|
负载均衡 网络协议 算法
Docker容器环境中服务发现与负载均衡的技术与方法,涵盖环境变量、DNS、集中式服务发现系统等方式
本文探讨了Docker容器环境中服务发现与负载均衡的技术与方法,涵盖环境变量、DNS、集中式服务发现系统等方式,以及软件负载均衡器、云服务负载均衡、容器编排工具等实现手段,强调两者结合的重要性及面临挑战的应对措施。
59 3

热门文章

最新文章