項(xiàng)目背景:
項(xiàng)目中目前用到了多數(shù)據(jù)中心的consul,并且生產(chǎn)環(huán)境處于安全原因的考慮要開啟acl。多數(shù)據(jù)中心代表的是多機(jī)房,不同的機(jī)房搭建各自的consul集群。然后2個(gè)集群在通過join wan關(guān)聯(lián)上。
雖然是不通的機(jī)房,但是其實(shí)為了滿足高可用,2個(gè)機(jī)房其實(shí)是部署相同的服務(wù),比如說服務(wù)jetty。目前在2個(gè)機(jī)房都存在,這樣就涉及到了跨機(jī)房(跨dc)訪問了。
面臨的問題
如果單純不開啟acl的話,跨機(jī)房訪問很簡單,只要在請(qǐng)求上加上&dc=dc2這樣既可,而且這些參數(shù)springcloud sdk也是支持的。但是如果開啟了acl之后,情況就不同了。
有以下兩種情況:
- 2個(gè)dc使用1個(gè)token
這就需要把2個(gè)dc關(guān)聯(lián)起來了。官網(wǎng)是有一種方式的。叫做ACL Replication for Multiple Datacenters.
官網(wǎng)地址如下:
https://learn.hashicorp.com/tutorials/consul/access-control-replication-multiple-datacenters
相關(guān)截圖:
image.png
-
2個(gè)dc使用2個(gè)token
2個(gè)dc是獨(dú)立的,都是自己使用自己的acl配置。雖然acl配置時(shí)可以選擇all datacenter或者是global,但是測試時(shí)發(fā)現(xiàn)dc2用第一個(gè)dc的token訪問的時(shí)候還是會(huì)提示acl not found。
image.png

下面就開始實(shí)踐一下,這兩種方式來實(shí)現(xiàn)帶acl的多dc訪問方式
2個(gè)dc使用1個(gè)token方式
找一臺(tái)騰訊云服務(wù)器,按照官網(wǎng)說明進(jìn)行配置,因?yàn)橹挥幸慌_(tái),所以需要把端口避開。
dc1的配置如下,這里需要注意配置中要有primary_datacenter,這個(gè)代表它是主dc
[root@VM_0_13_centos consul]# cat dc1.json
{
"bootstrap_expect": 1,
"server": true,
"data_dir": "dc1",
"node_name": "node1",
"client_addr": "0.0.0.0",
"bind_addr": "172.21.0.13",
"ports": {
"http": 18081,
"dns": 18082,
"serf_lan": 18083,
"serf_wan": 18084,
"server": 18085
},
"datacenter": "primary_dc",
"primary_datacenter": "primary_dc",
"acl": {
"enabled": true,
"default_policy": "deny",
"down_policy": "extend-cache",
"enable_token_persistence": true,
"tokens": {
"master":"cd76a0f7-5535-40cc-8696-073462acc6c7",
"agent":"deaa315d-98c5-b9f6-6519-4c8f6574a551"
}
},
"pid_file": "./consul.pid"
}
啟動(dòng)dc1
./consul agent -config-file=dc1.json -ui
開始配置dc2,dc2不需要指定token了。因?yàn)殚_啟acl replication模式后dc2用的都是dc1的token,而且dc2也不要忘記配置primary_datacenter參數(shù)為dc1
{
"bootstrap_expect": 1,
"server": true,
"data_dir": "dc2",
"node_name": "node2",
"client_addr": "0.0.0.0",
"bind_addr": "172.21.0.13",
"ports": {
"http": 18091,
"dns": 18092,
"serf_lan": 18093,
"serf_wan": 18094,
"server": 18095
},
"datacenter": "second_dc",
"primary_datacenter": "primary_dc",
"acl": {
"enabled": true,
"default_policy": "deny",
"down_policy": "extend-cache",
"enable_token_persistence": true,
"enable_token_replication": true
},
"pid_file": "./consul.pid"
}
啟動(dòng)dc2
./consul agent -config-file=dc2.json -ui
訪問dc2的接口查看是否replication設(shè)置成功,就看ReplicationType是否是tokens就行了,只能查dc2,查dc1不顯示
[root@VM_0_13_centos consul]# curl http://localhost:18091/v1/acl/replication?pretty
{
"Enabled": true,
"Running": true,
"SourceDatacenter": "primary_dc",
"ReplicationType": "tokens",
"ReplicatedIndex": 0,
"ReplicatedRoleIndex": 0,
"ReplicatedTokenIndex": 0,
"LastSuccess": "0001-01-01T00:00:00Z",
"LastError": "0001-01-01T00:00:00Z"
}
登錄ui頁面就能看到dc1和dc2設(shè)置的token是一樣的


自己驗(yàn)證時(shí)還發(fā)現(xiàn)幾個(gè)小問題
- dc1(主dc)添加policy和token都沒有問題,dc2(從dc)添加policy后在頁面看不到,但是也能添加成功,在dc1頁面能看到
- dc2(token)可以添加token,添加完dc1里面也能看到,但是由于dc2的policy是空的,所以dc2無法選擇policy,也就說明這個(gè)添加也沒什么用
- dc1如果壞了,dc2的acl菜單打不開(500報(bào)錯(cuò)),但是dc2現(xiàn)有的token還是能夠正常使用,相當(dāng)于只是acl配置無法使用
跨dc訪問服務(wù)方式如下
# 18081代表dc1 訪問自己dc的服務(wù),dc參數(shù)也可以不加
curl "127.0.0.1:18081/v1/catalog/service/jetty?dc=primary_dc&token=17bc5403-23e8-b09f-a3ef-799f9325e9c4"
or
curl "127.0.0.1:18081/v1/catalog/service/jetty?token=17bc5403-23e8-b09f-a3ef-799f9325e9c4"
# 返回報(bào)文ServiceAddress=127.0.0.1代表dc1注冊(cè)的服務(wù)
[
{
"ID": "2abbfa79-3102-a79e-837e-8345a7460017",
"Node": "node1",
"Address": "172.21.0.13",
"Datacenter": "primary_dc",
"TaggedAddresses": {
"lan": "172.21.0.13",
"wan": "172.21.0.13"
},
"NodeMeta": {
"consul-network-segment": ""
},
"ServiceKind": "",
"ServiceID": "jetty",
"ServiceName": "jetty",
"ServiceTags": [
"dev"
],
"ServiceAddress": "127.0.0.1",
"ServiceWeights": {
"Passing": 1,
"Warning": 1
},
"ServiceMeta": {},
"ServicePort": 10035,
"ServiceEnableTagOverride": false,
"ServiceProxyDestination": "",
"ServiceProxy": {},
"ServiceConnect": {},
"CreateIndex": 120,
"ModifyIndex": 120
}
]
# dc1訪問dc2的服務(wù),直接訪問,token不用換
curl "127.0.0.1:18081/v1/catalog/service/jetty?dc=second_dc&token=17bc5403-23e8-b09f-a3ef-799f9325e9c4"
# 返回報(bào)文ServiceAddress=127.0.0.2代表dc2注冊(cè)的服務(wù)
[
{
"ID": "3f5f8948-ab09-cde6-8aa0-9a4ccdab1245",
"Node": "node2",
"Address": "172.21.0.13",
"Datacenter": "second_dc",
"TaggedAddresses": {
"lan": "172.21.0.13",
"wan": "172.21.0.13"
},
"NodeMeta": {
"consul-network-segment": ""
},
"ServiceKind": "",
"ServiceID": "jetty",
"ServiceName": "jetty",
"ServiceTags": [
"dev"
],
"ServiceAddress": "127.0.0.2",
"ServiceWeights": {
"Passing": 1,
"Warning": 1
},
"ServiceMeta": {},
"ServicePort": 10035,
"ServiceEnableTagOverride": false,
"ServiceProxyDestination": "",
"ServiceProxy": {},
"ServiceConnect": {},
"CreateIndex": 5,
"ModifyIndex": 5
}
]
2個(gè)dc使用2個(gè)token方式
在上面環(huán)境的基礎(chǔ)上在增加dc3,由于dc3沒有配置primary_datacenter,所以他是普通的dc模式,不是replication模式
[root@VM_0_13_centos consul]# cat dc3.json
{
"bootstrap_expect": 1,
"server": true,
"data_dir": "dc3",
"node_name": "node3",
"client_addr": "0.0.0.0",
"bind_addr": "172.21.0.13",
"ports": {
"http": 18096,
"dns": 28092,
"serf_lan": 28093,
"serf_wan": 28094,
"server": 28095
},
"datacenter": "third_dc",
"acl": {
"enabled": true,
"default_policy": "deny",
"down_policy": "extend-cache",
"enable_token_persistence": true,
"enable_token_replication": true,
"tokens": {
"master":"cd76a0f7-5535-40cc-8696-073462acc6c7",
"agent":"deaa315d-98c5-b9f6-6519-4c8f6574a551"
}
},
"pid_file": "./consul.pid"
}
啟動(dòng)dc3
./consul agent -config-file=dc3.json -ui
看dc3的ui頁面,token是獨(dú)立的

用dc1訪問dc3的服務(wù)需要加上dc3的token,不能用dc1的token
# dc1用自己的token無法訪問dc3的服務(wù)
[root@VM_0_13_centos consul]#
curl "127.0.0.1:18081/v1/catalog/service/jetty?dc=third_dc&token=17bc5403-23e8-b09f-a3ef-799f9325e9c4&pretty"
rpc error making call: ACL not found
#dc1將token換成dc3的token就可以訪問,ServiceAddress=127.0.0.3表示是dc3的服務(wù)
[root@VM_0_13_centos consul]# curl "127.0.0.1:18081/v1/catalog/service/jetty?dc=third_dc&token=f49c40fb-9bb2-0da3-d158-3abcbc4339bc&pretty"
[
{
"ID": "5e118452-e8dc-b66f-2ba0-dd3dcacd609a",
"Node": "node3",
"Address": "172.21.0.13",
"Datacenter": "third_dc",
"TaggedAddresses": {
"lan": "172.21.0.13",
"wan": "172.21.0.13"
},
"NodeMeta": {
"consul-network-segment": ""
},
"ServiceKind": "",
"ServiceID": "jetty",
"ServiceName": "jetty",
"ServiceTags": [
"dev"
],
"ServiceAddress": "127.0.0.3",
"ServiceWeights": {
"Passing": 1,
"Warning": 1
},
"ServiceMeta": {},
"ServicePort": 10035,
"ServiceEnableTagOverride": false,
"ServiceProxyDestination": "",
"ServiceProxy": {},
"ServiceConnect": {},
"CreateIndex": 15,
"ModifyIndex": 15
}
]
具體項(xiàng)目可以根據(jù)實(shí)際的情況進(jìn)行選擇使用哪種方式
有問題請(qǐng)指正,歡迎交流

