Consul服務注冊發現與Fabio反向代理

Consul服務注冊發現

Consul是一個輕量級的服務注冊與發現工具, 支持集群, 支持k/v存儲, 支持對服務的健康檢查. 同類工具有etcd, zookeeper等..

二進制安裝

https://releases.hashicorp.com/consul/1.2.2/consul_1.2.2_linux_amd64.zip
下載并解壓, 然后拷貝二進制文件到 /usr/local/bin


快速啟動consul

開發模式啟動consul是最快的方式
consul agent -dev -config-dir=/etc/consul -bind=0.0.0.0 -client=0.0.0.0

參數說明

  • agent -- 使用agent模式跑起來
  • -dev -- 使用開發模式啟動agent
  • -config-dir -- 配置文件目錄, 這里存放json文件以文件的形式注冊服務
  • -bind=0.0.0.0 -- 綁定集群通訊的ip地址, 默認是127.0.0.1
  • -client=0.0.0.0 -- 綁定客戶端API,DNS等服務監聽的地址, 默認是127.0.0.1

Consul主配置文件

/etc/consul/config.json

{
    "acl_datacenter": "aliyun", # 開啟ACL必選 數據中心名稱, 表示啟用acl的數據中心, all表示所有數據中心
    "acl_default_policy": "deny", # 可選 默認為allow, 所有操作都允許 改為deny即表示開啟acl(既白名單模式), 第一次啟動consul請勿配置deny否則自己進不去
    "acl_master_token": "5d79de96-106f-11e7-9381-005056abff5a", # 開啟ACL必選 這個token必須是uuid格式, 任何可生成uuid的工具生成, 在訪問API時必須帶上此uuid, 包括UI界面, UI界面點擊右側的setting進入后, 在ACL TOKEN中填入acl_master_token的值, 點擊save 即可配置ACL
    "bootstrap_expect": 2, # 在一個datacenter中期望提供的server節點數目,當該值提供的時候,consul一直等到達到指定sever數目的時候才會引導整個集群,該標記不能和bootstrap公用
    "client_addr": "0.0.0.0",
    "bind_addr": "0.0.0.0",
    "advertise_addr": "192.168.1.200", # 當服務器有多個私網IP時, 必須指定一個IP作為集群通信IP, 需要個bind_addr一起使用
    "data_dir": "/opt/consul",
    "datacenter": "aliyun", # 數據中心名稱
    "dns_config": { # DNS發現功能的配置
        "allow_stale": true,
        "enable_truncate": true,
        "node_ttl": "60s",
        "service_ttl": {
            "*": "5s"
        }
    },
    "enable_script_checks": true, # 允許服務使用腳本進行健康檢查
    "encrypt": "NnKESxGToysca68P7FM2sA==", # consul的server和client通信秘鑰 使用consul keygen創建, 不管server還是client都要這個參數和相同的值
    "log_level": "INFO", # 日志記錄等級
    "node_name": "consulServer1", # 本節點名稱
    "server": true, # consul以server模式啟動
    "ui": true # 啟用UI界面
}

注: 關于ACL的配置還有:

Consul的CLI啟動參數絕大部分都也可以配置在config.json中, 但有些參數在json中配置時名稱和cli中使用有所不同
詳見官方文檔 https://www.consul.io/docs/agent/options.html#configuration-files


Consul監聽的端口

協議 端口 說明
tcp 8300 Server 服務器節點與集群通訊
tcp 8301 Cluster LAN -- 集群sever間通信
udp 8301 Cluster LAN -- 集群sever間通信
tcp 8302 Cluster WAN -- 集群sever間通信
udp 8302 Cluster WAN -- 集群sever間通信
tcp 8500 Client HTTP Server -- 節點對外HTTP服務
tcp 8600 Client DNS Server(TCP) -- 節點對外DSN服務
udp 8600 Client DNS Server(UDP) -- 節點對外DNS服務

這些端口在config.json或者啟動參數中都是可以修改的


本地json文件服務注冊

/etc/consul/web.json

{
    "service": {
        "checks": [ # 健康檢查配置
            {
                "tcp": ":80", # 檢查模式, tcp, http, https, script幾種模式, :80表示訪問本機任何ip的80端口
                "interval": "5s",
                "timeout": "1s"
            }
        ],
        "id": "web-1", # 服務id
        "name": "web-1", # 服務名稱
        "port": 80 , # 服務端口
        "tags": [ # 標簽
            "urlprefix-/web" # 給fabio使用的標簽, 后面會詳細說
        ]
    }
}

Consul的UI界面

cli方式啟動時必須 -ui 啟動UI界面
config.json方式配置時需要增加 { "ui": ture }才能啟動UI界面
http://x.x.x.x:/8500/ui 可以進入UI界面

image.png

服務健康檢查

常見的有http, script, tcp等, 同一個服務可以有多種檢查方法,例如:

{
  "checks": [
    {
      "id": "chk1",
      "name": "mem",
      "args": ["/bin/check_mem", "-limit", "256MB"], # 帶參數的script類型檢查
      "interval": "5s",
      "timeout": "1s"
    },
    {
      "id": "chk2",
      "name": "/health",
      "http": "http://localhost:5000/health", # http類型檢查
      "tls_skip_verify": false,
      "method": "POST",
      "header": {"x-foo":["bar", "baz"]},
      "interval": "15s",
      "timeout": "1s"
    },
    {
      "id": "chk3",
      "name": "cpu",
      "script": "/bin/check_cpu", # 不帶參數的script檢查
      "interval": "10s"
    },
    ...
  ]
}

更多健康檢查方法和參數詳見官方文檔
https://www.consul.io/docs/agent/checks.html


ConsulAPI

請參見 官方文檔 https://www.consul.io/api/agent.html


Consul集群配置

Consul集群配置要注意幾點:

  • ACL 權限要配好, 不然權限不足會導致servers/clients之間不能通信
  • encrypt 所有server, client節點的通信秘鑰必須一致

手動加入集群方法

[root@localhost ~]# consul join 192.168.1.xxx
Successfully joined cluster by contacting 1 nodes.

自動加入集群方法

  • consul agent CLI方式啟動參數 -retry-join="192.168.1.1 192.168.1.2 192.168.1.3"
  • config.json配置文件方式啟動參數 { "retry_join": ["192.168.1.1", "192.168.1.2","192.168.1.3"] }
    注: retry-join參數允許失敗, 未指定重試次數和間隔將永遠嘗試, 直到成功未知

Consul ACL訪問控制列表

如何進入ACL管理界面?
1.打開UI界面
2.點擊導航欄右側的Settings
3.將consul配置文件中的 acl_master_token拷貝粘貼到web界面中的ACL TOKEN
4.點擊Save按鈕
5.再點擊導航欄中的ACL菜單

UI界面配置訪問的Token

創建ACL策略
策略內容

key "" {                # 針對訪問k/v存儲的策略
   policy = "read" # 只讀
}
service "fabio-" { # 針對訪問服務的策略(僅針對以"fabio-"開頭命名的服務
    policy = "write" # 可讀可寫
}
service "" { # 針對訪問服務的策略 (所有服務)
    policy = "read" # 可讀
}
node "" { # 針對訪問節點信息的策略 (所有節點)
    policy = "read" # 可讀
} 
agent "" { # 針對訪問agent代理信息的策略 (所有agent)
    policy = "read" # 可讀
}
session "" { 
    policy = "write"
}

UI界面創建ACL策略示例


創建ACL策略
策略對象 說明
agent Agent API中的實用程序操作,而不是服務和檢查注冊
event Event API中檢索時間和觸發事件
key KV Store API中的鍵/值存儲操作
keyring 密鑰環API中的密鑰環操作
node Catalog APIHealth APIPrepared Query APINetwork Coordinate APIAgent API中的節點級目錄操作
operator Keyring API之外的Operator API中的集群級操作
query 發現查詢的查詢操作
service Catalog APIHealth APIPrepared Query APIAgent API中的服務級目錄操作
session 會話API操作

ACL策略類型

  • read 只讀
  • write 讀寫
  • deny 不能讀也不能寫

API操作ACL詳見官方API文檔 https://www.consul.io/docs/guides/acl.html#rule-specification


Network Segments 網格

待完善


Consul 監控

待完善


Fabio反向代理

Fabio是為consul而生的一個反向代理服務器, 支持負載均衡, http, https, tcp等. 你可以把它想象成nginx, 與nginx不同的是fabio可以根據consul服務的tag來進行自動轉發請求

安裝Fabio

首先需要安裝git 和go環境 使用yum安裝即可
# yum -y install git golang

獲取fabio
# go get github.com/eBay/fabio

拷貝fabio二進制文件到彬bin目錄
# cp go/bin/fabio /usr/local/bin/

拷貝配置文件到etc目錄
# cp go/src/github.com/eBay/fabio/fabio.properties /etc/

/etc/fabio.properties常見配置

proxy.addr = :9999 # fabio代理監聽端口
proxy.localip = # 代理監聽的本地ip地址, 默認是空也就是0.0.0.0
proxy.strategy = rnd # 代理策略 rr(輪訓)和rnd(基于微秒時間隨機分配)
proxy.matcher = prefix # fabio反代請求給consul的匹配方式, prefix是使用uri前綴匹配, glob是使用通配符匹配(通配符不是正則表達式哦, 雖然有些相通)
proxy.maxconn = 10000 # 緩存的連接數
registry.consul.addr = localhost:8500 # fabio 去個consul服務注冊自己? 一般指定任意一個client的8500端口即可
registry.consul.token = # fabio去consul注冊自己時, 需要使用的token(當consul啟用了acl才需要)
registry.consul.kvpath = /fabio/config # fabio在consul的k/v數據庫中寫入數據的路徑
# fabio轉發請求到consul時, 如果使用prefix策略, 則需要指定前綴是啥
# 比如 當請求fabio地址http://fabio_ip:9999/urlprefix-/webService 
# fabio將會把請求轉發到consul中tag為"urlprefix-/webService"的服務
# 也就是說"urlprefix-"是fabio和consule服務注冊者在consul注冊服務打標簽時約定的標簽前綴
registry.consul.tagprefix = urlprefix-

fabio還有很多關于反代的參數, 比如代理https時使用的證書, http頭的修改等等配置, 詳情參見官方文檔 https://fabiolb.net/ref/


自定義代理路由

fabio默認會按照proxy.matcher配置的匹配方法自動向consul轉發請求, 當然也可以自定義路由進行轉發

如何配置自定義轉發路由規則?
登陸consul的UI界面, 在Key/Value中創建
Key:
fabio/config
Value:
route add serviceName1 /abc http://192.168.1.1/
如下圖所示

新增自定義轉發路由

轉發的路由規則語法請參見官方文檔
https://fabiolb.net/cfg/

查看Fabio路由表
http://fabio_ip:9998/routes

Fabio路由表: 其中第1條是fabio自動轉發的路由, 第2條是我們自定義的路由規則

路由有各種Option, 這些Option在add route自定義路由或consul注冊服務時都需要注意

比如consul注冊如下服務時:

{
    "service": {
        "checks": [
            {
                "tcp": ":443",
                "interval": "5s",
                "timeout": "1s"
            }
        ],
        "id": "web-2",
        "name": "web-2",
        "port": 443 ,
        "tags": [
            "urlprefix-/web2, proto=https, tlsskipverify=true"
        ]
    }
}

consul注冊服務時已定義好如果fabio向自己轉發請求時自己應該告訴fabio些什么:

  • urlprefix-/web2: 當用戶請求fabio(你)的uri前綴是"/urlprefix-/web2"的時候才轉發到consul(我)這個服務(注意urlprefix-/web2在tag里時前面時沒有/的)
  • proto=https:consul(我)的這個服務是https的
  • tlsskipverify=true:fabio(你)在訪問consul(我)的這個服務時請跳過證書檢查

比如在fabio新增一個路由時:
route add web2 /web2 https://x.x.x.x:8080/ opts "proto=https, tlsskipverify=true"
這個自定義路由是fabio告訴自己, 當匹配到uri為/web2的請求時, 應該將請求轉發的目標是什么, 轉發給目標時需要哪些參數:

  • proto=https 目標是https協議
  • tlsskipverify=true 轉發給目標時, 忽略目標的ssl證書檢查
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容