docker容器網路

来源:https://www.cnblogs.com/Their-own/archive/2022/08/09/16567590.html
-Advertisement-
Play Games

docker容器網路 容器的四種網路模式 | 網路模式 | 配置 | 說明 | | : | : | : | | host | --network host | 容器和宿主機共用Network namespace | | container | --network container:NAME_OR_ ...


docker容器網路

目錄

容器的四種網路模式

網路模式 配置 說明
host --network host 容器和宿主機共用Network namespace
container --network container:NAME_OR_ID 容器和另外一個容器共用Network namespace
none --network none 容器有獨立的Network namespace, 但並沒有對其進行任何網路設置, 如分配veth pair 和網橋連接,配置IP等
bridge --network bridge 預設模式

image

bridge模式

當Docker進程啟動時,會在主機上創建一個名為docker0的虛擬網橋,此主機上啟動的Docker容器會連接到這個虛擬網橋上。虛擬網橋的工作方式和物理交換機類似,這樣主機上的所有容器就通過交換機連在了一個二層網路中。

從docker0子網中分配一個IP給容器使用,並設置docker0的IP地址為容器的預設網關。在主機上創建一對虛擬網卡veth pair設備,Docker將veth pair設備的一端放在新創建的容器中,並命名為eth0(容器的網卡),另一端放在主機中,以vethxxx這樣類似的名字命名,並將這個網路設備加入到docker0網橋中。可以通過brctl show命令查看。

bridge模式是docker的預設網路模式,不寫--network參數,就是bridge模式。使用docker run -p時,docker實際是在iptables做了DNAT規則,實現埠轉發功能。可以使用iptables -t nat -vnL查看。

//查看bridge網路的詳細配置
[root@localhost ~]# docker network inspect bridge
[
    {
        "Name": "bridge",
        "Id": "7745119b7bcae42a77fa0b69cb73ec6abc0a31e552602cf026e7c91940bcdeb3",
        "Created": "2022-08-09T19:33:15.212537879+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]

bridge模式如下圖所示:

img

Docker網橋是宿主機虛擬出來的,並不是真實存在的網路設備,外部網路是無法定址到的,這也意味著外部網路無法通過直接Container-IP訪問到容器。如果容器希望外部訪問能夠訪問到,可以通過映射容器埠到宿主主機(埠映射),即docker run創建容器時候通過 -p 或 -P 參數來啟用,訪問容器的時候就通過[宿主機IP]:[容器埠]訪問容器。

container模式

這個模式指定新創建的容器和已經存在的一個容器共用一個 Network Namespace,而不是和宿主機共用。新創建的容器不會創建自己的網卡,配置自己的 IP,而是和一個指定的容器共用 IP、埠範圍等。同樣,兩個容器除了網路方面,其他的如文件系統、進程列表等還是隔離的。兩個容器的進程可以通過 lo 網卡設備通信。

container模式如下圖所示:

img

host模式

如果啟動容器的時候使用host模式,那麼這個容器將不會獲得一個獨立的Network Namespace,而是和宿主機共用一個Network Namespace。容器將不會虛擬出自己的網卡,配置自己的IP等,而是使用宿主機的IP和埠。但是,容器的其他方面,如文件系統、進程列表等還是和宿主機隔離的。

使用host模式的容器可以直接使用宿主機的IP地址與外界通信,容器內部的服務埠也可以使用宿主機的埠,不需要進行NAT,host最大的優勢就是網路性能比較好,但是docker host上已經使用的埠就不能再用了,網路的隔離性不好。

Host模式如下圖所示:

img

none模式

使用none模式,Docker容器擁有自己的Network Namespace,但是,並不為Docker容器進行任何網路配置。也就是說,這個Docker容器沒有網卡、IP、路由等信息。需要我們自己為Docker容器添加網卡、配置IP等。

這種網路模式下容器只有lo迴環網路,沒有其他網卡。none模式可以在容器創建時通過--network none來指定。這種類型的網路沒有辦法聯網,封閉的網路能很好的保證容器的安全性。

應用場景:

  • 啟動一個容器處理數據,比如轉換數據格式
  • 一些後臺的計算和處理任務

none模式如下圖所示:

img

容器的四種網路模式配置

bridge模式配置

[root@localhost ~]# docker run -it --name t1 --rm busybox		//-rm 退出後刪除
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02  
          inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:11 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:1042 (1.0 KiB)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

/ # exit			//退出
[root@localhost ~]# docker container ls -a
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

//在創建容器時添加--network bridge與不加--network選項效果是一致的
[root@localhost ~]# docker run -it --name t1 --network bridge --rm busybox
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02  
          inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:736 (736.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

/ # exit

none模式配置

[root@localhost ~]# docker run -it --name t1 --network none --rm busybox
/ # ifconfig -a
lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

/ # exit

container模式配置

啟動第一個容器

[root@localhost ~]# docker run -it --name b1 --rm busybox
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:02  
          inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:736 (736.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

啟動第二個容器

[root@localhost ~]# docker run -it --name b2 --rm busybox
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:03  
          inet addr:172.17.0.3  Bcast:172.17.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:6 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:516 (516.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

可以看到名為b2的容器IP地址與第一個容器的IP地址不是一樣的,也就是說並沒有共用網路,此時如果我們將第二個容器的啟動方式改變一下,就可以使名為b2的容器IP與B1容器IP一致,也即共用IP,但不共用文件系統。

在b1容器上創建一個目錄

/ # mkdir /tmp/data
/ # ls /tmp/
data
/ # 

到b2容器上檢查/tmp目錄會發現並沒有這個目錄,因為文件系統是處於隔離狀態,僅僅是共用了網路而已。

在b2容器上部署一個站點

/ # ls /tmp/
/ # 

//創建一個站點
/ # echo 'hello world' > /tmp/index.html
/ # ls /tmp/
index.html
/ # httpd -h /tmp
/ # netstat -anlt
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       
tcp        0      0 :::80                   :::*                    LISTEN      

在b1容器上用本地地址去訪問此站點

/ # wget -O - -q 127.0.0.1:80	//沒有共用是無法訪問b2上的網站 //127.0.0.1只能在本機上才能訪問
wget: can't connect to remote host (127.0.0.1): Connection refused

//在b2上訪問
/ # wget -O - -q 127.0.0.1:80
hello world

由此可見,container模式下的容器間關係就相當於一臺主機上的兩個不同進程

host模式配置

啟動容器時直接指明模式為host

[root@localhost ~]# docker run -it --name b2 --rm --network host busybox
/ # ifconfig
docker0   Link encap:Ethernet  HWaddr 02:42:DC:1B:B2:1E  
          inet addr:172.17.0.1  Bcast:172.17.255.255  Mask:255.255.0.0
          inet6 addr: fe80::42:dcff:fe1b:b21e/64 Scope:Link
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:1 errors:0 dropped:0 overruns:0 frame:0
          TX packets:13 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:28 (28.0 B)  TX bytes:1406 (1.3 KiB)

ens33     Link encap:Ethernet  HWaddr 00:0C:29:6D:53:62  
          inet addr:192.168.111.135  Bcast:192.168.111.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fe6d:5362/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:58165 errors:0 dropped:0 overruns:0 frame:0
          TX packets:96466 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:5386642 (5.1 MiB)  TX bytes:19720040 (18.8 MiB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

真機的網卡

[root@localhost ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:0c:29:6d:53:62 brd ff:ff:ff:ff:ff:ff
    inet 192.168.111.135/24 brd 192.168.111.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe6d:5362/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:dc:1b:b2:1e brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:dcff:fe1b:b21e/64 scope link 
       valid_lft forever preferred_lft forever

此時如果我們在這個容器中啟動一個http站點,我們就可以直接用宿主機的IP直接在瀏覽器中訪問這個容器中的站點了。

/ # echo 'hello world' > /tmp/index.html
/ # httpd -h /tmp/
/ # netstat -anlt
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      
tcp        0     52 192.168.111.135:22      192.168.111.1:62588     ESTABLISHED 
tcp        0      0 192.168.111.135:22      192.168.111.1:62452     ESTABLISHED 
tcp        0      0 192.168.111.135:22      192.168.111.1:62589     ESTABLISHED 
tcp        0      0 192.168.111.135:22      192.168.111.1:62451     ESTABLISHED 
tcp        0      0 :::80                   :::*                    LISTEN      
tcp        0      0 :::22                   :::*                    LISTEN     

//需要在真機上放行
[root@localhost ~]# firewall-cmd --add-rich-rule 'rule family=ipv4 source address=0.0.0.0/0 service name=http accept' --permanent
success
[root@localhost ~]# firewall-cmd --reload
success

image

linux內核實現名稱空間的創建

ip netns命令

可以藉助ip netns命令來完成對 Network Namespace 的各種操作。ip netns命令來自於iproute安裝包,一般系統會預設安裝,如果沒有的話,請自行安裝。

註意:ip netns命令修改網路配置時需要 sudo 許可權。

可以通過ip netns命令完成對Network Namespace 的相關操作,可以通過ip netns help查看命令幫助信息:

//如果使用不了命令需要下載iproute包
[root@localhost ~]# dnf -y install iproute

//查看命令幫助
[root@localhost ~]# ip netns help
Usage:  ip netns list
        ip netns add NAME
        ip netns attach NAME PID
        ip netns set NAME NETNSID
        ip [-all] netns delete [NAME]
        ip netns identify [PID]
        ip netns pids NAME
        ip [-all] netns exec [NAME] cmd ...
        ip netns monitor
        ip netns list-id [target-nsid POSITIVE-INT] [nsid POSITIVE-INT]
NETNSID := auto | POSITIVE-INT

預設情況下,Linux系統中是沒有任何 Network Namespace的,所以ip netns list命令不會返回任何信息。

創建network Namespace

不能使用touch創建,創建了也用不了

[root@localhost ~]# ip netns list
[root@localhost ~]# ip netns add ns0
[root@localhost ~]# ip netns list
ns0

新創建的 Network Namespace 會出現在/var/run/netns/目錄下。如果相同名字的 namespace 已經存在,命令會報Cannot create namespace file "/var/run/netns/ns0": File exists的錯誤。

//名稱空間存放位置
[root@localhost ~]# ls /var/run/netns/
ns0
[root@localhost ~]# file /var/run/netns/ns0 		
/var/run/netns/ns0: empty		//m進程類型

//測試重名
[root@localhost ~]# ls /var/run/netns/
ns0
[root@localhost ~]# ip netns add ns0
Cannot create namespace file "/var/run/netns/ns0": File exists

對於每個 Network Namespace 來說,它會有自己獨立的網卡、路由表、ARP 表、iptables 等和網路相關的資源。

操作network Namespace

ip命令提供了ip netns exec子命令可以在對應的 Network Namespace 中執行命令。

查看新創建 Network Namespace 的網卡信息

[root@localhost ~]# ip netns exec ns0 ip a
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN group default qlen 1000	//網卡未激活
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

可以看到,新創建的Network Namespace中會預設創建一個lo迴環網卡,此時網卡處於關閉狀態。此時,嘗試去 ping 該lo迴環網卡,會提示Network is unreachable

[root@localhost ~]# ip netns exec ns0 ping 127.0.0.1
connect: Network is unreachable

通過下麵的命令啟用lo迴環網卡

[root@localhost ~]# ip netns exec ns0 ip link set lo up
[root@localhost ~]# ip netns exec ns0 ping 127.0.0.1
PING 127.0.0.1 (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.247 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.062 ms
^C
--- 127.0.0.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1007ms
rtt min/avg/max/mdev = 0.062/0.154/0.247/0.093 ms

轉移設備

我們可以在不同的 Network Namespace 之間轉移設備(如veth)。由於一個設備只能屬於一個 Network Namespace ,所以轉移後在這個 Network Namespace 內就看不到這個設備了。

其中,veth設備屬於可轉移設備,而很多其它設備(如lo、vxlan、ppp、bridge等)是不可以轉移的。

veth pair

veth pair 全稱是 Virtual Ethernet Pair,是一個成對的乙太網埠,所有從這對埠一 端進入的數據包都將從另一端出來,反之也是一樣。
引入veth pair是為了在不同的 Network Namespace 直接進行通信,利用它可以直接將兩個 Network Namespace 連接起來。

img

創建veth pair

[root@localhost ~]# ip link add type veth
[root@localhost ~]# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:0c:29:6d:53:62 brd ff:ff:ff:ff:ff:ff
    inet 192.168.111.135/24 brd 192.168.111.255 scope global noprefixroute ens33
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe6d:5362/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:dc:1b:b2:1e brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
    inet6 fe80::42:dcff:fe1b:b21e/64 scope link 
       valid_lft forever preferred_lft forever
16: veth0@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether e6:c1:94:d2:dc:de brd ff:ff:ff:ff:ff:ff
17: veth1@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 2e:99:b0:9c:c2:23 brd ff:ff:ff:ff:ff:ff

可以看到,此時系統中新增了一對veth pair,將veth0和veth1兩個虛擬網卡連接了起來,此時這對 veth pair 處於”未啟用“狀態。

實現Network Namespace間通信

下麵我們利用veth pair實現兩個不同的 Network Namespace 之間的通信。剛纔我們已經創建了一個名為ns0的 Network Namespace,下麵再創建一個信息Network Namespace,命名為ns1

[root@localhost ~]# ip netns add ns1
[root@localhost ~]# ip netns list
ns1
ns0
[root@localhost ~]# ip netns exec ns1 ip link set lo up		//開啟ns1的lo網卡

然後我們將veth0加入到ns0,將veth1加入到ns1

[root@localhost ~]# ip link set veth0 netns ns0
[root@localhost ~]# ip link set veth1 netns ns1

//ns0
[root@localhost ~]# ip netns exec ns0 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
16: veth0@if17: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether e6:c1:94:d2:dc:de brd ff:ff:ff:ff:ff:ff link-netns ns1

//ns1
[root@localhost ~]# ip netns exec ns1 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
17: veth1@if16: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 2e:99:b0:9c:c2:23 brd ff:ff:ff:ff:ff:ff link-netns ns0

然後我們分別為這對veth pair配置上ip地址,並啟用它們

[root@localhost ~]# ip netns exec ns0 ip link set veth0 up
[root@localhost ~]# ip netns exec ns0 ip addr add 10.0.0.1/24 dev veth0
[root@localhost ~]# ip netns exec ns1 ip link set veth1 up
[root@localhost ~]# ip netns exec ns1 ip addr add 10.0.0.2/24 dev veth1

查看這對veth pair的狀態

//ns0
[root@localhost ~]# ip netns exec ns0 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
16: veth0@if17: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether e6:c1:94:d2:dc:de brd ff:ff:ff:ff:ff:ff link-netns ns1
    inet 10.0.0.1/24 scope global veth0
       valid_lft forever preferred_lft forever
    inet6 fe80::e4c1:94ff:fed2:dcde/64 scope link 
       valid_lft forever preferred_lft forever

//ns1
[root@localhost ~]# ip netns exec ns1 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
17: veth1@if16: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 2e:99:b0:9c:c2:23 brd ff:ff:ff:ff:ff:ff link-netns ns0
    inet 10.0.0.2/24 scope global veth1
       valid_lft forever preferred_lft forever
    inet6 fe80::2c99:b0ff:fe9c:c223/64 scope link 
       valid_lft forever preferred_lft forever

從上面可以看出,我們已經成功啟用了這個veth pair,併為每個veth設備分配了對應的ip地址。我們嘗試在ns1中訪問ns0中的ip地址:

[root@localhost ~]# ip netns exec ns1 ping 10.0.0.1
PING 10.0.0.1 (10.0.0.1) 56(84) bytes of data.
64 bytes from 10.0.0.1: icmp_seq=1 ttl=64 time=0.064 ms
64 bytes from 10.0.0.1: icmp_seq=2 ttl=64 time=0.041 ms
^C
--- 10.0.0.1 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1013ms
rtt min/avg/max/mdev = 0.041/0.052/0.064/0.013 ms

可以看到,veth pair成功實現了兩個不同Network Namespace之間的網路交互。

veth設備重命名

[root@localhost ~]# ip netns exec ns0 ip link set veth0 down
[root@localhost ~]# ip netns exec ns0 ip link set dev veth0 name eth0
[root@localhost ~]# ip netns exec ns0 ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
16: eth0@if17: <BROADCAST,MULTICAST> mtu 1500 qdisc noqueue state DOWN group default qlen 1000
    link/ether e6:c1:94:d2:dc:de brd ff:ff:ff:ff:ff:ff link-netns ns1
    inet 10.0.0.1/24 scope global eth0
       valid_lft forever preferred_lft forever
[root@localhost ~]# ip netns exec ns0 ip link set eth0 up

容器常用操作

查看容器主機名

[root@localhost ~]# docker run -it --name t1 --network bridge --rm busybox
/ # hostname
a0e82ecbc3e1

在容器啟動時註入主機名

[root@localhost ~]# docker run -it --name t1 --network bridge --hostname zxr --rm busybox
/ # hostname
zxr
/ # cat /etc/hosts
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      zxr			//註入主機名時會自動創建主機名到IP的映射關係
/ # cat /etc/resolv.conf 
# Generated by NetworkManager
nameserver 114.114.114.114		//DNS也會自動配置為宿主機的DNS
nameserver 8.8.8.8
/ # ping www.baidu.com
PING www.baidu.com (14.215.177.39): 56 data bytes
64 bytes from 14.215.177.39: seq=0 ttl=127 time=25.073 ms
64 bytes from 14.215.177.39: seq=1 ttl=127 time=26.718 ms
^C
--- www.baidu.com ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 25.073/25.895/26.718 ms

手動指定容器要使用的DNS

[root@localhost ~]# docker run -it --name t1 --network bridge --hostname zxr --dns 114.114.114.114 --rm busybox
/ # cat /etc/resolv.conf 
nameserver 114.114.114.114
/ # nslookup 114.114.114.114
Server:         114.114.114.114
Address:        114.114.114.114:53

Non-authoritative answer:
114.114.114.114.in-addr.arpa    name = public1.114dns.com

/ # nslookup www.baidu.com
Server:         114.114.114.114
Address:        114.114.114.114:53

Non-authoritative answer:
www.baidu.com   canonical name = www.a.shifen.com
Name:   www.a.shifen.com
Address: 14.215.177.38
Name:   www.a.shifen.com
Address: 14.215.177.39

手動往/etc/hosts文件寫入主機名到IP地址的映射

[root@localhost ~]# docker run -it --name t1 --network bridge --hostname zxr --add-host www.zxr.com:1.1.1.1 --rm busybox
/ # cat /etc/hosts
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
1.1.1.1 www.zxr.com
172.17.0.2      zxr

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 線程本地存儲 · 語雀 (yuque.com) 線程本地存儲提供了線程記憶體儲變數的能力,這些變數是線程私有的。 線程本地存儲一般用在跨類、跨方法的傳遞一些值。 線程本地存儲也是解決特定場景下線程安全問題的思路之一(每個線程都訪問本線程自己的變數)。 Java 語言提供了線程本地存儲,ThreadLo ...
  • 在大部分涉及到資料庫操作的項目裡面,事務控制、事務處理都是一個無法迴避的問題。這裡我們一起探討下關於事務控制相關的一些內容。 ...
  • 來源: blog.csdn.net/fumitzuki/article/details/81630048 volatile關鍵字是由JVM提供的最輕量級同步機制。與被濫用的synchronized不同,我們並不習慣使用它。想要正確且完全的理解它並不容易。 Part1Java記憶體模型 Java記憶體模型 ...
  • 多商戶商城系統,也稱為B2B2C(BBC)平臺電商模式多商家商城系統。可以快速幫助企業搭建類似拼多多/京東/天貓/淘寶的綜合商城。 多商戶商城系統支持商家入駐加盟,同時滿足平臺自營、旗艦店等多種經營方式。平臺可以通過收取商家入駐費,訂單交易服務費,提現手續費,簡訊通道費等多手段方式,實現整體盈利。 ...
  • [演算法1-排序](.NET源碼學習)& LINQ & Lambda 說起排序演算法,在日常實際開發中我們基本不在意這些事情,有API不用不是沒事找事嘛。但必要的基礎還是需要瞭解掌握。 排序的目的是為了讓無序的數據,變得“有序”。此處的有序指的是,滿足當前使用需求的順序,除了自帶的API,我們還可以自定 ...
  • 作為一個沒有系統學習過依賴註入的開發者而言,如果直接在一個使用依賴註入的框架下進行開發,往往對於依賴註入的存在是沒有明顯的察覺,通過代碼追根溯源你都會看不出對象是從哪裡創建的。但這並不影響你進行開發的工作,你可以參照現有代碼的使用形式,將需要使用的對象加入到構造函數的參數列表上,你就可以使用對象,調 ...
  • PDF/X-1a是一種PDF文件規範標準,在製作、使用PDF以及印刷時所需要遵循的技術條件,屬於PDF/X-1標準下的一個子標準。 PDF/X-1標準有由CGATS於1999年制定的PDF/X-1:1999,由ISO於2001年制的PDF/X-1:2001、PDF/X-1a:2001以及PDF/X- ...
  • 二、驅動 2.1.hello world 1.創建項目 2.刪除Driver Files裡面的helloworld.inf文件 3.右鍵屬性 Inf2Cat->General->Run Inf2Cat 改成否 Driver Settings->General->Traget OS VERSION和T ...
一周排行
    -Advertisement-
    Play Games
  • 前言 在我們開發過程中基本上不可或缺的用到一些敏感機密數據,比如SQL伺服器的連接串或者是OAuth2的Secret等,這些敏感數據在代碼中是不太安全的,我們不應該在源代碼中存儲密碼和其他的敏感數據,一種推薦的方式是通過Asp.Net Core的機密管理器。 機密管理器 在 ASP.NET Core ...
  • 新改進提供的Taurus Rpc 功能,可以簡化微服務間的調用,同時可以不用再手動輸出模塊名稱,或調用路徑,包括負載均衡,這一切,由框架實現並提供了。新的Taurus Rpc 功能,將使得服務間的調用,更加輕鬆、簡約、高效。 ...
  • 順序棧的介面程式 目錄順序棧的介面程式頭文件創建順序棧入棧出棧利用棧將10進位轉16進位數驗證 頭文件 #include <stdio.h> #include <stdbool.h> #include <stdlib.h> 創建順序棧 // 指的是順序棧中的元素的數據類型,用戶可以根據需要進行修改 ...
  • 前言 整理這個官方翻譯的系列,原因是網上大部分的 tomcat 版本比較舊,此版本為 v11 最新的版本。 開源項目 從零手寫實現 tomcat minicat 別稱【嗅虎】心有猛虎,輕嗅薔薇。 系列文章 web server apache tomcat11-01-官方文檔入門介紹 web serv ...
  • C總結與剖析:關鍵字篇 -- <<C語言深度解剖>> 目錄C總結與剖析:關鍵字篇 -- <<C語言深度解剖>>程式的本質:二進位文件變數1.變數:記憶體上的某個位置開闢的空間2.變數的初始化3.為什麼要有變數4.局部變數與全局變數5.變數的大小由類型決定6.任何一個變數,記憶體賦值都是從低地址開始往高地 ...
  • 如果讓你來做一個有狀態流式應用的故障恢復,你會如何來做呢? 單機和多機會遇到什麼不同的問題? Flink Checkpoint 是做什麼用的?原理是什麼? ...
  • C++ 多級繼承 多級繼承是一種面向對象編程(OOP)特性,允許一個類從多個基類繼承屬性和方法。它使代碼更易於組織和維護,並促進代碼重用。 多級繼承的語法 在 C++ 中,使用 : 符號來指定繼承關係。多級繼承的語法如下: class DerivedClass : public BaseClass1 ...
  • 前言 什麼是SpringCloud? Spring Cloud 是一系列框架的有序集合,它利用 Spring Boot 的開發便利性簡化了分散式系統的開發,比如服務註冊、服務發現、網關、路由、鏈路追蹤等。Spring Cloud 並不是重覆造輪子,而是將市面上開發得比較好的模塊集成進去,進行封裝,從 ...
  • class_template 類模板和函數模板的定義和使用類似,我們已經進行了介紹。有時,有兩個或多個類,其功能是相同的,僅僅是數據類型不同。類模板用於實現類所需數據的類型參數化 template<class NameType, class AgeType> class Person { publi ...
  • 目錄system v IPC簡介共用記憶體需要用到的函數介面shmget函數--獲取對象IDshmat函數--獲得映射空間shmctl函數--釋放資源共用記憶體實現思路註意 system v IPC簡介 消息隊列、共用記憶體和信號量統稱為system v IPC(進程間通信機制),V是羅馬數字5,是UNI ...