Docker-网络初体验

Posted guardwhy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Docker-网络初体验相关的知识,希望对你有一定的参考价值。

1.1 Docker0初体验

1、清空服务器所有的容器和正在运行的所有镜像

docker rm -f $(docker ps -a -q)       # 删除所有容器
docker rmi -f $(docker images -qa)      # 删除全部镜像

2、查看本地ip,执行命令:ip addr

网络端口分析

1: lo: 127.0.0.1/8  #本机回环地址
2: eth0: 172.17.183.201 #阿里云内网地址
3: docker0: 172.18.0.1 # docker0 地址

3、docker是如何处理容器间的网络访问的?

# 启动 mytomcat01
[root@guardwhy ~]# docker run -d -P --name mytomcat01 tomcat
latest: Pulling from library/tomcat
42d8171e56e6: Pull complete 
774078a3f8bb: Pull complete 
Digest: sha256:71703331e3e7f8581f2a8206a612dbeedfbc7bb8caeee972eadca1cc4a72e6b1
Status: Downloaded newer image for tomcat:latest
eb4d1a5d5884ab76d06aaa6b1209d96905f0f822b78ca0ce82bea6a1532c9566

# 查看容器的内部网络地址:ip addr
# 容器启动的时候会得到一个 eth0@if33的IP地址,这是docker分配的!!!
[root@guardwhy ~]# docker exec -it mytomcat01 ip addr
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
32: eth0@if33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:12:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.18.0.2/16 brd 172.18.255.255 scope global eth0
       valid_lft forever preferred_lft forever

 
## 宿主机能ping通容器内部!!
[root@guardwhy ~]# ping 172.18.0.2
PING 172.18.0.2 (172.18.0.2) 56(84) bytes of data.
64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.088 ms
64 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.070 ms
64 bytes from 172.18.0.2: icmp_seq=3 ttl=64 time=0.050 ms
64 bytes from 172.18.0.2: icmp_seq=4 ttl=64 time=0.070 ms
[root@guardwhy ~]# 

小结:docker会给每个容器都分配一个ip,且容器和容器之间是可以互相访问的

原理分析

1、每当启动一个docker容器,docker就会给docker容器分配一个ip,只要安装了docker,就会有一个网卡docker0

2、注意:这是一个桥接模式,使用的技术是evth-pair技术。

## 再次查看主机的 ip addr
[root@guardwhy ~]# ip addr
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
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:16:3e:03:c4:87 brd ff:ff:ff:ff:ff:ff
    inet 172.17.183.201/20 brd 172.17.191.255 scope global dynamic eth0
       valid_lft 280172255sec preferred_lft 280172255sec
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ff:a3:f7:8a brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.1/16 brd 172.18.255.255 scope global docker0
       valid_lft forever preferred_lft forever
## 本来有三个网络,在启动了1个tomcat容器之后,多了一个if33的网络!!!
33: vethdeea84c@if32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether fe:d3:88:7b:b5:85 brd ff:ff:ff:ff:ff:ff link-netnsid 0
[root@guardwhy ~]# 

3、每启动一个容器,linux主机就会多了一个虚拟网卡。

[root@guardwhy ~]# docker run -d -P --name mytomcat02 tomcat
1f2a56ea7754f4c31a7713c840baa5af163a78332bb3a1edcc9e670d3718af3a
[root@guardwhy ~]# docker exec -it mytomcat02 ip addr
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
34: eth0@if35: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:12:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.18.0.3/16 brd 172.18.255.255 scope global eth0
       valid_lft forever preferred_lft forever
## 再次查看主机的 ip addr
[root@guardwhy ~]# ip addr
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
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:16:3e:03:c4:87 brd ff:ff:ff:ff:ff:ff
    inet 172.17.183.201/20 brd 172.17.191.255 scope global dynamic eth0
       valid_lft 280169868sec preferred_lft 280169868sec
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ff:a3:f7:8a brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.1/16 brd 172.18.255.255 scope global docker0
       valid_lft forever preferred_lft forever
## 本来有三个网络,在启动了2个tomcat容器之后,多了一个if33,if35的网络!!!
33: vethdeea84c@if32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether fe:d3:88:7b:b5:85 brd ff:ff:ff:ff:ff:ff link-netnsid 0
35: veth62d856a@if34: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP group default 
    link/ether 1e:fa:6d:dd:06:12 brd ff:ff:ff:ff:ff:ff link-netnsid 1
[root@guardwhy ~]# 

4、小结:

这个容器带来网卡,都是一对一对的。

veth-pair 就是一对的虚拟设备接口,它都是成对出现的。一端连着协议栈,一端彼此相连着。

正因为有这个特性,evth-pair充当一个桥梁,连接各种虚拟网络设备的。

OpenStack, Docker容器之间的连接,OVS的连接,都是使用evth-pair的技术。

5、测试mytomcat01和mytomcat02容器间是否可以互相ping通?

docker exec -it mytomcat02 ping 172.18.0.2


结论:容器和容器之间是可以互相访问的

6、绘制一个网络模型图

结论:mytomcat01和tomcat02共用一个路由器(docker0),任何一个容器启动默认都是docker0网络,docker默认会给容器分配一个可用ip。

7、Docker0小结

Docker使用Linux桥接,在宿主机虚拟一个Docker容器网桥(docker0),Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接
通信。

Docker中的所有网络接口都是虚拟的,虚拟的转发效率高!!(内网传递文件),只要容器删除,对应网桥一对就没了。。

1.2 自定义网络

1、基本命令查看

docker network --help


2、查看所有网络

[root@guardwhy ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
835529da25a3        bridge              bridge              local
12b6d842b3ab        host                host                local
6b4770ba279b        none                null                local
[root@guardwhy ~]# 
网络模式配置具体说明
bridge模式–net=bridge默认值,在Docker网桥docker0上为容器创建新的网络栈。
none模式–net=none不配置网络。
container 模式– net=container:name/id容器网络连接!!(用的少!!局限很大)
host模式–net=host容器和宿主机共享Network namespace
用户自定义–net=自定义网络用户自己使用network相关命令定义网络,创建容器的
时候可以指定为自己定义的网络

3、删除原来的所有容器

[root@guardwhy ~]# docker rm -f $(docker ps -aq)
Remove one or more containers

# 恢复到了最开始的样子
[root@guardwhy ~]# ip addr
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
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:16:3e:03:c4:87 brd ff:ff:ff:ff:ff:ff
    inet 172.17.183.201/20 brd 172.17.191.255 scope global dynamic eth0
       valid_lft 280125789sec preferred_lft 280125789sec
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default 
    link/ether 02:42:ff:a3:f7:8a brd ff:ff:ff:ff:ff:ff
    inet 172.18.0.1/16 brd 172.18.255.255 scope global docker0
       valid_lft forever preferred_lft forever
[root@guardwhy ~]# 

注意: 默认创建的容器都是docker0网卡

# docker0网络的特点
1.它是默认的
2.域名访问不通
3.--link 域名通了,但是删了又不行

4、使用自定义网络创建容器

查看命令: docker network create --help

[root@guardwhy ~]# docker network create --help

Usage:	docker network create [OPTIONS] NETWORK

Create a network

Options:
      --attachable           Enable manual container attachment
      --aux-address map      Auxiliary IPv4 or IPv6 addresses used by Network driver (default map[])
      --config-from string   The network from which copying the configuration
      --config-only          Create a configuration only network
  -d, --driver string        Driver to manage the Network (default "bridge")
      --gateway strings      IPv4 or IPv6 Gateway for the master subnet
      --ingress              Create swarm routing-mesh network
      --internal             Restrict external access to the network
      --ip-range strings     Allocate container ip from a sub-range
      --ipam-driver string   IP Address Management Driver (default "default")
      --ipam-opt map         Set IPAM driver specific options (default map[])
      --ipv6                 Enable IPv6 networking
      --label list           Set metadata on a network
  -o, --opt map              Set driver specific options (default map[])
      --scope string         Control the network's scope
      --subnet strings       Subnet in CIDR format that represents a network segment
[root@guardwhy ~]# 

自定义创建一个网络

## --driver bridge 桥接
## --subnet 192.168.0.0/16 子网
## --gateway 192.168.0.1  网关
[root@guardwhy ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
9f140b28095cf395ead5572e3dd5189519380ba3ea8fcd7cdf98e65f25d534f4
[root@guardwhy ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
835529da25a3        bridge              bridge              local
12b6d842b3ab        host                host                local
9f140b28095c        mynet               bridge              local
6b4770ba279b        none                null                local

# 查看网络,执行命令`docker network inspect mynet`
[root@guardwhy ~]# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "9f140b28095cf395ead5572e3dd5189519380ba3ea8fcd7cdf98e65f25d534f4",
        "Created": "2021-06-12T16:22:33.929558248+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {	# 网络
                    "Subnet": "192.168.0.0/16",
                    "Gateway": "192.168.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]
[root@guardwhy ~]# 

5、自定义两个容器,使用自己的 mynet

[root@guardwhy ~]# docker run -d -P --name tomcat-net-01 --net mynet tomcat
Digest: sha256:71703331e3e7f8581f2a8206a612dbeedfbc7bb8caeee972eadca1cc4a72e6b1
afa85e96d4f5ded21769674438d3f70b8eda2c1ea229a87e055d23ac49b1a024
[root@guardwhy ~]# docker run -d -P --name tomcat-net-02 --net mynet tomcat
68dabac6d09369bd3f39191bc08b954123cfc177af06aba5263a2e4fd5b6bdaf

## 查看镜像
[root@guardwhy ~]# docker ps 
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS                     NAMES
68dabac6d093        tomcat              "catalina.sh run"   About a minute ago   Up About a minute   0.0.0.0:32777->8080/tcp   tomcat-net-02
afa85e96d4f5        tomcat              "catalina.sh run"   About a minute ago   Up About a minute   0.0.0.0:32776->8080/tcp   tomcat-net-01

# 查看网络,执行命令`docker network inspect mynet`
[root@guardwhy ~]# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "9f140b28095cf395ead5572e3dd5189519380ba3ea8fcd7cdf98e65f25d534f4",
        "Created": "2021-06-12T16:22:33.929558248+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.0.0/16",
                    "Gateway": "192.168.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "68dabac6d09369bd3f39191bc08b954123cfc177af06aba5263a2e4fd5b6bdaf": {
                "Name": "tomcat-net-02",
                "EndpointID": "a153fdec599850124a3610716e7e174eb1992079a353cb3903fc00c85465ec20",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            },
            "afa85e96d4f5ded21769674438d3f70b8eda2c1ea229a87e055d23ac49b1a024": {
                "Name": "tomcat-net-01",
                "EndpointID": "0a41c7b5ebf089e9114268891f67df4595e856185543b69c06c3dc39edcbe357",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]
[root@guardwhy ~]# 

6、测试容器间是否可以互相ping通

# 1、测试ping连接(ip地址)
[root@guardwhy ~]# docker exec -it tomcat-net-01 ping 192.168.0.3
PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data.
64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.120 ms
64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.087 ms
64 bytes from 192.168.0.3: icmp_seq=3 ttl=64 time=0.095 ms
64 bytes from 192.168.0.3: icmp_seq=4 ttl=64 time=0.085 ms

# 2、测试ping连接(容器名),现在不需要使用--link也可以ping
[root@guardwhy ~]# 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.073 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.085 ms
[root@guardwhy ~]# 

小结:

自定义的网络docker都已经帮助我们维护好了对应的关系,推荐平时这样使用网络!!!

好处:

Redis 、mysql- 不同的集群使用不同的网络,保证集群是安全和健康的。

1.3 网络连通

1、docker0和自定义网络肯定不通,使用自定义网络的好处就是网络隔离,如何让tomcat-net-01 访问 tomcat1?

2、案例说明

# 0、查看现有运行的容器
[root@guardwhy ~]# docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                     NAMES
68dabac6d093        tomcat              "catalina.sh run"   4 hours ago         Up 4 hours          0.0.0.0:32777->8080/tcp   tomcat-net-02
afa85e96d4f5        tomcat              "catalina.sh run"   4 hours ago         Up 4 hours          0.0.0.0:32776->8080/tcp   tomcat-net-01

# 1、启动默认的容器,在docker0网络下
[root@guardwhy ~]# docker run -d -P --name tomcat01 tomcat
39506e89093fa3923bfd840d3f9c0223ba09c3a01fce5d000464149b87509563
[root@guardwhy ~]# docker run -d -P --name tomcat02 tomcat
f0a1b251d28519f6360b7340befbd57acb2c974b7cae678b4c0eea6194e7971e

# 2、查看当前的容器
[root@guardwhy ~]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                     NAMES
f0a1b251d285        tomcat              "catalina.sh run"   8 seconds ago       Up 8 seconds        0.0.0.0:32779->8080/tcp   tomcat02
39506e89093f        tomcat              "catalina.sh run"   18 seconds ago      Up 18 seconds       0.0.0.0:32778->8080/tcp   tomcat01
68dabac6d093        tomcat              "catalina.sh run"   4 hours ago         Up 4 hours          0.0.0.0:32777->8080/tcp   tomcat-net-02
afa85e96d4f5        tomcat              "catalina.sh run"   4 hours ago         Up 4 hours          0.0.0.0:32776->8080/tcp   tomcat-net-01

# 3、查看下network帮助,发现一个命令 connect
[root@guardwhy ~]# docker network --help
Commands:
	# 连接一个容器到一个网络
  connect     Connect a container to a network
  create      Create a network
  disconnect  Disconnect a container from a network
  inspect     Display detailed information on one or more networks
  ls          List networks
  prune       Remove all unused networks
  rm          Remove one or more networks
  
 # 4、测试打通 mynet-docker0,基本语法: `docker network connect [OPTIONS] NETWORK CONTAINER`
[root@guardwhy ~]# docker network connect mynet tomcat01
[root@guardwhy ~]# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "9f140b28095cf395ead5572e3dd5189519380ba3ea8fcd7cdf98e65f25d534f4",
        "Created": "2021-06-12T16:22:33.929558248+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.0.0/16",
                    "Gateway": "192.168.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "39506e89093fa3923bfd840d3f9c0223ba09c3a01fce5d000464149b87509563": {
            	# 连通之后就是将tomcat01放到了mynet网络下面,一个容器有两个IP地址,类似于阿里云服务的公网IP和私网IP。
                "Name": "tomcat01",
                "EndpointID": "6608306aa8fd6144bf8f74451cca8cb5a1dac6ffa314a8cd604253eaeaf84608",
                "MacAddress": "02:42:c0:a8:00:04",
                "IPv4Address": "192.168.0.4/16",
                "IPv6Address": ""
            },
            "68dabac6d09369bd3f39191bc08b954123cfc177af06aba5263a2e4fd5b6bdaf": {
                "Name": "tomcat-net-02",
                "EndpointID": "a153fdec599850124a3610716e7e174eb1992079a353cb3903fc00c85465ec20",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            },
            "afa85e96d4f5ded21769674438d3f70b8eda2c1ea229a87e055d23ac49b1a024": {
                "Name": "tomcat-net-01",
                "EndpointID": "0a41c7b5ebf089e9114268891f67df4595e856185543b69c06c3dc39edcbe357",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]
# 5、连通OK,tomcat01可以ping通了
[root@guardwhy ~]# 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.114 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.103 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=3 ttl=64 time=0.106 ms

# tomcat02 依旧ping不通
[root@guardwhy ~]# docker exec -it tomcat02 ping tomcat-net-01
ping: tomcat-net-01: Name or service not known
[root@guardwhy ~]# 

3、小结

如果要跨网络操作别人,就需要使用 docker network connect [OPTIONS] NETWORKCONTAINER 连接。

以上是关于Docker-网络初体验的主要内容,如果未能解决你的问题,请参考以下文章

docker从零开始容器初体验

Docker 初体验安装及使用

实战:区块链hyperledger fabric 初体验 - 2: 测试网络

Docker-Compose初体验

Docker深入浅出系列 | 容器初体验

vs code初体验