[TOCM]
Consul版本 v0.9.2
1. 配置
1.1 CLI配置
Consul Agent有各種各樣的配置項可以在命令行或者配置文件進行定義扮匠,所有的配置項都是可選擇的苟蹈,當加載配置文件的時候疆股,Consul從配置文件或者配置目錄加載配置抒巢。后面定義的配置會合并前面定義的配置伐脖,但是大多數(shù)情況下,合并的意思是后面定義的配置會覆蓋前面定義的配置喷鸽,但是有些情況众雷,例如event句柄,合并僅僅是添加到前面定義的句柄后面做祝。Consul重新加載配置文件也支持以信號的方式接收update信號砾省。
- -advertise:通知展現(xiàn)地址用來改變我們給集群中的其他節(jié)點展現(xiàn)的地址,一般情況下-bind地址就是展現(xiàn)地址
- -bootstrap:用來控制一個server是否在bootstrap模式混槐,在一個datacenter中只能有一個server處于bootstrap模式编兄,當一個server處于bootstrap模式時,可以自己選舉為raft leader声登。
- -bootstrap-expect:在一個datacenter中期望提供的server節(jié)點數(shù)目狠鸳,當該值提供的時候,consul一直等到達到指定sever數(shù)目的時候才會引導整個集群悯嗓,該標記不能和bootstrap公用
- -bind:該地址用來在集群內部的通訊件舵,集群內的所有節(jié)點到地址都必須是可達的,默認是0.0.0.0
- -client:consul綁定在哪個client地址上绅作,這個地址提供HTTP芦圾、DNS蛾派、RPC等服務俄认,默認是127.0.0.1
- -config-file:明確的指定要加載哪個配置文件
- -config-dir:配置文件目錄,里面所有以.json結尾的文件都會被加載
- -data-dir:提供一個目錄用來存放agent的狀態(tài)洪乍,所有的agent允許都需要該目錄眯杏,該目錄必須是穩(wěn)定的,系統(tǒng)重啟后都繼續(xù)存在
- -dc:該標記控制agent允許的datacenter的名稱壳澳,默認是dc1
- -encrypt:指定secret key岂贩,開啟gossip加密,使consul在通訊時進行加密巷波,同一個集群中的節(jié)點必須使用相同的key萎津。
key必須是16bytes長度的base64加密卸伞,也可以通過consul keygen直接產生一個。生成secret key的方法
root@server1:~# consul keygen
WAFhifMUpMk0IISXSOQnhw==
- -join:加入一個已經啟動的agent的ip地址锉屈,可以多次指定多個agent的地址荤傲。如果consul不能加入任何指定的地址中,則agent會啟動失敗颈渊,默認agent啟動時不會加入任何節(jié)點遂黍。
- -retry-join:和join類似,但是允許你在第一次失敗后進行嘗試俊嗽。
- -retry-interval:兩次join之間的時間間隔雾家,默認是30s
- -retry-max:嘗試重復join的次數(shù),默認是0绍豁,也就是無限次嘗試
- -log-level:consul agent啟動后顯示的日志信息級別芯咧。默認是info,可選:trace竹揍、debug唬党、info、warn鬼佣、err驶拱。
- -node:節(jié)點在集群中的名稱,在一個集群中必須是唯一的晶衷,默認是該節(jié)點的主機名
- -protocol:consul使用的協(xié)議版本
- -rejoin:使consul忽略先前的離開蓝纲,在再次啟動后仍舊嘗試加入集群中。
- -server:定義agent運行在server模式晌纫,每個集群至少有一個server税迷,建議每個集群的server不要超過5個
- -syslog:開啟系統(tǒng)日志功能,只在linux/osx上生效
- -ui-dir:提供存放web ui資源的路徑锹漱,該目錄必須是可讀的
- -pid-file:提供一個路徑來存放pid文件箭养,可以使用該文件進行SIGINT/SIGHUP(關閉/更新)agent
1.2 FILE配置
除了命令行參數(shù)外,配置也可以寫入文件中哥牍,啟動時候使用-config-file參數(shù)毕泌。
在某些情況下配置文件會更簡單一些,例如:Consul被用來管理系統(tǒng)嗅辣。配置文件是json格式的撼泛,很容易編寫。配置文件不僅被用來設置Agent的啟動澡谭,也可以用來提供健康檢測和服務發(fā)現(xiàn)的定義愿题。配置文件的一般格式如下:
{
"datacenter": "consul",
"data_dir": "/opt/consul",
"ui": true,
"log_level": "INFO",
"node_name": "consul",
"server": true,
"watches": [
{
"type": "checks",
"handler": "/usr/bin/health-check-handler.sh"
}
]
}
詳細的配置文件參數(shù):
- acl_datacenter:只用于server,指定的datacenter的權威ACL信息,所有的servers和datacenter必須同意ACL datacenter
- acl_default_policy:默認是allow
- acl_down_policy:
- acl_master_token:
- acl_token:agent會使用這個token和consul server進行請求
- acl_ttl:控制TTL的cache潘酗,默認是30s
- addresses:一個嵌套對象杆兵,可以設置以下key:dns、http仔夺、rpc
- advertise_addr:等同于-advertise
- bootstrap:等同于-bootstrap
- bootstrap_expect:等同于-bootstrap-expect
- bind_addr:等同于-bind
- ca_file:提供CA文件路徑拧咳,用來檢查客戶端或者服務端的鏈接
- cert_file:必須和key_file一起
- check_update_interval:
- client_addr:等同于-client
- datacenter:等同于-dc
- data_dir:等同于-data-dir
- disable_anonymous_signature:在進行更新檢查時禁止匿名簽名
- disable_remote_exec:禁止支持遠程執(zhí)行,設置為true囚灼,agent會忽視所有進入的遠程執(zhí)行請求
- disable_update_check:禁止自動檢查安全公告和新版本信息
- dns_config:是一個嵌套對象骆膝,可以設置以下參數(shù):allow_stale、max_stale灶体、node_ttl 阅签、service_ttl、enable_truncate
- domain:默認情況下consul在進行DNS查詢時蝎抽,查詢的是consul域政钟,可以通過該參數(shù)進行修改
- enable_debug:開啟debug模式
- enable_syslog:等同于-syslog
- encrypt:等同于-encrypt
- key_file:提供私鑰的路徑
- leave_on_terminate:默認是false,如果為true樟结,當agent收到一個TERM信號的時候养交,它會發(fā)送leave信息到集群中的其他節(jié)點上。
- log_level:等同于-log-level
- node_name:等同于-node
- ports:這是一個嵌套對象瓢宦,可以設置以下key:dns(dns地址:8600)碎连、http(http api地址:8500)、rpc(rpc:8400)驮履、serf_lan(lan port:8301)鱼辙、serf_wan(wan port:8302)、server(server rpc:8300)
- protocol:等同于-protocol
- recursor:Address of an upstream DNS server. Can be specified multiple times.
- rejoin_after_leave:等同于-rejoin
- retry_join:等同于-retry-join
- retry_interval:等同于-retry-interval
- server:等同于-server
- server_name:會覆蓋TLS CA的node_name玫镐,可以用來確認CA name和hostname相匹配
- skip_leave_on_interrupt:和leave_on_terminate比較類似倒戏,不過只影響當前句柄
- start_join:一個字符數(shù)組提供的節(jié)點地址會在啟動時被加入
- statsd_addr:
- statsite_addr:
- syslog_facility:當enable_syslog被提供后,該參數(shù)控制哪個級別的信息被發(fā)送恐似,默認Local0
- ui: 是否啟用web ui杜跷,不能和底下的ui_dir同時啟用,會報錯矫夷。
- ui_dir:等同于-ui-dir
- verify_incoming:默認false葛闷,如果為true,則所有進入鏈接都需要使用TLS口四,需要客戶端使用ca_file提供ca文件孵运,只用于consul server端秦陋,因為client從來沒有進入的鏈接
- verify_outgoing:默認false蔓彩,如果為true,則所有出去鏈接都需要使用TLS,需要服務端使用ca_file提供ca文件赤嚼,consul server和client都需要使用旷赖,因為兩者都有出去的鏈接
- watches:watch一個詳細名單
Consul Agent支持所有的網(wǎng)絡通訊進行加密,關于加密的具體信息可以參考 官方描述 更卒,有兩個分開的系統(tǒng)等孵,一個是gossip流量,一個是RPC蹂空。
使用TLS為RPC加密俯萌,主要是上面介紹的verify_incoming和verify_outgoing參數(shù)來設置。
2. K/V 存儲
除了提供服務發(fā)現(xiàn)和綜合健康檢查,Consul還提供了一個易于使用的鍵/值存儲上枕。這可以用來保存動態(tài)配置,協(xié)助服務協(xié)調,建立領導人選舉,并啟用其他開發(fā)人員可以想構建的任何其他內容咐熙。
有兩種方法可以使用:通過HTTP API和通過CLI API。下面的例子顯示使用CLI API
root@server1:~# consul kv get redis/config/minconns
Error! No key exists at: redis/config/minconns
你將看到沒有結果返回辨萍,由于KV存儲中沒有該鍵返回了一個錯誤棋恼,接下來我們將插入或"put"一個值到KV存儲中。
root@server1:~# consul kv put redis/config/minconns 1
Success! Data written to: redis/config/minconns
現(xiàn)在再次查詢該鍵你將看到如下結果:
root@server1:~# consul kv get redis/config/minconns
1
Consul保留額外的元數(shù)據(jù)在該字段,你可以使用-detailed標志檢索詳細信息:
root@server1:~# consul kv get -detailed redis/config/minconns
CreateIndex 1049
Flags 0
Key redis/config/minconns
LockIndex 0
ModifyIndex 1049
Session -
Value 1
設置值的時候推穷,還可以使用-flags標志
-
-flags=<uint>
Unsigned integer value to assign to this key-value pair. This value is not read by Consul, so clients can use this value however makes sense for their use case. The default value is 0 (no flags).
flags用來做客戶端自定義標志安吁,consul并不使用它贺归,你可以在你自己的程序中隨便定義
root@server1:~# consul kv put -flags=42 redis/config/users/admin abcd1234
Success! Data written to: redis/config/users/admin
設置flag值為42,想設置成什么就設置成什么.所有的鍵都支持設置一個64位的整型值师崎。
使用-recurse選項可以列出KV存儲中所有keys,返回的結果將按照字母排序。
root@server1:~# consul kv get -recurse
redis/config/minconns:1
redis/config/users/admin:abcd1234
使用delete命令刪除KV存儲中指定的key椅棺。
root@server1:~# consul kv delete redis/config/minconns
Success! Deleted key: redis/config/minconns
還可以使用recurse選項遞歸選項刪除含某個前綴的所有keys:
root@server1:~# consul kv delete -recurse redis
Success! Deleted keys with prefix: redis
如果要更新一個存在鍵的值抡诞,可以put一個新值在同樣的路徑上。
root@server1:~# consul kv put foo bar
Success! Data written to: foo
root@server1:~# consul kv get foo
bar
root@server1:~# consul kv put foo zip
Success! Data written to: foo
root@server1:~# consul kv get foo
zip
Consul可以使用Check_And_Set提供原子鍵更新操作土陪。執(zhí)行CAS操作時需指定-cas標志昼汗。至于什么是CAS,請自行百度吧
-
-modify-index=<uint>
Unsigned integer representing the ModifyIndex of the key. This is used in combination with the -cas flag.
首先查詢foo這個key的詳細信息
root@server1:~# consul kv get -detailed foo
CreateIndex 1065
Flags 0
Key foo
LockIndex 0
ModifyIndex 1067
Session -
Value zip
看到foo的索引編號ModifyIndex是1067鬼雀。然后使用CAS操作的方式來修改它
root@server1:~# consul kv put -cas -modify-index=1067 foo bar
Success! Data written to: foo
修改成功顷窒,再查詢
root@server1:~# consul kv get -detailed foo
CreateIndex 1065
Flags 0
Key foo
LockIndex 0
ModifyIndex 1091
Session -
Value bar
ModifyIndex變成1091了。依然使用上面那個修改命令試試
root@server1:~# consul kv put -cas -modify-index=1067 foo bar
Error! Did not write to foo: CAS failed
失敗了源哩。原因是第一次CAS操作成功鞋吉,因為ModifyIndex的值是1067,我們輸入的也是-modify-index=1067励烦。
第二次操作失敗谓着,ModifyIndex已經變成1091了,我們還用-modify-index=1067坛掠,Check_And_SetS中的Check這步就失敗了赊锚,不會再Set了治筒。
3. ACL
Access Control List,有沒有發(fā)現(xiàn)consul web ui是可以直接訪問做各種操作的舷蒲,傳說中的登錄這種屏障都沒有啊耸袜。so,需要一個ACL來限制操作權限牲平,就像“登錄”了一樣堤框。
官方文檔:https://www.consul.io/docs/guides/acl.html
3.1 服務端ACL
1.啟動consul的all模式時,我的核心配置文件:
{
"acl_datacenter": "dc1",
"acl_master_token": "xxxhelloworldxxx",
"acl_default_policy": "deny" //開啟acl
......
}
這三個配置是使用ACL的必須選項
- acl_datacenter:數(shù)據(jù)中心名稱纵柿◎谧ィ可填all表示所有的數(shù)據(jù)中心都啟用acl。
- acl_master_token:服務端選舉的令牌昂儒。這個是自己指定的资昧,隨便來一串字符串就可以了。當然如果正式上線則不能隨便荆忍,可以使用
uuidgen | awk '{print tolower($0)}'
生成格带,每臺主機都不相同。需要在每個server上配置刹枉,有management級別的權限叽唱,相當于一個種子token用來生成其余token。 - acl_default_policy:默認策略
不配置rule規(guī)則的情況下默認值是allow微宝,即能夠執(zhí)行任何操作棺亭。(可配置為allow,deny)
當acl_default_policy為deny是蟋软,默認的api(寫)行為都會被阻止镶摘,我們可以配置其子項,讓比如配置key可寫岳守,這樣在全部deny的情況下凄敢,出現(xiàn)了一個默認可寫的行為,這就是白名單
黑名單反之湿痢,當acl_default_policy為allow時涝缝,默認行為都是允許的,我們可以配置子項使它某些行為為deny譬重,這就是黑名單的概念
若要開啟all拒逮,acl_default_policy需要設置成deny - acl_ttl:控制TTL的cache,默認是30s
按這個配置啟動帶web ui的consul server后臀规,訪問 http://10.111.152.242:8500/ui/#/dc1/services 滩援,發(fā)現(xiàn)頁面是空的,什么都沒有塔嬉,一片空白啊玩徊,連個字都沒有租悄。同時sever打印日志
2017/09/08 16:04:51 [ERR] http: Request GET /v1/internal/ui/nodes?dc=dc1&token=<hidden>, error: ACL not found from=10.111.152.150:61226
這下連web ui都不讓我訪問了,報403 forbidden佣赖。其實這是個bug恰矩,要清理瀏覽器緩存记盒,然后才能訪問web ui憎蛤。
清理緩存后,可以進入web ui中纪吮,但是沒法看到service俩檬、nodes、kv等信息了碾盟,點擊ACL棚辽,提示
Access Denied
Your ACL token does not have the appropriate permissions to perform the expected action.
同時在server端日志顯示
2017/09/08 18:31:10 [ERR] http: Request GET /v1/acl/list?dc=dc1&token=<hidden>, error: Permission denied from=10.111.152.150:57776
說明ACL已經生效了,目前阻止了我們的訪問冰肴。
2.創(chuàng)建子token
要訪問那些被阻止的信息屈藐,就要申請token
root@server1:~# curl -H "X-Consul-Token: secret" -X PUT -d '{"Name": "dc1", "Type": "management"}' http://10.111.152.242:8500/v1/acl/create?token=xxxhelloworldxxx
{"ID":"fc6cad19-4323-9a93-4e5a-9d2e00d91360"}
- Name:token的name
- Type:token的類型,有client跟management
- token:我們上面說到的master token
返回這個ID就是我們需要的子token熙尉,將這個management權限的token配置在web ui節(jié)點的server上联逻,便于管理ACL、k/v检痰、service等
{
"acl_datacenter": "dc1",
"acl_master_token": "xxxhelloworldxxx",
"acl_default_policy": "deny", //開啟acl
"acl_token" : "dae1911a-a81f-136b-7ad2-20a65fe98d9d"
......
}
這次重啟就可以訪問acl了包归,瀏覽器緩存別忘了先清理下。這次再訪問web ui铅歼,就能看到services和nodes都給訪問了公壤,點擊ACL也能看到列表了。
當然也可以用命令行訪問椎椰,要加上token
root@server1:~# curl "http://10.111.152.242:8500/v1/internal/ui/nodes?dc=dc1&token=fc6cad19-4323-9a93-4e5a-9d2e00d91360"
[{"ID":"27b5e48b-08f5-9605-434b-dfbfcb7acdb9","Node":"server1","Address":"10.111.152.242","TaggedAddresses":{"lan":"10.111.152.242","wan":"10.111.152.242"},"Meta":{},"Services":[{"ID":"consul","Service":"consul","Tags":null,"Address":"","Port":8300,"EnableTagOverride":false,"CreateIndex":5,"ModifyIndex":5}],"Checks":[{"Node":"server1","CheckID":"serfHealth","Name":"Serf Health Status","Status":"passing","Notes":"","Output":"Agent alive and reachable","ServiceID":"","ServiceName":"","ServiceTags":null,"CreateIndex":5,"ModifyIndex":5}]},{"ID":"ce41eb68-411b-a80f-4e8f-557fb838edb0","Node":"server3","Address":"10.111.152.246","TaggedAddresses":{"lan":"10.111.152.246","wan":"10.111.152.246"},"Meta":{},"Services":[{"ID":"registrator-3:root_web_1:80","Service":"my-web-server","Tags":["backend-3"],"Address":"10.111.152.246","Port":32768,"EnableTagOverride":false,"CreateIndex":9,"ModifyIndex":9}],"Checks":[{"Node":"server3","CheckID":"serfHealth","Name":"Serf Health Status","Status":"passing","Notes":"","Output":"Agent alive and reachable","ServiceID":"","ServiceName":"","ServiceTags":null,"CreateIndex":7,"ModifyIndex":7}]}]
后來我發(fā)現(xiàn)厦幅,直接把acl_master_token的值復制給acl_token也是可以訪問的,哈哈慨飘,不用中間生成token那一步了慨削,生了不少事啊。
3.2 客戶端ACL
上面我們配置了server端的acl套媚,客戶端均鏈接不上去缚态,日志報
[ERR] consul: RPC failed to server 192.168.56.101:8300: rpc error: Permission denied
這樣的錯誤,顯然被server給拒絕了堤瘤,現(xiàn)在我們要在client節(jié)點上配置acl_token玫芦,以通過server的驗證。
server ACL頁面
先回到server的ACL頁面本辐。默認ACL有anonymous token桥帆,type是client医增;master token, type是management。現(xiàn)在我們添加一個自定義ACL老虫,命名為client-1叶骨,type選擇client,然后往rules里面寫規(guī)則祈匙。
rules語法:
規(guī)則對象 "" { policy = "read" }
規(guī)則對象有:agent忽刽、event、key夺欲、keyring跪帝、node、operator些阅、query伞剑、service、session市埋。
read黎泣、write、deny是規(guī)則權限缤谎。
例如抒倚,往rules中填入
agent "" { policy = "read" }
這個意思是所有agent的請求都有讀的權限。
如果要指定過濾某些特定的標簽有寫權限弓千,類似白名單衡便,可以這樣
規(guī)則對象 "過濾名稱" { policy = "write" }
例如,對-node=host-2的節(jié)點
agent "host-2" { policy = "write" }
多個規(guī)則洋访,可以換行排列镣陕,例如我的配置
agent "" { policy = "read" }
agent "host-2" { policy = "write" }
service "" { policy = "read" } #
service "" { policy = "write" } #這個可以把client的Service上報到server上去。
node "" { policy = "write" }
event "" { policy = "write" }
query "" { policy = "write" }
看看效果
https://offical.b0.upaiyun.com/static/article/1508904606718228503.png
添加成功的時候姻政,會生成一個token呆抑,我這里是a724b77f-1ad6-57e4-c553-127a51d6beda,把它給客戶端汁展,準備接入吧鹊碍。
client節(jié)點
到客戶端機器上,修改配置文件食绿。acl_master_token只有server端可以配置侈咕,客戶端只要配置這兩個重啟下,就可以通過認證了
{
"acl_datacenter": "dc1",
"acl_token": "a724b77f-1ad6-57e4-c553-127a51d6beda"
......
}
在server端的ui上就能看到重新鏈接上的client上報的信息了器紧。
4. 常見問題
4.1 Failed to get advertise address
Error starting agent: Failed to get advertise address: Multiple private IPs found.
啟動的時候加-bind參數(shù)綁定ip
consul agent -dev -bind 192.168.231.18
4.2 8500端口沒開
檢查一下是不是直接連這個端口就會拒絕呢耀销?
ncat -v localhost 8500
或者
nc -v localhost 8500
如果這樣連還是『connection refused』說明Consul服務有問題。
參考:
http://bbotte.com/server-config/consul-acl-rule-usage/
創(chuàng)建于 2017-09-08 北京铲汪,更新于 2017-10-25 北京
該文章在以下平臺同步
- HICOOL.TOP: https://www.hicool.top/article/143
- CSDN:
- 簡書: http://www.reibang.com/p/05741685af33