Docker 提供了便捷的介面和工具,簡化容器化應用程式的構建、執行和管理。透過 Dockerfile,開發者可以定義映象的構建過程,並利用 Docker 的快取機制提升構建效率。Docker Compose 則簡化了多容器應用程式的佈署,透過 YAML 檔案定義服務及其依賴關係,實作一鍵啟動和管理。理解 Docker 的網路功能對於構建可擴充套件和可靠的應用至關重要。Docker 提供多種網路模式,包括橋接、主機和無網路模式,滿足不同應用場景的需求。橋接網路是預設模式,提供容器間的隔離和通訊;主機模式則讓容器與主機分享網路堆積疊;無網路模式則完全隔離容器網路。此外,Docker 還支援自定義網路,提供更精細的網路控制。深入理解 Linux 網路名稱空間、橋接、虛擬乙太網路裝置和 iptables 等底層技術,有助於開發者更好地掌握 Docker 網路的工作原理。
Docker介面詳解
Docker 提供了一個強大的介面來管理和操作容器化的應用程式。在本章中,我們將探討 Docker 的介面,包括如何構建、執行和管理容器,以及如何使用 Docker Compose 來簡化多容器應用程式的佈署。
Docker 構建過程
Docker 的構建過程是根據 Dockerfile 的,這是一個包含了一系列指令的文字檔案,用於定義如何構建一個 Docker 映象。當你執行 docker build 命令時,Docker 會按照 Dockerfile 中的指令順序執行,並將每個指令的結果快取起來。這樣,如果你再次執行相同的 docker build 命令,並且 Dockerfile 沒有發生變化,Docker 就不會重新構建任何東西,因為所有的指令都已經被快取了。
Dockerfile 範例
假設我們有一個簡單的 Dockerfile,用於構建一個 MySQL 映象:
FROM mysql:5.7
EXPOSE 3306
CMD /usr/bin/mysqld_safe
當我們執行 docker build 命令時,Docker 會按照以下步驟進行構建:
- 從
mysql:5.7映象建立一個新的容器。 - 暴露 3306 埠。
- 設定預設命令為
/usr/bin/mysqld_safe。
內容解密:
FROM mysql:5.7:使用官方的 MySQL 5.7 映象作為基礎映象。EXPOSE 3306:暴露容器的 3306 埠,允許外部存取 MySQL 服務。CMD /usr/bin/mysqld_safe:設定容器的預設命令,當容器啟動時執行/usr/bin/mysqld_safe命令來啟動 MySQL 服務。
執行 Docker 映象
一旦我們構建好了 Docker 映象,就可以執行它。使用 docker run 命令可以啟動一個新的容器,並執行指定的命令。例如:
docker run -d -p 3306:3306 pkocher/mysql
這個命令會在後台啟動一個新的容器,將容器的 3306 埠對映到主機的 3306 埠,並執行 pkocher/mysql 映象。
內容解密:
-d:以分離模式執行容器,即在後台執行。-p 3306:3306:將容器的 3306 埠對映到主機的 3306 埠。pkocher/mysql:要執行的 Docker 映象名稱。
使用 Docker Compose
Docker Compose 是用於定義和執行多容器 Docker 應用程式的工具。它使用 YAML 檔案來組態應用程式的服務,並允許你使用一個命令來建立和啟動所有服務。
docker-compose.yml 範例
以下是一個簡單的 docker-compose.yml 檔案,用於定義一個包含 Tomcat 和 MySQL 的應用程式:
version: '2'
services:
tomcat:
image: 'tomcat:7'
container_name: appserver
ports:
- '8080:80'
depends_on:
- db
db:
image: 'mysql:5.7'
container_name: dbserver
ports:
- '3306:3306'
environment:
- MYSQL_ROOT_PASSWORD=sample
- MYSQL_DATABASE=helpdesk
- MYSQL_USER=helpdesk
- MYSQL_PASSWORD=helpdesk
這個檔案定義了兩個服務:Tomcat 和 MySQL。Tomcat 服務依賴於 MySQL 服務,因此 Docker Compose 會先啟動 MySQL 服務,然後再啟動 Tomcat 服務。
內容解密:
version: '2':指定 Docker Compose 檔案的版本。services:定義應用程式的服務。tomcat和db:定義兩個服務:Tomcat 和 MySQL。image:指定服務使用的 Docker 映象。container_name:指定容器的名稱。ports:將容器的埠對映到主機的埠。depends_on:指定服務之間的依賴關係。environment:設定環境變數。
第8章:容器網路
在前面的章節中,我們學習了容器的基礎知識以及 Docker 如何將容器提升到新的高度。但是,單純地啟動容器並不能滿足需求:容器之間需要相互通訊,並且需要設計與外部世界的連線,作為佈署的一部分。在本章中,我們將討論和學習容器世界中的網路選項。首先,讓我們回顧一些基本的 Linux 概念,這些概念將有助於我們對容器網路的討論。
關鍵的 Linux 概念
容器是自包含且隔離的虛擬環境。它們可以執行整個應用程式或應用程式的一部分。在任何一種情況下,連線都是關鍵需求之一。
我們一直在使用客戶端連線到我們的容器,但我們需要的是全域連線。我們需要在主機內、跨多個主機之間以及跨多個資料中心之間實作容器之間的連線——也就是說,我們需要建立自己的網路。Docker 使用 Linux 網路和核心功能來提供這種能力。
我們不會深入討論 Linux 的基礎知識,但您需要了解一些關鍵的 Linux 網路概念,以便理解 Docker 網路:
- Linux 網路名稱空間:通常,Linux 安裝會提供一套標準的網路介面和路由表項。這套組態被整個作業系統使用,以實作路由和網路功能。可以將網路名稱空間視為一個具有自己的網路介面和路由表項的網路堆積疊,它們在隔離狀態下運作。Docker 使用網路名稱空間的功能來隔離容器並提供安全性。您可以建立多個網路名稱空間,從而能夠以隔離方式執行每個容器,使它們無法與同一主機上的其他容器通訊,直到管理員進行組態。主機有其自己的名稱空間,其中包含主機介面和路由表。
- Linux 網橋:這是 Linux 核心模組的一部分,能夠實作 Linux 網路功能。可以將其視為一個第2層虛擬交換器,它還可以進行過濾。它根據動態學習的 MAC 位址表進行轉發決策。
- Linux 虛擬乙太網裝置:也被稱為 veth(虛擬乙太網)裝置,這些介面連線了網路名稱空間。我們可以在網路名稱空間堆積疊上建立多個條目,並組態 veth 以建立連線。可以將其視為連線網路名稱空間彼此以及與外部網路的管道。
- Linux iptables:iptables 是 Linux 核心的一部分,為作業系統提供封包過濾和防火牆功能。您可以定義策略和一系列策略,以允許或阻止流量。Docker 利用此功能來區分容器之間的流量、實作埠對映(將容器埠繫結到主機埠)等。
既然我們已經概述了 Linux 網路功能,接下來讓我們討論容器中的連線型別,從最簡單的「連結」開始。
連結
在 Docker 發布先進的網路功能之前(稍後會討論),連線兩個或多個容器的最簡單方法是「連結」容器。現在已被棄用的 --link 旗標允許容器發現並保護連線,以便在容器之間傳輸資訊。這種技術更多是一種通用的實作連線的方式,而不是真正的根據埠的網路方法。它是透過分享環境變數和 /etc/hosts 檔案條目來實作的,這些條目由 Docker 引擎自動建立,以便連線容器。
例如,讓我們啟動 Tomcat 應用伺服器和 MySQL 資料函式庫,並在它們之間建立連線。這兩個容器應該能夠相互互動。首先,讓我們透過執行以下命令來取得最新的 Tomcat 映像:
docker pull tomcat
接下來,我們啟動 Tomcat 容器,並將其命名為 tomcatContainer:
docker run -d --name tomcatContainer tomcat
為了確保我們的容器正在執行,我們使用:
docker ps
內容解密:
此命令用於檢查目前正在執行的 Docker 容器的狀態。它會列出所有正在執行的容器,包括其 ID、映像名稱、建立時間、狀態、埠對映和名稱等資訊。在此範例中,我們確認 tomcatContainer 正在執行。
現在,讓我們啟動 MySQL 容器,並使用 --link 旗標將其與 Tomcat 容器連結:
docker run --link tomcatContainer:tomcat --name sqlcontainer -e MYSQL_ROOT_PASSWORD=password -d mysql
內容解密:
此命令啟動一個新的 MySQL 容器,並將其與之前建立的 tomcatContainer 連結。 --link 選項允許兩個容器之間進行通訊,透過在 MySQL 容器的 /etc/hosts 檔案中新增一個條目指向 tomcatContainer 。 -e MYSQL_ROOT_PASSWORD=password 設定了 MySQL 的 root 使用者密碼。 -d 選項讓 MySQL 容器在背景執行。
@startuml
skinparam backgroundColor #FEFEFE
skinparam defaultTextAlignment center
skinparam rectangleBackgroundColor #F5F5F5
skinparam rectangleBorderColor #333333
skinparam arrowColor #333333
title 內容解密:
rectangle "內容解密:" as n1
rectangle "實作" as n2
rectangle "應用" as n3
n1 --> n2
n2 --> n3
@enduml
此圖示展示了 Tomcat 容器與 MySQL 容器之間的連結關係。兩個容器透過 Docker 的 --link 功能相互連線,實作了彼此之間的通訊。
容器網路連線
在 Docker 中,容器之間的網路連線是透過不同的網路模式來實作的。本章將探討 Docker 的網路功能,包括連結容器、預設網路選項等。
連結容器
在早期的 Docker 版本中,容器之間的連線是透過 --link 引數來實作的。例如,我們可以建立一個 Tomcat 容器和一個 MySQL 容器,並使用 --link 將它們連線起來。
docker run --name tomcatContainer -d tomcat
docker run --link tomcatContainer:tomcat --name sqlcontainer -e MYSQL_ROOT_PASSWORD=password -d mysql
內容解密:
docker run --name tomcatContainer -d tomcat:建立一個名為tomcatContainer的 Tomcat 容器,並在背景執行。docker run --link tomcatContainer:tomcat --name sqlcontainer -e MYSQL_ROOT_PASSWORD=password -d mysql:建立一個名為sqlcontainer的 MySQL 容器,並將其與tomcatContainer連線起來。-e MYSQL_ROOT_PASSWORD=password設定 MySQL 的 root 密碼。
連線建立後,我們可以進入 MySQL 容器檢查 /etc/hosts 檔案,確認 Tomcat 容器的 IP 位址是否正確記錄。
docker exec -it sqlcontainer /bin/bash
cat /etc/hosts
內容解密:
docker exec -it sqlcontainer /bin/bash:進入sqlcontainer容器的互動式終端。cat /etc/hosts:檢視/etc/hosts檔案內容,確認 Tomcat 容器的 IP 位址。
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2 tomcat 90d4a06e190e tomcatContainer
172.17.0.3 f864f6e4150f
透過檢查 /etc/hosts 檔案,我們可以看到 Tomcat 容器的 IP 位址(172.17.0.2)已經正確記錄。
驗證 IP 位址
為了驗證 Tomcat 容器的 IP 位址,我們可以使用 docker inspect 命令。
docker inspect tomcatContainer | grep IP
內容解密:
docker inspect tomcatContainer:檢視tomcatContainer容器的詳細資訊。grep IP:過濾出包含 “IP” 的行。
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
結果顯示 Tomcat 容器的 IP 位址確實是 172.17.0.2,與 /etc/hosts 檔案中的記錄一致。
測試連線
現在,我們可以測試 MySQL 容器是否能夠 ping 通 Tomcat 容器。
ping 172.17.0.2
內容解密:
ping 172.17.0.2:從 MySQL 容器 ping Tomcat 容器的 IP 位址。
PING 172.17.0.2 (172.17.0.2): 56 data bytes
64 bytes from 172.17.0.2: icmp_seq=0 ttl=64 time=0.190 ms
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.109 ms
...
結果顯示 MySQL 容器能夠成功 ping 通 Tomcat 容器,證明兩個容器之間的連線是正常的。
預設網路選項
由於 --link 引數已經被棄用,Docker 提供了三種預設的網路選項:none、host 和 bridge。我們可以使用 docker network ls 命令列出這些網路。
docker network ls
內容解密:
docker network ls:列出 Docker 中的網路。
NETWORK ID NAME DRIVER SCOPE
fe3118460998 bridge bridge local
4a8e216f9a47 host host local
1bb6d94233c0 none null local
None 網路
None 網路是最簡單的網路選項,它基本上意味著沒有網路。容器不會被分配 IP 位址,也無法與其他容器或外部網路連線。
docker run -it --network=none tomcat /bin/bash
docker inspect <container_id> | grep IP
內容解密:
docker run -it --network=none tomcat /bin/bash:建立一個 Tomcat 容器,並指定使用 none 網路。docker inspect <container_id> | grep IP:檢視容器的 IP 位址。
結果顯示該容器的 IP 位址為空,證明它沒有被分配 IP 位址。
Host 網路
Host 網路將容器新增到主機的網路名稱空間中,使容器與主機分享相同的網路介面。
docker run --network=host -d centos
內容解密:
docker run --network=host -d centos:建立一個 CentOS 容器,並指定使用 host 網路。
在 host 網路模式下,容器可以使用主機的所有網路介面,但需要注意的是,這種模式下不能使用埠對映,因為容器和主機分享相同的網路名稱空間。
容器網路深入解析
容器網路是現代軟體開發與佈署的核心技術之一。Docker 提供多種網路模式,以滿足不同應用場景的需求。本章將探討 Docker 的預設網路選項、橋接網路、自定義網路等關鍵概念,並透過例項演示其工作原理。
預設網路模式解析
Docker 提供三種預設網路模式:bridge、host 和 none。其中,bridge 是預設的網路模式,為容器提供一個獨立的網路名稱空間,使其能夠與其他容器進行通訊。
橋接網路(Bridge)詳解
橋接網路是 Docker 的預設網路模式。它建立一個內部的私有網路,讓容器之間可以互相通訊。需要注意的是,這種模式下分配給容器的 IP 位址無法從主機外部直接存取,除非透過埠對映來實作外部存取。
docker network inspect bridge
執行上述命令,可以檢視 bridge 網路的詳細組態資訊,包括子網路、閘道器等關鍵設定。
容器間通訊例項
首先,啟動兩個容器,分別指定 bridge 網路和預設網路:
docker run -d --network=bridge mysql
docker run -d --network=default tomcat
再次執行 docker network inspect bridge 命令,可以觀察到兩個容器都已連線到 bridge 網路,並分配了各自的 IP 位址。
"Containers": {
"04c7ae5a7e73b249b729b2927244122b82e114d45e63291a260847ca8634ad48": {
"Name": "wonderful_kalam",
"EndpointID": "30ad3accb403119dc09ae38207fdb1aa44e9f13647df980ce349181e2d2b01f7",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/16",
"IPv6Address": ""
},
"3c056870b9a7db53de33914a12edb65415e5e14fd26c8916d629d8439e47d928": {
"Name": "blissful_babbage",
"EndpointID": "1d365a32d1aea32e3e00d35e4d074f1cf8d293006dd88b3320010272920c5ae0",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
}
}
驗證容器間連通性
進入任意一個容器,使用 ifconfig 命令檢視其網路組態,並嘗試 ping 另一個容器的 IP 位址,以驗證它們之間的連通性。
自定義網路的高階應用
除了預設的網路模式,Docker 還允許使用者建立自定義網路,以滿足更複雜的網路需求。自定義網路提供了更大的靈活性與控制能力,使容器之間的通訊更加安全和高效。
建立自定義網路
docker network create --driver bridge my_custom_network
透過上述命令,可以建立一個名為 my_custom_network 的自定義橋接網路。
網路組態背後的技術原理
Docker 利用 Linux 的底層網路技術實作容器之間的通訊。在橋接網路模式下,Docker 會在主機上建立一個虛擬橋接器(通常命名為 docker0),並將所有使用 bridge 網路的容器連線到這個橋接器上。這樣,容器之間就可以像在同一區域網內一樣進行通訊。
結語
本章探討了 Docker 的網路功能,從預設的 bridge 網路到自定義網路,詳細介紹了容器間通訊的實作機制。透過理解這些核心概念,開發者可以更好地設計和實施根據容器的應用架構,為現代軟體開發提供堅實的基礎設施支援。