Website logo

Robert Chang

技術部落格

Docker - 網路世界 ( 上 )

在前幾天我們學到如何進入容器內部,也算是對容器有了一些瞭解。

但是這樣子似乎和串連成為一個服務還有很大的距離,我們想像中最基本的 Web 應用程式應該會有一個 Web Server ( Nginx, Apache, Traefik… ),App Server ( Ruby on Rails, Laravel, Django … ) 再搭配資料庫 ( PostgreSQL, MySQL, SQLite… ) 之類的。

能夠將這些服務串連在一起也是 Docker 如此強大的原因,可以透過 Docker 虛擬網路將容器們串連在一起,或者將它們串連到非 Docker 的服務上。

Docker 的容器或是服務本身不需要知道自己是不是被部署在 Docker 上,也不需要確認對方是不是也在 Docker 上。無論你的主機是運行在 Linux、Windows 或是兩者混合,都可以用一個超脫作業系統框架的方式來管理它們。

接下來的內容講述了一些基本的 Docker 網路概念,為了後面 Docker Compose 章節以及部署 Web 應用程式做足準備。

檢查容器的 Port

首先我們可以透過以下指令來確認容器本身及本機對應的 port:

$ docker container run --detach --publish 80:80 --name nginx nginx # 不換行
4de98848ecca383e48ca8a02ec767... # 先啟動一個 nginx 的服務

$ docker container port nginx
80/tcp -> 0.0.0.0:80

看到回應中,左邊是容器本身開啟的 port 而右邊則是對應到本機的 port。

首先關於容器應該要打開什麼 port 則會等到介紹映像檔的時候做解說,因為每一個不同的服務預設打開的 port 都是不一樣的,這邊我們先專注在右邊本機開啟的 port。

0.0.0.0 以及 127.0.0.1 在 Docker 有什麼不同?

首先,在 Docker 的回應中有看到 0.0.0.0:80,這是因為我們沒有預設 IP 位置,Docker 則會默認為 0.0.0.0。

這可能會和一般我們在開發常常使用的 127.0.0.1 ( localhost ) 不太一樣,那這個 0.0.0.0 代表的是什麼呢?

在 Docker 中,127.0.0.1 意味著 這個容器本身,而不是 這台機器

如果你從一個容器向外連接到 127.0.0.1,對於容器來說,它就像是連接到自己一樣,這樣的問題常常發生在之後 Docker Compose 的使用,當容器需要互相溝通的時候,卻不小心綁定在 127.0.0.1,將沒辦法向外部連接。

而 0.0.0.0 本身意味著所有的網路接口,它將接受來自其他容器的連接,以及外部的連接都能成功到達容器內部。

不論是現在或是以後使用 Docker,除非有特殊情境,不然我們都是預設綁定到 0.0.0.0 的 IP 地址,這樣可以減少很多不必要的麻煩。

Docker 會隨機分配容器的 IP 位置?

在這之前,還沒有談論過關於容器的 IP 位置,你或許會認為容器一直以相同的 IP 位置在主機上存活,但事實完全相反,我們可以透過以下指令來看到容器的 IP 位置:

$ docker container inspect --format '{{ .NetworkSettings.IPAddress }}' nginx # 不換行
172.17.0.2

接著可以透過以下指令來查看本機的 IP 位置:

$ ifconfig en0
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMP...
options=400<CHANNEL_IO>
ether 8c:85:90:11:17:bd
inet6 fe80::1c63:5f4c:ca77:69cc%en0 prefixlen 64 secue..
inet 192.168.1.101 netmask 0xffffff00 broadcast 192.168.1.255
....

上圖中的 inet 192.168.1.101 就是我們本機的 IP 位置,但這似乎和我們啟動的 nginx 服務 IP 位置不相同呀。

可見 Docker 的容器和我們本機並不在同一個網路內,這是什麼情況呢?那就得先從電腦的防火牆說起了。

結語

明天將從防火牆的概念開始介紹 Docker 的虛擬網路究竟做了一些什麼,以及是如何讓外部的請求進入到容器內部呢?

稍微賣個關子!

上一篇文章Docker - 深入了解 Container 內部 ( 下 )

下一篇文章Docker - 網路世界 ( 下 )