背景知識
Docker 網(wǎng)絡
在 Docker 中,網(wǎng)絡是一個重要抽象。一個 Docker 可以有多個網(wǎng)絡,每個容器可以連接到一個或多個中。
docker 安裝完成后,會自動創(chuàng)建三個網(wǎng)絡,分別是 bridge、host 和 none。通過 docker network ls 命令可以查看:
NETWORKIDNAMEDRIVERSCOPE 11da7fc827b4bridgebridgelocal 4cd2eae9c4cdhosthostlocal 12730ca5becanonenulllocal
其中名字為 bridge 的 bridge 類型網(wǎng)絡,就是 docker 的默認網(wǎng)絡(docker run 默認使用的網(wǎng)絡)。
默認網(wǎng)絡的實現(xiàn)是在宿主機環(huán)境創(chuàng)建一個名為 docker0 的 bridge 設備,并為其配置一個私有網(wǎng)段的網(wǎng)關(guān) IP 地址。通過 ip addr show docker0 可以查看更該設備信息。
3:docker0:mtu1500qdiscnoqueuestateUPgroupdefault link/ether02xxxx:xxbrdffffff:ff inet172.17.0.1/16brd172.17.255.255scopeglobaldocker0 valid_lftforeverpreferred_lftforever inet6fe80:xxxxxx/64scopelink valid_lftforeverpreferred_lftforever
docker bridge 網(wǎng)絡,在 IPv4 場景下拓撲如下所示(來自于:KVM + LinuxBridge 的網(wǎng)絡虛擬化解決方案實踐):
+----------------------------------------------------------------+-----------------------------------------+-----------------------------------------+ |Host|Container1|Container2| |||| |+------------------------------------------------+|+-------------------------+|+-------------------------+| ||NewworkProtocolStack|||NewworkProtocolStack|||NewworkProtocolStack|| |+------------------------------------------------+|+-------------------------+|+-------------------------+| |↑↑|↑|↑| |............|.............|.....................................|...................|.....................|....................|....................| |↓↓|↓|↓| |+------++--------+|+-------+|+-------+| ||.3.101||.9.1|||.9.2|||.9.3|| |+------++--------++-------+|+-------+|+-------+| ||eth0||br0|<--->|veth|||eth0|||eth0|| |+------++--------++-------+|+-------+|+-------+| |↑↑↑|↑|↑| |||+-------------------------------------------+||| ||↓|||| ||+-------+|||| |||veth||||| ||+-------+|||| ||↑|||| ||+-------------------------------------------------------------------------------|--------------------+| ||||| ||||| ||||| +------------|---------------------------------------------------+-----------------------------------------+-----------------------------------------+ ↓ PhysicalNetwork(192.168.3.0/24)
通過 docker network inspect bridge 可以查看某該默認網(wǎng)絡配置:
[ { "Name":"bridge", "Id":"11da7fc827b4dxxx", "Created":"2021-11-22T1203.408536176+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":{ "0d744147030829f0247xx":{ "Name":"container1", "EndpointID":"6f539a054ae35cbxx", "MacAddress":"02xxxx:xx", "IPv4Address":"172.17.0.14/16", "IPv6Address":"" }, }, "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":{} } ]
可以通過 docker network create 命令,創(chuàng)建一個自定義 bridge 網(wǎng)絡。關(guān)于,默認網(wǎng)絡和自定義 bridge,有如下不同:
自定義 bridge 網(wǎng)絡會使用 docker 內(nèi)嵌的 dns server 服務,配置地址為 127.0.0.11,通過 iptables 轉(zhuǎn)發(fā)到 43747 端口。因此可以直接通過 container name 訪問同一個自定義網(wǎng)絡下的其他容器網(wǎng)絡。而默認網(wǎng)絡則不支持。
自定義 bridge 有更好的隔離性。
一個容器可以在運行時動態(tài)的連接/斷開一個自定義 bridge,默認網(wǎng)絡只能重新創(chuàng)建。
自定義 bridge 可以在創(chuàng)建的時候配置 Linux bridge,如果要修改默認網(wǎng)絡的 bridge 則需要重啟 docker daemon。因此,官方更推薦在生產(chǎn)環(huán)境使用自定義 bridge 而非默認網(wǎng)絡。
默認網(wǎng)絡支持 IPv6
本章節(jié)介紹的是如何配置默認的 bridge 網(wǎng)絡支持 ipv6。(未經(jīng)過測試,僅供參考)
前置條件:確保自己的設備被分配了一個 IPv6。通過 ip addr show 查看當前設備的 IPv6。其輸出的物理網(wǎng)卡存在包含 inet6 和 scope global 的行時,表示該網(wǎng)卡支持 IPv6。需要注意的是:其 IPv6 地址的前綴不能是 /128,如果是 /128,建議通過 IPv6NAT 方式去支持 IPv6。
2:eth0:mtu1500qdiscmqstateUPgroupdefaultqlen1000 link/etherfaxxxx:xxbrdffffff:ff inet10.227.8.141/22brd10.227.11.255scopeglobaleth0 valid_lftforeverpreferred_lftforever inet62xxx:xxxx/64scopeglobal valid_lftforeverpreferred_lftforever inet6fe80:xxxxxxxx/64scopelink valid_lftforeverpreferred_lftforever
修改 /etc/docker/daemon.json,其中 fixed-cidr-v6 是上一步獲取到的 IPv6 網(wǎng)段的子網(wǎng)(配置默認網(wǎng)絡,前綴長度最大為 /80)。
{ "ipv6":true, "fixed-cidr-v6":"2xxx:/80" }
reload 配置,docker daemon 將會使用 IPv6 網(wǎng)絡。
sudosystemctlreloaddocker
通過 docker network inspect bridge 命令檢查是否生效。若生效,則 EnableIPv6 值為 true,IPAM.Config[1].Subnet 是上一步配置的 fixed-cidr-v6。
注意經(jīng)測試,如下場景可能不會生效:
/etc/docker/daemon.json 存在 "live-restore": true 字段。
reload 時有容器仍然存在。
根據(jù)眾多博客的說法,還需如下兩步:
/etc/sysctl.conf 添加,并執(zhí)行 sysctl -f,配置宿主機和 docker0 網(wǎng)卡支持 NDP proxy。
#docker0是docker默認的網(wǎng)橋(bridge) net.ipv6.conf.docker0.proxy_ndp=1 #eth0表示物理網(wǎng)卡,注意替換為物理網(wǎng)卡 net.ipv6.conf.eth0.proxy_ndp=1
默認的 ndp 鄰居發(fā)現(xiàn)配置僅允許單個 IP 配置。需要安裝 ndppd 服務來轉(zhuǎn)發(fā)鄰居發(fā)現(xiàn)消息(這一步還有一個替代方案:手動為每一個容器配置如:ip -6 neigh add proxy 2xxx:1 dev ens3,其中,2xxx:1 為容器的分配的 IPv6,ens3 為宿主機綁定 IPv6 的網(wǎng)卡)。
apt-getupdate-y apt-getinstall-yndppd cp/usr/share/doc/ndppd/ndppd.conf-dist/etc/ndppd.conf
更改 proxy eth0 { 行到宿主機綁定 IPv6 的網(wǎng)卡,如:proxy ens3 {。更改 rule 1111:: { 行為需要暴露的網(wǎng)段 2xxx:/80 {。最后執(zhí)行 systemctl restart ndppd
注意:
本方法僅針對新裝 Docker 場景
本章節(jié) 和 自定義網(wǎng)絡支持 IPv6 配置的 IPv6 和 docker 默認 IPv4 是不同的。容器的 IPv6 用的不是私有網(wǎng)段,而是宿主機網(wǎng)絡或者是宿主機網(wǎng)絡的一個子網(wǎng)。因此,宿主機所在的網(wǎng)絡的所有實例可以直接通過 IPv6 的地址。也就是說:容器的所有端口對于 IPv6 來說都是公開的,而無需 public。而容器的 IPv4 分配的是私有網(wǎng)段,因此,容器網(wǎng)段和宿主機網(wǎng)段是通過 NAT 轉(zhuǎn)發(fā)數(shù)據(jù)的,因此宿主機所在網(wǎng)絡的其他實例是無法直接訪問容器。也就是說:容器的所有端口對于 IPv4 來說都是私有的,需 public 到 host 網(wǎng)絡才能被外部訪問到。
自定義網(wǎng)絡支持 IPv6
本章節(jié)介紹的是如何創(chuàng)建一個支持 IPv6 的 bridge 網(wǎng)絡。(未經(jīng)過測試,僅供參考)
前置條件:確保自己的設備被分配了一個 IPv6。
創(chuàng)建一個支持 IPv6 的 bridge 網(wǎng)絡。其中 --subnet 參數(shù)為上一步獲取到的 IPv6 網(wǎng)段的子網(wǎng)(自定義 bridge 網(wǎng)絡,前綴長度不限制,可以大于于 80)。
dockernetworkcreatemy-net-ipv6--ipv6--subnet="2xxx:/80"
通過 docker network inspect my-net-ipv6 命令檢查是否生效。若生效,則 EnableIPv6 值為 true,IPAM.Config[1].Subnet 是上一步配置的 fixed-cidr-v6。
創(chuàng)建容器時,通過 --network my-net-ipv6 參數(shù),給容器開啟 IPv6 網(wǎng)絡,如 docker run --network my-net-ipv6 -it busybox ip addr show,可以看到,網(wǎng)卡被分配了 IPv6 地址。
通過 IPv6NAT 方式支持 IPv6
測試可行,推薦使用該方式。
上文也提到,上文展示的方案,容器獲得的 IPv6 IP 并不是私有網(wǎng)絡 IP,是和外部網(wǎng)絡直接連通,而不會經(jīng)過 NAT。在如下場景下,以上方式可能不能滿足要求:
安全性,要求容器的網(wǎng)絡是私有的,需要容器的網(wǎng)絡行為和 Docker IPv4 的行為一致,只有特定端口才能訪問。
宿主機處于一個很小范圍的網(wǎng)段(前綴大于 /80),如 xxx::xx/128,沒有多余的 IPv6 可以分給容器。此時就需要,給容器配置一個私有 IPv6 網(wǎng)段,并啟用 NAT。
但是 Docker 官方并沒有內(nèi)置 IPv6 的 NAT,如果想要使用 IPv6 NAT,需要安裝外掛的 IPv6 啟動,參見:https://github.com/robbertkl/docker-ipv6nat。
有這些準備后,實施步驟如下所示:
使用如下命令,后臺啟動 IPv6 NAT(通過 --restart always 配置了開機自啟)。
dockerrun-d--nameipv6nat--privileged--networkhost--restartalways-v/var/run/docker.sock:/var/run/docker.sock:ro-v/lib/modules:/lib/modules:rorobbertkl/ipv6nat
和 自定義網(wǎng)絡支持 IPv6 類似,創(chuàng)建一個支持 IPv6 的 bridge 網(wǎng)絡。其中 --subnet 參數(shù)為 fe80::/10 的一個子網(wǎng)。
dockernetworkcreatemy-net-ipv6--ipv6--subnet="fd00:1/80"--gateway="fd00:1"
通過 docker network inspect my-net-ipv6 命令檢查是否生效。若生效,則 EnableIPv6 值為 true,IPAM.Config[1].Subnet 是上一步配置的 fixed-cidr-v6。
創(chuàng)建容器時,通過 --network my-net-ipv6 參數(shù),給容器開啟 IPv6 網(wǎng)絡,如 docker run --network my-net-ipv6 -it busybox sh:
ip addr show ,可以看到,網(wǎng)卡被分配了 IPv6 地址。 wget https://ipv6.icanhazip.com -O /dev/stdout 2>/dev/null 可以看到出網(wǎng) IPv6 地址。
審核編輯:湯梓紅
-
網(wǎng)絡
+關(guān)注
關(guān)注
14文章
7389瀏覽量
88211 -
IPv6
+關(guān)注
關(guān)注
6文章
657瀏覽量
59190 -
容器
+關(guān)注
關(guān)注
0文章
490瀏覽量
21986 -
命令
+關(guān)注
關(guān)注
5文章
658瀏覽量
21928 -
Docker
+關(guān)注
關(guān)注
0文章
446瀏覽量
11738
原文標題:Docker 開啟 IPv6
文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運維】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論