Docker四种通信模式:
-
封闭式容器:只存在Lo,无任何网络设备,Closed container,孤岛模式。
[root@ci_jenkins ~]# docker run -it --network none --rm busybox # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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 # ifconfig 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)
-
Bridge模式:一端在容器上,一段在docker0桥上,kvm上brctl就能实现。
[root@ci_jenkins ~]# docker run --name n2 -it --network bridge --rm busybox # ip a ... eth0@if32: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue link/ether 02:42:ac:11:00:05 brd ff:ff:ff:ff:ff:ff inet 172.17.0.5/16 brd 172.17.255.255 scope global eth0 ... # ifconfig eth0 |grep "inet addr" inet addr:172.17.0.5 Bcast:172.17.255.255 Mask:255.255.0.0 //补充知识 //为容器注入hostname,不再让其为ID,注意hostname和容器名字是两码事儿 # docker run -it --rm --name shit-con --hostname shit.com --add-host damn.com:233.233.233.233 busybox # cat /etc/hosts 172.17.0.5 shit.com shit //自动解析 233.233.233.233 damn.com //自己填的DNS解析 --dns 8.8.8.8 这个是添加DNS服务器,默认是docker0桥网关 # hostname shit.com
-
联盟式容器:共享Network,IPC,UST,一个容器加入另一个容器,共享容器的网络,容器AB之间进程可以使用lo本地通信,类似同一个主机上两个互通的进程。
[root@ci_jenkins ~]# docker run -itd --name n1 --rm alpine [root@ci_jenkins ~]# docker run -itd --name n2 --network container:n1 --rm alpine //这样n2就共享n1容器的network, IPC, UST了,但是Mount,PID,User还是独立的。 //n1创建一个文件,同一个目录下n2是不存在的。 //但是n1如果启动了web服务器,那么n2可以直接通过Lo来获得网页值。
-
开放式容器:联盟式容器延伸,由另一个容器变成共享宿主机的网络空间,容器进程可以和宿主机的进程通过lo互相通信。
[root@ci_jenkins ~]# docker run -it --network host alpine //相当于可以使用宿主机的网络NS
Expose端口的四种方式:
-
-p <container-port> : 将指定容器的端口映射至主机所有地址的一个动态端口,30000以上,纯随机不指定,不是well-known的,对于访问者有麻烦,但是好处是,同时启动N个nginx等类似服务器,可以不用担心80端口冲突,因为映射到宿主机的端口全部不一致,查看iptables发现映射规则自动生成,随着容器停止,映射规则自动删除。
[root@ci_jenkins ~]# docker run -d -p 80 nginx:1.14-alpine [root@ci_jenkins ~]# docker run -d -p 80 nginx:1.14-alpine [root@ci_jenkins ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES a4bedc6c7095 nginx:1.14-alpine "nginx -g 'daemon of…" 22 seconds ago Up 21 seconds 0.0.0.0:32770->80/tcp affectionate_darwin 2e817ca7c024 nginx:1.14-alpine "nginx -g 'daemon of…" 23 seconds ago Up 22 seconds 0.0.0.0:32769->80/tcp jolly_merkle [root@ci_jenkins ~]# docker port a4be 80/tcp -> 0.0.0.0:32770
-
-p <host-port>:<container-port>:固定了宿主机所有地址和容器指定端口映射关系,例如nginx都是用80:80
[root@ci_jenkins ~]# docker run -d -p 8000:80 nginx:1.14-alpine [root@ci_jenkins ~]# docker port xxxx 80/tcp -> 0.0.0.0:80
-
-p <hostxip>::<container-port>:固定宿主机指定ip,动态端口和容器指定端口的映射关系。
[root@ci_jenkins ~]# docker run -d -p 192.168.240.221::80 nginx:1.14-alpine [root@ci_jenkins ~]# docker port xxxx 80/tcp -> 192.168.240.221:32769
-
-p <hostx-ip>:<host-port>:<container-port>:固定宿主机指定ip,指定端口和容器指定端口的映射关系。
[root@ci_jenkins ~]# docker run -d -p 192.168.240.221:8000:80 nginx:1.14-alpine [root@ci_jenkins ~]# docker port xxxx 80/tcp -> 192.168.240.221:8000
如何修改docker默认的docker0网桥的IP网段
[root@ci_jenkins ~]# vim /etc/docker/daemon.json
{
"registry-mirrors": ["http://f1361db2.m.daocloud.io"],
"bip":"12.192.0.0/16", //修改docker0桥网段
"dns":["<dns1>","<dns2>"], //不让docker容器使用default dns,要求使用自定义的dns
"default-gateway":"<gateway>",
"host":["unix:///var/run/docker.sock","tcp://0.0.0.0:2375"] //不仅仅是通过本地sock监听,可以使用tcp远程操作docker,
}
如何创建区别于docker0类型的其他网桥,网桥通信
[root@ci_jenkins ~]# docker network create -d bridge --subnet "10.1.0.0/16" --gateway "10.1.0.1" sdbr0
5f3cf3544245d93b9d3492e5d188bb6e6672fcb53cebbdf581a7b592f80306b2
[root@ci_jenkins ~]# ip a
...
49: br-5f3cf3544245: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:4e:89:9b:91 brd ff:ff:ff:ff:ff:ff
inet 10.1.0.1/16 brd 10.1.255.255 scope global br-5f3cf3544245
valid_lft forever preferred_lft forever
[root@ci_jenkins ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
54d2ba21ece8 bridge bridge local
a866160bd2c7 host host local
53fc291f024c none null local
5f3cf3544245 sdbr0 bridge local
[root@ci_jenkins ~]# docker run -d --net sdbr0 nginx:1.14-alpine
//后通过docker inspect xx 查看可以看到--net是指定网桥类型。
//两个网桥之间只要服务器打开net.ipv4.ip_forward = 1就可以通信。