先簡單說下業務邏輯,etcd是一個分部式k/v存儲系統,confd是一個對etcd的key或者目錄作變化監控的軟件,並配有相關語法,能夠將變化的k/v處理後造成配置文件,nginx不用多說了,作docker容器的負載均衡流量調度。node
在業務過程當中,docker容器健康起來後,會經過接口向etcd註冊相關k/v信息,confd檢測到etcd的k/v變化後,當即觸發程序經過模板造成新的nginx配置文件,先作離線語法測試,若是沒問題就覆蓋原配置,進而reload,測試不經過就不覆蓋原配置,整個過程是安全可控的。在容器註冊到nginx的upstream後,nginx會對容器作健康檢查發現,若是正常,則分發流量過去。對應的業務流程圖以下:nginx
根據業務狀況,要解決以下幾個問題:git
一、nginx負載均衡的混合註冊,使得nginx能夠混合負載多個業務;github
二、不一樣機房如何在同一etcd集羣上進行註冊,如何規劃;docker
三、confd更新頻率如何週期可控制,k/v每有變化實時觸發reload太敏感,何況每一個容器要註冊多個k/v,在總體註冊完以前,是不須要reload的;api
四、confd啓動時如何關聯多個etcd的地址,保證高可用;安全
五、權限問題如何處理,怎麼作,若是任何人知道ip和端口就能夠註冊,那麼服務就垮了。bash
1、nginx負載均衡的混合註冊,使得nginx能夠混合負載多個業務域名容器服務器
先分析下nginx作負載均衡時的配置文件,分析後註冊時的變化因子主要有3個,1是server_name的域名,2是upstream的名稱,3是upstream裏的server,這三個元素就決定了不一樣的註冊服務。有了這個思路後,設計confd對應的nginx的模板文件,先簡單說下confd,confd能夠直接下載二進制包,不存在安裝的問題,配置好path後直接使用命令,在使用中默認讀取/etc/confd下的conf.d和templates下兩個目錄的配置,對應github是https://github.com/coreos/etcd ,建立過程以下:app
mkdir -p /etc/confd/{conf.d,templates}
而後在conf.d下建立.toml配置文件,在templates下建立.tmpl模板文件。
根據nginx的3個元素去分析規劃k/v規則,優化後發現註冊一個服務要添加兩個健值,並用etcdctl命令進行模擬測試,註冊第一個服務以下:
etcdctl set /service_sgin/subdomain/service1 "www.service1.com" etcdctl set /service_sgin/upstream/service1/server1 192.168.1.1
其中service1是對應業務名稱,"www.service1.com"是域名,192.168.1.1對應是server,先看下注冊後的結果:
而後我再繼續註冊第二個服務,對應命令以下:
etcdctl set /service_sgin/subdomain/service2 "www.service2.com page.service2.com" etcdctl set /service_sgin/upstream/service2/server1 192.168.1.2
註冊後配置文件截圖以下:
要的就是這個效果,另外加了一個默認的server,當過來沒有符合業務的域名,直接302到某個業務地址,好了剖開看confd的兩個概要配置以下:
/etc/confd/conf.d/nginx.conf.toml
[template] prefix = "/service_sgin" #此配置對應etcd的默認目錄 src = "nginx.conf.tmpl" #對應templates下的模板文件 dest = '/usr/local/nginx/conf/nginx.conf' #對應nginx的配置文件 owner = "root" mode = "0666" keys = [ "/upstream", #監控的鍵值目錄 "/subdomain", #監控的鍵值目錄 ] check_cmd = "/usr/local/nginx/sbin/nginx -t -c ``.`src`" #檢測到變化後的測試 reload_cmd = "/usr/local/nginx/sbin/nginx -s reload" #配置文件沒問題後的reload
/etc/confd/templates/nginx.conf.tmpl
user root; worker_processes auto; worker_cpu_affinity auto; pid logs/nginx.pid; #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #error_log_bind 192.168.1.31; worker_rlimit_nofile 512000; events { use epoll; worker_connections 20480; } http { include mime.types; default_type application/octet-stream; resolver 127.0.0.1 valid=10m; sendfile on; keepalive_timeout 65s; proxy_next_upstream error timeout; proxy_buffering on; proxy_buffer_size 8k; proxy_buffers 32 4k; ######################對應upstream的模板部分################ {{range $sub := ls "/subdomain"}} upstream {{base $sub}} { {{$subdir := printf "/upstream/%s/*" $sub}}{{range getvs $subdir}} server ``.``; `end` keepalive_timeout 65s; } `end` ############################################################# server { listen 80 backlog=65535 default; server_name localhost; location / { rewrite ^/(.*)$ http://www.sina.cn redirect; } } #####################對應server的模板部分#################### {{range gets "/subdomain/*"}} server { listen 80; server_name ``.`Value`; location / { proxy_pass http://{{base .Key}}; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } } `end` }
2、不一樣機房如何在同一etcd集羣上進行註冊,如何規劃
這個其實看起來複雜,實施起來很是簡單,爲了節省資源,不可能每一個機房都對應建etcd集羣,這個時候就能夠複用etcd集羣,好比北顯和亦莊機房的註冊,可使用改變默認etcd鍵值目錄來實現:
prefix = "/service_sgin_bx" prefix = "/service_sgin_yz"
3、confd更新頻率如何週期可控制,k/v每有變化實時觸發reload太敏感,何況每一個容器要註冊多個k/v,在總體註冊完以前,是不須要reload的
這個一樣,看起來複雜,其實confd改一下模式就能實現,不要用watch模式,改而週期性去探測etcd的鍵值變化,好比說2秒探測一次,對應啓動時的命令以下:
./confd -backend="etcd" -node=10.211.103.151:2379 -interval=2
4、confd啓動時如何關聯多個etcd的地址,保證高可用
一樣,只要修改下confd的啓動命令便可,讓confd監控更多node,我目前的etcd有3個node,所有監控進去以下:
./confd -backend="etcd" -node=10.211.103.151:2379 -node=10.211.103.152:2379 -node=10.211.103.153:2379 -interval=2
5、權限問題的處理
對於權限有兩種方式,一個是證書,一個是帳號,業務本就跑到內網,再加之帳號的配合是靈活迅速的,就從帳號着手了,對於etcd的權限,主要是經過用戶、規則來管理的,將用戶和規則對應起來就是用戶的權限,默認安裝後是不開啓權限的,整理後相關的權限操做以下:
用戶管理:
etcdctl user add root:123 #加root用戶,開啓權限必須先加 etcdctl auth enable #權限管理開啓 etcdctl --username root:123 user list #查看用戶 etcdctl --username root:123 user remove test_user #刪除用戶
role規則管理:
etcdctl --username root:123 role add test_role etcdctl --username root:123 role grant --path "/*" --rw test_role #加權限 etcdctl --username root:123 role revoke --path "/*" --write test_role #減權限 etcdctl --username root:123 role remove test_role etcdctl --username root:123 role list etcdctl --username root:123 role get test_role
用戶規則管理:
etcdctl --username root:123 user add test_user:123 etcdctl --username root:123 user grant --roles test_role test_user #加規則 etcdctl --username root:123 user revoke --roles test_role test_user #減規則 etcdctl --username root:123 user get test_user #查看某個用戶下的規則
備註:一、guest用戶的規則是guest,默認是所有權限;
二、confd是以訪客guest身份監控k/v的,對應的規則就是guest;
後附一:etcd的集羣配置,擴容
假設初始化3臺etcd分別是10.211.103.15二、10.211.103.15三、10.211.103.154,etcd下載下來就能夠用,主要是如何配置啓動,分別再三臺機器上編寫以下啓動腳本etcdnew.sh,而後依次啓動便可:
10.211.103.152服務器:
#/bin/sh #writer:gaolixu /usr/local/etcd/etcd --name etcd152 --data-dir /data1/etcd \ --initial-advertise-peer-urls http://10.211.103.152:2380 \ --listen-peer-urls http://0.0.0.0:2380 \ --listen-client-urls http://0.0.0.0:2379 \ --advertise-client-urls http://10.211.103.152:2379 \ --initial-cluster-token etcd-cluster-1 \ --initial-cluster etcd152=http://10.211.103.152:2380,etcd153=http://10.211.103.153:2380,etcd154=http://10.211.103.154:2380 \ --initial-cluster-state new &
10.211.103.153服務器:
#/bin/sh #writer:gaolixu /usr/local/etcd/etcd --name etcd153 --data-dir /data1/etcd \ --initial-advertise-peer-urls http://10.211.103.153:2380 \ --listen-peer-urls http://0.0.0.0:2380 \ --listen-client-urls http://0.0.0.0:2379 \ --advertise-client-urls http://10.211.103.153:2379 \ --initial-cluster-token etcd-cluster-1 \ --initial-cluster etcd152=http://10.211.103.152:2380,etcd153=http://10.211.103.153:2380,etcd154=http://10.211.103.154:2380 \ --initial-cluster-state new &
10.211.103.154服務器:
#/bin/sh #writer:gaolixu /usr/local/etcd/etcd --name etcd154 --data-dir /data1/etcd \ --initial-advertise-peer-urls http://10.211.103.154:2380 \ --listen-peer-urls http://0.0.0.0:2380 \ --listen-client-urls http://0.0.0.0:2379 \ --advertise-client-urls http://10.211.103.154:2379 \ --initial-cluster-token etcd-cluster-1 \ --initial-cluster etcd152=http://10.211.103.152:2380,etcd153=http://10.211.103.153:2380,etcd154=http://10.211.103.154:2380 \ --initial-cluster-state new &
啓動後能夠看到集羣成員和健康狀況以下:
添加、刪除etcd集羣節點操做:
好比添加10.211.103.151節點
etcdctl member add etcd151 http://10.211.103.151:2380
執行命令後會有提示,而後再151上編寫以下腳本etcdadd.sh:
#/bin/sh #writer:gaolixu /usr/local/etcd/etcd --name etcd151 --data-dir /data1/etcd \ --initial-advertise-peer-urls http://10.211.103.151:2380 \ --listen-peer-urls http://0.0.0.0:2380 \ --listen-client-urls http://0.0.0.0:2379 \ --advertise-client-urls http://10.211.103.151:2379 \ --initial-cluster-token etcd-cluster-1 \ --initial-cluster etcd153=http://10.211.103.153:2380,etcd154=http://10.211.103.154:2380,etcd151=http://10.211.103.151:2380,etcd152=http://10.211.103.152:2380 \ --initial-cluster-state existing &
刪除節點的話執行以下命令:
etcdctl member remove cf5e47596c46611a #經過etcdctl member list 查看到id
後附2:etcd的api 2和api 3的轉換及confd的使用轉換
1、etcd經過環境變量的調整來修改
export ETCDCTL_API=2 #api2版本 export ETCDCTL_API=3 #api3版本
2、confd經過監控時的參數修改
下載二進制文件直接使用: https://github.com/bacongobbler/confd/releases
-backend etcdv3 即 etcd api v3 -backend etcd 即 etcd api v2
自建我的原創站運維網咖社(www.net-add.com),新的博文會在網咖社更新,歡迎瀏覽。