zoukankan      html  css  js  c++  java
  • Fleet-运行一个高可用的服务

    运行一个高可用的服务

    使用CoreOS最大的好处就是你可以以高可用的方式来运行你的服务。接下来我们将部署两个一样的Apache web server容器。然后,我们将通过让一台机器出现故障,fleet将在其它机器上重新启动我们的任务。

    首先,让我们写一个将会运行两个副本的unit文件。为了实现这个目标,我们用一个unit模板,名字是apache@.service。它将会是apache@1.service 和 apache@2.service的基础配置。

    [Unit]
    Description=My Apache Frontend
    After=docker.service
    Requires=docker.service
    
    [Service]
    TimeoutStartSec=0
    ExecStartPre=-/usr/bin/docker kill apache1
    ExecStartPre=-/usr/bin/docker rm apache1
    ExecStartPre=/usr/bin/docker pull coreos/apache
    ExecStart=/usr/bin/docker run --rm --name apache1 -p 80:80 coreos/apache /usr/sbin/apache2ctl -D FOREGROUND
    ExecStop=/usr/bin/docker stop apache1
    
    [X-Fleet]
    Conflicts=apache@*.service
    

    fleet通过Conflicts属性来知道这两个服务将不会运行在同一个机器上,提供了高可用。更详细的配置配置节点将会在fleet units guide找到。

    让我们在启动两个unit在不同的机器吧。

    $ fleetctl start apache@1
    $ fleetctl start apache@2
    $ fleetctl list-units
    UNIT              MACHINE                 ACTIVE    SUB
    myapp.service     c9de9451.../10.10.1.3   active    running
    apache@1.service  491586a6.../10.10.1.2   active    running
    apache@2.service  148a18ff.../10.10.1.1   active    running
    

    就像你看到的一样,Apache单元现在已经运行在我们集群中的两个不同的机器中了。

    那我们怎么样给这些容器分发请求呢?最好的策略就是运行一个搭档容器来履行相关的职责,而不是直接内置到应用里面。例如搭档容器就是用来服务发现和控制外部负载均衡或DNS

    故障恢复

    fleet集群中的机器不断地与集群中的其他人进行通信,并选出一个领导者做出决策。领导负责解析新提交units,并找到一个合格的机器运行(通过x-fleet参数),然后通知机器启动unit。

    当一个机器没能给fleet leader发回心跳包,所有运行在这台机器上的units会被重新调度。通过这个流程,每个unit都能找到合适的机器来运行,他们将运行在新的机器上。在这个合适的机器没有找到之前,units不会重新运行。如果失败的机器恢复了,fleet leader 会告诉他停掉已经重新调度的units,并且这台机器将被用来新的工作。

    你可以通过停掉一台机器上的fleet进程(sudo systemctl stop fleet)来测试Apache unit。fleet的日志(sudo journalctl -u fleet)将会体统更清晰的过程。

    运行一个简单的搭档

    这个简单的搭档的例子就是服务发现,这个unit连续的宣布我们的容器已经在运行了。我们可以为每一个已经运行了的Apache unit运行一个搭档,我们将要用一个unit的模板来启动两个实例。做一个模板叫做apache-discovery@.service。

    [Unit]
    Description=Announce Apache1
    BindsTo=apache@%i.service
    After=apache@%i.service
    
    [Service]
    ExecStart=/bin/sh -c "while true; do etcdctl set /services/website/apache@%i '{ "host": "%H", "port": 80, "version": "52c7248a14" }' --ttl 60;sleep 45;done"
    ExecStop=/usr/bin/etcdctl rm /services/website/apache@%i
    
    [X-Fleet]
    MachineOf=apache@%i.service
    

    这个unit有几个简单的特性。首先,它使用BindsTo来连接我们的apache@%i.service unit。当Apache unit 停止运行的时候,他也会从我们的etcd中的/services/website目录中移除。当我们的机器因某种原因突然停止的时候,60秒后将会把unit从我们的目录中移除。

    第二就是%i,一个内置的系统变量,代表一个实例化单元实例名称(一个单元推出一个模板)。这个变量在单元名称中的任何值之后扩展到任何值。在我们的例子中,它将扩大到1(Apache-discovery@1)和2(apache-discovery@2)。

    Third is %H, a variable built into systemd, that represents the hostname of the machine running this unit. Variable usage is covered in our Getting Started with systemd guide as well as in systemd documentation.

    第三为%H,一个内置的系统变量,表示运行机器的主机名。变量使用说明详见Getting Started with systemd或是systemd documentation

    第四是一个fleet特有的属性,叫做MachineOf。这个属性的作用是让单元被放置在运行Apache服务的同一机器上(例如,apache-discovery@1.service将被安排在同一台机器上的Apache@1.service)。

    让我们来验证每个单元被放置在Apache服务的同一台机器上:

    $ fleetctl start apache-discovery@1
    $ fleetctl start apache-discovery@2
    $ fleetctl list-units
    UNIT                        MACHINE                 ACTIVE    SUB
    myapp.service               c9de9451.../10.10.1.3   active    running
    apache@1.service            491586a6.../10.10.1.2   active    running
    apache@2.service            148a18ff.../10.10.1.1   active    running
    apache-discovery@1.service  491586a6.../10.10.1.2   active    running
    apache-discovery@2.service  148a18ff.../10.10.1.1   active    running
    

    现在,我们来验证一下服务发现是否能正常工作

    $ etcdctl ls /services/ --recursive
    /services/website
    /services/website/apache@1
    /services/website/apache@2
    $ etcdctl get /services/website/apache@1
    { "host": "ip-10-182-139-116", "port": 80, "version": "52c7248a14" }
    

    运行一个外部的伙伴服务

    如果你在云中运行,许多服务都可以在集群中的行为的基础上实现自动化。例如,您可以更新DNS记录或添加新的容器来负载均衡。我们的fleet的例子部署包含预存在容器更新亚马逊的弹性负载平衡器与新的后台。 视频地址

  • 相关阅读:
    EFCore 中使用覆盖查询(ForSqlServerInclude方法)来优化查询速度
    Asp.Net Core中使用FTP读取大文件并使用SqlBulkCopy实现大批量插入SQL SERVER数据库
    EFCore 2.2 报错 Data is Null. This method or property cannot be called on Null values
    在Asp.Net Core中集成Refit
    EFCore通过Include关联清单不存在时返回值为默认值的方式
    工作中常用英语单词
    参数的 in out in/out 修饰
    C# 的属性的写法和赋值
    raspberry pi 4b 常见的一些配置信息
    树莓派4B 更新wiringPi库到2.52的方法的wiringPi库2.5.2版本wiringpi-latest.deb下载
  • 原文地址:https://www.cnblogs.com/wanghongxu/p/5004973.html
Copyright © 2011-2022 走看看