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

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

配置中心選型

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

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

配置中心架構圖

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

配置中心部署

Etcd集羣

  • 系統環境linux

    • System:Debian 8
    • Etcd:v3.3.9
  • 服務器地址nginx

    • 192.168.107.101
    • 192.168.107.102
    • 192.168.107.103
全部服務器都須要執行如下命令來安裝etcd和建立目錄

1.下載etcd安裝包並解壓git

# 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,github

# mv etcd-v3.3.9-linux-amd64/etcd* /usr/bin/
複製代碼

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

# mkdir /etc/etcd /home/data/etcd
複製代碼
三個node節點etcd配置文件分別以下

node1配置redis

# 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了吧,我也沒有好方法

掃碼關注公衆號查看更多原創文章

若是你以爲文章對你有幫助,請轉發分享讓更多好友看到。若是你以爲讀的不盡興,推薦閱讀如下文章:

相關文章
相關標籤/搜索