容器网络管理

发布时间 2024-01-04 17:57:46作者: FuShudi

容器的默认网络类型

默认的网络类型有3种,分别是bridge,host和none,可以通过命令docker network ls 查看

[root@docker ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
26867c6deb71   bridge    bridge    local
6b45760395f7   host      host      local
b892c408a462   none      null      local

在我们使用镜像去创建容器时,默认使用的类型就是bridge类型,当然,也可以在创建时通过命令去指定使用的网络
我们可以启动一个容器去看看他的IP地址

[root@docker ~]# docker run -it --name test  alpine
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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
13: eth0@if14: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP 
    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

我们可以看到这个容器使用的IP地址是172.17.0.2,那么这个IP是怎么来的呢,为什么是这个IP段呢

bridge网络类型

其实在安装完docker之后,你的机器上就会多出来一个网卡叫做docker0,可以自行验证,那么这个docker0的IP地址就是172.17.0.1/16
那么现在就能解释的通了,docker0就是用来桥接容器和宿主机之间的一个网桥,使宿主机和容器之间的网络可以互通,并且会给新启动的容器分配这个地址段的IP地址,那么这个就是bridge类型

这种类型的接口我们可以通过命令brctl去查看

brctl 命令

这个命令如果不存在的话,可以这样操作

[root@docker ~]# yum install bridge-utils

安装完成之后就可以使用这个命令了

[root@docker ~]# brctl show
bridge name	bridge id		STP enabled	interfaces
docker0		8000.024257f2b6f4	no		veth2f3436b

如果你的interfaces下面没有显示接口,说明你现在没有正在运行的容器,你可以尝试启动一个容器,他这里就会正常显示了
这条命令的回显我们可以看到interfaces 显示的是veth2f3436b,那么这个接口是哪里来的呢,我们可以通过 ip a去查看

[root@docker ~]# ip a
其他的接口省略
16: veth2f3436b@if15: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether 1a:dc:39:07:fb:d9 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::18dc:39ff:fe07:fbd9/64 scope link 
       valid_lft forever preferred_lft forever

我们可以看到是16号接口,名字叫veth2f3436b@if15,那么这个veth2f3436b跟上面的interfaces对应上了,那么后面这个@15是什么意思呢
这个@15的意思是链接到容器内的15号接口了,我们可以进入容器查看他的网卡是不是15号接口,或者说容器内的网卡是不是也链接到宿主机的16号接口上了,也就是xxxx@if16

# 通过docker exec 进入容器
[root@docker ~]# docker exec -it linux /bin/sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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
15: eth0@if16: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP 
    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
/ # 

我们可以看到,他的接口确实是15,而且网卡名是eth0@if16,跟我们之前的预想完全一样
说明了他们是一对veth pair这样他们就建立起了连接

host网络类型

这个host模式并不是vmware里面的那个仅主机模式,这个host模式是将你宿主机的网卡信息复制到容器里面,也就是说你的宿主机的网卡有哪些,那么你使用host模式的容器的网卡也就是那些
看示例

验证步骤是 1.先本地查看网卡信息 2. 启动容器使用host模式 3.在容器内查看网卡信息,对比是否一致
# 查看本地网卡
[root@docker ~]# 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: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether 00:0c:29:de:74:05 brd ff:ff:ff:ff:ff:ff
    altname enp3s0
    inet 192.168.200.200/24 brd 192.168.200.255 scope global noprefixroute ens160
       valid_lft forever preferred_lft forever
    inet 192.168.200.133/24 brd 192.168.200.255 scope global secondary dynamic noprefixroute ens160
       valid_lft 1403sec preferred_lft 1403sec
    inet6 fe80::20c:29ff:fede:7405/64 scope link 
       valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:57:f2:b6:f4 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:57ff:fef2:b6f4/64 scope link 
       valid_lft forever preferred_lft forever
16: veth2f3436b@if15: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether 1a:dc:39:07:fb:d9 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::18dc:39ff:fe07:fbd9/64 scope link 
       valid_lft forever preferred_lft forever

# 启动容器
[root@docker ~]# docker run -it --name linux3 --network host alpine
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
    link/ether 00:0c:29:de:74:05 brd ff:ff:ff:ff:ff:ff
    inet 192.168.200.200/24 brd 192.168.200.255 scope global ens160
       valid_lft forever preferred_lft forever
    inet 192.168.200.133/24 brd 192.168.200.255 scope global secondary dynamic ens160
       valid_lft 1391sec preferred_lft 1391sec
    inet6 fe80::20c:29ff:fede:7405/64 scope link 
       valid_lft forever preferred_lft forever
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP 
    link/ether 02:42:57:f2:b6:f4 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:57ff:fef2:b6f4/64 scope link 
       valid_lft forever preferred_lft forever
16: veth2f3436b@if15: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue master docker0 state UP 
    link/ether 1a:dc:39:07:fb:d9 brd ff:ff:ff:ff:ff:ff
    inet6 fe80::18dc:39ff:fe07:fbd9/64 scope link 
       valid_lft forever preferred_lft forever

在启动容器的时候使用 --network 是可以指定使用的网络类型的
我们可以看到,容器内的网卡信息与宿主机的网卡信息完全一致,连IP,MAC地址都是完全一致的,这个很好理解

none网络类型

见名知意,none就是没有,使用这个网络类型的容器除了环回口之后是没有任何其他的IP地址的,也就是没有网络

# 创建容器使用none模式查看
[root@docker ~]# docker run -it --name linux4 alpine
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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

可以看到,容器内部现在只有一个loopback接口

自定义网络(自行创建)

[root@docker ~]# docker network create -d bridge --subnet 10.0.0.0/8 --gateway 10.255.255.254 mynet
# -d 指定的是网络的类型,我想再创建一个桥接网络
# --subnet 是指定子网,后面我如果使用这个网络去启动容器,那么容器的IP地址会在我指定的这个子网里面去分配
# --gateway 是指定网关
# mynet 是我要创建的网络名

创建完之后我们可以使用docker network ls去查看是否已经创建成功了,也可以在宿主机上使用ip a去查看,会多出来一个网卡,ip地址就是你刚刚指定的网关地址

其他的网卡省略
21: br-437cc00b0002: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:c4:0e:ad:88 brd ff:ff:ff:ff:ff:ff
    inet 10.255.255.254/8 brd 10.255.255.255 scope global br-437cc00b0002
       valid_lft forever preferred_lft forever
    inet6 fe80::42:c4ff:fe0e:ad88/64 scope link
[root@docker ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
26867c6deb71   bridge    bridge    local
6b45760395f7   host      host      local
437cc00b0002   mynet     bridge    local
b892c408a462   none      null      local

可以看到,刚刚创建的mynet是存在的,那么我们使用这个网络去启动一个容器,看看IP地址是否是我们指定的子网

/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN 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
22: eth0@if23: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP 
    link/ether 02:42:0a:00:00:01 brd ff:ff:ff:ff:ff:ff
    inet 10.0.0.1/8 brd 10.255.255.255 scope global eth0
       valid_lft forever preferred_lft forever

可以看到,IP地址就是我们刚刚指定的子网里面的一个地址

容器网络互联

实验 使用容器搭建wordpress,不能将MySQL进行端口映射到本地

实验步骤:

  1. 拉取MySQL镜像,wordpress镜像
  2. 启动MySQL容器,使用环境变量设置初始化密码,并创建wordpress数据库,将数据持久化存储到本地
  3. 启动wordpress数据库,使用环境变量让他自己对接数据库,映射80端口到本地,允许其他人访问

实验开始:

# 第一步操作
# 拉取镜像,默认拉取最新版本
[root@docker ~]# docker pull mysql
[root@docker ~]# docker pull wordpress

# 第二步操作
# 启动MySQL容器,并设置密码,设置数据库
docker run -itd --name db -e MYSQL_ROOT_PASSWORD=123 -e MYSQL_DATABASE=wordpress -v /db/:/var/lib/mysql mysql

# 第三步操作
# 启动wordpress容器,并使用环境变量对接数据库
# 环境变量的参数可以启动一个容器并进入,然后cat容器里面的wp-config-docker.php 这个文件来查看需要哪些参数
# 1.WORDPRESS_DB_NAME
# 2.WORDPRESS_DB_USER
# 3.WORDPRESS_DB_PASSWORD
# 4.WORDPRESS_DB_HOST
# 可以看到使用这些参数就可以了
# 开始启动容器
[root@docker ~]# docker run -itd --name wordpress --link db:db -e WORDPRESS_DB_NAME=wordpress -e WORDPRESS_DB_USER=root -e WORDPRESS_DB_PASSWORD=123 -e WORDPRESS_DB_HOST=db -p 80:80 wordpress
0da2368bc8e286c183c541b232a10482ccd3fbd79fc2ee755930dbb1b16be8c6

# --link db:db的意思是 将名叫db的容器做一个hosts映射,在容器内我可以通过db就可以访问到db这个容器,当然 后面这个db是可以随便修改的
[root@docker ~]# docker exec -it wordpress /bin/bash
root@0da2368bc8e2:/var/www/html# cat /etc/hosts
…… 省略其他
172.17.0.2	db d2973aefaf2e
172.17.0.3	0da2368bc8e2
# 可以看到hosts文件里面是有映射的
# 现在容器没有报错,我们可以通过浏览器来访问映射的80端口来查看是否正确

我们往下翻找到简体中文,点击下一步

设置好这些之后我们点击安装wordpress他就进入了wordpress的页面了

实验就做完了