docker入门(6)--docker单主机网络

1. 容器网络模型

docker定义了一个非常简单的网络模型,被称为“container network model (CNM)”。


CNM

CNM有三要素:

  • Sandbox: The sandbox perfectly isolates a container from the outside world. No inbound network connection is allowed into the sandboxed container. Yet, it is very unlikely that a container will be of any value in a system if absolutely no communication with it is possible. To work around this, we have element number two, which is the endpoint.
  • Endpoint: An endpoint is a controlled gateway from the outside world into the network's sandbox that shields the container. The endpoint connects the network sandbox (but not the container) to the third element of the model, which is the network.
  • Network: The network is the pathway that transports the data packets of an instance of communication from endpoint to endpoint, or ultimately from container to container.

CNM只是定义了一种模型,关于它的一些具体实际应用以及相关特性如下:

Network Company Scope Description
Bridge Docker Local Simple network based on Linux bridges allowing networking on a single host
Macvlan Docker Local Configures multiple layer 2 (that is,MAC) addresses on a single physical host interface
Overlay Docker Global Multinode-capable container network based on Virtual Extensible LAN (VXLan)
Weave Net Weaveworks Global Simple, resilient, multihost Docker networking
Contiv Network Plugin Cisco Global Open source container networking

以上所有不被docker直接支持的网络类型,都可以以插件的形式使用。

2. 桥接网络

在安装好docker host之后,默认就创建了一个桥接网络,同时还创建了一个主机网络和空网络。使用docker network ls命令可以查看:

[root@node2 ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
5e159057e92a        bridge              bridge              local
c2921c2d8a83        host                host                local
85ba00ab2fed        none                null                local

使用docker network inspect bridge可以查看该网络的详细情况,主要包括网络驱动类型,网络IP地址范围,当前有哪些容器连接到了该网络,以及各个容器获取的IP地址等。
使用docker network create命令可以创建一个自定的网络:

[root@node2 ~]# docker network create --driver bridge sample-net
0b482881387b37702c7e28a14cb20e0b9242baf1c1b72221a7c356decf2bf7a0

桥接网络的工作原理大致如下:



eth0为主机的物理网卡地址,docker0为docker host默认创建的桥接网络,默认的容器也都连接到这个网络,并获取相应的网络地址。
桥接网络有以下一些特性:

  • 一个主机上可以存在多个桥接网络。
  • 连接到同一个桥接网络的容器,通过IP或者容器名称,可以互相访问。
  • 两个分别连接到不同桥接网络上的容器之间,默认无法互相访问。
  • 一个容器可以连接多个桥接网络。

下面我们举一个例子来验证上面的特性:
我们将创建5个容器c1-c5,c1、c2连接网络my-network1,c3、c4连接网络my-network2,c5同时连接这两个网络。

[root@node2 ~]# docker container run --name c1 --network my-network1 -d alpine:latest ping 127.0.0.1
325dcba69349462c0b483d5c21134439d2994cbb4b95a73c507b81025b0bb4ea
[root@node2 ~]# docker container run --name c2 --network my-network1 -d alpine:latest ping 127.0.0.1
f865664592ae0a2cae84261d7150984e93d3b64021bf5f80057e922ffdd645fd
[root@node2 ~]# docker container run --name c3 --network my-network2 -d alpine:latest ping 127.0.0.1
079a851285047cb949c3406706ff71499b203ed86f3b36d4df518a1ee99f1efb
[root@node2 ~]# docker container run --name c4 --network my-network2 -d alpine:latest ping 127.0.0.1
06c792f004281d2147c719ae1ee42cc08805686e55a7201f42b586559c81ee84
# 我参考书籍上的命令,使用如下命令准备将c5同时连接到两个网络,但最终发现无法生效,c5始终只能连接到一个网络,并且是后出现的--network参数会覆盖前面的。
# 也就是下面的命令只会让c5连接到my-network2网络。(可能是docker版本不同导致)
[root@node2 ~]# docker container run --name c5 --network my-network1 --network my-network2 -d alpine:latest ping 127.0.0.1
5c64d82cab34f42fd8b6b114fa826c088241205869e8609034ab750c75d9ce11
# 经过查询,发现可以通过如下命令,分成两步,将一个容器连接到两个网络。
[root@node2 ~]# docker container run --name c5 --network my-network1 -d alpine:latest ping 127.0.0.1
[root@node2 ~]# docker network connect my-network2 c5

现在简单进入c5进行验证:

[root@node2 ~]# docker container exec -it c5 /bin/sh
/ # ping c1
PING c1 (172.19.0.2): 56 data bytes
64 bytes from 172.19.0.2: seq=0 ttl=64 time=0.203 ms
64 bytes from 172.19.0.2: seq=1 ttl=64 time=0.123 ms
^C
--- c1 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.123/0.163/0.203 ms
/ # ping c2
PING c2 (172.19.0.3): 56 data bytes
64 bytes from 172.19.0.3: seq=0 ttl=64 time=0.189 ms
64 bytes from 172.19.0.3: seq=1 ttl=64 time=0.127 ms
^C
--- c2 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.127/0.158/0.189 ms
/ # ping c3
PING c3 (172.20.0.2): 56 data bytes
64 bytes from 172.20.0.2: seq=0 ttl=64 time=0.200 ms
64 bytes from 172.20.0.2: seq=1 ttl=64 time=0.123 ms
^C
--- c3 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.123/0.161/0.200 ms
/ # ping c4
PING c4 (172.20.0.3): 56 data bytes
64 bytes from 172.20.0.3: seq=0 ttl=64 time=0.180 ms
64 bytes from 172.20.0.3: seq=1 ttl=64 time=0.126 ms
^C
--- c4 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss
round-trip min/avg/max = 0.126/0.153/0.180 ms

可以发现c5与c1-c4都可以连通,c1、c2、c5互通,c3、c4、c5互通,其他的无法互通。
最后,可以通过如下命令,删除网络:
docker network rm my-network1
备注:删除前,必须确认没有容器在使用该网络。

3. 主机网络

创建容器时,使用主机网络的话,容器将会获取与主机一样的IP地址,一般不推荐使用主机网络。
docker container run --rm -it --network host alpine:latest /bin/sh

4. 空网络

有些时候,我们可能出于测试的目的,所需的容器并不需要网络,这时候,可以使用空网络。
docker container run --rm -it --network none alpine:latest /bin/sh

5. 连接一个已经存在的网络命名空间

通常来说,每个容器都有自己的network namespace,容器之间的互相访问取决于我们前面提到过的网络设置相关。但还有一种方式,可以让两个容器共用一个网络命名空间,从而达到让这两个容器之间,通过localhost就可以互相访问。具体示例如下:

[root@node2 ~]# docker network create --driver bridge my-net
3095dc7e2e9e4f52f0e47ad9d4d450478a06946c5353e1d0968e4198424e2c4f
[root@node2 ~]# docker container run --name my-web --network my-net -d nginx:alpine
db87165666e901bbe3875f1f236ed22feb5088e93d0e02859897ff8c3c8a3db1
[root@node2 ~]# docker container run -it --network container:my-web alpine /bin/sh
/ # wget -O- http://localhost
Connecting to localhost (127.0.0.1:80)
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>

上面的例子中,第二个容器使用了--network container:my-web参数,让这两个容器使用同一个网络命名空间,从而实现类似访问本机服务一样,访问第一个容器的服务。
在Kubernetes的pod中就使用了这样的特性,以后将会介绍。

6. 网络端口管理

docker中的端口管理用于,映射主机IP端口与容器内IP端口之间的关系。
例如:
docker container run --name my-web1 -d -p 8080:80 nginx:alpine
-p参数将主机的8080端口映射至容器内的80端口。
-P(大写)参数随机的将主机端口映射至容器的80端口。
如果你需要映射udp关系,可以使用类似-p 3000:4321/udp的参数。特别说明的是,如果既需要tcp,也需要udp,你必须单独指定两个参数。

参考:Multiple Docker Networks

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容