由於service consumer跟provider之間網路連結是透過hardcode的, 因此service consumer要切換provider往往不太容易。若用ambassador來切換provider,只需重啟ambassador並連接至新的provider
關係由原本的 (consumer) -> (provider) 變成 (consumer) -> (ambassador) -> (provider)
想像一下,假如今天有n個consumers, 未使用ambassador,你需要重啟每個consumers。若使用ambassador,你只需要重啟一個ambassador。
這邊你可能會想,用dns來解決這問題不就好,何必用ambassador呢?但如果是連到不同port的service呢?(哈,該不會說手動用iptables來導吧XD)
- 原本的ambassador跟service provider的關係是一對一
- Omni mode讓ambassador跟service provider的關係變成一對多
host$ docker run -d -v /var/run/docker.sock:/var/run/docker.sock --name backends progrium/ambassadord --omnimode
首先把host的docker socket(/var/run/docker.sock
) mount到backends container上的相同位置,backends container會expose port 10000,
然而我們希望把所有連接到backends container的ports都導向port 10000,所以可以啟動一個新的container來做這件事 (也可以透過nsenter
來做, 請看[using nsenter
to perform port forwarding])
host$ docker run --rm --privileged --net container:backends progrium/ambassadord --setup-iptables
- 由於docker不允許container修改另一個container的network設定,因此需要指定
--privileged
, 讓container有權限可以修改另一個container的network設定 --net container:backends
是讓container使用跟backends container相同的ip與port,意味著loopback interface--setup-iptables
的實際指令是iptables -t nat -A PREROUTING -p tcp -j REDIRECT --to-ports 10000
用nsenter讓所有連接到backends container的ports都導向port 10000
host$ sudo docker-enter backends
backends$ iptables -t nat -A PREROUTING -p tcp -j REDIRECT --to-ports 10000
ambassadord裡面是用go-dockerclient連接到本機的docker socket, 來做provider container的lookup
個人的一點小心得,如果有錯的地方還麻煩各位指正 >"<