1 关于docker的网络通信

1.1 宿主机和容器的通信

在单机环境中:宿主机上的Docker Daemon启动时会为宿主机创建一块名为docker0的虚拟网卡,在Docker初始化时系统会分配一个IP地址绑定在这个网卡上。如

5: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
    link/ether 02:42:a1:3f:a3:d0 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:a1ff:fe3f:a3d0/64 scope link
       valid_lft forever preferred_lft forever

docker0的角色就是一个宿主机与容器间的网桥,作为一个二层交换机,负责数据包的转发。

docker 用宿主机私钥 docker与宿主机通信_docker

当使用docker创建一个容器时,如果使用了bridge模式,docker会创建一个vet对,一端绑定到docker0上,而另一端则作为容器的eth0虚拟网卡,比如docker容器中的网卡情况如下:

root@a5458e9d4096:/workspace/webdemo/controller# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.9  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:ac:11:00:09  txqueuelen 0  (Ethernet)
        RX packets 24  bytes 1600 (1.6 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 16  bytes 804 (804.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 10  bytes 1348 (1.3 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 10  bytes 1348 (1.3 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

简述为:宿主机的docker0和容器的eth0
过程:
运行容器设置端口映射实际上是docker会通过iptables创建一条nat规则。
数据包发送到宿主机的端口,该端口将数据包转发到docker0网关,docker0网关将通过广播的方式找到对应ip的容器,将数据包转发到该容器的端口上。
docker要跟外部的网络进行通信,也是通过docker0和iptables的nat进行转发。

"Networks": {
    "bridge": {
        "IPAMConfig": null,
        "Links": null,
        "Aliases": null,
        "NetworkID": "e2e12bf8a8ab187be867478a3d29c3b3a233cb85e961a870ccecae3fba9b2184",
        "EndpointID": "26ce7607c932c80ad7e977ecc67d90c945807e24eca95ce2123aad9e122df9a2",
        "Gateway": "172.17.0.1", // 指向宿主机的虚拟网卡docker0
        "IPAddress": "172.17.0.9", // 容器的网卡地址
        "IPPrefixLen": 16,
        "IPv6Gateway": "",
        "GlobalIPv6Address": "",
        "GlobalIPv6PrefixLen": 0,
        "MacAddress": "02:42:ac:11:00:09",
        "DriverOpts": null
    }
}

案例

问题1:容器内可以使用curl -X GET “http://127.0.0.1:80/api/v1/items” 访问,在宿主机中不可以访问?
分析:
首先确定了web服务是启动的,因为在容器中是可以访问的。
宿主机不可以访问说明容器和宿主机是无法通信的。
那宿主机和容器怎么通信呢?
网络模式选择桥接模式,然后进行端口映射,这样通过宿主机的端口就可以访问到容器的端口了。
然后发现我的问题:
web服务在容器中运行的端口是80(默认运行的端口,我在程序中没有指定),然后我暴露容器的接口是8080,所以我访问8080是访问不到web服务的。

解决办法:

  1. 将web服务的端口暴露在8080
  2. 映射主机的端口映射到80
    如:docker run -d -p 8064:80 --net=bridge --name=hcy_test hcy_test_webdemo:1.0

容器内部可以通过curl -X GET “http://127.0.0.1:80/api/v1/items”
这样在宿主机可以通过暴露的端口 curl -X GET “http://127.0.0.1:8064/api/v1/items”
远程主机可以通过宿主主机的ip地址来访问,如 curl -X GET “http://10.67.43.10:8064/api/v1/items”

1.2 容器与容器互联

1.2.1 两个容器的简单连接

方法一:
创建一个网络,然后两个容器运行的时候都接入这个网络,然后容器之间就可以互相通信了。
参考网址:菜鸟教程
方法二:
通过docker run --link参数实现连接
举个例子:
需求:web容器能够访问db数据库容器
步骤1:实例化数据库容器
docker run -d --name db training/postgres
步骤2:实例化web容器连接到数据库容器
docker run -d -P --name web --link db:db training/webapp python app.y
步骤3:测试
在web容器中,ping db,看是否ping通
或者查看配置文件:
cat /etc/hosts
在web容器中查看hosts是否有db
参考:Dock人技术从入门到精通第75页

1.2.2 多个容器的连接(使用Docker Compose)

背景:一个完整的项目通常需要多个容器互相配合,如一个web容器,会需要后端的数据库服务容器,前台的负载均衡容器。
编写docker-compose.yml

  1. 几个概念
    任务:一个容器
    服务:同意镜像实例化的多个容器的集合
    服务栈:多个服务,如web服务、数据库服务共同构成web服务栈
    Compose默认管理的是服务栈,通过子命令可以对栈中的多个服务进行管理
  2. 使用docker compose的三个步骤
  • 使用 Dockerfile 定义应用程序的环境。
  • 使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。
  • 最后,执行 docker-compose up 命令来启动并运行整个应用程序。

详细配置指令见菜鸟教程

举个例子:
一个Python的web应用:django的web容器配合redis容器进行通信
1、实例化redis容器
如:
$ docker pull redis
$ docker run -d --name=redis -p 6379 redis

2、实例化Django容器连接到redis容器
$ docker run -it --name=app -p 8080:8000 -v /code:/usr/src/app --link=redis:db django bash
参数说明:
-v /code:/usr/src/app 表示把宿主机上的/code目录挂载到容器内的/usr/src/app目录,可以通过直接管理宿主机上的挂载目录来管理容器内部的挂载目录。
–link=redis:db 表示把redis容器以db别名与该容器建立关系,在该容器内以db作为主机名表示了redis容器的主机地址。

3、测试Django容器是否连接到redis容器
ping db

参考地址:https://zhuanlan.zhihu.com/p/26418829