概要
上一节记录了docker的安装、命令总结、范例,今日学习并记录的是docker 容器之间的通信。
大体思路:
1.理解单主机网络;
2.容器如何创建自定义网络;
3.容器间通过自定义网络进行通信;
目录
docker容器原有网络
docker容器创建自定义网络
docker容器间通信
后续
docker容器原有网络:
在这之前,先学习下docker默认创建的三个网络:none、host、bridge
# 网络查看
docker network ls
NETWORK ID NAME DRIVER SCOPE
594430d2d4bb bridge bridge local
d855b34c5d51 host host local
b1ecee29ed5e none null local
接下来,我会依次介绍这三个网络:
none 网络
# 在启动容器时加上 --network=none 即可指定使用none网络,其他网络也是这样
docker run -it --network=none --name=container0 image0 /bin/bash
bridge 网络
host 网络
namespace是 Linux 内核用来隔离内核资源的方式。通过 namespace 可以让一些进程只能看到与自己相关的一部分资源,而另外一些进程也只能看到与它们自己相关的资源,这两拨进程根本就感觉不到对方的存在。具体的实现方式是把一个或多个进程的相关资源指定在同一个 namespace 中。
Linux namespaces 是对全局系统资源的一种封装隔离,使得处于不同 namespace 的进程拥有独立的全局系统资源,改变一个 namespace 中的系统资源只会影响当前 namespace 里的进程,对其他 namespace 中的进程没有影响。
来自:(46条消息) Docker 网络:host模式_thlzjfefe的博客-CSDN博客_docker host模式
host模式特殊:
1.性能:省去中间网络插件,网络性能会更好;
2.灵活性:有些docker host使用的端口,其他容器就不能使用,会引起端口冲突;
docker容器创建自定义网络
除了默认的三种网络,其实用户可以自主创建网络。docker 提供三种驱动:bridge 、 overlay 、 macvlan。
因为目的是容器之间通信,所以这里只记录 bridge。overlay 、 macvlan用于创建跨主机网络。
创建容器网络:
# 格式 --driver bridge
docker network create --driver bridge net0
创建后生成一个网桥id
# 查看网桥信息
brctl show
# 查看 net0 信息
docker network inspect net0
但是 net0 的网关和 ip 是 docker 默认分配的,如果需要指定:
# 格式:--subnet 和 --gateway
docker network create --driver bridge --subnet 172.20.0.0/24 --gateway 172.20.0.1 net1
# 可以查看 net1 信息验证
docker network inspect net1
那么如果使用 net1 网络,只需:
docker run -it --network=net1 --name=container_name image_name /bin/bash
# 如果想要指定容器分配的 IP 格式:--ip “ip_id”
docker run -it --network=net1 --ip 172.20.0.30 --name=container_name image_name /bin/bash
# 补充:--subnet 创建静态 IP
如果两个容器同时使用的是 net1 网络,那么应该是可以互相 ping 通,docker 规定是同一网段可以互相访问。大家可以自己试验下。
还有个问题:自己设置的网络和默认的 bridge 使用的不同的网桥,ping bridge默认创建的容器(这里用 httpd 代之)肯定不通。
# 打开 host 的防火墙,查看 iptables ,这里是网上的,容器名字不准
# iptables-save
......
-A DOCKER-ISOLATION -i br-5d863e9f78b6 -o docker0 -j DROP
-A DOCKER-ISOLATION -i docker0 -o br-5d863e9f78b6 -j DROP
......
发现iptables 丢掉了网桥 docker0 与 br-5d863e9f78b6(net1的网桥)之间双向的流量。因为本来 docker 是隔离不同 network,所以如果通信,需要:
# 为 httpd 容器添加 net1 的网卡
# 格式:通过docker network connect 命令实现
docker network connect net1 "CONTAINER ID"
# CONTAINER ID 这里是 httpd 容器的,通过 docker ps 查看
# 可以到 httpd 容器查看网络信息,会发现增加了一个网卡,分配了 net1 的 IP,这样可以互相 ping 通
总结:
docker容器间通信:
IP 通信
这里不在重复描述
Docker DNS Server
docker daemon 通过 DNS server使容器可以直接通过容器名字进行通信。
# 格式:--name 为容器命名
# 建立两个容器,使用自定义网络 net1
docker run -it --network=net1 --name=container0 image0 /bin/bash
docker run -it --network=net1 --name=container1 image0 /bin/bash
# 通过名字可以互相通信
ping -C 3 container1
# 注意:1.需同在自定义网络才能使用docker DNS
Joined容器
# 新生成一个容器 container0
container0 image0 /bin/bash =
# 新生成一个容器 container1 并指定 Joined 容器为 container0
# 格式: --network=container:container0
container:container0 --name=container1 image0 /bin/bash =
# 查看 IP 信息 格式:ip a
# 发现 container0 和 container1 的 mac 地址与 IP 一样,共享了相同的网络栈。container1 可以直接用 127.0.0.1 访问 container0
# 使用场景:来自:https://mp.weixin.qq.com/s/pkkir--MRC1Vz9z8CcNc6Q 优秀的公众号:小白运维之路
# 1.不同容器中的程序希望通过 loopback 高效快速地通信,比如 web server 与 app server。
# 2.希望监控其他容器的网络流量,比如运行在独立容器中的网络监控程序。
后续:
导出、导入、更新镜像,容器转移等知识
解决镜像下载网速问题
dockerfile学习使用