前言

現在對於Docker容器的隔離性都有所瞭解了,但對容器IP地址的分配、容器間的訪問等還是有點小疑問,如果容器的IP由於新啟動導致變動,那又怎麼才能保證原有業務不會被影響,這就和網路有掛鉤了,接下來就大概說說。

正文

1. Docker網路模式簡介

當Docker程序啟動時,會在主機上建立一個名為docker0的虛擬網橋,此主機上啟動的Docker容器預設會連線到這個虛擬網橋上。這樣所有容器通過這個虛擬網橋就打通了,所以這裡的docker0工作方式和物理交換機很像。

在主機上可以執行命令ip link show docker0檢視:

Docker在啟動容器時可以指定網路模式,如果不指定,預設就是採用Bridge模式;Docker的網路模式有如下幾種:

  • Bridge(橋接)模式:預設的網路模式,比較適用於在同一Docker Daemon主機上執行的容器,使用者也可以自定義bridge網路,優於預設的bridge網路;如果需要不同Docker主機進行通訊,可以通過作業系統網路配置,也可以使用Overlay模式。
  • Host模式:和宿主機共用一個Network Namespace。即容器不會虛擬出自己的網絡卡和配置自己的IP等,而是使用宿主機的IP和埠;
  • Overlay模式:覆蓋網路可以將多個 Docker Daemon主機連線在一起,並使 swarm 服務能夠相互通訊;也可以讓Docker Daemon主機上的兩個獨立容器進行通訊。
  • Macvlan模式:Macvlan 網路允許為容器分配 MAC 地址,使其在網路上顯示為物理裝置。Docker Deamon通過容器的 MAC 地址將流量路由到容器。
  • None模式:Docker容器擁有自己的Network Namespace,但是並不為容器進行任何網路配置。即容器沒有網絡卡、IP、路由等資訊。需要單獨為Docker容器新增網絡卡、配置IP

Docker在啟動容器的時候可以通過--net指定網路模式,不指定,預設就是bridge模式,如下:

# --net指定網路模式,這裡指定為host模式
docker run -d --name testnet --net host nginx
# 通過docker inspect 容器 看網路細節,如下圖
docker inspect testnet

2. Bridge預設模式瞭解一下

這裡就以預設的Bridge(橋接)展開來說說,其他模式後續根據應用場景再具體細說。

這裡主要看看主機和容器之間的網路、容器和容器之間的網路。

在Bridge模式下,當啟動容器時,Docker會分配一個IP給容器,並設定docker0的IP地址為容器的預設閘道器;這個時候會在主機上建立一對虛擬網絡卡veth pair裝置介面,Docker將veth pair裝置的一端配置在新啟動的容器中,並命名為eth0@ifxxx(容器的網絡卡),另一端在主機中以veth***@ifxxx這樣類似的名字命名,並將這個網路裝置加入到docker0網橋中。

容器沒有啟動時主機的網路配置如下:

當啟動容器時,Docker主機就會建立一對虛擬網絡卡vethpair裝置介面,如下:

可以進入到容器看看IP分配情況,如果ip addr命令在容器內找不到,那是因為基礎映象只包含核心命令,如果要執行其他命令,需要額外安裝。可以在容器內執行如下命令進行安裝。

apt update && apt install -y iproute2

安裝好之後,就可以檢視容器內的IP情況了,如下:

這裡有沒有發現容器內的IP是和主機多出來的虛擬網絡卡是成對出現,這樣主機網路和容器之間肯定能通;

當然容器內部也可以ping通主機。

那容器之間能不能訪問呢?

容器內ping命令也找不到,需要進行安裝,執行如下命令:

apt update && install iputils-ping

這裡新啟動一個容器mynginx2,IP內部分配如下:

mynginx容器內能ping通mynginx2,那是因為兩個容器之間共用了docker0,通過docker0進行轉發

大概一個網路流程如下:

這裡的Docker0就好比是交換機,形成了網路橋樑。

3. 如何能通過容器名進行訪問

預設情況,容器間的訪問只能通過IP,不能通過容器名訪問;

這種情況對於線上專案很不靈活,比如資料庫備份需要臨時遷移,IP可能會不一樣,所以專案中的地址要重新配置,如果能通過容器名訪問,那麼就不用操心更換啦,只要容器名一樣即可,就好比域名和IP的關係一樣,IP再怎麼變,域名不變就行。

3.1 通過--link方式;

新啟動一個容器mynginx3,如下:

# 通過--link關聯 mynginx容器
docker run -d --name mynginx3 --link mynginx nginx

容器啟動之後,可以進入到容器測試:

# 進入容器
docker exec -it mynginx3 /bin/bash
# 安裝ping工具
apt update && apt install iputils-ping

內部原理其實是在mynginx3內部做了個對映配置,容器mynginx3的hosts內容如下:

這樣只能在容器mynginx3內部通過mynginx容器名ping通,不能在mynginx內部通過容器名mynginx3訪問,如果要達到同樣的效果,就得在啟動mynginx時通過--link和mynginx3關聯起來。

如果每個容器都這樣的顯示指定的話,感覺就有點麻煩啦,通常的做法都是通過自定義網路方式來達到這個目的。

3.2 通過自定義網路方式;

首先新建立一個網路,如下:

命令解析:

# --driver 指定網路模式,這裡為bridge橋接模式
# --subnet 指定子網IP 192.168.0.0/16
# --gateway 指定閘道器 192.168.0.1
# my-net 建立的網路名
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 my-net
# 顯示網路
docker network ls

讓啟動的容器使用自定義的網路,即在啟動容器時使用--net指定即可:

啟動容器時不需要--link,只需要接入到自定義網路就可以通過容器名ping通了,如下:

自定義網路之所以能通過容器名ping通,那是容器內運行了一個本地DNS解析器,該解析器將請求轉發到Docker內部DNS伺服器當中,DNS伺服器中記錄了容器啟動時通過--name或--net-alias引數指定的名稱與容器之間的關係

另外還有一個點,現在分配給容器的IP是按照預先設定的子網範圍進行分配的,而不是預設的docker0子網範圍,執行如下命令看詳細:

# 看容器詳細資訊
docker inspect testmynetnginx1

總結

關於Docker網路簡單先說這麼多,後續根據實際應用場景再好好細說,這裡主要的目的是瞭解一下預設的網路模式和自定義網路方式的使用和解決的問題。

Docker之前文章目錄:

  1. Docker小白到實戰之開篇概述
  2. Docker小白到實戰之常用命令演示,通俗易懂
  3. Docker小白到實戰之容器資料卷,整理的明明白白
  4. Docker小白到實戰之Dockerfile解析及實戰演示,果然順手

到目前為止,一般的Docker使用沒問題了,但當容器比較多時,一個一個的拉取映象和啟動容器就顯得有點不方便了,所以下次我們來學學Docker Compose,關注“Code綜藝圈”,和我一起學習吧;