容器网络配置

Linux内核实现名称空间的创建

ip netns

可以借助ip netns命令来完成对 Network Namespace 的各种操作。ip netns命令来自于iproute安装包,一般系统会默认安装,如果没有的话,请自行安装。

注意:ip netns命令修改网络配置时需要 sudo 权限。

[root@localhost ~]# ip netns help
Usage: ip netns list
       ip netns add NAME
       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

创建network namespace

//创建一个名为ns0的命名空间
[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 ~]# ip netns add ns0
Cannot create namespace file "/var/run/netns/ns0": File exists

操作network namespace

//查看命名空间ns0的网卡信息
[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
//默认拥有一个环回网卡,而且处于关闭状态

//启动命名空间ns0的环回网卡
[root@localhost ~]# ip netns exec ns0 ip link set lo up
[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
[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.020 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.021 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.020 ms
64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.024 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 连接起来。

创建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: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:0c:29:f1:77:ce brd ff:ff:ff:ff:ff:ff
    inet 192.168.169.139/24 brd 192.168.169.255 scope global noprefixroute eth0
       valid_lft forever preferred_lft forever
    inet 192.168.169.141/24 brd 192.168.169.255 scope global secondary noprefixroute eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fef1:77ce/64 scope link 
       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:d6:9b:16:e9 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:d6ff:fe9b:16e9/64 scope link 
       valid_lft forever preferred_lft forever
6: veth0@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 6e:0e:68:16:e5:9e brd ff:ff:ff:ff:ff:ff
7: veth1@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 92:43:8d:7b:45:6e brd ff:ff:ff:ff:ff:ff
//新增了一对veth pair,并且处于未开启状态

实现network namespace间的通信

//再新创建一个命名空间ns1
[root@localhost ~]# ip netns add ns1
[root@localhost ~]# ip netns list
ns1
ns0

//将veth0和veth1分别加入到ns0和ns1
[root@localhost ~]# ip link set veth0 netns ns0
[root@localhost ~]# ip link set veth1 netns ns1
[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: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:0c:29:f1:77:ce brd ff:ff:ff:ff:ff:ff
    inet 192.168.169.139/24 brd 192.168.169.255 scope global noprefixroute eth0
       valid_lft forever preferred_lft forever
    inet 192.168.169.141/24 brd 192.168.169.255 scope global secondary noprefixroute eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fef1:77ce/64 scope link 
       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:d6:9b:16:e9 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:d6ff:fe9b:16e9/64 scope link 
       valid_lft forever preferred_lft forever
//加入到命名空间后,这对veth pair就移到命名空间里去了,想要进行操作就要对network namespace进行操作
[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
6: veth0@if7: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 6e:0e:68:16:e5:9e brd ff:ff:ff:ff:ff:ff link-netns ns1
[root@localhost ~]# ip netns exec ns1 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
7: veth1@if6: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000
    link/ether 92:43:8d:7b:45:6e brd ff:ff:ff:ff:ff:ff link-netns ns0


//将veth0和veth1激活平配置IP地址
[root@localhost ~]# ip netns exec ns0 ip link set veth0 up
[root@localhost ~]# ip netns exec ns0 ip addr add 10.1.1.1/24 dev veth0
[root@localhost ~]# ip netns exec ns1 ip link set lo up
[root@localhost ~]# ip netns exec ns1 ip link set veth1 up
[root@localhost ~]# ip netns exec ns1 ip addr add 10.1.1.2/24 dev veth1

//查看两个命名空间的网卡信息
[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
6: veth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 6e:0e:68:16:e5:9e brd ff:ff:ff:ff:ff:ff link-netns ns1
    inet 10.1.1.1/24 scope global veth0
       valid_lft forever preferred_lft forever
    inet6 fe80::6c0e:68ff:fe16:e59e/64 scope link 
       valid_lft forever preferred_lft forever
[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
7: veth1@if6: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 92:43:8d:7b:45:6e brd ff:ff:ff:ff:ff:ff link-netns ns0
    inet 10.1.1.2/24 scope global veth1
       valid_lft forever preferred_lft forever
    inet6 fe80::9043:8dff:fe7b:456e/64 scope link 
       valid_lft forever preferred_lft forever
       
//两个命名空间进行互通测试
[root@localhost ~]# ip netns exec ns0 ping 10.1.1.2
PING 10.1.1.2 (10.1.1.2) 56(84) bytes of data.
64 bytes from 10.1.1.2: icmp_seq=1 ttl=64 time=0.029 ms
64 bytes from 10.1.1.2: icmp_seq=2 ttl=64 time=0.026 ms

veth设备重命名

//关闭veth网卡
[root@localhost ~]# ip netns exec ns0 ip link set veth0 down

//将veth0重命名为eth0
[root@localhost ~]# ip netns exec ns0 ip link set dev veth0 name eth0

//打开eth网卡
[root@localhost ~]# ip netns exec ns0 ip link set eth0 up

//查看网卡信息
[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
6: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 6e:0e:68:16:e5:9e brd ff:ff:ff:ff:ff:ff link-netns ns1
    inet 10.1.1.1/24 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::6c0e:68ff:fe16:e59e/64 scope link 
       valid_lft forever preferred_lft forever
//命名空间ns1的更改也是同样的操作

docker的4种网络模式

网络模式 配置 说明
host --network host 容器和宿主机共享Network namespace
container --network container:NAME_OR_ID 容器和另外一个容器共享Network namespace
none --network none 容器有独立的Network namespace, 但并没有对其进行任何网络设置, 如分配veth pair 和网桥连接,配置IP等
bridge --network bridge 默认模式

bridge

当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。

从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。在主机上创建一对虚拟网卡veth pair设备,Docker将veth pair设备的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到docker0网桥中。

bridge模式是docker的默认网络模式,不写--network参数,就是bridge模式。使用docker run -p时,docker实际是在iptables做了DNAT规则,实现端口转发功能。

Docker网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,这也意味着外部网络无法通过直接Container-IP访问到容器。如果容器希望外部访问能够访问到,可以通过映射容器端口到宿主主机(端口映射),即docker run创建容器时候通过 -p 或 -P 参数来启用,访问容器的时候就通过[宿主机IP]:[容器端口]访问容器。

[root@localhost ~]# docker run -it --rm --name b1 busybox /bin/sh
/ # 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
12: eth0@if13: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
/ # exit

//--network bridge选项加不加都一样,默认就是bridge模式
[root@localhost ~]# docker run -it --rm --network bridge --name b1 busybox /bin/sh
/ # 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
14: eth0@if15: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
/ # exit

container

这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信。



//由此可见,container模式下的容器间关系就相当于一台主机上的两个不同进程//启动一个容器
[root@localhost ~]# docker run -it  --name b1 busybox /bin/sh
/ # 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
16: eth0@if17: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
 
//再打开一个终端,启动第二个容器,使用container网络模式与容器b1共享同一块网卡
[root@localhost ~]# docker run -it --network container:b1 --name b2 busybox /bin/sh
/ # 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
16: eth0@if17: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue 
    link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

//在容器b1上创建目录
/ # mkdir /tmp/data

//在容器b2上检查
/ # ls /tmp/
/ #
//到b2容器上检查/tmp目录会发现并没有这个目录,因为文件系统是处于隔离状态,仅仅是共享了网络而已

//在b2上部署一个站点
/ # echo "hello world!" > /tmp/index.html
/ # httpd -h /tmp/
/ # netstat -antl
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       
tcp        0      0 :::80                   :::*                    LISTEN 

//在b1容器上使用本地地址去访问
/ # ls /tmp/
data
/ # ls /tmp/data/
/ # wget -O - -q 127.0.0.1
hello world!

//由此可见,container模式下的容器间关系就相当于一台主机上的两个不同进程

host

如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。

使用host模式的容器可以直接使用宿主机的IP地址与外界通信,容器内部的服务端口也可以使用宿主机的端口,不需要进行NAT,host最大的优势就是网络性能比较好,但是docker host上已经使用的端口就不能再用了,网络的隔离性不好。

//将上面创建的两个容器删除
[root@localhost ~]# docker rm -f $(docker ps -aq)
b1db9818dce0
41a63756c9b1

//创建一个容器指定网络模式为host
[root@localhost ~]# docker run -it --rm --network host --name b1 busybox /bin/sh
/ # 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
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel qlen 1000
    link/ether 00:0c:29:f1:77:ce brd ff:ff:ff:ff:ff:ff
    inet 192.168.169.139/24 brd 192.168.169.255 scope global noprefixroute eth0
       valid_lft forever preferred_lft forever
    inet 192.168.169.141/24 brd 192.168.169.255 scope global secondary noprefixroute eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fef1:77ce/64 scope link 
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue 
    link/ether 02:42:83:93:e7:2d 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:83ff:fe93:e72d/64 scope link 
       valid_lft forever preferred_lft forever
/ # exit

none

使用none模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置。也就是说,这个Docker容器没有网卡、IP、路由等信息。需要我们自己为Docker容器添加网卡、配置IP等。

这种网络模式下容器只有lo回环网络,没有其他网卡。none模式可以在容器创建时通过--network none来指定。这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性。

应用场景:

  • 启动一个容器处理数据,比如转换数据格式
  • 一些后台的计算和处理任务
[root@localhost ~]# docker run -it --rm --network none --name b1 busybox /bin/sh
/ # 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
/ # exit

容器的常用操作

查看容器的主机名

[root@localhost ~]# docker run -it --rm --name b1 busybox /bin/sh
/ # hostname 
a2ed01d59162

在创建容器是指定容器的主机名

[root@localhost ~]# docker run -it --rm --name b1 --hostname zic busybox /bin/sh
/ # hostname 
zic

手动指定容器要使用的dns

//默认情况下,容器的dns和docker主机的dns一样
[root@localhost ~]# docker run -it --rm --name b1 --dns 114.114.114.114 busybox /bin/sh
/ # cat /etc/resolv.conf 
nameserver 114.114.114.114

/ # nslookup -type=a 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: 182.61.200.7
Name:	www.a.shifen.com
Address: 182.61.200.6

创建容器是手动向/etc/hosts文件下添加IP地址映射

[root@localhost ~]# docker run -it --rm --name b1 --add-host a.com:1.1.1.1 --add-host b.com:2.2.2.2 busybox /bin/sh
/ # 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	a.com
2.2.2.2	b.com
172.17.0.2	8f8ab041a170

开放容器端口

执行docker run的时候有个-p选项,可以将容器中的应用端口映射到宿主机中,从而实现让外部主机可以通过访问宿主机的某端口来访问容器内应用的目的。

-p选项能够使用多次,其所能够暴露的端口必须是容器确实在监听的端口

  • -p
    • 将指定的容器端口映射至主机所有地址的一个动态端口
[root@localhost ~]# docker run -it -d --name h1 -p 80 httpd
fc3e9d2515328be05ce771451c2abe24348bb80738a6d9f7ae662d27b54506cb
[root@localhost ~]# docker port h1
80/tcp -> 0.0.0.0:49153
80/tcp -> :::49153
  • -p :
    • 将容器端口映射至指定的主机端口
[root@localhost ~]# docker run -it -d --name h2 -p 81:80 httpd
971963de377d6de2611dff0d4cf25c3c0991a096be1a360f0e40318d2b97190b
[root@localhost ~]# docker port h2
80/tcp -> 0.0.0.0:81
80/tcp -> :::81
  • -p : :
    • 将指定的容器端口映射至主机指定的动态端口
[root@localhost ~]# docker run -id -d --name h3 -p 192.168.169.139::80 httpd
6d301f90e0f28aad0b38eb8c5a9e2f8ef1e5efd37e7701e250d2d5f605b15390
[root@localhost ~]# docker port h3
80/tcp -> 192.168.169.139:49153
[root@localhost ~]# curl 192.168.169.139:49153
<html><body><h1>It works!</h1></body></html>
  • -p ::
    • 将指定的容器端口映射至主机指定的端口
[root@localhost ~]# docker run -it -d --name h4 -p 192.168.169.139:80:80 httpd
25aa69c4bd33bcf468081aacd98dfc61f056ac47863e85728dadce4d099204dc
[root@localhost ~]# docker port h4
80/tcp -> 192.168.169.139:80

自定义docker0桥的网络属性信息

自定义docker0桥的网络属性信息需要修改/etc/docker/daemon.json配置文件

//查看docker0网桥的IP地址
[root@localhost ~]# ip a | grep docker0
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
    
//修改daemon.json文件
[root@localhost ~]# vim /etc/docker/daemon.json 
{
  "registry-mirrors": ["https://l3f007f6.mirror.aliyuncs.com"],
  "bip": "192.168.1.1/24"  //添加这一行
}

//重启docker
[root@localhost ~]# systemctl restart docker

//查看docker0网桥的ip地址
[root@localhost ~]# ip a | grep docker0
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    inet 192.168.1.1/24 brd 192.168.1.255 scope global docker0

//创建一个容器,并查看容器的IP地址
[root@localhost ~]# docker run --name web -itd httpd
5252a55a8982899585e500b314730f5bff51b88e2b61e027a903cd3084ea38ce
[root@localhost ~]# docker container inspect web | grep -i ipaddress
            "SecondaryIPAddresses": null,
            "IPAddress": "192.168.1.2",
                    "IPAddress": "192.168.1.2",

docker远程连接

修改docker.service文件

[root@localhost ~]# vim /usr/lib/systemd/system/docker.service 
$(修改ExecStart如下)
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 - H fd:// --containerd=/run/containerd/containerd.sock

重启docker

[root@localhost ~]# systemctl daemon-reload 
[root@localhost ~]# systemctl restart docker.service 

配置防火墙规则,允许2375端口通过

[root@localhost ~]# firewall-cmd --permanent --add-rich-rule='rule family=ipv4 source address=0.0.0.0/0 port port=2375 protocol=tcp accept'
success
[root@localhost ~]# firewall-cmd --reload 
success

在客户机进行尝试(客户机也需要安装docker)

//查看镜像
[root@harbor ~]# docker -H tcp://192.168.169.139:2375 images
REPOSITORY                         TAG       IMAGE ID       CREATED         SIZE
harbor.example.com/library/httpd   v1.1      d12b6463ed10   12 days ago     601MB
busybox                            latest    beae173ccac6   7 months ago    1.24MB
httpd                              latest    dabbfbe0c57b   8 months ago    144MB
centos                             latest    5d0da3dc9764   11 months ago   231MB

//查看容器
[root@harbor ~]# docker -H tcp://192.168.169.139:2375 ps -a
CONTAINER ID   IMAGE     COMMAND              CREATED          STATUS                     PORTS     NAMES
5252a55a8982   httpd     "httpd-foreground"   21 minutes ago   Exited (0) 9 minutes ago             web

docker创建自定义桥

创建一个额外的自定义桥,区别于docker0

//查看当前docker的网络
[root@localhost ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
ee87c4c234e4   bridge    bridge    local
de97ae7a9cca   host      host      local
5df53278d91b   none      null      local

//创建一个自定义网络,名为zicbr0,参数'--subnet'是网段,'--gateway'是网关,也就是这个网络的ip
[root@localhost ~]# docker network create -d bridge --subnet "192.168.2.0/24" --gateway "192.168.2.1" zicbr0
7be387430a2a634b9c8341020a28045bf9bb09dc31e26f16a617830de1c17907
[root@localhost ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
ee87c4c234e4   bridge    bridge    local
de97ae7a9cca   host      host      local
5df53278d91b   none      null      local
7be387430a2a   zicbr0    bridge    local

使用新创建的自定义桥来创建容器:

[root@localhost ~]# docker run -it --network zicbr0 busybox
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:C0:A8:02:02  
          inet addr:192.168.2.2  Bcast:192.168.2.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:10 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:836 (836.0 B)  TX bytes:0 (0.0 B)

新建会话再创建一个容器,使用默认的bridge桥

[root@localhost ~]# docker run -it busybox
/ # ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:C0:A8:01:02  
          inet addr:192.168.1.2  Bcast:192.168.1.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:13 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:1102 (1.0 KiB)  TX bytes:0 (0.0 B)

测试一下两个容器可不可以通讯

/ # ping 192.168.1.2
PING 192.168.1.2 (192.168.1.2): 56 data b

让两个容器之间可以相互通讯

//新建一个会话,让两个容器分别连接到对方的网络
[root@localhost ~]# docker network connect bridge d7fa80741843
[root@localhost ~]# docker network connect zicbr0 b2f050a482e1

//再次进行测试,是否能够通讯
/ # ping -c 4 192.168.1.2
PING 192.168.1.2 (192.168.1.2): 56 data bytes
64 bytes from 192.168.1.2: seq=0 ttl=64 time=0.062 ms
64 bytes from 192.168.1.2: seq=1 ttl=64 time=0.046 ms
64 bytes from 192.168.1.2: seq=2 ttl=64 time=0.099 ms
64 bytes from 192.168.1.2: seq=3 ttl=64 time=0.053 ms

--- 192.168.1.2 ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 0.046/0.065/0.099 ms
posted @ 2022-08-10 10:25  Zic师傅  阅读(79)  评论(0编辑  收藏  举报