摘要:服務(wù)發(fā)現(xiàn)服務(wù)發(fā)現(xiàn)被容器處理。主機(jī)首先,我們啟動(dòng)注冊(cè)我們的地址是。首先,啟動(dòng)然后,啟動(dòng)一個(gè)簡單的客戶端容器并傳給它。這時(shí),構(gòu)造一些請(qǐng)求給服務(wù)端口來看他們的負(fù)載。同樣地,的事件和容器減輕了服務(wù)注冊(cè)和使用注冊(cè)服務(wù)發(fā)現(xiàn)比如的困難。
使用 Etcd 和 Haproxy 做 Docker 服務(wù)發(fā)現(xiàn)
標(biāo)簽(空格分隔): Etcd Haproxy Docker 服務(wù)發(fā)現(xiàn) architecture discovery docker-gen golang service
本文作者是 jwilder,本文的原文是 Docker Service Discovery Using Etcd and Haproxy
在前一篇文章中,我們展示了一種為 Docker 容器在同一臺(tái)主機(jī)上創(chuàng)建一個(gè)自動(dòng)化 Nginx 反向代理的方式。那個(gè)設(shè)置對(duì)于前端 web app 來說工作的很好,但是對(duì)于后端服務(wù)來說它不是一個(gè)好的點(diǎn)子,因?yàn)橥ǔK鼈兛缭蕉鄠€(gè)主機(jī)。
這篇文章描述了一個(gè)為后端服務(wù)的 Docker 容器提供服務(wù)發(fā)現(xiàn)的解決方案。
我們將構(gòu)建的架構(gòu)體系是模仿 SmartStack,但是使用 etcd 代替 Zookeeper,和兩個(gè) docker 容器運(yùn)行 docker-gen 和 haproxy 代替 nerve 和 synapse。
它怎樣工作的類似于 SmartStack,我們的組件服務(wù)作為一個(gè)注冊(cè)(etcd),一個(gè)注冊(cè)伙伴進(jìn)程(docker-register),發(fā)現(xiàn)伙伴進(jìn)程(docker-discover),一些后端服務(wù)(whoami)以及最后一個(gè)消費(fèi)者(ubuntu/curl)。
注冊(cè)和發(fā)現(xiàn)組件作為設(shè)備與應(yīng)用程序容器工作,因此在后端或消費(fèi)者容器的注冊(cè)或發(fā)現(xiàn)代碼不是被嵌入的。它們僅僅監(jiān)聽端口或連接其他本地端口。
服務(wù)注冊(cè) - Etcd在任何事情被注冊(cè)之前,我們需要一些地方跟蹤注冊(cè)條目(比如,服務(wù)的 IP 和端口)。我們使用 etcd,因?yàn)樗煞?wù)注冊(cè)的簡單程序模型和支持鍵的 TTLs 以及目錄。
通常,你將運(yùn)行 3到5個(gè) etcd 節(jié)點(diǎn),但是我們僅僅使用一個(gè)來保持事情簡化。
沒有理由為什么我們不能使用 Consul 或任何其他存儲(chǔ)選項(xiàng)支持 TTL 過期。
開始 etcd:
docker run -d --name etcd -p 4001:4001 -p 7001:7001 coreos/etcd服務(wù)注冊(cè) - docker-register
注冊(cè)服務(wù)容器被 jwilder/docker-register 容器處理。這個(gè)容器注冊(cè)其他運(yùn)行在同一臺(tái)主機(jī)上的容器到 etcd 中。我們想注冊(cè)的容器必須暴露一個(gè)端口。容器在不同的主機(jī)上運(yùn)行相同的鏡像是在 etcd 中被分組并將構(gòu)成一個(gè)負(fù)載均衡集群。容器怎樣分組是有點(diǎn)亂的,為這個(gè)演練我已經(jīng)選擇了容器鏡像名字。在一個(gè)真實(shí)的部署中,你可能想通過環(huán)境變量,服務(wù)版本或其他的元數(shù)據(jù)分組。
(當(dāng)前的實(shí)現(xiàn)僅僅支持每個(gè)容器一個(gè)端口并假設(shè)它當(dāng)前是 TCP,沒有理由為什么不能支持多個(gè)端口和類型以及不同的分組屬性)
docker-register 使用 docker-gen連同一個(gè) Python 腳本作為一個(gè)模板。當(dāng)運(yùn)行的時(shí)候,動(dòng)態(tài)的生成一個(gè)腳本,將在 /backends 目錄注冊(cè)每個(gè)容器的 IP 和端口。
docker-gen 關(guān)注監(jiān)控 docker events和調(diào)用在一個(gè)間隔調(diào)用生成腳本來確保 TTLs 始終在最近的日期,如果 docker-register 停止了,注冊(cè)過期。
為了啟動(dòng) docker-register,我們需要傳遞主機(jī)的外部 IP,其他的主機(jī)能訪問它的容器以及你的 etcd 主機(jī)的地址。 為了調(diào)用它的 API,docker-gen 要求訪問 docker daemon,因此我們也綁定掛載 docker 的 unix socket 到容器中。
HOST_IP=$(hostname --all-ip-addresses | awk "{print $1}") ETCD_HOST=w.x.y.z:4001 docker run --name docker-register -d -e HOST_IP=$HOST_IP -e ETCD_HOST=$ETCD_HOST -v /var/run/docker.sock:/var/run/docker.sock -t jwilder/docker-register服務(wù)發(fā)現(xiàn) - docker-discover
服務(wù)發(fā)現(xiàn)被 jwilder/docker-discover 容器處理。 docker-discover 周期性的投票 etcd 并通過監(jiān)聽每個(gè)服務(wù)類型來生成一個(gè) haproxy 配置文件。
比如,容器運(yùn)行 jwilder/whoami 被注冊(cè)在 /backends/whoami/
其他的容器需要調(diào)用 jwilder/whoami 服務(wù),可以發(fā)送請(qǐng)求到 docker bridge IP:8000 或主機(jī) IP:8000。
如果任何的后端服務(wù)宕了,haproxy 健康檢查從池子中移除它并將在一臺(tái)健康的主機(jī)上嘗試請(qǐng)求。這確保后端服務(wù)可以隨著需求被啟動(dòng)和停止,以及處理注冊(cè)信息的不一致同時(shí)確保最小化的客戶端影響。
最后,stats 可以通過在 docker-discover 容器上訪問端口 1936 來查看。
運(yùn)行 docker-discover:
ETCD_HOST=w.x.y.z:4001 docker run -d --net host --name docker-discover -e ETCD_HOST=$ETCD_HOST -p 127.0.0.1:1936:1936 -t jwilder/docker-discover
我們正在使用 --net host 以至于容器使用主機(jī)網(wǎng)絡(luò)棧。當(dāng)這個(gè)容器綁定 8000 端口,它實(shí)際是綁定在主機(jī)的網(wǎng)絡(luò)上。這個(gè)簡化了代理的設(shè)置。
AWS Demo我們將在 4 臺(tái) AWS 主機(jī)上運(yùn)行整套服務(wù):一臺(tái) etcd 主機(jī), 一臺(tái) client 主機(jī) 和 兩臺(tái)后端主機(jī)。后端服務(wù) 是一個(gè)簡單的返回主機(jī)名的 golang HTTP 服務(wù)。
Etcd 主機(jī)首先,我們啟動(dòng) etcd 注冊(cè):
$ hostname --all-ip-addresses | awk "{print $1}" 10.170.71.226 $ docker run -d --name etcd -p 4001:4001 -p 7001:7001 coreos/etcd
我們的 etcd 地址是 10.170.71.226。我們將在其他主機(jī)上使用它。如果我們正在運(yùn)行的是一個(gè)在線環(huán)境,我們可以分配一個(gè) EIP 和 DNS 地址給它使得它更容易配置。
后端主機(jī)下一步,我們?cè)诿颗_(tái)主機(jī)上啟動(dòng)這個(gè)服務(wù)和 docker-register。該服務(wù)被配置成監(jiān)聽容器中的 8000 端口并且我們讓 docker 把它發(fā)布在一臺(tái)主機(jī)上的隨機(jī)端口。
后端主機(jī) 1:
$ docker run -d -p 8000:8000 --name whoami -t jwilder/whoami 736ab83847bb12ffffdd8b09969433f3a02d64d5b0be48f7a5c59a594e3a6a3541 $ docker run --name docker-register -d -e HOST_IP=$(hostname --all-ip-addresses | awk "{print $1}") -e ETCD_HOST=10.170.71.226:4001 -v /var/run/docker.sock:/var/run/docker.sock -t jwilder/docker-register 77a49f732797333ca0c7695c6b590a64a7d75c14b5ffa0f89f8e0e21ae47ae3e $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 736ab83847bb jwilder/whoami:latest /app/http 48 seconds ago Up 47 seconds 0.0.0.0:49153->8000/tcp whoami 77a49f732797 jwilder/docker-register:latest "/bin/sh -c "docker- 28 minutes ago Up 28 minutes docker-register
后端主機(jī) 2:
$ docker run -d -p 8000:8000 --name whoami -t jwilder/whoami 4eb0498e52076275ee0702d80c0d8297813e89d492cdecbd6df9b263a3df1c28 $ docker run --name docker-register -d -e HOST_IP=$(hostname --all-ip-addresses | awk "{print $1}") -e ETCD_HOST=10.170.71.226:4001 -v /var/run/docker.sock:/var/run/docker.sock -t jwilder/docker-register 832e77c83591cb33bba53859153eb91d897f5a278a74d4ec1f66bc9b97deb221 $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4eb0498e5207 jwilder/whoami:latest /app/http 59 seconds ago Up 58 seconds 0.0.0.0:49154->8000/tcp whoami 832e77c83591 jwilder/docker-register:latest "/bin/sh -c "docker- 34 minutes ago Up 34 minutes docker-register客戶端主機(jī)
在客戶端主機(jī),我們需要啟動(dòng) docker-discover 和一個(gè)客戶端服務(wù)。對(duì)于這個(gè)客戶端容器,我使用 Ubuntu Trusty 并將做一些 curl 請(qǐng)求。
首先,啟動(dòng) docker-discover:
$ docker run -d --net host --name docker-discover -e ETCD_HOST=10.170.71.226:4001 -p 127.0.0.1:1936:1936 -t jwilder/docker-discover
然后,啟動(dòng)一個(gè)簡單的客戶端容器并傳給它 HOST_IP。我們正在使用 eth0 地址,但也可以使用 docker0 IP。我們正以一個(gè)環(huán)境變量傳給它因?yàn)樗潜慌渲玫脑趦蓚€(gè)部署之間變化的。
$ docker run -e HOST_IP=$(hostname --all-ip-addresses | awk "{print $1}") -i -t ubuntu:14.04 /bin/bash $ root@2af5f52de069:/# apt-get update && apt-get -y install curl
這時(shí),構(gòu)造一些請(qǐng)求給 whoami 服務(wù)端口 8000 來看他們的負(fù)載。
$ root@2af5f52de069:/# curl $HOST_IP:8000 I"m 4eb0498e5207 $ root@2af5f52de069:/# curl $HOST_IP:8000 I"m 736ab83847bb $ root@2af5f52de069:/# curl $HOST_IP:8000 I"m 4eb0498e5207 $ root@2af5f52de069:/# curl $HOST_IP:8000 I"m 736ab83847bb
我們可以在后端啟動(dòng)一些實(shí)例:
$ docker run -d -p :8000 --name whoami-2 -t jwilder/whoami $ docker run -d -p :8000 --name whoami-3 -t jwilder/whoami $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5d5c12c96192 jwilder/whoami:latest /app/http 3 seconds ago Up 1 seconds 0.0.0.0:49156->8000/tcp whoami-2 bb2a408b8ec5 jwilder/whoami:latest /app/http 21 seconds ago Up 20 seconds 0.0.0.0:49155->8000/tcp whoami-3 4eb0498e5207 jwilder/whoami:latest /app/http 2 minutes ago Up 2 minutes 0.0.0.0:49154->8000/tcp whoami 832e77c83591 jwilder/docker-register:latest "/bin/sh -c "docker- 36 minutes ago Up 36 minutes docker-register
然后再次在客戶端主機(jī)上構(gòu)造一些請(qǐng)求:
$ root@2af5f52de069:/# curl $HOST_IP:8000 I"m 736ab83847bb $ root@2af5f52de069:/# curl $HOST_IP:8000 I"m 4eb0498e5207 $ root@2af5f52de069:/# curl $HOST_IP:8000 I"m bb2a408b8ec5 $ root@2af5f52de069:/# curl $HOST_IP:8000 I"m 5d5c12c96192 $ root@2af5f52de069:/# curl $HOST_IP:8000 I"m 736ab83847bb
最后,我們關(guān)閉一些容器,路由將被更新。這個(gè)殺死在后端 2 的任何東西。
$ docker kill 5d5c12c96192 bb2a408b8ec5 4eb0498e5207 $ root@2af5f52de069:/# curl $HOST_IP:8000 I"m 736ab83847bb $ root@2af5f52de069:/# curl $HOST_IP:8000 I"m 67c3cccbb8ba $ root@2af5f52de069:/# curl $HOST_IP:8000 I"m 736ab83847bb $ root@2af5f52de069:/# curl $HOST_IP:8000 I"m 67c3cccbb8ba
如果你想看 haproxy 是怎樣負(fù)載流量的或監(jiān)控錯(cuò)誤,我們可以在 web 瀏覽器訪問客戶端主機(jī)的 1936 端口。
總結(jié)雖然有不同的方式來實(shí)現(xiàn)服務(wù)發(fā)現(xiàn),SmartStack 的伙伴注冊(cè)行為和代理保持應(yīng)用程序代碼簡單以及非常容易的融合進(jìn)一個(gè)分布式環(huán)境,真的適合 Docker 容器。
同樣地,Docker 的事件和容器 APIs 減輕了服務(wù)注冊(cè)和使用注冊(cè)服務(wù)發(fā)現(xiàn)(比如 etcd)的困難。
docker-register 和 docker-discover 的代碼在 github 上。雖然兩個(gè)都是有用的,但是有很多地方需要提升。請(qǐng)隨時(shí)提交或提出改進(jìn)意見。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/26353.html
摘要:是一個(gè)鍵值存儲(chǔ),用于共享配置以及服務(wù)發(fā)現(xiàn)。對(duì)于我們而言,意味著注冊(cè)進(jìn)程必須考慮到端口映射。這個(gè)方法被用于管理服務(wù)發(fā)現(xiàn)。如果未指定,將被從的端口映射找到意味著,你必須在運(yùn)行的命令中指定它,比如。為了測試取消登記,停止一個(gè)容器將立即從中移除。 注:該文由 adetante 編寫,該文的原文地址為 Service discovery with Docker - 2 該文緊接著上篇文...
摘要:為了動(dòng)態(tài)配置管理,當(dāng)我們啟動(dòng)和停止一個(gè)新容器的時(shí)候,我們想后端能自動(dòng)注冊(cè)進(jìn)負(fù)載均衡器。這是基本需求,叫做服務(wù)發(fā)現(xiàn)我們想負(fù)載均衡器能自動(dòng)發(fā)現(xiàn)提供服務(wù)的容器。一個(gè)團(tuán)隊(duì)開發(fā)的簡單的服務(wù)發(fā)現(xiàn)的工具。服務(wù)發(fā)現(xiàn)目標(biāo)是減少或消除組件之間的手動(dòng)的連接。 注:該文由 adetante 編寫,原文地址為 Service discovery with Docker 這篇博客的第一篇文章,我將寫一篇...
摘要:主要介紹的主要特性和一些經(jīng)驗(yàn)。先從整體上看一下的一些理念和基本架構(gòu),然后從網(wǎng)絡(luò)資源管理存儲(chǔ)服務(wù)發(fā)現(xiàn)負(fù)載均衡高可用安全監(jiān)控等方面向大家簡單介紹的這些主要特性。集群范圍內(nèi)的監(jiān)控主要由和如構(gòu)建。 主要介紹 Kubernetes 的主要特性和一些經(jīng)驗(yàn)。先從整體上看一下Kubernetes的一些理念和基本架構(gòu), 然后從網(wǎng)絡(luò)、 資源管理、存儲(chǔ)、服務(wù)發(fā)現(xiàn)、負(fù)載均衡、高可用、rolling upgra...
摘要:主要介紹的主要特性和一些經(jīng)驗(yàn)。先從整體上看一下的一些理念和基本架構(gòu),然后從網(wǎng)絡(luò)資源管理存儲(chǔ)服務(wù)發(fā)現(xiàn)負(fù)載均衡高可用安全監(jiān)控等方面向大家簡單介紹的這些主要特性。集群范圍內(nèi)的監(jiān)控主要由和如構(gòu)建。 主要介紹 Kubernetes 的主要特性和一些經(jīng)驗(yàn)。先從整體上看一下Kubernetes的一些理念和基本架構(gòu), 然后從網(wǎng)絡(luò)、 資源管理、存儲(chǔ)、服務(wù)發(fā)現(xiàn)、負(fù)載均衡、高可用、rolling upgra...
閱讀 3010·2021-10-13 09:39
閱讀 2706·2021-09-27 13:34
閱讀 2046·2019-08-30 15:55
閱讀 3269·2019-08-30 15:43
閱讀 3650·2019-08-30 11:16
閱讀 1769·2019-08-26 18:28
閱讀 1302·2019-08-26 13:56
閱讀 928·2019-08-26 13:35