該文章同步發佈於:我的部落格
也歡迎關注我的 Facebook 以及 Instagram 接收軟體相關的資訊!
以及這個 30 天的 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:
$ 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。
首先,在 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 地址,這樣可以減少很多不必要的麻煩。
在這之前,我們還沒有談論過關於容器的 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 的虛擬網路究竟做了一些什麼,以及是如何讓外部的請求進入到容器內部呢?
賣個關子,明天見!