中小團隊落地配置中心詳解

不知道配置文件上次什麼時候修改的、修改了什麼內容?改了配置文件還要重新發布項目或者手動觸發重啓服務?無緣無故發現配置文件錯了影響到線上正常部署?你是否正在因爲這些問題而困擾?50+線上項目,數百+配置文件,我們經常被這些配置文件虐的生無可戀,是時候作出改變了!本文將帶你解決這些問題,喝着咖啡輕鬆運維

配置中心選型

選型的原則:簡單,易落地,不挑平臺,不挑語言,儘量少的依賴。

對比了Disconf、Apollo等方案,最終選擇了Etcd+Confd的方案,基本符合上邊的原則,且Etcd我們在部署Kubernetes的時候已經有過使用,算是輕車熟路。

配置中心架構圖

  • 配置中心整體採用C/S的模式,用Etcd作爲服務端來存儲數據,Confd作爲客戶端去Etcd取數據更新
  • 爲了更方便的管理寫了WebUI,實際上是一個Etcd服務的WebUI,主要與Etcd服務交互,去Etcd存取數據
  • Confd根據配置文件去Etcd集羣拉取數據,然後根據模板文件將數據按照設定的格式填充的固定的位置生成最終的配置文件
  • 配置文件生成後還可以配合check_cmdreload_cmd命令對配置文件進行檢查和重新加載

配置中心部署

Etcd集羣

  • 系統環境
    • System:Debian 8
    • Etcd:v3.3.9
  • 服務器地址
    • 192.168.107.101
    • 192.168.107.102
    • 192.168.107.103
所有服務器都需要執行以下命令來安裝etcd和創建目錄

1.下載etcd安裝包並解壓

# wget https://github.com/coreos/etcd/releases/download/v3.3.9/etcd-v3.3.9-linux-amd64.tar.gz
# tar -zxvf etcd-v3.3.9-linux-amd64.tar.gz 

2.拷貝程序到/usr/bin目錄下方便執行,etcd爲go編寫,直接可運行,主要有兩個文件etcd和ectdctl,

# mv etcd-v3.3.9-linux-amd64/etcd* /usr/bin/

3.創建etcd配置文件目錄/etc/etcd和數據存放目錄/home/data/etcd

# mkdir /etc/etcd /home/data/etcd
三個node節點etcd配置文件分別如下

node1配置

# cat /etc/etcd/etcd.conf 
name: 'node1'
data-dir: /home/data/etcd

listen-peer-urls: http://192.168.107.101:2380
listen-client-urls: http://192.168.107.101:2379,http://127.0.0.1:2379

initial-cluster-state: 'new'
initial-cluster-token: 'etcd-cluster-conf'
advertise-client-urls: http://192.168.107.101:2379
initial-advertise-peer-urls: http://192.168.107.101:2380
initial-cluster: node1=http://192.168.107.101:2380,node2=http://192.168.107.102:2380,node3=http://192.168.107.103:2380

node2配置

# cat /etc/etcd/etcd.conf 
name: 'node2'
data-dir: /home/data/etcd

listen-peer-urls: http://192.168.107.102:2380
listen-client-urls: http://192.168.107.102:2379,http://127.0.0.1:2379

initial-cluster-state: 'new'
initial-cluster-token: 'etcd-cluster-conf'
advertise-client-urls: http://192.168.107.102:2379
initial-advertise-peer-urls: http://192.168.107.102:2380
initial-cluster: node1=http://192.168.107.101:2380,node2=http://192.168.107.102:2380,node3=http://192.168.107.103:2380

node3配置

# cat /etc/etcd/etcd.conf 
name: 'node3'
data-dir: /home/data/etcd

listen-peer-urls: http://192.168.107.103:2380
listen-client-urls: http://192.168.107.103:2379,http://127.0.0.1:2379

initial-cluster-state: 'new'
initial-cluster-token: 'etcd-cluster-conf'
advertise-client-urls: http://192.168.107.103:2379
initial-advertise-peer-urls: http://192.168.107.103:2380
initial-cluster: node1=http://192.168.107.101:2380,node2=http://192.168.107.102:2380,node3=http://192.168.107.103:2380
每個節點配置完成後均啓動

需要放在後臺運行,推薦使用screen工具

# /usr/bin/etcd --config-file /etc/etcd/etcd.conf 

三個節點全部啓動完成後,可通過etcdctl member list命令查看集羣列表,確認集羣狀態

# etcdctl member list
732ca490026f580d: name=node3 peerURLs=http://192.168.107.103:2380 clientURLs=http://192.168.107.103:2379 isLeader=false
bc16d35c3ad1c5ee: name=node2 peerURLs=http://192.168.107.102:2380 clientURLs=http://192.168.107.102:2379 isLeader=true
f7a043d3b65cd4a4: name=node1 peerURLs=http://192.168.107.101:2380 clientURLs=http://192.168.107.101:2379 isLeader=false

Confd

1.下載confd並放到/usr/bin/目錄下方便使用

# wget https://github.com/kelseyhightower/confd/releases/download/v0.16.0/confd-0.16.0-linux-amd64
# mv confd-0.16.0-linux-amd64 /usr/bin/confd
# chmod +x /usr/bin/confd

2.新建confd配置文件目錄

# mkdir /etc/confd/{conf.d,templates}

3.新建資源文件,.toml文件結尾已經成了固定格式

# cat /etc/confd/conf.d/nginx.conf.toml 
[template]
src = "nginx.conf.tmpl"
dest = "/tmp/nginx.conf"

keys = [
   "/conf/project/env/nginx/nginx.conf",
]

check_cmd = "/usr/sbin/nginx -t -c {{.src}}"
reload_cmd = "/usr/sbin/service nginx reload"

這裏我們新建了一個nginx配置的資源文件,參數解釋:

  • src:指定模板文件的位置,也就是nginx配置文件模板tmpl的位置
  • dest:指定最終生成或更新的配置文件絕對路徑,這裏爲了測試我們給指定到/tmp/下
  • keys:模板文件裏邊要用到的key,也就是etcd裏邊對應的這個項目配置文件的key
  • check_cmd:在更新配置文件完成後執行的check命令,這裏我們就check下nginx配置文件是否有語法錯誤
  • reload_cmd:在check通過後可以執行這裏配置的命令,上一步的check沒有問題,就會執行reload命令重新加載配置文件
  • prefix:配置key的前綴,例如我們的key都是以/conf開頭的,那麼可以增加個配置prefix="/conf",在下邊keys裏就可以省略掉/conf了
  • owner:配置生成配置文件的用戶
  • mode:配置生成配置文件的權限

4.新建模板文件

# cat /etc/confd/templates/nginx.conf.tmpl 
{{getv "/conf/project/env/nginx/nginx.conf"}}
  • confd的模板語法有很多,這裏不贅述,具體可查官網
  • 我們是把整個配置文件的內容作爲一個value存在etcd裏邊的,所以這裏只需要一個getv指令獲取到value的值填充到目標文件就可以了

聯調測試

部署好了etcd集羣和confd服務,接下來我們就要測試下他們是否能夠正常協同工作了

1.在Etcd服務器新建一個KV值

# etcdctl set /conf/project/env/nginx/nginx.conf 'user  www-data;
> worker_processes 4;
> 
> pid        /var/run/nginx.pid;
> error_log  /home/logs/nginx/error.log  warn;
> 
> events  {
>     use epoll;
>     worker_connections 51200;
> }
> 
> http {
>     default_type  application/octet-stream;
> 
>     server {
>         listen       80;
>         server_name  domain.com;
> 
>         root /home/project/webroot;
>         index index.shtml index.html;
>     }
> }'
# 查看設置key的內容
# etcdctl get /conf/project/env/nginx/nginx.conf
user  www-data;
worker_processes 4;

pid        /var/run/nginx.pid;
error_log  /home/logs/nginx/error.log  warn;

events  {
    use epoll;
    worker_connections 51200;
}

http {
    default_type  application/octet-stream;

    server {
        listen       80;
        server_name  domain.com;

        root /home/project/webroot;
        index index.shtml index.html;
    }
}
  • Etcd API分v2和v3版本,兩個版本差別較大,v3優化了很多,但考慮兼容性等問題我們這裏使用v2版本
  • 默認爲v2版本,可以通過環境變量export ETCDCTL_API=3來切換到v3版本,v2通過etcdctl -v可以查看api版本,v3通過etcdctl version查看api版本

2.啓動confd

# confd -watch -backend etcd -node=http://192.168.107.101:2379 -node=http://192.168.107.102:2379 -node=http://192.168.107.103:2379
2018-08-23T13:46:13+08:00 onlinegame.i.nease.net confd[17084]: INFO Backend set to etcd
2018-08-23T13:46:13+08:00 onlinegame.i.nease.net confd[17084]: INFO Starting confd
2018-08-23T13:46:13+08:00 onlinegame.i.nease.net confd[17084]: INFO Backend source(s) set to http://192.168.107.101:2379, http://192.168.107.102:2379, http://192.168.107.103:2379
2018-08-23T13:46:13+08:00 onlinegame.i.nease.net confd[17084]: INFO Target config /tmp/nginx.conf out of sync
2018-08-23T13:46:13+08:00 onlinegame.i.nease.net confd[17084]: INFO Target config /tmp/nginx.conf has been updated

配置參數說明

  • -watch:開啓watch模式,監聽etcd配置中心文件變化,一旦有變這邊立即更新,沒有這個選項配置中心修改client不會更新
  • -backend:後端類型,目前支持etcd、zookeeper、consul、vault、redis、file、rancher等多種類型,confd也有一些針對不通後端類型的單獨配置,具體可以通過confd --help命令查看
  • -node:etcd節點地址,有多個節點的話就這麼寫多個-node就好了,我們etcd是三個節點的集羣所以這裏寫三次'-node'
  • -onetime:可用來替換上邊的-watch參數,表示運行一次就退出,如果你不想讓配置文件實時更新,只是想更新一次,可以用這個參數
  • -interval:可用來替換上邊的-watch參數,表示每隔多少秒去backend取一次數據,如果想降低etcd服務器壓力,又想讓客戶端配置文件能自動更新,可以通過這個參數來控制

3.通過上邊日誌可以看到/tmp/nginx.conf文件已經正常同步且更新了,查看/tmp/nginx.conf確定內容正確

WebUI Kerrigan

總不能所有的配置文件更新都通過命令行的方式吧?爲了方便管理,花了三天(真的是三天)寫了個WebUI,命名爲Kerrigan,能夠實現目錄樹,在線查看配置、修改配置、查看配置更新歷史等實用功能

配置頁面,通過這個頁面可以配置etcd的連接信息

首頁,左側項目列表(項目信息同步CMDB)

點擊項目列表後,根據對應規則去etcd裏邊取出目錄結構按樹狀呈現出來

點擊配置文件,右側會展示當前配置文件內容

點擊“編輯”按鈕可以編輯這個配置,新建頁面一樣,只是編輯不允許修改路徑

點擊“歷史”按鈕,則跳轉到配置文件的歷史頁面,這個頁面展示了這個配置文件所有的修改歷史

寫在最後

  1. 是不是要說這個界面醜爆了!沒辦法,前端後端測試加上線都我一人幹,沒有設計細胞,就這麼看吧,並且最重要的不是功能好用麼
  2. 爲什麼不用K8S的configmap?我們最初是想用K8S的configmap來做配置中心的,但是並非所有的項目都跑在K8S裏,且修改configmap也需要重啓容器才能生效,所以就沒有采用了
  3. etcd誰都可以修改麼,感覺不安全啊?實際上我們是用了賬號密碼認證的,且只在內網,限制IP,安全一點吧,另一種解決方案是etcd走ssl,但client端要放證書比較麻煩沒有采用
  4. 怎麼確認Client端配置文件更新成功了?如果你是一次性啓動可以在啓動命令之後判斷啓動命令是否正常執行,如果你是watch模式或者interval,那麼。。只能人肉check了吧,我也沒有好方法
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章