偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

一篇文章講明白 Docker 網(wǎng)絡(luò)原理

網(wǎng)絡(luò) 網(wǎng)絡(luò)管理
Docker 原生網(wǎng)絡(luò)是基于 Linux 的 網(wǎng)絡(luò)命名空間(net namespace) 和 虛擬網(wǎng)絡(luò)設(shè)備(veth pair)實現(xiàn)的。當(dāng) Docker 進(jìn)程啟動時,會在宿主機(jī)上創(chuàng)建一個名稱為 docker0 的 虛擬網(wǎng)橋,在該宿主機(jī)上啟動的 Docker 容器會連接到這個虛擬網(wǎng)橋上。

概述

Docker 原生網(wǎng)絡(luò)是基于 Linux 的 網(wǎng)絡(luò)命名空間(net namespace) 和 虛擬網(wǎng)絡(luò)設(shè)備(veth pair)實現(xiàn)的。當(dāng) Docker 進(jìn)程啟動時,會在宿主機(jī)上創(chuàng)建一個名稱為 docker0 的 虛擬網(wǎng)橋,在該宿主機(jī)上啟動的 Docker 容器會連接到這個虛擬網(wǎng)橋上。

$ ifconfig

# 輸出如下

docker0: ... mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 172.17.255.255
...

虛擬網(wǎng)橋的工作方式和物理交換機(jī)類似,宿主機(jī)上所有的容器通過虛擬網(wǎng)橋連接在一個二層網(wǎng)絡(luò)中。

從 docker0 子網(wǎng)中分配一個 IP 給容器使用,并設(shè)置 docker0 的 IP 地址為容器的默認(rèn)網(wǎng)關(guān)。在宿主機(jī)上創(chuàng)建一對虛擬網(wǎng)卡 veth pair 設(shè)備, Docker 將 veth pair 設(shè)備的一端放在新創(chuàng)建的容器中,并命名為 eth0(容器的網(wǎng)卡), 另一端放在宿主機(jī)中,以 vethxxx 類似的名字命名, 并將這個網(wǎng)絡(luò)設(shè)備連接到 docker0 網(wǎng)橋中。

Docker 會自動配置 iptables 規(guī)則和配置 NAT,便于連通宿主機(jī)上的 docker0 網(wǎng)橋,完成這些操作之后,容器就可以使用它的 eth0 虛擬網(wǎng)卡,來連接其他容器和訪問外部網(wǎng)絡(luò)。

Docker 中的網(wǎng)絡(luò)接口默認(rèn)都是虛擬的接口,Linux 在內(nèi)核中通過 數(shù)據(jù)復(fù)制 實現(xiàn)接口之間的數(shù)據(jù)傳輸,可以充分發(fā)揮數(shù)據(jù)在不同 Docker 容器或容器與宿主機(jī)之間的轉(zhuǎn)發(fā)效率, 發(fā)送接口發(fā)送緩存中的數(shù)據(jù)包,將直接復(fù)制到接收接口的緩存中,無需通過物理網(wǎng)絡(luò)設(shè)備進(jìn)行交換。

# 查詢主機(jī)上 veth 設(shè)備
$ ifconfig | grep veth*

veth06f40aa:
...
vethfdfd27a:

圖片

圖片來源: https://www.suse.com/c/rancher_blog/introduction-to-container-networking/

虛擬網(wǎng)橋 docker0 通過 iptables 配置與宿主機(jī)器上的網(wǎng)卡相連,符合條件的請求都會通過 iptables 轉(zhuǎn)發(fā)到 docker0, 然后分發(fā)給對應(yīng)的容器。

# 查看 docker 的 iptables 配置
$ iptables -t nat -L

# 輸出如下

Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DOCKER all -- anywhere anywhere ADDRTYPE match dst-type LOCAL

Chain DOCKER (2 references)
target prot opt source destination
RETURN all -- anywhere anywhere

網(wǎng)絡(luò)驅(qū)動

Docker 的網(wǎng)絡(luò)子系統(tǒng)支持插拔式的驅(qū)動程序,默認(rèn)存在多個驅(qū)動程序,并提供核心網(wǎng)絡(luò)功能。

名稱

描述

bridge

默認(rèn)的網(wǎng)絡(luò)設(shè)備,當(dāng)應(yīng)用程序所在的容器需要通信時使用

host

移除容器與宿主機(jī)之間的網(wǎng)絡(luò)隔離,直接使用宿主機(jī)的網(wǎng)絡(luò)

overlay

將多個容器連接,并使集群服務(wù)能夠相互通信

ipvlan

使用戶可以完全控制 IPv4 和 IPv6 尋址

macvlan

可以為容器分配 MAC 地址

none

禁用所有網(wǎng)絡(luò)

Network plugins

通過 Docker 安裝和使用第三方網(wǎng)絡(luò)插件

圖片

圖片來源: Docker——容器與容器云

Docker daemon 通過調(diào)用 libnetwork 提供的 API 完成網(wǎng)絡(luò)的創(chuàng)建和管理等功能。libnetwork 中使用了 CNM 來完成網(wǎng)絡(luò)功能, CNM 中主要有沙盒(sandbox)、端點(diǎn)(endpoint)和網(wǎng)絡(luò)(network)3 種組件。

? 沙盒:一個沙盒包含了一個容器網(wǎng)絡(luò)棧的信息。一個沙盒可以有多個端點(diǎn)和多個網(wǎng)絡(luò),沙盒可以對容器的接口、路由和 DNS 設(shè)置等進(jìn)行管理,沙盒的實現(xiàn)可以是 Linux network namespace、FreeBSD Jail或者類似的機(jī)制

? 端點(diǎn):一個端點(diǎn)可以加入一個沙盒和一個網(wǎng)絡(luò)。一個端點(diǎn)只屬于一個網(wǎng)絡(luò)和一個沙盒,端點(diǎn)的實現(xiàn)可以是 veth pair、Open vSwitch 內(nèi)部端口或者相似的設(shè)備

? 網(wǎng)絡(luò):一個網(wǎng)絡(luò)是一組可以直接互相聯(lián)通的端點(diǎn)。一個網(wǎng)絡(luò)可以包含多個端點(diǎn),網(wǎng)絡(luò)的實現(xiàn)可以是Linux bridge、VLAN 等

bridge 模式

bridge 是默認(rèn)的網(wǎng)絡(luò)模式,為容器創(chuàng)建獨(dú)立的網(wǎng)絡(luò)命名空間,容器具有獨(dú)立的網(wǎng)卡等所有的網(wǎng)絡(luò)棧。使用該模式的所有容器都是連接到 docker0 這個網(wǎng)橋, 作為 虛擬交換機(jī) 使容器可以相互通信,但是由于宿主機(jī)的 IP 地址與容器 veth pair 的 IP 地址不在同一個網(wǎng)段,所以為了和宿主機(jī)以外的網(wǎng)絡(luò)通信, Docker 采用了端口綁定的方式,也就是通過 iptables 的 NAT,將宿主機(jī)上的端口流量轉(zhuǎn)發(fā)到容器。

bridge 模式已經(jīng)可以滿足 Docker 容器最基本的使用需求了,但是其與外界通信時使用 NAT,增加了通信的復(fù)雜性,在復(fù)雜場景下使用會有限制。

$ docker network inspect bridge

# 輸出如下 (節(jié)選部分信息)
[
{
"Name": "bridge",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
}
]
},
"Containers": {
# 使用 bridge 網(wǎng)絡(luò)的容器列表
},
}
]

通過上面的輸出可以看到,虛擬網(wǎng)橋 的 IP 地址就是 bridge 網(wǎng)絡(luò)類型的網(wǎng)關(guān)地址。

我們可以從輸出的 Containers 容器列表中找一個容器,查看其網(wǎng)絡(luò)類型和配置:

$ docker inspect 容器ID

# 輸出如下 (節(jié)選部分信息)
[
...

"NetworkSettings": {
"Bridge": "",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.4",
"Networks": {
"bridge": {
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.4",
}
}

...
]

通過上面的輸出可以看到,虛擬網(wǎng)橋 的 IP 地址就是 bridge 網(wǎng)絡(luò)類型的容器的網(wǎng)關(guān)地址。

實現(xiàn)機(jī)制

在 iptables 做了 DNAT 規(guī)則,實現(xiàn)端口轉(zhuǎn)發(fā)功能:

# iptables 配置查看
$ iptables -t nat -vnL

# 輸出如下
Chain PREROUTING (policy ACCEPT 37M packets, 2210M bytes)

...

0 0 DNAT tcp -- !docker0 * 0.0.0.0/0 0.0.0.0/0 tcp dpt:8080 to:172.17.0.4:80

當(dāng)容器需要將端口映射到宿主機(jī)時,Docker 會自動為該容器分配一個 IP 地址,同時新增一個 iptables 規(guī)則。

host 模式

容器不會獲得一個獨(dú)立的網(wǎng)絡(luò)命名空間,而是和宿主機(jī)共用一個。容器不會虛擬出自己的網(wǎng)卡,配置自己的IP等,而是直接使用宿宿主機(jī)的。但是容器的其他方面,如文件系統(tǒng)、進(jìn)程列表等還是和宿宿主機(jī)隔離的,容器對外界是完全開放的,能夠訪問到宿主機(jī),就能訪問到容器。

host 模式降低了容器與容器之間、容器與宿主機(jī)之間網(wǎng)絡(luò)層面的隔離性,雖然有性能上的優(yōu)勢,但是引發(fā)了網(wǎng)絡(luò)資源的競爭與沖突,因此適用于容器集群規(guī)模較小的場景。

啟動一個網(wǎng)絡(luò)類型為 host 的 Nginx 容器:

$ docker run -d --net host nginx

Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
...
f202870092fc40bc08a607dddbb2770df9bb4534475b066f45ea35252d6e76e2

查看網(wǎng)絡(luò)類型為 host 的容器列表:

$ docker network inspect host

# 輸出如下 (節(jié)選部分信息)
[
{
"Name": "host",
"Scope": "local",
"Driver": "host",
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"Containers": {
# 使用 host 網(wǎng)絡(luò)的容器列表
"f202870092fc40bc08a607dddbb2770df9bb4534475b066f45ea35252d6e76e2": {
"Name": "frosty_napier",
"EndpointID": "7306a8e4103faf4edd081182f015fa9aa985baf3560f4a49b9045c00dc603190",
"MacAddress": "",
"IPv4Address": "",
"IPv6Address": ""
}
},
}
]

查看 Nginx 容器網(wǎng)絡(luò)類型和配置:

$ docker inspect f202870092fc4

# 輸出如下 (節(jié)選部分信息)
[
...

"NetworkSettings": {
"Bridge": "",
"Gateway": "",
"IPAddress": "",
"Networks": {
"host": {
"Gateway": "",
"IPAddress": "",
}
}
...
]

通過上面的輸出可以看到,Nginx 容器使用的網(wǎng)絡(luò)類型是 host,沒有獨(dú)立的 IP。

查看 Nginx 容器 IP 地址:

# 進(jìn)入容器內(nèi)部 shell

$ docker exec -it f202870092fc4 /bin/bash

# 安裝 ip 命令

$ apt update && apt install -y iproute2

# 查看 IP 地址
$ ip a

# 輸出如下
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
...
2: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
...
10: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
...

# 退出容器,查看宿主機(jī) IP 地址
$ exit
$ ip a

# 輸出如下
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
...
2: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
...
10: eth0@if11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
...

通過上面的輸出可以看到,Nginx 容器內(nèi)部并沒有獨(dú)立的 IP,而是使用了宿主機(jī)的 IP。

查看宿主機(jī)的端口監(jiān)聽狀態(tài):

$ sudo netstat -ntpl

# 輸出如下
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1378/nginx: master
tcp6 0 0 :::80 :::* LISTEN 1378/nginx: master

通過上面的輸出可以看到,監(jiān)聽 80 端口的進(jìn)程為 nginx, 而不是 docker-proxy。

none 模式

容器擁有自己的 Network Namespace,但是并不進(jìn)行任何網(wǎng)絡(luò)配置。也就意味著該容器沒有網(wǎng)卡、IP、路由等信息,需要手動為容器添加網(wǎng)卡、配置 IP 等, none 模式下的容器會完全隔離,容器中只有 lo 這個 loopback(回環(huán)網(wǎng)絡(luò))網(wǎng)卡用于進(jìn)程通信。

none 模式為容器做了最少的網(wǎng)絡(luò)設(shè)置,在沒有網(wǎng)絡(luò)配置的情況下,通過自定義配置容器的網(wǎng)絡(luò),提供了最高的靈活性。

啟動一個網(wǎng)絡(luò)類型為 host 的 Nginx 容器:

$ docker run -d --net none nginx

Unable to find image 'nginx:latest' locally
latest: Pulling from library/nginx
...
d2d0606b7d2429c224e61e06c348019b74cd47f0b8c85347a7cdb8f1e30dcf86

查看網(wǎng)絡(luò)類型為 none 的容器列表:

$ docker network inspect none

# 輸出如下 (節(jié)選部分信息)
[
{
"Name": "none",
"Scope": "local",
"Driver": "null",
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"Containers": {
# 使用 none 網(wǎng)絡(luò)的容器列表
"d2d0606b7d2429c224e61e06c348019b74cd47f0b8c85347a7cdb8f1e30dcf86": {
"Name": "hardcore_chebyshev",
"EndpointID": "b8ff645671518e608f403818a31b1db34d7fce66af60373346ea3ab673a4c6b2",
"MacAddress": "",
"IPv4Address": "",
"IPv6Address": ""
}
},
}
]

查看 Nginx 容器網(wǎng)絡(luò)類型和配置:

$ docker inspect d2d0606b7d242

# 輸出如下 (節(jié)選部分信息)
[
...

"NetworkSettings": {
"Bridge": "",
"Gateway": "",
"IPAddress": "",
"Networks": {
"none": {
"Gateway": "",
"IPAddress": "",
}
}
...
]

通過上面的輸出可以看到,Nginx 容器使用的網(wǎng)絡(luò)類型是 none,沒有獨(dú)立的 IP。

查看 Nginx 容器 IP 地址:

# 進(jìn)入容器內(nèi)部 shell

$ docker exec -it d2d0606b7d242 /bin/bash

# 訪問公網(wǎng)鏈接

$ curl -I "https://www.docker.com"

curl: (6) Could not resolve host: www.docker.com

# 為什么會報錯呢? 這是因為當(dāng)前容器沒有網(wǎng)卡、IP、路由等信息,是完全獨(dú)立的運(yùn)行環(huán)境,所以沒有辦法訪問公網(wǎng)鏈接。

# 查看 IP 地址
$ hostname -I

# 沒有任何輸出,該容器沒有 IP 地址

查看宿主機(jī)的端口監(jiān)聽狀態(tài):

$ docker port d2d0606b7d242

或者

$ sudo netstat -ntpl | grep :80

# 沒有任何輸出,Nginx 進(jìn)程運(yùn)行在容器中,端口沒有映射到宿主機(jī)

container 模式

與 host 模式類似,容器與指定的容器共享網(wǎng)絡(luò)命名空間。這兩個容器之間不存在網(wǎng)絡(luò)隔離,但它們與宿主機(jī)以及其他的容器存在網(wǎng)絡(luò)隔離。該模式下的容器可以通過 localhost 來訪問同一網(wǎng)絡(luò)命名空間下的其他容器,傳輸效率較高,且節(jié)約了一定的網(wǎng)絡(luò)資源。在一些特殊的場景中非常有用,例如 k8s 的 Pod。

其他模式

出于篇幅考慮,這里不再贅述其他網(wǎng)絡(luò)模式,感興趣的讀者可以根據(jù)文章末尾的引用連接自行閱讀。

網(wǎng)絡(luò)驅(qū)動概述

  • ? 當(dāng)需要多個容器在同一臺宿主機(jī)上進(jìn)行通信時,使用 bridge
  • ? 當(dāng)網(wǎng)絡(luò)棧不應(yīng)該與宿主機(jī)隔離,但是希望容器的其他方面被隔離時,使用 host
  • ? 當(dāng)需要在不同宿主機(jī)上運(yùn)行的容器進(jìn)行通信時,使用 overlay
  • ? 當(dāng)從虛擬機(jī)遷移或需要使容器看起來像物理宿主機(jī)時,使用 Macvlan, 每個容器都有一個唯一的 MAC 地址
  • ? 當(dāng)需要將 Docker 與專門的網(wǎng)絡(luò)棧集成,使用 Third-party

Docker 和 iptables

如果在公網(wǎng)可以訪問的服務(wù)器運(yùn)行 Docker,需要對應(yīng)的 iptables 規(guī)則來限制訪問主機(jī)上的容器或其他服務(wù)。

在 Docker 規(guī)則之前添加 iptables 規(guī)則

Docker 安裝了兩個名為 DOCKER-USER 和 DOCKER 的自定義 iptables 鏈,確保傳入的數(shù)據(jù)包始終先由這兩個鏈進(jìn)行檢查。

# 可以通過該命令查看

$ iptables -L -n -v | grep -i docker

Docker 的所有 iptables 規(guī)則都被添加到 Docker 鏈中,不要手動修改此鏈 (可能會引發(fā)問題)。如果需要添加在一些在 Docker 之前加載的規(guī)則,將它們添加到 DOCKER-USER 鏈中,這些規(guī)則應(yīng)用于 Docker 自動創(chuàng)建的所有規(guī)則之前。

添加到 FORWARD 鏈中的規(guī)則在這些鏈之后進(jìn)行檢測,這意味著如果通過 Docker 公開一個端口,那么無論防火墻配置了什么規(guī)則,該端口都會被公開。如果想讓這些規(guī)則在通過 Docker 暴露端口時仍然適用,必須將這些規(guī)則添加到 DOCKER-USER 鏈中。

限制到 Docker 主機(jī)的連接

默認(rèn)情況下,允許所有 外部 IP 連接 Docker 主機(jī),為了只允許特定的 IP 或網(wǎng)絡(luò)訪問容器,在 DOCKER-USER 過濾器鏈的頂部插入一個規(guī)則。

例如,只允許 192.168.1.1 訪問:

# 假設(shè)輸入接口為 eth0
$ iptables -I DOCKER-USER -i eth0 ! -s 192.168.1.1 -j DROP

也可以允許來自源子網(wǎng)的連接,例如,允許 192.168.1.0/24 子網(wǎng)的用戶訪問:

# 假設(shè)輸入接口為 eth0
$ iptables -I DOCKER-USER -i eth0 ! -s 192.168.1.0/24 -j DROP

阻止 Docker 操作 iptables

在 Docker 引擎的配置文件 /etc/docker/daemon.json 設(shè)置 iptables 的值為 false,但是最好不要修改,因為這很可能破壞 Docker 引擎的容器網(wǎng)絡(luò)。

為容器設(shè)置默認(rèn)綁定地址

默認(rèn)情況下,Docker 守護(hù)進(jìn)程將公開 0.0.0.0 地址上的端口,即主機(jī)上的任何地址。如果希望將該行為更改為僅公開內(nèi)部 IP 地址上的端口,則可以使用 --ip  選項指定不同的IP地址。

集成到防火墻

如果運(yùn)行的是 Docker 20.10.0 或更高版本,在系統(tǒng)上啟用了 iptables, Docker 會自動創(chuàng)建一個名為 docker 的防火墻區(qū)域, 并將它創(chuàng)建的所有網(wǎng)絡(luò)接口 (例如 docker0 ) 加入到 docker 區(qū)域,以允許無縫組網(wǎng)。

運(yùn)行命令將 docker 接口從防火墻區(qū)域中移除:

firewall-cmd --znotallow=trusted --remove-interface=docker0 --permanent
firewall-cmd --reload

Reference

? Networking overview[1]

? Networking tutorials[2]

? Docker and iptables[3]

? 容器Docker詳解[4]

? Introduction to Container Networking[5]

? docker 容器網(wǎng)絡(luò)方案:calico 網(wǎng)絡(luò)模型[6]

? Docker——容器與容器云[7]

引用鏈接

[1]? Networking overview: ??https://docs.docker.com/network/[2]??? Networking tutorials: ??https://docs.docker.com/network/network-tutorial-standalone/[3]??? Docker and iptables: ??https://docs.docker.com/network/iptables/??

[4]? 容器Docker詳解: ??https://juejin.cn/post/6844903766601236487??

[5]? Introduction to Container Networking: ??https://www.suse.com/c/rancher_blog/introduction-to-container-networking/??

[6]? docker 容器網(wǎng)絡(luò)方案:calico 網(wǎng)絡(luò)模型: ??https://cizixs.com/2017/10/19/docker-calico-network/??

[7] Docker——容器與容器云: https://book.douban.com/subject/26894736/

責(zé)任編輯:武曉燕 來源: 洋芋編程
相關(guān)推薦

2021-05-08 07:14:38

MySQL數(shù)據(jù)庫安全性

2023-01-03 18:32:32

2021-04-09 08:40:51

網(wǎng)絡(luò)保險網(wǎng)絡(luò)安全網(wǎng)絡(luò)風(fēng)險

2022-05-25 08:31:31

ArthasInstrument

2021-02-15 13:38:38

多線程異步模型

2020-10-22 08:25:22

JavaScript運(yùn)作原理

2018-10-22 12:50:20

CDN網(wǎng)絡(luò)內(nèi)容發(fā)布網(wǎng)絡(luò)

2020-06-03 11:06:26

DNS域名緩存

2024-06-05 08:51:08

2020-10-09 08:15:11

JsBridge

2019-08-29 14:46:15

Kubernetes網(wǎng)絡(luò)通信

2024-08-07 09:02:51

2021-10-15 07:57:04

Docker 日志容器

2017-11-02 14:06:40

2015-07-15 17:09:48

HiveHadoop分布式文件系統(tǒng)

2017-09-05 08:52:37

Git程序員命令

2022-02-21 09:44:45

Git開源分布式

2019-04-17 15:16:00

Sparkshuffle算法

2024-06-25 08:18:55

2021-06-30 00:20:12

Hangfire.NET平臺
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號