写点什么

基于 Keepalived 实现京东云接入服务组件高可用

  • 2019-11-10
  • 本文字数:5873 字

    阅读完需:约 19 分钟

基于Keepalived实现京东云接入服务组件高可用

本文转载来源:京东云开发者社区公众号


通常,公有云厂商提供的云主机服务可用性不低于 99.95%,也就是一台云主机,每月的最大不可用时间是 21.92 分钟(365.25 * 24 * 60 * (1 - 0.9995) / 12)。对一些要求更高可用性的应用组件(比如 Web 前端、数据库服务等),通常会采用主备份方式搭建,并通过自动切换主备满足更高的可用性。


京东云提供的高可用组功能,把主服务器(Master Server)和备用服务器(Slave Server)分别部署在不同可用区的不同故障域(故障域是相互隔离的物理资源池),并利用通过 Keepalived 调用京东云命令行实现公网 IP 在两台云主机之间自动漂移,缩短故障恢复时间(MTTR, Mean time to recovery),从而提升整个接入服务组件的可用性。


本文包括如下内容:


  • 京东云命令行简介

  • 如何利用高可用组实现云主机反亲和部署

  • 利用 Keepalived 和京东云命令行实现弹性公网 IP 漂移

京东云命令行简介

京东云控制台提供浏览器操作界面,同时也提供 OpenAPI 和命令行。通过命令行,可快速批量创建京东云资源,并避免图形化界面的手工操作错误。


京东云命令行的详细介绍可参考


注意,安装京东云命令行的云主机需要能访问互联网。


下面是当前京东云命令行的版本信息和帮助信息:


 1MacBook:~ user001$ jdc --help 2usage: jdc [-h] [--debug] [--quiet] [--output {json}] [-v] 3           {mps,cps,rds,jke,vpc,xdata,mongodb,configure,streambus,ipanti,baseanti,datastar,redis,nc,monitor,iam,disk,cr,streamcomputer,sop,clouddnsservice,vm,oss} 4           ... 5 6        京东云CLI使用方法简介: 7 8        1) 配置默认Profile 9           jdc configure add --access-key your-ak --secret-key your-sk10           说明:access-key和secret-key可以从京东云控制台申请开通。默认为华北区域。1112        2) 配置自动完成,方便输入指令。输入两次TAB键可联想出子命令或参数。13        ...14MacBook:~ user001$ jdc --version150.7.2
复制代码


在使用命令行之前,需要通过 jdc configure 配置访问信息。下面是 jdc configure add 增加配置信息的命令:


1jdc configure add --access-key {ACCESS_KEY} --secret-key {SECRET_KEY} --region-id {REGION_ID} --endpoint {ENDPOIN} --scheme {SCHEME} --profile {PROFILE}
复制代码


上述命令中每个参数的简要介绍如下:


  • ACCESS_KEY 和 SECRET_KEY:是从京东云控制台的账户管理, Access Key 管理界面获得。

  • REGION_ID:当前京东云提供华北-北京、华东-宿迁、华东-上海和华南-广州四个区域,每个区域对应的 Region ID 分布是 cn-north-1、cn-east-1、cn-east-2 和 cn-south-1。

  • ENDPOINT: 命令行操作的服务器 URL。在公网环境下使用命令行,endpoint 是 www.jdcloud-api.com,如果是在京东云服务器通过内网使用命令行时,endpoint 是 openapi.internal.{region_id}.jdcloud-api.com。其中 {region_id}替换为对应区域的 region_id 值。

  • SCHEME: 使用命令行时的传输协议,在公网环境使用命令行时 scheme 是“https",在内网环境时 shceme 是“http"。

  • PORFILE: 创建的配置名称,可为任意字符串,但配置名称不能相同。


下面是在公网环境下的命令行配置信息,通过该配置,可操作京东云华东-上海区域的云资源:


1MacBook:~ user001$ jdc configure show-current2================= cn-east-2 ================3access_key:      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX4secret_key:      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX5region_id:      cn-east-26endpoint:      www.jdcloud-api.com7scheme:      https8timeout:      20
复制代码


以下是在京东云华东-上海区域云主机上命令行配置,可通过内网操作京东云华东-上海区域的云资源:


1[root@jdcoe-srv016 ~]# jdc configure show-current2================= cn-east-2 ================3access_key:      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX4secret_key:      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX5region_id:      cn-east-26endpoint:      openapi.internal.cn-east-2.jdcloud-api.com7scheme:      http8timeout:      20
复制代码

如何利用高可用组实现云主机反亲和部署

京东云云主机通过完善的网络模型实现资源的高效管理和合理分布。下图描述了京东云云主机和网络相关对象的相互关系。



反亲和性是确保一组云主机运行在不同的物理机、不同的机架、不同的机房区域、不同的机房而所定义的主机创建规则。这样,当该云主机组中的一台云主机因为物理原因不可用时,该组的其他云主机还能正常提供服务。


首先京东云的子网可以跨多个可用区,这样一个应用可以根据软件架构层次分为不同的子网,而每个子网的云主机可以跨不同的可用区。此外,通过高可用组特性,可让属于该组的云主机分散到不同可用区的不同故障域(数据中心内相互隔离的物理资源池,可以理解为数据中心内机架组)下,进一步提高了云主机组的整体可用性。下图是基于高可用组 jdcoe-nginx-ha 创建的 4 台云主机。这 4 台云主机都属于子网 10.0.1.x,但运行在可用区 A 和可用区 B,而运行在同一可用区的 2 台云主机,也分别属于不同的故障域 1 和故障域 2。当前京东云每个可用区包含 5 个故障域。


利用 Keepalived 和京东云命令行实现弹性公网 IP 漂移

部署在公有云上的应用向外提供服务时,通常是通过公有云厂商提供的负载均衡器,并绑定一个公网 IP。负载均衡器具有配置简单,弹性伸缩和完善的监控功能,但有时流量分发规则不够灵活,需要在云主机上自建基于 Nginx 或者 HAProxy 的负载均衡服务,此时如何提高自建负载均衡服务的可用性就成为新的问题。本节将介绍如何利用 Keepalived 和京东云命令行实现弹性公网 IP 在主服务器和备服务器之间的自动漂移,提高自建负载均衡服务的可用性。


本节用到两台云主机,并安装 Nginx 作为负载均衡器,通过修改 Nginx 的 /usr/share/nginx/html/index.html 文件内容区分主服务器和备服务器。具体配置信息如下:



此外,申请一个公网 IP,IP 地址为 114.67.95.123,通过京东云控制台可获得该公网 IP 的内部 ID 是 fip-b6f37survq(该 ID 将在后续 master.sh 脚本中使用)。正常情况下该 IP 是绑定在主服务器云主机上,并通过公网 IP 向外提供服务。


1MacBook:~ user001$ curl http://114.67.95.123 2<h1>Master Server</h1>
复制代码

配置云主机京东云命令行

首先在云主机 10.0.1.18 和 10.0.1.19 上安装京东云命令行,并完成命令行配置。其中 ACCESS_KEY 和 SECRET_KEY 替换成相应的值。


1jdc configure add --access-key {ACCESS_KEY} --secret-key {SECRET_KEY} --region-id     cn-east-2 --endpoint openapi.internal.cn-east-2.jdcloud-api.com --scheme http --profile cn-east-2
复制代码


在京东云命令行配置成功后,可在云主机上执行如下命令,能查看云主机信息。


1[root@jdcoe-nginx-master ~]# jdc vm describe-instance  --instance-id i-bszab8pxg02{3    "error": null, 4    "result": {5     ...6     }7 }
复制代码

安装 keepalived 服务

在主、备负载均衡云主机上安装和配置 keepalived 服务,命令如下:


 1#安装keepalived软件包  2yum install keepalived -y 3#配置keepalived服务为自动启动 4chkconfig keepalived on 5#启动keepalived服务 6service keepalived start 7#查看服务状态 8service keepalived status 9#查看keepalvied版本信息10yum info keepalived11...12Installed Packages13Name        : keepalived14Arch        : x86_6415Version     : 1.3.5
复制代码

配置 keepalived 服务,实现公网 IP 自动漂移

配置主服务器 Keepalimatchvedmatch


Keepalived 服务的配置文件是 /etc/keepalived/keepalived.conf。主服务器 10.0.1.18 的配置文件内容如下:


 1vrrp_script chk_nginx 2{ 3#检查nginx服务是否存在 4  script “pidof nginx” 5  interval 2 6} 7 8vrrp_instance VI_1 9{10  debug 211  interface eth0 # interface to monitor1213  state MASTER14  virtual_router_id 1 # Assign one ID for this route15  priority 101 # 101 on master, 100 on backup16  unicast_src_ip 10.0.1.18 # My IP17  unicast_peer18  {19    10.0.1.19 # peer IP20  }2122  track_script23  {24    chk_nginx25  }26  notify_master /etc/keepalived/master.sh27}
复制代码


同时,在主服务器下创建/etc/keepalived/master.sh,该文件的内容为如下:


 1[root@jdcoe-nginx-master ~]# ls -al /etc/keepalived/master.sh  2-rwxr-xr-x 1 root root 305 Dec  3 23:27 /etc/keepalived/master.sh 3[root@jdcoe-nginx-master ~]# cat  /etc/keepalived/master.sh  4#!/bin/bash 5 6EIP_ID=fip-b6f37survq # Elastic IP to be associated 7MASTER_INSTANCE_ID=i-bszab8pxg0 8SLAVE_INSTANCE_ID=i-pi9w6jp716 910jdc vm disassociate-elastic-ip --instance-id $SLAVE_INSTANCE_ID --elastic-ip-id $EIP_ID1112jdc vm associate-elastic-ip --instance-id $MASTER_INSTANCE_ID --elastic-ip-id $EIP_ID
复制代码


运行 master.sh,能看到如下信息。因为当前公网 IP 已经和主服务器绑定,所以解绑备云主机和再绑定主云主机失败,输出结果证明该脚本没有错误。


 1[root@jdcoe-nginx-master ~]# /etc/keepalived/master.sh 2{ 3    "error": { 4        "status": "FAILED_PRECONDITION",  5        "message": "Elastic ip isn't associated to this instance's primary network interface",  6        "code": 400 7    },  8    "result": null,  9    "request_id": "bg2kogiib9wh962u5d7uhp2e4w3s101g"10}11{12    "error": {13        "status": "FAILED_PRECONDITION", 14        "message": "ElasticIp 114.67.95.123 already in use", 15        "code": 40016    }, 17    "result": null, 18    "request_id": "bg2kogwrpct3kjqp7id40m4sq2a2bhn0"19}
复制代码


配置备服务器 keepalived


备服务器 10.0.1.19 的配置文件内容如下:


 1vrrp_script chk_nginx 2{ 3#检查nginx服务是否存在 4  script “pidof nginx” 5  interval 2 6} 7 8vrrp_instance VI_1 9{10  debug 211  interface eth0 # interface to monitor1213  state BACKUP14  virtual_router_id 1 # Assign one ID for this route15  priority 100 # 101 on master, 100 on backup16  unicast_src_ip 10.0.1.19 # My IP17  unicast_peer18  {19    10.0.1.18 # peer IP20  }2122  track_script23  {24    chk_nginx25  }26  notify_master /etc/keepalived/master.sh27}
复制代码


同时,在备服务器下创建/etc/keepalived/master.sh,该文件的内容为如下:


 1[root@jdcoe-nginx-slave ~]# ls -al /etc/keepalived/master.sh  2-rwxr-xr-x 1 root root 306 Dec  3 23:37 /etc/keepalived/master.sh 3[root@jdcoe-nginx-slave ~]# cat  /etc/keepalived/master.sh  4#!/bin/bash 5 6EIP_ID=fip-b6f37survq # Elastic IP to be associated 7 8MASTER_INSTANCE_ID=i-bszab8pxg0 9SLAVE_INSTANCE_ID=i-pi9w6jp7161011jdc vm disassociate-elastic-ip --instance-id $MASTER_INSTANCE_ID --elastic-ip-id $EIP_ID1213jdc vm associate-elastic-ip --instance-id $SLAVE_INSTANCE_ID --elastic-ip-id $EIP_ID
复制代码


运行 master.sh,能看到如下信息。表示首先成功解绑公网 IP 和主服务器,再成功绑定公网 IP 和备服务器。


 1[root@jdcoe-nginx-slave ~]# /etc/keepalived/master.sh 2{ 3    "error": null,  4    "result": null,  5    "request_id": "bg2kuinedrw632wkop847ffpatk643t1" 6} 7{ 8    "error": null,  9    "result": null, 10    "request_id": "bg2kuivfc95aiaitu32e6c2s8tftbawt"11}
复制代码


测试公网 IP 在主备服务器之间自动漂移


在修改完主、备服务器的 keepalived 配置后,需要重新启动 keepalived 服务。当前主负载均衡提供服务:


1MacBook:~ user001$ curl 114.67.95.1232<h1>Master Server</h1>
复制代码


运行如下命令停止主服务器:


1MacBook:~ user001$ jdc vm stop-instance --instance-id i-bszab8pxg02{3    "error": null, 4    "result": null, 5    "request_id": "bg2m30sdcctb5pobicmegnap9ebw3nn9"6}
复制代码


重新执行如下命令,发现已切换为备服务器提供服务:


1MacBook:~ user001$ curl 114.67.95.1232<h1>Slave Server</h1>

复制代码


重新启动主服务器,过几秒后检查,将发现主服务器重新提供服务,表示公网 IP 已重新从备服务器自动绑定到主服务器:


1MacBook:~ user001$ jdc vm start-instance --instance-id i-bszab8pxg0 2{ 3    "error": null,  4    "result": null,  5    "request_id": "bg2m3vf2qt48hunj61i3k3pkhqmi34d7" 6} 7MacBook:~ user001$ curl 114.67.95.123 8... 9MacBook:~ user001$ curl 114.67.95.12310<h1>Slave Server</h1>11MacBook:~ user001$ curl 114.67.95.12312<h1>Master Server</h1>
复制代码


也可以执行如下命令" while true; do curl http ://114.67.95.123; sleep 2; done" 命令检查公网 IP 自动漂移功能。在命令执行过程中先后停止和启动主服务器,可看到公网 IP 将自动漂移,在漂移期间会报一两次网络连接错误,但也大大缩短了故障修复时间。


 1MacBook:~ user001$ while true; do curl http://114.67.95.123; sleep 2; done 2<h1>Master Server</h1> 3<h1>Master Server</h1> 4<h1>Master Server</h1> 5<h1>Master Server</h1> 6<h1>Master Server</h1> 7<h1>Master Server</h1> 8<h1>Master Server</h1> 9<h1>Master Server</h1>10<h1>Master Server</h1>11<h1>Master Server</h1>12<h1>Master Server</h1>13<h1>Master Server</h1>14<h1>Master Server</h1>15<h1>Master Server</h1>16<h1>Master Server</h1>17curl: (56) Recv failure: Connection reset by peer18curl: (7) Failed to connect to 114.67.95.123 port 80: Connection refused19<h1>Slave Server</h1>20<h1>Slave Server</h1>21<h1>Slave Server</h1>22<h1>Slave Server</h1>23<h1>Slave Server</h1>24<h1>Slave Server</h1>25<h1>Slave Server</h1>26<h1>Slave Server</h1>27<h1>Slave Server</h1>28<h1>Slave Server</h1>29<h1>Slave Server</h1>30<h1>Slave Server</h1>31<h1>Slave Server</h1>32<h1>Slave Server</h1>33<h1>Slave Server</h1>34<h1>Slave Server</h1>35<h1>Slave Server</h1>36<h1>Slave Server</h1>37curl: (55) getpeername() failed with errno 22: Invalid argument38<h1>Master Server</h1>39<h1>Master Server</h1>40<h1>Master Server</h1>41<h1>Master Server</h1>42<h1>Master Server</h1>
复制代码


2019-11-10 18:561265

评论

发布
暂无评论
发现更多内容

HDC2022的无障碍参会体验,手语服务是如何做到的?

HarmonyOS SDK

HMS Core

好好的系统,为什么要分库分表?

程序员小富

Java 数据库 面试 分库分表

火山引擎 DataTester 应用故事:一个A/B测试,将产品DAU提升了数十万

字节跳动数据平台

大数据 AB testing实战

信创产业多点开花,AntDB数据库积极参与行业标准研制,协同价值链伙伴共促新发展

亚信AntDB数据库

AntDB aisware antdb AntDB数据库

BSN-DDC基础网络DDC SDK详细设计(六):交易查询、区块查询、签名事件

BSN研习社

BSN

基于 RocketMQ 的 Dubbo-go 通信新范式

Apache RocketMQ

RocketMQ RPC dubbo-go dubbogo

ISV 的亚马逊云科技 marketplace ( 中国区) 之旅

亚马逊云科技 (Amazon Web Services)

亚马逊云科技 Tech 专栏 Marketplace

只需5步注册成为亚马逊云科技 Marketplace (海外区)专家

亚马逊云科技 (Amazon Web Services)

亚马逊云科技 Tech 专栏 Marketplace

【11.18-11.25】写作社区优秀技术博文回顾

InfoQ写作社区官方

热门活动

【从零开始学爬虫】采集猫眼电影热门资讯数据

前嗅大数据

爬虫 数据采集 爬虫软件 爬虫教程 数据采集教程

BSN开放联盟链“武汉链”新版浏览器wuscan.io正式上线发布

BSN研习社

BSN 武汉链

袋鼠云数据湖平台「DataLake」,存储全量数据,打造数字底座

袋鼠云数栈

数据中台 数据仓库 数据湖 数据中台场景实践 数据湖分析

云享·人物丨造梦、探梦、筑梦,三位开发者在华为云上的寻梦之旅

华为云开发者联盟

云计算 后端 华为云

从 Uber 数据泄露事件我们可以学到什么?

SEAL安全

数据安全 企业安全 PAM

链上挖矿分红智能合约DAPP系统开发部署模式定制

开发微hkkf5566

从源码角度看React-Hydrate原理

flyzz177

React

从recat源码角度看setState流程

flyzz177

React

转化10亿GMV:螺丝钉也能变小马达

博文视点Broadview

华为云区块链三大核心技术国际标准立项通过

华为云开发者联盟

区块链 华为云

python常用内置函数用法精要(二)

乔乔

11月月更

流程编排、如此简单-通用流程编排组件JDEasyFlow介绍

京东科技开发者

数据库 架构 服务端 流程引擎 流程编排

【看球和学Go】错误和异常、CGO、fallthrough

王中阳Go

Go golang 面试题 Go web 11月月更

Spring中获取bean的八种方式,你get了几种?

小小怪下士

Java spring bean

云原生系列 【轻松入门容器基础操作】

叶秋学长

云原生 沙箱实验 11月月更

为什么 NGINX 的 reload 不是热加载?

API7.ai 技术团队

Apache nginx 开源 api 网关 APISIX

Fiori Elements 框架里 Smart Table 控件的工作原理介绍

汪子熙

SAP Fiori SAP UI5 ui5 11月月更

从元宇宙、地产数字化到呼叫中心,华为云携手伙伴共创新价值

华为云开发者联盟

云计算 华为云 元宇宙

一个PMO从0-1建设的工作思路 | 对你绝对有用!

PMO实践

项目管理 PMO

经营型项目经理是不是伪需求?

PMO实践

项目管理 敏捷 PMO 项目经理

从react源码看hooks的原理

flyzz177

React

数据卡顿怎么办,瓴羊Quick BI强劲数据引擎来帮忙

小偏执o

基于Keepalived实现京东云接入服务组件高可用_软件工程_杨敏强_InfoQ精选文章