一:Kong的集群方案
Kong支持集群方案,可以加入多个Kong节点来保障服务的高可用性以及提高负载的能力,如下面官方图所示,多个kong组成的集群需要使用共享数据库,以保证集群数据的一致性。
(1)集群状态
检查集群的状态
$kong cluster reachability
检查群集的成员
$kong cluster members
(2)集群配置
集群配置包含以下几项
cluster_listen 用于与群集中其他节点之间通信的地址和端口。
默认值: 0.0.0.0:7946
cluster_listen_rpc 此节点用于与群集通信的地址和端口。。
默认值: 127.0.0.1:7373
cluster_advertise 指定向外广播的ip
默认值:none
cluster_encrypt_key Base64编码的16字节密钥用于加密集群流量。
默认值:none
cluster_ttl_on_failure 集群健康检查的间隔
默认值: 3600
cluster_profile 集群间Ping和超时的时序配置文件。local , lan , wan 。
默认值: wan
二:节点间的发现
节点之间的发现采用的gossip协议,当Kong节点启动后,会将自己的IP信息加入到node列表,广播给任何其他的Kong节点,当另一个Kong节点启动后,会去读取数据库中的node列表,并将自己的信息加入到列表中。
三:容器方式部署集群
集群是为了保证服务的高可用性和提高服务的支撑能力,必然是要部署在多台独立服务器上。那么要使用容器部署,就必须要实现宿主机间的容器网络互通。
下面以rancher为例,在rancher上部署Kong集群。再分享一下部署的时候出现的一些问题。
docker-compose:
kong-database: p_w_picpath: postgres:9.4 ports: - 5432:5432/tcp environment: - POSTGRES_USER=kong - POSTGRES_DB=kong labels: io.rancher.container.hostname_override: container_name io.rancher.container.pull_p_w_picpath: always kong: p_w_picpath: kong links: - kong-database:kong-database environment: - KONG_DATABASE=postgres - KONG_CASSANDRA_CONTACT_POINTS=kong-database - KONG_PG_HOST=kong-database ports: - 8000:8000/tcp - 8443:8443/tcp - 8001:8001/tcp - 7946:7946/tcp - 7946:7946/udp - 7373:7373/tcp labels: io.rancher.container.hostname_override: container_name io.rancher.container.start_once: true
rancher-compose:
.catalog: kong: scale: 3 kong-database: scale: 1
部署成功后,集群由1个数据库,三个kong容器,貌似没问题
然而,当通过sehll进入到容器内部,使用kong cluster reachability发现集群只有一个成员。
并且发现,节点是带着172.17.0.5这个地址,显然节点向外宣告了这个地址。
这是为什么呢?
因为我们知道Rancher的默认manage网络是10.42段的地址,能够跨宿主机实现容器互通。为什么会宣告172的地址呢?
我们用ip a命令查看,发现,原来eth0下面有两个ip,172和10.42的ip。
一个是docker0的默认的172段地址不能跨主机通信,一个是rancher的manage的10.42网络的地址。
显然!!!如果要想让集群节点之间成功通信,那么必须要使节点向外宣告的ip为10.42的地址才行。
这就要用到上面配置中的cluster_advertise参数。
默认情况下
cluster_listen= 0.0.0.0:7946
cluster_advertise=NONE
在***、nat等情况下,网卡拥有多个IP地址,0.0.0.0就导致无法向外宣告正确的IP
这时就需要使用cluster_advertise:10.42.60.14:7946来指定广播的ip,
在后面修改的过程中发现,/usr/local/kong/kong.conf文件是不存在于镜像中的,而是kong进程启动的时候生成的。
后来发现是通过/usr/local/share/lua/5.1/kong/templates/kong_defaults.lua这个配置模板来生成的的配置文件,即使预先写好的配置文件,也会在kong进程启动后被替换掉。
所以只能修改配置文件的模板,/usr/local/share/lua/5.1/kong/templates/kong_defaults.lua将里面的
cluster_advertise = NONE替换成cluster_advertise = container_ip:7946
而container_ip是容器启动后才知道,但是当容器启动后,在进去容器,修改配置文件,重启进程也不太现实。
所以就需要我们在容器启动后,自动将IP信息配置到配置文件中,然后再启动容器。
梳理一下流程应该是
1:容器启动-->2:读取容器IP-->3:修改配置文件模板-->4:自动创建配置文件-->5:启动kong
利用官方kong镜像,重新打一下镜像
Dockerfile
FROM kong #精简镜像缺少命令,copy ip命令 COPY ./ip /bin/ #在启动脚本中,查出容器ip RUN sed -i "4i export RANCHER_IP=\`/bin/ip a|grep 10.42|sed 's/ //g'|awk -F'[t/]' '{print \$2}'\`" /docker-entrypoint.sh #将容器IP替换到lua的配置模板中(直接改配置文件没用,因为是从模板copy过去覆盖的) RUN sed -i "5i sed -i 's/cluster_advertise = NONE/cluster_advertise = '\$RANCHER_IP':7946/g' /usr/local/share/lua/5.1/kong/templates/kong_defaults.lua" /docker-entrypoint.sh ENTRYPOINT ["/docker-entrypoint.sh"] CMD ["kong","start"]
$docker build -t kong:rancher_cluster .
镜像打好后,使用上面的compose新启动服务,再进去容器看一下,发现集群已经组建成功了,向外宣告的是10.42的地址
于是乎!!!集群组建成功,可以随意增加集群节点个数。