Docker网络

Docker理解

问题:docker如何处理容器网络访问的?如容器与容器之间,宿主机与容器之间能否ping通

通过ip addr查看本地ip地址,我们发现除了本机回环地址和阿里云的内网地址外,还多了一个网卡:Docker0,这是Docker服务启动后自动生成的
在这里插入图片描述

测试如下:

// 启动tomcat容器并查看tomcat1中的ip
[root@us4ci6jaxom1jjz2 tomcat]# docker run -d -P --name tomcat01 tomcat:9  
df6b5e81ac59dda7d9e9f68ea446c4cf8ed3df51844a149634cdf095cac10ba5
[root@us4ci6jaxom1jjz2 tomcat]# docker exec -it tomcat01 ip addr

tomcat1中的网络:158:enth0@if159
在这里插入图片描述

宿主机上查看,发现多了个网卡,159:enth0@if158
都是一对一的,这是Docker为其自动分配的
在这里插入图片描述

// 知道ip后测试主机和容器之间是否能ping通
[root@us4ci6jaxom1jjz2 tomcat]# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.100 ms
...可以ping通容器内部     

//测试tomcat01和tomcat02是否可以ping通
[root@us4ci6jaxom1jjz2 tomcat]#docker run -d -P --name tomcat02 tomcat
[root@us4ci6jaxom1jjz2 tomcat]# docker exec -it tomcat02 ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.089 ms
64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.109 ms
...可以ping通容器内部      

原理
1、linux可以ping通docker容器内部,因为docker0的ip地址为172.17.0.1,容器为172.17.0.2。
2、Docker使用的是Linux的桥接,我们每启动一个docker容器,docker就会给docker容器分配一个默认可用的ip,我们只要安装了docker,就会有一个网卡docker0桥接模式【桥接到真实物理网络上】,使用的技术是evth-pair技术!【evth-pair就是一对的虚拟设备接口,他们都是成对出现的,一段连着协议,一段彼此相连,充当一个桥梁】
正因为有这个特性,evth-pair充当一个桥梁,连接着各种虚拟网络设备的
OpenStack,Docker容器之间的连接,OVS的连接,都是使用的evth-pair技术
3、docker中的所有网络接口都是虚拟的 ,转发效率高。删除容器后,对应的网桥也随之删除。
4、Docker使用的是Linux的桥接,宿主机中是一个Docker容器的网桥docker0,所有容器不指定网络的情况下,都是docker0转接的,docker会给我们的容器分配一个默认可用的ip
在这里插入图片描述

结论:tomcat01和tomcat02是共同用一个交换机,docker0
所有容器不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用ip
在这里插入图片描述

–link

场景思考:我们编写一个微服务其连接了数据库,如果数据库ip换掉了,我们希望不用换ip而是通过容器名进行访问容器从而正常运行项目,如何解决呢? 在容器启动命令中加入选项:–link,即可根据容器名访问容器。
docker run -d -P --link 容器名/id 镜像名/id

//通过容器名无法ping通
[root@us4ci6jaxom1jjz2 ~]# docker exec -it tomcat02 ping tomcat01
ping: tomcat01: Name or service not known

[root@us4ci6jaxom1jjz2 ~]# docker run -d -P --name tomcat03 --link tomcat02 tomcat
ca7a4887868f17f3c92de628612bed1e65a6e0ae7edf9e3a7be4edc95c6446e1
[root@us4ci6jaxom1jjz2 ~]# docker exec -it tomcat03 ping tomcat02
PING tomcat02 (172.17.0.3) 56(84) bytes of data.
64 bytes from tomcat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.100 ms
....ping成功
//--link的设置是单向的,tomcat3能ping通tomcat2,而tomcat2不能ping通3
[root@us4ci6jaxom1jjz2 ~]# docker exec -it tomcat02 ping tomcat03
ping: tomcat03: Name or service not known

//查看tomcat03的网络情况,发现tomcat03的host文件中写了tomcat02的ip映射,所以可以ping通
[root@us4ci6jaxom1jjz2 ~]# docker exec -it tomcat03 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
172.17.0.3	tomcat02 fa0e92f1732f    //发现其包含了tomcat02名字与ip的映射
172.17.0.4	ca7a4887868f
[root@us4ci6jaxom1jjz2 ~]#

–link就是在hosts配置中将域名和ip地址直接绑定在了一起,而tomcat02的host文件中没有配置,所以tomcat02无法ping通tomcat03
这种绑定网络的方式太繁琐了,不推荐使用,一般是自定义网络

自定义网络

//查看docker的网络情况
##
网络模式
bridge:桥接docker(默认,自己创建也是用bridge模式)
none:不配自网络(特定场景使用,比如,高安全环境,随机生成字符串的功能,那么这个容器就可以用none)
host:和宿主机共享的网络
container:容器网络连通!(用的少,局限大)
##
[root@us4ci6jaxom1jjz2 ~]# docker network ls  
NETWORK ID     NAME      DRIVER    SCOPE
0516cf2f35f9   bridge    bridge    local  //bridge就是docker0
c0106ffe0a08   host      host      local
b320f8de1c23   none      null      local
[root@us4ci6jaxom1jjz2 ~]# docker network inspect 0516cf2f35f9  //查看docker0中的网络情况
[
    {
        "Name": "bridge",
     ....
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1" #docker0
                }
....
如下docker0网络中还有其配置的容器信息

在这里插入图片描述

docker run -d -P --name tomcat01 tomcat #该命令默认参数–net bridge
docker run -d -P --name tomcat01 --net bridge tomcat
docker run 命令默认带有一个参数–-net bridge,此处的bridge指的就是docker0。(docke0特点,默认,域名不能访问,–link可以打通连接或自定义网络)
可以使用docker network create 命令创建一个网络,然后将容器连接到网络中

测试

# 我们可以自定义一个网络
# --dirver bridge
# --subnet 192.168.0.0/16   子网
# -- geteway 192.168.0.1  #网关
[root@us4ci6jaxom1jjz2 ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
40b2744053d99b7d372cd42583ec6d4f455f05293939c445bbc2947d5953756b

///我们不仅在docker network ls命令下发现了这个新创建的网络newnet,还可以使用docker network inspect命令查看其详细信息,包括了我们创建时定义的子网ip和网关
[root@us4ci6jaxom1jjz2 ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
0516cf2f35f9   bridge    bridge    local
c0106ffe0a08   host      host      local
40b2744053d9   mynet     bridge    local
b320f8de1c23   none      null      local

在这里插入图片描述

//我们自己的网络就创建好了,以后可以自己将服务挂到上面
[root@us4ci6jaxom1jjz2 ~]# docker run -d -P --name tomcat-net-01 --net mynet tomcat
775d1ec746a61787a85e8cd3739f2f96082af06d2453b7af517522230c87c90c
[root@us4ci6jaxom1jjz2 ~]# docker run -d -P --name tomcat-net-02 --net mynet tomcat
b3797ebf069b7e1c920db35956d101f6a3e2f086a1c95a39d025b6ee465e4c50
[root@us4ci6jaxom1jjz2 ~]# docker network inspect mynet

可看到容器添加到了该网络下:
在这里插入图片描述

主要是让容器之间从默认走docker0的方式(无法直接通过容器名链接),改变到将两个容器都放在一个局域网内,使两个容器可通信

#再次测试,可以直接ping通
[root@us4ci6jaxom1jjz2 ~]# docker exec  -it tomcat-net-01 ping tomcat-net-02  
PING tomcat-net-02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.089 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.070 ms

我们自定义的网络docker都已经帮我们维护好了对应的关系,推荐我们平时这样使用网络!
好处:
redis 集群,mysql集群,不同的集群使用不同的网络,保证集群的安全和健康的

网络连通

如下,不同网段之间无法连通,如何让一个网段中的一个容器访问到另一个网段的容器?
在这里插入图片描述
Docker0和mynet两网卡之间不能打通,而是将一个容器连到目的网络上
在这里插入图片描述

查看帮助信息可看到docker network connect可将容器连接到一个网络上
在这里插入图片描述
在这里插入图片描述

#测试打通 tomcat01 - mynet
//由于tomcat01和mynet两个网段不同,不能彼此ping通,此时可通过docker network connect命令打通容器与网络之间的连接
[root@us4ci6jaxom1jjz2 ~]# docker network connect mynet tomcat01
[root@us4ci6jaxom1jjz2 ~]# docker network inspect mynet

容器连到自定义网络后,发现实际是将tomcat01的配置到了mynet中
一个容器两个ip!,阿里云服务器公网ip,私网络ip
在这里插入图片描述

//01连通成功
[root@us4ci6jaxom1jjz2 ~]# docker exec -it tomcat01 ping tomcat-net-01
PING tomcat-net-01 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.082 ms
...
[root@us4ci6jaxom1jjz2 ~]# docker start tomcat02
tomcat02
//02由于没有加入mynet中,依旧打不通
[root@us4ci6jaxom1jjz2 ~]# docker exec -it tomcat02 ping tomcat-net-01
ping: tomcat-net-01: Name or service not known
[root@us4ci6jaxom1jjz2 ~]#

连接之后,指定的容器与指定的网络下的所有容器都是互联的
相当于把当前容器加到某个已经设置好的局域网中

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值