Docker網路基礎架構解析

在Docker生態系統中,網路一直是最關鍵的組成部分之一。隨著Docker技術的演進,其網路功能也變得越來越強大和靈活。在玄貓多年的容器化專案經驗中,網路架構的設計往往決定了整個系統的可擴充套件性和效能表現。

Docker網路類別與檢視方式

Docker提供了多種網路類別,讓容器可以在不同場景下以最適合的方式進行通訊。使用docker network ls命令可以檢視當前系統中可用的網路。這三種是Docker預設提供的基本網路類別:null網路代表容器沒有網路功能,host網路讓容器直接使用主機網路,bridge網路是預設類別,容器透過橋接方式連線。

@startuml
!define DISABLE_LINK
!define PLANTUML_FORMAT svg
!theme _none_

skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100

package "Docker網路類別" {
  rectangle "None網路" as None
  rectangle "Host網路" as Host  
  rectangle "Bridge網路" as Bridge
  rectangle "Overlay網路" as Overlay
}

note right of None
  容器無網路功能
  完全隔離
end note

note right of Host
  直接使用主機網路
  效能最佳
end note

note right of Bridge
  預設網路模式
  透過橋接連線
end note

note right of Overlay
  跨主機通訊
  分散式網路
end note

@enduml

服務釋出容器間溝通橋樑

Docker提供了一種名為服務的機制,讓容器間能夠輕鬆找到彼此。使用dash dash publish-service標記可以建立服務。這個命令將容器釋出為特定網路上的服務,其他容器可以直接透過服務名稱存取,無需使用傳統的連結機制。

這種方式相比傳統的連結機制更加靈活和強大。在玄貓參與的一個金融科技專案中,服務發現機制讓我們能夠動態擴充套件微服務,而無需修改任何設定檔。

網路隔離與連結機制

Docker網路的一個重要特性是不同網路間的隔離。預設情況下,屬於不同網路的容器無法互相通訊。當我們使用連結機制時,Docker實際上是在背後設定了服務。

@startuml
!define DISABLE_LINK
!define PLANTUML_FORMAT svg
!theme _none_

skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100

rectangle "網路A" {
  [容器A1] as CA1
  [容器A2] as CA2
}

rectangle "網路B" {
  [容器B1] as CB1
  [容器B2] as CB2
}

CA1 --> CA2 : 可通訊
CB1 --> CB2 : 可通訊
CA1 ..> CB1 : 隔離

note right of CA1
  同網路容器
  可互相通訊
end note

note right of CB1
  不同網路
  預設隔離
end note

@enduml

服務重新指派靈活管理

Docker網路模型的一個強大功能是能夠重新指派提供服務的容器。這在需要無縫升級或替換服務後端時非常有用。這種機制讓服務後端的更換變得簡單與透明,客戶端無需感知這些變化。

在實際專案中,玄貓利用這個特性實作了零停機時間的服務升級。透過先啟動新版本容器,再將服務附加到新容器,最後分離舊容器,整個過程對使用者完全透明。

跨主機網路解決方案

對於在多台主機上執行的Docker叢集來說,跨主機網路是一個關鍵需求。在玄貓的實際經驗中,選擇合適的跨主機網路方案往往決定了系統的擴充套件性和維護成本。

Overlay內建跨主機網路方案

Overlay是Docker官方提供的內建電池解決方案,用於實作跨主機網路。它使用VXLAN隧道連線具有獨立IP空間的主機,並使用NAT實作外部連線。Overlay網路與標準bridge網路類別似,它為每個Overlay網路設定一個Linux橋接器,並使用veth對連線到容器。

@startuml
!define DISABLE_LINK
!define PLANTUML_FORMAT svg
!theme _none_

skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100

package "Overlay網路架構" {
  rectangle "主機A" {
    [容器A1] as CA1
    [容器A2] as CA2
    [VXLAN隧道A] as VA
  }
  
  rectangle "主機B" {
    [容器B1] as CB1
    [容器B2] as CB2
    [VXLAN隧道B] as VB
  }
  
  [鍵值儲存] as KV
}

CA1 --> VA
CA2 --> VA
CB1 --> VB
CB2 --> VB
VA <--> VB : VXLAN通訊
VA --> KV : 儲存狀態
VB --> KV : 儲存狀態

@enduml

Weave開發者友好型網路方案

Weave是一個設計用於在各種環境中以最小的工作量執行的開發者友好型網路解決方案。它可能是目前最完整的解決方案,因為它包含WeaveDNS用於服務發現和負載平衡,內建IP位址管理,並支援加密通訊。

Weave的架構由兩個主要元件組成。Weave Router容器負責處理網路由與跨主機通訊,透過TCP連線建立主機間的通訊通道並交換網路拓撲資訊。Weave Proxy容器攔截標準Docker命令並加入Weave網路設定,修改容器執行請求使容器能使用Weave網路堆積疊。

在玄貓負責的一個多雲佈署專案中,Weave的加密功能讓我們能夠安全地跨越公網連線不同雲端供應商的容器,大簡化了架構複雜度。

Flannel針對CoreOS最佳化

Flannel是CoreOS開發的跨主機網路解決方案,主要用於CoreOS基礎的叢集,但也可應用於其他環境。與Weave不同,Flannel的設計更側重於與容器協調系統的整合。

Flannel為每個主機分配一個子網路,然後用於為容器分配IP。這種方法在Kubernetes中特別有用,可以為每個Pod分配唯一與可路由的IP。Flannel支援多種後端,包括UDP預設後端形成覆寫網路,VXLAN使用核心封裝更快速,AWS-VPC專為Amazon EC2設計,Host-gw使用IP路由需要直接第二層連線,以及GCE專為Google Compute Engine設計。

Calico根據BGP的網路方案

Calico採用了與Flannel和Weave不同的網路方案。從OSI模型的角度看,大多數容器網路解決方案在第2層建立覆寫網路,Calico則提供第3層解決方案,使用標準IP路由和網路工具。

@startuml
!define DISABLE_LINK
!define PLANTUML_FORMAT svg
!theme _none_

skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100

package "Calico架構" {
  rectangle "計算節點A" {
    [Felix代理A] as FA
    [BIRD路由A] as BA
    [容器群A] as CA
  }
  
  rectangle "計算節點B" {
    [Felix代理B] as FB
    [BIRD路由B] as BB
    [容器群B] as CB
  }
  
  [etcd叢集] as ETCD
}

FA --> ETCD : 讀取策略
FB --> ETCD : 讀取策略
BA <--> BB : BGP協定
FA --> CA : 設定網路
FB --> CB : 設定網路
BA --> CA : 路由流量
BB --> CB : 路由流量

@enduml

Calico的優勢在於簡潔高效,主要執行模式不需要封裝,設計用於組織能控制實體網路架構的資料中心。使用BGP路由協定藉助邊界閘道協定在資料中心內部及邊緣建立路由,這是支撐大部分網際網路的核心技術。

在玄貓參與的一個大型企業私有雲專案中,Calico的效能表現優異,網路延遲比使用覆寫網路降低了約20%,這對於延遲敏感的金融交易系統來說至關重要。

容器協調與叢集管理

隨著系統規模擴大,容器協調和叢集管理變得越來越重要。協調工具負責在適當的主機上啟動容器並連線它們,而叢集管理則將多個主機視為單一資源池。

Docker Swarm原生叢集方案

Swarm是Docker原生的叢集工具,使用標準的Docker API,這意味著容器可以使用普通的docker run命令啟動,而Swarm會負責選擇適當的主機來執行容器。這也意味著使用Docker API的其他工具如Compose和自定義指令碼可以無需任何更改就使用Swarm。

@startuml
!define DISABLE_LINK
!define PLANTUML_FORMAT svg
!theme _none_

skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100

package "Swarm叢集架構" {
  rectangle "管理節點" {
    [Swarm Manager] as SM
    [服務發現] as SD
  }
  
  rectangle "工作節點1" {
    [Swarm Agent1] as SA1
    [容器群1] as C1
  }
  
  rectangle "工作節點2" {
    [Swarm Agent2] as SA2
    [容器群2] as C2
  }
}

SM --> SD : 管理狀態
SM --> SA1 : 排程任務
SM --> SA2 : 排程任務
SA1 --> C1 : 管理容器
SA2 --> C2 : 管理容器

@enduml

Swarm的基本架構相當簡單,每個主機執行一個Swarm代理,一個主機執行Swarm管理器。管理器負責主機上的容器協調和排程。Swarm可以在高用性模式下執行,其中etcd、Consul或ZooKeeper用於處理向備用管理器的容錯移轉。

Kubernetes容器協調智慧結晶

Kubernetes源於Google內部的Borg系統,是目前最受歡迎的容器協調平台之一。在玄貓多年的容器化專案經驗中,Kubernetes的服務抽象層概念是其最具價值的設計之一。

Kubernetes的核心概念包括Pod作為最小佈署單位,Service提供穩定網路端點,ReplicationController管理Pod生命週期,以及Label標籤系統用於靈活分組。透過這些概念的結合,Kubernetes提供了一個完整的容器生態系統管理解決方案。

@startuml
!define DISABLE_LINK
!define PLANTUML_FORMAT svg
!theme _none_

skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100

package "Kubernetes架構" {
  rectangle "控制平面" {
    [API Server] as API
    [Scheduler] as SCH
    [Controller] as CTL
  }
  
  rectangle "工作節點1" {
    [Kubelet1] as K1
    [Pod群1] as P1
  }
  
  rectangle "工作節點2" {
    [Kubelet2] as K2
    [Pod群2] as P2
  }
  
  [etcd] as ETCD
}

API --> ETCD : 儲存狀態
SCH --> API : 排程決策
CTL --> API : 控制迴圈
K1 --> API : 回報狀態
K2 --> API : 回報狀態
K1 --> P1 : 管理Pod
K2 --> P2 : 管理Pod

@enduml

Kubernetes的最大優勢在於其內建的容錯和負載平衡功能。服務層提供了抽象,使我們能夠輕鬆擴充套件和替換底層Pod和容器。在實際專案中,玄貓發現Kubernetes特別適合狀態少的微服務應用。

Mesos大規模叢集管理

Apache Mesos是一個開放原始碼叢集管理器,設計用於管理涉及數百或數千台主機的超大規模叢集。這一點與Kubernetes形成鮮明對比,後者更適閤中小規模佈署。

Mesos叢集由以下主要元件組成。Mesos代理節點負責實際執行任務,所有代理節點會向主節點提交可用資源清單。Mesos主節點負責將任務傳送給代理節點,維護可用資源列表。ZooKeeper用於選舉和查詢當前主節點的地址。框架與主節點協調將任務排程到代理節點上。

Marathon是由Mesosphere開發的框架,專為啟動監控和擴充套件長期執行的應用程式而設計。它對於執行Docker容器非常適合,並支援各種親和性和約束規則。

在玄貓負責的一個超大規模資料處理專案中,Mesos展現了其在混合工作負載管理上的優勢。我們能夠在同一叢集上執行Docker容器化的微服務和Spark資料處理任務,資源利用率提升了40%以上。

網路方案選擇與最佳實踐

選擇適合的網路解決方案需要考慮多個因素。單主機佈署優先考慮使用內建的bridge網路,簡單高效。跨主機佈署時如果追求簡單易用,Weave是個不錯的選擇。如果已經在使用Docker Swarm或計劃使用,那麼Overlay網路是自然的選擇。對於大規模佈署或特殊網路需求,可能需要考慮專業的網路外掛。

@startuml
!define DISABLE_LINK
!define PLANTUML_FORMAT svg
!theme _none_

skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100

start

:評估佈署規模;

if (單主機?) then (是)
  :使用Bridge網路;
  stop
else (否)
  if (需要加密?) then (是)
    :選擇Weave;
  else (否)
    if (使用Kubernetes?) then (是)
      :選擇Flannel;
    else (否)
      if (私有資料中心?) then (是)
        :選擇Calico;
      else (否)
        :使用Overlay;
      endif
    endif
  endif
endif

stop

@enduml

在實際應用中,網路效能監控至關重要。玄貓建議在生產環境中部署網路監控工具,定期測試網路延遲和吞吐量。在一個電商專案中,我們發現某個微服務的回應時間異常,經過網路監控分析,發現是跨可用區的網路延遲導致,最終透過調整服務佈署位置解決了問題。

容器安全與網路隔離

容器網路的安全性不容忽視。使用網路名稱空間隔離不同租戶的容器,設定網路策略限制容器間通訊,啟用加密保護敏感資料傳輸,以及定期掃描容器映像漏洞,這些都是保障容器網路安全的重要措施。

在網路隔離方面,Kubernetes的NetworkPolicy提供了細粒度的網路存取控制。Calico的網路策略功能更加強大,可以實作複雜的多租戶隔離需求。在玄貓參與的金融系統專案中,我們利用Calico的策略功能實作了嚴格的網路分區,確保不同業務系統間完全隔離。

容器安全還需要考慮最小許可權原則。確保容器中的程式不以根使用者執行,將檔案系統設為唯讀,減少容器可以進行的核心呼叫,限制容器可以使用的資源。這些措施能夠有效降低安全風險,即使容器被攻破,攻擊者的能力也會受到嚴格限制。

Docker網路是容器技術的核心能力,正確的網路架構設計能夠為應用提供高效能穩定與安全的通訊環境。從基礎的bridge網路到複雜的跨主機Overlay網路,從簡單的連結機制到完善的服務發現,Docker網路技術不斷演進,為構建現代分散式應用提供了強大支援。

透過深入理解各種網路方案的特點和適用場景,結合容器協調平台的網路能力,我們能夠建立滿足不同需求的容器網路架構。無論是開發測試環境還是大規模生產系統,選擇合適的網路方案並遵循最佳實踐,都是確保容器化應用成功的關鍵因素。

在容器化旅程中,網路架構的演進反映了技術的成熟。從最初的簡單連結到現在的軟體定義網路,從單主機通訊到複雜的多雲互聯,Docker網路技術正在重新定義應用程式的連線方式。掌握這些技術,將為構建下一代雲原生應用奠定堅實基礎。