这一节内容有点长,我们将介绍如何基于docker搭建一client一server的consul测试环境,以及如何搭建多server consul测试集群.在基于docker搭建多server的consul集群时出碰到了一些坑,这对我们是很有益的提醒,很多时候我们不能仅仅满足于最小化的环境搭建及简单使用,而是要朝着接近生产环境的方向努力.同时,我们这里基于docker搭建集群其实和在宿主机上直接搭建并没有太大区别,也就是我们仅仅把docker当作类似虚拟机来使用,本系列我们多次强调新瓶装老酒,我们要真正思考新的技术方案到底能为我们的项目带来什么,如何充分利用新技术新方案来更好的服务于我们的项目.后面我们会基于k8s来搭建一个接近生产环境的集群,实现节点节点自动组成集群,某个节点挂掉后新增补的节点如何自动加入原有集群.后来我们还会探索如何使用k8s的服务发现功能,实现consul节点的自动扩容.相比传统的方法手动启动宕掉的节点或者使用脚本来实现自动化,我们完全基于kubernetes的能力来实现自动化.闲言少叙.我们进入正题,开始讲如何使用docker来搭建consul测试集群.后面的具体章节我们再详细介绍这里讨论的内容.

使用docker镜像部署一个client和一个server

前面我们介绍了在windows下部署dev环境的consul,我们仅部署了一个节点,其实这个节点是一个client节点,不对数据做持久化存储,仅保存在内存中.生产环境需要持久化存储数据,因此需要server模式,本篇介绍如何使用consul docker镜像部署一个server和一个client

拉取consul镜像

使用docker pull consul命令来拉取consul的docker镜像.

启动server 端

通过以下命令启动server端

docker run -d -p 1234:8500 -h node1 --name node1  consul agent -server -bootstrap-expect=1  -node=node1 -client 0.0.0.0 -ui

执行命令后,docker返回容器id

d107a4eda2f84bee09c0ae9044a22aa99249d144a1751e270ef6641fead79884

注意这个数字是随机的,读者要看自己的docker实际返回的id

然后我们执行docker ps查看以上容器是否在运行

λ docker ps                                                                   CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                                                      NAMES
d107a4eda2f8 consul "docker-entrypoint.s…" 4 seconds ago Up 3 seconds 8300-8302/tcp, 8301-8302/udp, 8600/tcp, 8600/udp, 0.0.0.0:1234->8500/tcp node1

可以看到它已经在运行了.

此节点是server端,client需要加入它组成集群,client加入需要知道server的ip.我们有两种方式获取server的ip,实际上就是server所在容器的ip

  • 通过docker inspect -f '{{.NetworkSettings.IPAddress}}' node1来查看查看server端的ip.

  • 通过docker exec -it node1 /bin/sh进入到容器内部的交互shell,通过ip a命令获取容器ip

我获取到的ip为172.17.0.2.

启动client端

通过以下命令

docker run -d -p 8600:8600 -p 8300:8500 -p 8600:53/udp --name client1 -h client1 consul agent -ui -node=client1 -join=172.17.0.2

启动client端,这里启动时自动加入node1组成集群,启动client和server的区别在于server启动的时候带有-server选项.

通过以上操作,我们在宿主机访问localhost:1234就可以访问到consul web管理界面了.

docker多server consul集群部署及常用命令讲解

前面我们使用docker部署了一server一client的集群.非常顺利,也很容易理解,本节部署多server集群,其实和前面也基本类似,只要知道了主节点的ip,新的节点便可以在运行时使用join ip的形式加入到集群中.但是在实际部署中,包括后面的k8s部署,由于节点数增加,很多坑便暴露出来.这里和后面使用k8s部署都会讲到其中的坑.以供大家参考,方便大家在自己的部署中减少不必要麻烦,快速上线产品.

坑一.

* Failed to join X.X.X.X: Member 'consul-deployment-2927201250-tlj1h' has conflicting node ID 'bd203bf1-2d59-42b0-901c-2a5dedf99c86' with this agent's ID)
Failed to join any nodes.

通过以上内容可以看到是节点的id冲突.通过查询官方文档,官方文档里描述说 node id是一个随机生成的uuid.然而这个id并不是每次创建都随机生成的,而是从宿主机获取到的一个随机字符串,这样同一台机器上启动多个consul容器实例就会出现冲突.k8s中部署也同样会有此问题.

需要注意的是,以上问题仅出现在同一个机器上启动多个consul节点,实际生产环境中,为了保证高可用,是要避免在同一台主机上部署多个server的.

以上问题请参看

github issue1

github issue2

解决方案有两种第一种是启动consul的时候指定node-id,并生成一个随机nodeid

docker run -d  --name=node2 consul agent -server -bind=172.17.0.3  -join=172.17.0.2 -node-id=$(uuidgen | awk '{print tolower($0)}')  -node=node2

注意以上生成uuid和awk命令都是在执行命令的时候生成的,也就是在宿主机生成的,而不是在容器生成后执行的,因此需要容器宿主机支持uuidgenawk命令,在docker for windows下是无法执行通过的.

第二种解决办法是在启动consul时加上-disable-host-node-id选项.

坑二. 无法访问ui

前面我们在windows上部署时候,直接通过consul agent -dev命令便可以启动consul,并且可以访问web管理界面.但是在集群部署时如果不指定-ui选项,则无法访问web管理界面(仅仅是web界面不能访问,其它路由还是可以正常访问)

访问web管理界面还必须指定client绑定,否则也无法正常访问

下面我们搭建一个3个server节点,一个client节点的集群.

集群搭建

启动节点一

docker run -d -p 8500:8500 -e  --name=node1 consul agent -server   -bootstrap-expect=3 -node=node1 -client=0.0.0.0 -ui

以上为了测试方便,防止暴露过多端口出现冲突(同一机器上展示),只暴露了http端口,实际上还需要暴露多个tcp和udp端口.下节在k8s集群中部署我们将完整介绍整个部署方案.

启动节点2和3

docker run -d  --name=node2 consul agent -server   -join=172.17.0.2   -node=node2 -disable-host-node-id

启动节点和节点3都是使用上面的命令,惟一要修改的是--name=node2-node=node2两处,节点3启动的时候以上两处都要改为node3(当然也可以是其它名字)

注意,大家不要混淆,--name是docker为容器取的名字,-node是consul运行时给当前启动节点取的名字

以上的-join里的ip为第一个启动节点的ip,大家可以通过docker inspect -f '{{.NetworkSettings.IPAddress}}' node1或者进入到第一个启动节点里面执行ip a获取它的ip

启动一个client节点

我们前面说过client和server的区别在于server启动的时候指定-server选项,如果不指定则启动的是client模式

docker run -d  -p 8400:8500 --name=node4 consul agent    -join=172.17.0.2   -node=node4 -disable-host-node-id -client=0.0.0.0 -ui

这里对client进行端口映射,以方便通过client进行http操作.

我们通过localhost:8400或者localhost:8500就可以看到整个集群的节点信息了

注 8500是leader映射出来的端口,而8400是client映射出来的端口

常用命令

我们任意进入一个节点内部,这里我们以进入node4(也就是client)为例

docker exec -it node4 /bin/sh
  • consul members

    此命令可以查看当前节点所在集群中所有节点信息
/ # consul members
Node Address Status Type Build Protocol DC Segment
node1 172.17.0.2:8301 alive server 1.4.4 2 dc1 <all>
node2 172.17.0.3:8301 alive server 1.4.4 2 dc1 <all>
node3 172.17.0.4:8301 alive server 1.4.4 2 dc1 <all>
node4 172.17.0.5:8301 alive client 1.4.4 2 dc1 <default>
/ #
  • consul info

    查看集群中的信息
/ # consul info
agent:
check_monitors = 0
check_ttls = 0
checks = 0
services = 0
build:
prerelease =
revision = ea5210a3
version = 1.4.4
consul:
acl = disabled
known_servers = 3
server = false
runtime:
arch = amd64
cpu_count = 2
goroutines = 49
max_procs = 2
os = linux
version = go1.11.4
serf_lan:
coordinate_resets = 0
encrypted = false
event_queue = 0
event_time = 2
failed = 0
health_score = 0
intent_queue = 0
left = 0
member_time = 4
members = 4
query_queue = 0
query_time = 1
/ #

以上信息量不小,我们比较关心的是consul部分的,server=false表明当前节点不是server,known_servers=3表明集群中共有3个server

如果当前执行命令的节点是server,还可以看到server 主(leader)信息

...
consul:
acl = disabled
bootstrap = false
known_datacenters = 1
leader = false
leader_addr = 172.17.0.2:8300
server = true
...
  • consul leave

当前节点从集群中离开

注,由于docker在启动容器时指定的要加入的ip,因此当前节点离开后通过docker start启动后会重新自动加入到集群.如果在实际生产中,不是以容器部署,当前节点挂掉后,需要再次执行前面我们执行过的命令以加入节点

还有一点需要注意的是,主节点也可能会挂掉,这时候会产生新的节点,这时候就需要知道新的leader的ip,然后把join选项里的ip改为新的leader的ip.下节我们使用k8s部署的时候我们将介绍一种新的思路来自动解决易主后节点重新加入集群的问题.

关于命令的详细信息,可以查看官方文档

创建键值存储

consul除了可以用于服务注册外,还可以用作键值存储.下面我们简单介绍一下键值存储用法

consul kv put user/config/connections 5

以上命令会在user目录下的config目录下存储一个键名为connections,值为5的键值对

我们可以通过下图查看其层次

我们可以通过以下命令获取刚存储的值

consul kv get -detailed user/config/connections

输出信息为

/ # consul kv get -detailed user/config/connections
CreateIndex 407
Flags 0
Key user/config/connections
LockIndex 0
ModifyIndex 407
Session -
Value 5
/ #

以上键值写入和读取可以在任意节点上进行操作

http api接口

consul提供了丰富的api接口,由于本教程是偏管理部分的,因此仅对少数对管理有帮助的接口做简单介绍

目前,使用的版本都是v1,因此所有请求地址的固定部分都是localhost:8500/v1

  • 获取集群中成员信息agent/members
[
...
{
"Name": "node2",
"Addr": "172.17.0.3",
"Port": 8301,
"Tags": {
"acls": "0",
"build": "1.4.4:ea5210a3",
"dc": "dc1",
"id": "1866ce4f-e219-78f9-2bee-64f567a1bf74",
"port": "8300",
"raft_vsn": "3",
"role": "consul",
"segment": "",
"vsn": "2",
"vsn_max": "3",
"vsn_min": "2",
"wan_join_port": "8302"
}
...
]

通过以上返回信息,我们可以看到节点的很多信息

  • 获取集群中server列表 /status/peers
[

    "172.17.0.2:8300",
"172.17.0.3:8300",
"172.17.0.4:8300" ]
  • 查看集群中的leader /status/leader
"172.17.0.2:8300"

通过执行命令查看主节点信息只能在server端执行,client无法获取到leader信息,而http api则可以在任意节点执行,都能获取到主节点信息

  • 查询注意的服务 catalog/services

  • 查询某一个服务 catalog/service/服务名

  • 获取键值 kv/key的路径

比如我们要获取我们刚才添加的key,则请求路径为kv/user/config/connections

[

    {
"LockIndex": 0,
"Key": "user/config/connections",
"Flags": 0,
"Value": "NQ==",
"CreateIndex": 407,
"ModifyIndex": 407
} ]

以上的值是base64编码过的字符串

  • 列举出所有的值 kv/?keys

kubernetes实战之consul简单测试环境搭建及填坑的更多相关文章

  1. kubernetes实战之consul篇及consul在windows下搭建consul简单测试环境

    consul是一款服务发现中间件,1.12版本后增加servicemesh功能.consul是分布式的,可扩展的,高可用的根据官方文档介绍,目前已知最大的consul集群有5000个节点,consul ...

  2. iOSIPV6简单测试环境搭建

    应苹果官方要求,iOS应用必须适配IPV6才能通过审核,这里分享一个简单的ipv6测试方法 一.工具原料 1.1 Mac电脑一台 1.2 iPhone手机两部 1.3 数据线一根 二.步骤方法 2.1 ...

  3. 测试环境部署之填坑记录-Expected one result (or null) to be returned by selectOne(), but found: 2

    最近在部署性能测试环境的时候,环境 部署好以后,部分功能出现接口查询异常,问题现象: 拿到错误,肯定要先判断是前端还是后端代码的问题,最简单的方式是抓包查看: 以上是报错页面捕获的接口报错,很明显的接 ...

  4. Python+selenium测试环境成功搭建,简单控制浏览器(firefox)接下来,继续学习其他浏览器上的测试环境搭建;学习Python语言,利用Python语言来写测试用例。加油!!!

    Python+selenium测试环境成功搭建,简单控制浏览器(firefox)接下来,继续学习其他浏览器上的测试环境搭建:学习Python语言,利用Python语言来写测试用例.加油!!!

  5. Linux测试环境搭建的学习建议

    随着Linux应用的扩展许多朋友开始接触Linux,根据学习Windwos的经验往往有一些茫然的感觉:不知从何处开始学起.这里介绍学习Linux测试环境搭建的一些建议. 一.Linux测试环境搭建从基 ...

  6. 【转2】Appium 1.6.3 在Xcode 8 (真机)测试环境搭建 经验总结

    Appium 1.6.3 在Xcode 8 (真机)测试环境搭建经验总结 关于 Appium 1.6.3 在Xcode 8, 1真机上环境搭建问题更多,写此文章,供大家参考,让大家少走弯路. 在开始i ...

  7. 【转1】Appium 1.6.3 在Xcode 8, iOS 10.2(模拟器)测试环境搭建 经验总结

    Appium 1.6.3 在Xcode 8, iOS 10.2(模拟器)测试环境搭建 经验总结 关于 Appium 1.6.3 在Xcode 8, 10.2 的iOS模拟器上的问题很多,本人也差点放弃 ...

  8. Activiti Workflow HelloWorld 示例与测试环境搭建

    作者:Rock 出处:http://www.ecmkit.com/zh-hans/2012/03/21/activiti-workflow-hell Activiti Workflow HelloWo ...

  9. Selenium Grid分布式测试环境搭建

    Selenium Grid简介 Selenium Grid实际上是基于Selenium RC的,而所谓的分布式结构就是由一个hub节点和若干个node代理节点组成.Hub用来管理各个代理节点的注册信息 ...

随机推荐

  1. react项目实践——(4)依赖安装与配置

    1. 修改package.json,添加需要安装的包 { "name": "myapp", "version": "1.0.0&q ...

  2. mysql重置root密码,并设置可远程访问

    linux系统: mysqld_safe --skip-grant-tables & mysql -u root use mysql UPDATE user SET host = '%' wh ...

  3. WPF特效-鱼游动动画

    原文:WPF特效-鱼游动动画   实现思路:           通过VisualBrush Binding方式获取鱼局部图像,在Viewport3D中创建ModelVisual3D块并把获取到的局部 ...

  4. 用MVVM模式开发中遇到的零散问题总结(4)——自制摄像头拍摄大头贴控件

    原文:用MVVM模式开发中遇到的零散问题总结(4)--自制摄像头拍摄大头贴控件 一直有个疑问,为什么silverlight对摄像头支持这么好,WPF却一个库都没有....于是我各种苦恼啊,各种Code ...

  5. 从PRISM开始学WPF(番外)共享上下文 RegionContext?

    原文:从PRISM开始学WPF(番外)共享上下文 RegionContext? RegionContext共享上下文 There are a lot of scenarios where you mi ...

  6. 关于Android 7.0更新后调用系统相机及电筒问题

    android升级到7.0后对权限又做了一个更新即不允许出现以file://的形式调用隐式APP,需要用共享文件的形式:content:// URI 因为系统相机是提供的共享 Provider , C ...

  7. Kali Linux安装TL-WN821N USB无线网卡驱动(make失败)

    主要有下面几个步骤: 1.刚插上网卡,network-manager识别出来了网卡,也能搜索到WiFi,但就是连接不上.查看/var/log/syslog日志或者使用nmcli m查看网络信息,显示认 ...

  8. 小米手机销量暴跌36% 雷军做错了什么?(人的需求是复杂的,而不是仅仅是一个性价比;要做体验价格比,而不是配置价格比)good

    小米手机销量暴跌36% 雷军做错了什么? 日前,小米科技创始人雷军在美国马萨诸塞州剑桥市出席了第20届哈佛中国论坛开幕式并发表了演讲.在演讲中,雷军说但小米却只用两年半的时间一跃成为了中国第一,世界第 ...

  9. 解决WPF中TextBox文件拖放问题

    在WPF中,当我们尝试向TextBox中拖放文件,从而获取其路径时,往往无法成功(拖放文字可以成功).造成这种原因关键是WPF的TextBox对拖放事件处理机制的不同,具体可参考这篇文章Textbox ...

  10. ML:单变量线性回归(Linear Regression With One Variable)

    模型表达(model regression) 用于描述回归问题的标记 m 训练集(training set)中实例的数量 x 特征/输入变量 y 目标变量/输出变量 (x,y) 训练集中的实例 (x( ...