开发者社区 > 博文 > 干货 | 基于Keepalived实现京东云接入服务组件高可用
分享
  • 打开微信扫码分享

  • 点击前往QQ分享

  • 点击前往微博分享

  • 点击复制链接

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

  • 京东科技开发者
  • 2019-02-27
  • IP归属:北京
  • 70240浏览

640 (1).jpg 

 摘 要   

通常,公有云厂商提供的云主机服务可用性不低于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和命令行。通过命令行,可快速批量创建京东云资源,并避免图形化界面的手工操作错误。

京东云命令行的详细介绍可参考:https://docs.jdcloud.com/cn/cli/introduction。

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

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

 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-sk
10           说明:access-key和secret-key可以从京东云控制台申请开通。默认为华北区域。
11
12        2) 配置自动完成,方便输入指令。输入两次TAB键可联想出子命令或参数。
13        ...
14MacBook:~ user001$ jdc --version
150.7.2

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

jdc 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。

    详细信息参:

    https://docs.jdcloud.com/cn/common-declaration/api/introduction

  • 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-current
2================= cn-east-2 ================
3access_key:      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
4secret_key:      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
5region_id:      cn-east-2
6endpoint:      www.jdcloud-api.com
7scheme:      https
8timeout:      20

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

1[root@jdcoe-srv016 ~]# jdc configure show-current
2================= cn-east-2 ================
3access_key:      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
4secret_key:      XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
5region_id:      cn-east-2
6endpoint:      openapi.internal.cn-east-2.jdcloud-api.com
7scheme:      http
8timeout:      20

如何利用高可用组实现

云主机反亲和部署


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

11.jpg

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

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


22.jpg



利用Keepalived和京东云

命令行实现弹性公网IP漂移



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

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

33.png

此外,申请一个公网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>
1

配置云主机京东云命令行

首先在云主机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-bszab8pxg0
2{
3    "error"null
4    "result": {
5     ...
6     }
7 }

2

安装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 keepalived
11...
12Installed Packages
13Name        : keepalived
14Arch        : x86_64
15Version     : 1.3.5


3

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


配置主服务器Keepalimatchved
match

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 2
11  interface eth0 # interface to monitor
12
13  state MASTER
14  virtual_router_id 1 # Assign one ID for this route
15  priority 101 # 101 on master, 100 on backup
16  unicast_src_ip 10.0.1.18 # My IP
17  unicast_peer
18  {
19    10.0.1.19 # peer IP
20  }
21
22  track_script
23  {
24    chk_nginx
25  }
26  notify_master /etc/keepalived/master.sh
27}

同时,在主服务器下创建/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
9
10jdc vm disassociate-elastic-ip --instance-id $SLAVE_INSTANCE_ID --elastic-ip-id $EIP_ID
11
12jdc 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"400
16    }, 
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 2
11  interface eth0 # interface to monitor
12
13  state BACKUP
14  virtual_router_id 1 # Assign one ID for this route
15  priority 100 # 101 on master, 100 on backup
16  unicast_src_ip 10.0.1.19 # My IP
17  unicast_peer
18  {
19    10.0.1.18 # peer IP
20  }
21
22  track_script
23  {
24    chk_nginx
25  }
26  notify_master /etc/keepalived/master.sh
27}

同时,在备服务器下创建/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-pi9w6jp716
10
11jdc vm disassociate-elastic-ip --instance-id $MASTER_INSTANCE_ID --elastic-ip-id $EIP_ID
12
13jdc 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.123
2<h1>Master Server</h1>

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

1MacBook:~ user001$ jdc vm stop-instance --instance-id i-bszab8pxg0
2{
3    "error"null
4    "result"null
5    "request_id""bg2m30sdcctb5pobicmegnap9ebw3nn9"
6}

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

1MacBook:~ user001$ curl 114.67.95.123
2<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.123
10<h1>Slave Server</h1>
11MacBook:~ user001$ curl 114.67.95.123
12<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 peer
18curl: (7) Failed to connect to 114.67.95.123 port 80: Connection refused
19<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 argument
38<h1>Master Server</h1>
39<h1>Master Server</h1>
40<h1>Master Server</h1>
41<h1>Master Server</h1>
42<h1>Master Server</h1>


总结:

本文介绍了京东云公网IP如何在两台云主机自动漂移的功能,对于很多在上云前就依赖Nginx或者HAProxy进行负载流量分发的应用来说,一方面快速实现上云,同时也提高了应用的整体可用性。后续文章将介绍如何利用Keepalived实现一个内网IP在两台云主机之间自动漂移,提高应用内部组件(比如数据库组件、内部API网关组件)的高可用。

641.jpg