如何访问service呢?

为了便于分析,我们重新部署web-server

1.删除service

执行命令docker service rm web-server

docker service rm删除web-server,service所有的副本会被同时删除

2.重新创建service,这次直接使用--replicas=2指定副本的数量

3.现在每个worker-node上分别运行了一个副本

那么现在如何访问service呢?

可以想成现在有两个docker host,分别运行了一个httpd容器,我们先去docker1上看一下网络情况

容器监听了80端口,但是没有映射到Docker host,所以只能通过容器的IP访问,查看容器的IP

容器的IP是172.17.0.2,实际上连接的是dcoker 默认的bridge网络

我们可以直接在docker1上访问容器的http服务

但这样的访问也仅仅是容器层面的访问,服务没有暴露给外部网络,只能在dcoker 主机上访问,也就是说,我们现在无法访问service web-server

如何做到从外部访问service呢?

之前我们学习dcoker网络时知道只要将service暴露到外部,service也是同样的方法,不同的是我们之前学习的是单台host上的单个容器,现在是多个host上的多个容器,

其实方法也很简单,我们只要个整个的web-server添加端口映射就可以了

执行一下命令

docker service update --publish-add 8080:80 web-server

如果是新建service,可以直接使用--publish参数,比如:

docker service create --name web-server --publish 8080:80 --replicas=2 httpd

可以看到现在service已经有端口了。

在浏览器中测试一下

 

当我们访问任何节点的8080端口时,swarm内部的load balancer会将请求转发给web-server其中的一个副本,这就是routing mesh的作用

盗图

所以,无论访问哪个节点,即使节点上没有运行service,最终都能访问到service

另外,我们还可以配置一个外部的load balancer,将请求路由到swarm service。比如配置haproxy,将请求分发到各个节点的8080端口。

ingress网络

当我们用--publish-add 8080:80时,swarm会重新配置service,我们看看容器发生了哪些变化

所有副本都被shutdown,然后重启了新的副本,我们查看一下新的副本的容器网络配置

容器的网络与--pubilc-add之前都不大一样了,现在有两块网卡,每块网卡连接不同的docker网络。

实际上:

1.eth0连接的是一个overlay类型的网络,名字为ingress,作用是让运行在不同主机上的容器之间可以相互通信。

2.eth1连接的是bridge类型的网络,名字为docker_gwbridge,作用是让容器能够访问到外网

ingress网络是swarm创建时dcoker为我们自动创建的,swarm中的每个node都能使用ingress

通过overlay网络,主机与容器,容器与容器之间可以互相访问;同时,routing mesh将外部请求路由到不同的主机,从而实现了外部网络对service的访问

service之间如何通信?

微服务的架构由若干service组成。比如:由运行httpd的web前端,有提供缓存的memcached,有存放数据库的mysql,每一层都是swarm的一个service,每个service都运行了若干容器,在这样的架构中,service之间时如何进行通信的呢?

服务发现:

一种实现方法是将所有的service都publish出去,然后通过routing mesh访问。但明显的缺陷是把memcache和mysql也暴露到外网,增加了安全隐患

如果不publish,swarm就要提供一种机制,能够:

1.让service通过简单的方法访问到其他service。

2.当service副本的IP发生变化的时候,不会影响到该service和其他的service

3.当service的副本数量发生变化的时候,不会影响该service和其他的service

这其实就是服务发现(service discovery)

docker swarm原生就提供了这种功能,通过服务发现,service的使用者都不需要知道service运行在哪里,IP是多少,有多少个副本,就能让service通信。

创建overlay网络

要使用服务发现,需要相互通信的service必须属于同一个overlay网络,所以我们先创建一个新的overlay网络。

直接使用ingress行不行呢?

答案是不行,因为目前ingress没有提供服务发现,必须创建自己的overlay网络。

部署service到新建的overlay

部署一个web服务,并将其挂载到新创建的overlay网络

docker service create --replicas=3 --network web --name my-web httpd

运行一个util服务用于测试,挂载到同一个overlay网络

docker service create --name util --network web busybox sleep 10000000

sleep 10000000的作用是保持busybox容器处于运行状态,我们才能进入到容器访问servcie my-web

验证:

通过docker service ps util确认util所在的节点是docker1

登录到docker1上的util容器中,ping my-web

可以看到,my-web的IP是10.0.0.5,这个IP是哪个副本的呢?我们先来查看一下

docker1上的my-web的副本的IP是10.0.0.6

docker2上的my-web的副本的IP也不是10.0.0.5,那这个10.0.0.5到底是什么呢?

其实他是一个VIP(virtual IP),swarm会将对VIP的访问负载均衡到每一个副本。

向上面那样一个一个的进入容器查看副本IP很麻烦,可以通过以下的方式来查看。

docker exec  util.1.ecqgk215q1g9mft3u02w4jrq6 nslookup tasks.my-web

可以看到解析出来的副本的IP与我们上面查询的一致,。

对于服务的使用者,这里是util根本就不需要知道my-web副本的IP,也不需要知道my-web的VIP,只需直接用service的名字就能访问服务

滚动更新service

滚动更新降低了应用更新的风险,如果某个副本更新失败,整个更新将暂停,其他副本则可以继续提供服务,同时,在更新的过程中,总是有副本在运行的,因此也保证了业务连续性。

试验:运行三个副本的service,镜像使用httpd:2.2.31,然后将其更新到httpd:2.2.32.

将web-update service更新到httpd:2.2.32

docker service update --image httpd:2.2.32 web-update

从这个更新的过程中可以看到,是从一个副本开始更新,这个副本更新完成后,再更新之后的两个

--image指定新的镜像

swarm按照如下的步骤执行滚动更新

1.停止第一个副本

2.调度任务,选择worker node

3.在worker上用新的镜像启动副本

4.如果更新成功则继续更新下一个,如果失败,暂停整个更新的过程

一个在更新,还有两个副本在运行,保障了服务不间断

默认情况下,swarm一次只更新一个副本,并且两个副本之间没有等待时间。

我们可以通过--update-parallelism设置并行更新的副本数,通过--update-delay指定滚动更新的时间间隔。

比如执行以下命令:

docker service update --repliacas 6 --update-parallelism 2 --update-delay 1m30s web-update

service副本增加到6个,每次更新两个副本,时间间隔为1分半钟

docker service inspect查看service当前的配置

docker service ps web-update确保6个副本处于运行的状态

将目前6个副本更新到httpd:2.4.16

docker service update --image httpd:2.4.16 web-update

可以看到现在是两个两个的并行进行更新,

现在可以看到由于docker2上的副本更新失败,所以已经暂停了更新,1分半钟之后并没有进行下一组副本的更新

现在遇到错误了,导致service中的副本版本不一致,怎么办呢?

rollback

swarm还有个方便回滚的功能,如果更新后的效果不理想,可以通过--rollback快速恢复到更新之前的状态

docker service update --rollback web-server

通过docker service ps web-server进行查看

注:--rollback只能回滚到上一次执行docker service update之前的状态,并不能无限制的回滚。

我们重新来更新一下

还是两个一组并行更新

centos7下安装docker(23.docker-swarm之如何访问service)的更多相关文章

  1. Centos7下安装redis并能使得外网访问

    一.安装脚本 #!/bin/bash #FileName: install_redis_centos7.sh #Date: #Author: LiLe #Contact: @qq.com #Versi ...

  2. Centos7下安装与卸载docker应用容器引擎

    Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从Apache2.0协议开源. Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级.可移植的容器中,然后发布到任何流行的 Li ...

  3. docker(一) Centos7下安装docker

    docker(一) Centos7下安装dockerdocker(二) windows10下安装dockerdocker(三) 镜像和容器常用命令 docker(四) 使用Dockerfile构建镜像 ...

  4. Docker学习之Centos7下安装

    Docker学习之Centos7下安装 centos7 64下直接使用yum安装docker环境,步骤如下: 卸载旧版本docker sudo yum remove docker docker-com ...

  5. CentOS7下安装docker(Docker系列1)

    CentOS7下安装docker 系统要求 为了安装docker,需要准备 64-bit的CentOS 7 删除非官方的Docker包 yum的仓库中有一个很旧的Docker包, 现在Docker官方 ...

  6. centos7下安装docker与镜像加速

    1.背景 centos7下安装docker 2.安装 第一步:检查是否为centos7版本 第二步:依赖环境安装 执行如下两个命令: yum -y install gcc yum -y install ...

  7. Docker学习笔记3:CentOS7下安装Docker-Compose

    Docker-Compose是一个部署多个容器的简单但是非常必要的工具. 安装Docker-Compose之前,请先安装 python-pip,请参考我的另一篇博文CentOS7下安装python-p ...

  8. centos7下安装指定版本mysql5.7.23

    现在mysql版本已经到MySQL 8.0(GA)稳定版本了,所以需求是想简单又快速在centos7下安装指定版本例如MySQL 5.7(GA)版本有下面这种方法 首先需要到mysql官网这里下载对应 ...

  9. MariaDB Centos7 下安装MariaDB

    Centos7 下安装MariaDB by:授客 QQ:1033553122 1.下载安装文件 rpm包为例,对于标准服务器安装,至少需要下载client,shared,serve文件(安装时如果少了 ...

  10. CentOS7 下 安装 supervisor以及使用

    CentOS7 下 安装 supervisor 以及使用 手动安装 [注] linux环境必须安装 python 1.获取supervisor包:[https://pypi.python.org/py ...

随机推荐

  1. 谈谈mysql的悲观和乐观锁

    悲观锁与乐观锁是两种常见的资源并发锁设计思路,也是并发编程中一个非常基础的概念.之前有写过一篇文章关于并发的处理思路和解决方案,这里我单独将对这两种常见的锁机制在数据库数据上的实现进行比较系统的介绍一 ...

  2. js 简单日历

    源地址:https://jingyan.baidu.com/article/546ae185fa4f721149f28cbf.htm 文件:index.htm <!DOCTYPE html> ...

  3. html 获取数据并发送给后端方式

    一.方式一 使用ajax提交 function detailed() { var date = $("#asset_ip").text() $.ajax({ url: " ...

  4. 在centos7上编译安装nginx

    题前,先放一个有图有真相的博客链接:https://www.cnblogs.com/zhang-shijie/p/5294162.html 虽然别人说的很详细,但还是记录一下 1.VMWare Wor ...

  5. 常用的JVM调优参数总结汇总【随时查阅学习】

    本文章参数根据后期用的参数会持续更新  --- (1)-Xms20M 表示设置JVM启动内存的最小值为20M,必须以M为单位 (2)-Xmx20M 表示设置JVM启动内存的最大值为20M,必须以M为单 ...

  6. Html:html是什麽、html文件结构

    相关内容: html是什麽 html文件结构 首发日期:2018-02-12 html是什么: hmtl超文本标记语言,标准通用标记语言下的一个应用. html专门用于网页,它的“标志符”告诉了浏览器 ...

  7. windows网络编程中文 笔记(一)

    OSI网络模型 OSI(Open System Interconnection)开放系统互联 第七层 应用层 为用户提供相应的界面,以便使用提供的连网功能 第六层 表示层 完成数据的格式化 第五层 会 ...

  8. Python中类的定义及使用

    类是一些有共同特征和行为事务事物的抽象概念的总和. 从中可以看出,方法只能使用实例直接调用(无需传self参数),而使用类调用必须传入实例对象: 属性可以使用实例调用,也可以使用类直接调用,因此可以看 ...

  9. SQL SERVER中LIKE使用变量类型不同输出结果不一致解惑

    一同事在写脚本时,遇到一个关于LIKE里面使用不同的变量类型导致查询结果不一致的问题,因为这个问题被不同的人问过好几次,索性总结一下,免得每次都要解释一遍,直接丢一篇博客岂不是更方便!其实看似有点让人 ...

  10. python len()函数的用法

    函数:len() 返回字符串.列表.字典.元组等长度. 语法:len(str) str:要计算的字符串.列表.字典.元组等 返回值:字符串.列表.字典.元组等元素的长度. Test: 1:计算字符串的 ...