前面我們已經通過jenkins+docker搭建了基本的持續集成環境,實現了服務的自動構建和部署,但是,我們遇到一個問題,jenkins構建出來的鏡像部署后,需要通過ip:port去訪問,有什么更好的方法嗎?肯定是通過域名啊!前提是你注冊一個域名,或者修改機器hosts文件。
本文介紹通過引入etcd+confd實現部署服務的自動注冊,自動生成nginx配置文件,實現每個服務獨立域名訪問。
配置域名
假設你的域名是: example.com,那么我們可以規划
- dev.$servicename.example.com作為開發環境,
- test.$servicename.example.comz作為服務的測試環境。
配置步驟:
- 首先將*.example.com 指向一台nginx服務器
- 增加vhost配置文件,假設86.6,86.8,86.11 是docker swarm集群中的機器,服務的名稱為allinoneservice,那么我們可以增加一個配置文件nginx_vhosts/service.conf:
upstream test_service_allinoneservice {
server 192.168.86.11:10091;
server 192.168.86.6:10091;
server 192.168.86.8:10091;
}
server {
listen 80;
server_name test.allinoneservice.example.com;
location / {
proxy_redirect off;
proxy_set_header Host $host;
proxy_read_timeout 300;
proxy_set_header X-Real-IP $http_x_forwarded_for;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://test_service_allinoneservice;
}
}
-
修改nginx配置文件nginx.conf,在最后一個大括號前,將剛新建的配置文件包含進去:
include nginx_vhosts/*.conf;
-
重啟nginx,就可以通過test.allinoneservice.example.com訪問服務了
通過服務注冊自動生成配置文件
第一步里,我們需要手動編寫配置文件,有更好的方式嗎?答案是通過服務注冊+confd,自動生成配置文件。
docker 安裝etcd集群
首先,docker安裝etcd作為注冊中心,我們安裝一個包含3個實例的集群,編寫docker-compose.yml:
version: '3'
services:
etcd0:
image: 192.168.86.8:5000/etcd
ports:
- "2379:2379"
volumes:
- etcd0:/etcd_data
command:
- /usr/local/bin/etcd
- -name
- etcd0
- --data-dir
- /etcd_data
- -advertise-client-urls
- http://etcd0:2379
- -listen-client-urls
- http://0.0.0.0:2379
- -initial-advertise-peer-urls
- http://etcd0:2380
- -listen-peer-urls
- http://0.0.0.0:2380
- -initial-cluster
- etcd0=http://etcd0:2380,etcd1=http://etcd1:2380,etcd2=http://etcd2:2380
etcd1:
image: 192.168.86.8:5000/etcd
ports:
- "2380:2379"
volumes:
- etcd1:/etcd_data
command:
- /usr/local/bin/etcd
- -name
- etcd1
- --data-dir
- /etcd_data
- -advertise-client-urls
- http://etcd1:2379
- -listen-client-urls
- http://0.0.0.0:2379
- -initial-advertise-peer-urls
- http://etcd1:2380
- -listen-peer-urls
- http://0.0.0.0:2380
- -initial-cluster
- etcd0=http://etcd0:2380,etcd1=http://etcd1:2380,etcd2=http://etcd2:2380
etcd2:
image: 192.168.86.8:5000/etcd
ports:
- "2381:2379"
volumes:
- etcd2:/etcd_data
command:
- /usr/local/bin/etcd
- -name
- etcd2
- --data-dir
- /etcd_data
- -advertise-client-urls
- http://etcd2:2379
- -listen-client-urls
- http://0.0.0.0:2379
- -initial-advertise-peer-urls
- http://etcd2:2380
- -listen-peer-urls
- http://0.0.0.0:2380
- -initial-cluster
- etcd0=http://etcd0:2380,etcd1=http://etcd1:2380,etcd2=http://etcd2:2380
volumes:
etcd0:
etcd1:
etcd2:
注意,上面的image: 192.168.86.8:5000/etcd 是用的私有倉庫,大家可以使用官方版本quay.io/coreos/etcd
然后啟動etcd:
docker stack deploy -c docker-compose.yml etcd
服務注冊
etcd注冊就簡單了,可以通過etcd的rest api,例如:
curl http://192.168.86.11:2379/v2/keys/services/test/allinoneservice/service1 -XPUT -d value="192.168.86.8:10091"
所以,我們修改一下jenkins里的docker部署腳本,服務部署后自動向etcd注冊,由於是swarm集群,因此我們可以注冊多個ip。
echo "start remove old service"
docker service rm ${service_name}-${env}
echo "start create new service with latest builded image"
docker service create --name ${service_name}-${env} --replicas ${replicas} --publish ${service_port}:${docker_expose_port} 192.168.86.8:5000/${service_name}-${env}
echo "publish service to nginx"
curl http://192.168.86.11:2379/v2/keys/services/${env}/${service_name}/service1 -XPUT -d value="192.168.86.8:${service_port}"
curl http://192.168.86.11:2379/v2/keys/services/${env}/${service_name}/service2 -XPUT -d value="192.168.86.11:${service_port}"
curl http://192.168.86.11:2379/v2/keys/services/${env}/${service_name}/service3 -XPUT -d value="192.168.86.6:${service_port}"
注意,上面的service_name是jenkins參數化構建里定義的參數:
通過confd生成nginx配置文件
confd 是一個配置文件生成工具,可以從etcd、consul等注冊中心讀取數據根據模板生成配置文件,並在配置發生變化后自動更新配置文件,還能自動重啟服務,是服務自動發現的居家必備良葯。
首先講下怎么安裝,根據官方文檔:
wget https://github.com/kelseyhightower/confd/releases/download/v0.14.0/confd-0.14.0-linux-amd64
mkdir -p /opt/confd/bin
mv confd-0.14.0-linux-amd64 /opt/confd/bin/confd
chmod +x /opt/confd/bin/confd
export PATH="$PATH:/opt/confd/bin"
為了方便使用,最好修改下/etc/profile,加入export PATH="$PATH:/opt/confd/bin",然后source /etc/profile讓配置生效。
然后編寫confd配置文件/etc/confd/conf.d/myapp-nginx.toml:
[template]
src = "nginx.conf.tmpl"
dest = "/opt/third_party/nginx_vhosts/service.conf"
keys = [
"/services/dev",
"/services/test",
]
reload_cmd = "/opt/third_party/sbin/nginx -s reload"
上面配置了,會讀取的keys,以及dest目標配置文件地址,和配置文件更新后的reload_cmd,用於重啟nginx
接着編寫模板文件
{{range $dir := lsdir "/services/test"}}
upstream test_service_{{base $dir}} {
{{$custdir := printf "/services/test/%s/*" $dir}}{{range getvs $custdir}}
server {{.}};
{{end}}
}
server {
listen 80;
server_name test.{{base $dir}}.iflyresearch.com;
location / {
proxy_redirect off;
proxy_set_header Host $host;
proxy_read_timeout 300;
proxy_set_header X-Real-IP $http_x_forwarded_for;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://test_service_{{base $dir}};
}
}
{{end}}
上面的模板比較簡單,通過lsdir指令讀取服務列表,然后通過range getvs獲取服務對應的負載地址。
然后啟動confd,需要指定etcd的地址:
nohup confd -backend etcd -node http://192.168.86.11:2379 &
搞定!
延伸閱讀
Jenkins+Docker 搭建持續集成環境:
- Docker+Jenkins持續集成環境(1)使用Docker搭建Jenkins+Docker持續集成環境
- Docker+Jenkins持續集成環境(2)使用docker+jenkins構建nodejs前端項目
- Docker+Jenkins持續集成環境(3)集成PMD、FindBugs、Checkstyle靜態代碼檢查工具並郵件發送檢查結果
作者:Jadepeng
出處:jqpeng的技術記事本--http://www.cnblogs.com/xiaoqi
您的支持是對博主最大的鼓勵,感謝您的認真閱讀。
本文版權歸作者所有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責任的權利。