鏡像倉庫保存了所有容器的啟動鏡像,當面對大規模容器集群(1000 節點)時,由于所有的鏡像都需要從鏡像倉庫下載,鏡像倉庫往往會成為性能的瓶頸,幾年前,在筆者之前的工作環境中曾經遇到一次生産環境擴容2000個副本的場景,結果用了2個多小時才完成,等到擴容完成,業務的高峰期已經過去了。
臨時的解決方案是通過部署多個鏡像倉庫,然後通過劃分區域,将一部分主機節點使用的鏡像源指定到特定的鏡像倉庫(修改域名解析),從而分攤流量,并将兩個鏡像倉庫做同步,保持兩個鏡像倉庫數據一緻。
這種方案能夠很好解決中型的容器集群,但如果是大規模集群,就需要維護很多套鏡像倉庫。而且需要配置很多主機的域名解析,維護主機和域名解析的關系,很不靈活。多個鏡像倉庫之間還需要保持數據的一緻性,這些都需要花費很多的運維成本。那麼有沒有一種更加快速高效的鏡像分發技術呢?想必每個人都用過迅雷或者電驢之類的P2P下載技術,它的本質原理就是通過将每個下載節點也作為數據的服務節點,提供下載文件的能力,從而快速的分發文件,避免單點瓶頸。在這個技術背景下,開源社區有兩個相對成熟的項目,阿裡的Dragonfly(蜻蜓)以及Uber的Kraken(海怪)。
Dragonfly 是一款基于 P2P 的智能鏡像和文件分發工具。借助P2P分發技術提高文件傳輸的效率和速率,最大限度地利用網絡帶寬,尤其是在分發大量數據時,例如應用分發、緩存分發、日志分發和鏡像分發。
Dragonfly 是一種無侵入式的解決方案,并不需要修改Docker的源代碼。下圖展現了Dragonfly整個架構圖,在每個節點上面會啟動一個dfdaemon和dfget,dfdaemon是一個代理程序,它會截獲dockerd上傳或者下載鏡像的請求,dfget是一個下載客戶端工具,每個dfget啟動後首先通過“/peer/registry”接口将自己注冊到supernode。supernode超級節點以被動CDN的方式産生種子數據塊并調度數據塊分布。
當dockerd拉取鏡像分層的時候,dfdaemon通過dfget請求supernode下載數據,supernode會從最終的鏡像倉庫拉取鏡像分割成多個數據塊。dfdaemon下載數據塊并對外共享數據塊,後續如果有其它節點也需要下載該鏡像,那麼會直接從之前的節點的節點下載,避免将所以請求都轉發到鏡像倉庫。
,