docker网络

docker在提供服务的时候我们需要通过网络形式访问docker,才可以访问人家给提供的服务,在我们之前启动的那些容器,虽然启动成功了,但是还不能访问,因为没有做网络的设置,它只能是单独运行的容器
 
docker网络介绍
 
大量的互联网应用服务需要多个服务组件,这往往需要多个容器之间通过网络 通信进行相互配合
docker 网络从覆盖范围可分为单个 host 上的容器网络和跨多个 host 的网络 docker 目前提供了映射容器端口到宿主主机和容器互联机制来为容器提供网 络服务,在启动容器的时候,如果不指定参数,在容器外部是没有办法通过网 络来访问容器内部的网络应用和服务的
docker 安装时会自动在host上创建三个网络,我们查看一下docker网络:
#docker network ls
‘自带的三种  briage host  none
 
 
none 网络就是什么都没有的网络。挂在这个网络下的容器除了 lo,没有其他 任何网卡。容器创建时,可以通过 --network=none 指定使用 none 网络
 
 
none 网络的应用(一般用的都很少)
封闭的网络意味着隔离,一些对安全性要求高并且不需要联网的应用可以使用 none 网络。
比如某个容器的唯一用途是生成随机密码,就可以放到 none 网络中避免密 码被窃取。
当然大部分容器是需要网络的,我们接着看 host 网络。
 
 
 
host 网络(容器共享是宿主机的网络)
连接到 host 网络的容器,共享 docker host 的网络栈,容器的网络配置与 host 完全一样。可以通过 --network=host 指定使用 host 网络
在容器中可以看到 host 的所有网卡,并且连 hostname 也是 host 的。host 网络的使用场景又是什么呢?
直接使用 Docker host 的网络最大的好处就是性能,如果容器对网络传输效率 有较高要求,就可以选择 host 网络。 当然不便之处就是牺牲一些灵活性,比如要考虑端口冲突问题,Docker host 上已经使用的端口就不能再用了。
Docker host 的另一个用途是让容器可以直接配置 host 网路。比如某些跨 host 的网络解决方案,其本身也是以容器方式运行的,这些方案需要对网络进 行配置,比如管理 iptables
 
可以通过 --network=host 指定使用 host 网络
可以通过 --network=bridge 指定使用 bridge网络
 
 
bridge网络(网桥)
 
docker 安装时会创建一个 命名为 docker0 的 linux bridge。如果不指定 --network,创建的容器默认都会挂到 docker0 上
interfaces是容器的网卡的接口
容器连接的Linux bridge 的docker0上面的话interfaces上肯定会有一个容器网卡的接口
 
启动一个容器,连接bridge 的docker0上
[root@king ~]# docker run -it centos:latest /bin/bash
让它是启动的状态
完后查看
[root@king ~]# brctl show   会出现一个新连接的
查看命名空间 ip netns list   这个只能看网络的命名空间,不能看容器的命名空间
 
 
[root@king ~]# docker pull busybox
启动
[root@king ~]# docker run -itd --name busybox busybox:latest /bin/bash
下图报错就是不可以环境变量
[root@king ~]# docker ps -a
停止容器
[root@king ~]# docker stop 61a0be75c195
删除容器
[root@king ~]# docker rm 61a0be75c195
启动容器(换环境变量)
[root@king ~]# docker run -itd --name busybox busybox:latest /bin/sh  
进入容器
[root@king ~]# docker exec -it busybox /bin/sh
这样就有IP了
 
 
 
 
这样就是一队veth pair
veth pair 是一种成对出现的特殊网络设备,可以把它们想象成由一根虚拟网线 连接起来的一对网卡,网卡的一头(eth0@if34)在容器中,另一头 (vethb119512)挂在网桥 docker0 上,其效果就是将 eth0@if34 也挂在了 docker0 上
 
 
你启动一个容器,它是连接到bridge上面,这种桥接的网络的模式,我们现在看一下Linuxbridge的具体参数
[root@king /]# docker network inspec bridge
 
 
创建 user-defined 网络(自定义网络模式)
 
我们可通过 bridge 驱动创建类似前面默认的 bridge 网络
(1)利用bridge驱动创建名为my-net2网桥(docker会自动分配网段):
#docker network create --driver bridge my-net2
创建网络   指定驱动  bridge   名字叫my-net2
[root@king /]# docker network create --driver bridge my-net2
 
多了一个网桥
 
 
(2)查看一下当前 host 的网络结构变化: #docker network ls
[root@king /]# docker network list
 
(3)查看容器bridge网桥配置(bridge就是容器和网桥形成一对veth pair)
#docker network inspect bridge
 
 
(4)利用bridge驱动创建名为my-net3网桥(指定user-defined网段及网关)
 
[root@king /]# docker network create --driver bridge --subnet 10.10.10.0/24 --gateway 10.10.10.1 my-net3
 
网桥也多了
查看具体参数
[root@king /]# docker network inspect my-net3
 
(5)启动容器使用新建的my-net3网络
如果不--指定 它会自动连接到docker0上,所以这边要注意
 
[root@king /]# docker run -it --network=my-net3  busybox:latest /bin/sh
 
 
(6)启动容器使用my-net3网络并指定ip(只有使用 --subnet 创建的网络才 能指定静态 IP,如果是docker自动分配的网段不可以指定ip)
 
[root@king /]# docker run -it --network=my-net3 --ip 10.10.10.100 busybox:latest /bin/sh
 
(7)让已启动不同vlan的ningx容器,可以连接到my-net2(其实在nigx中新 建了my-net2的网卡)
让你这个容器同时访问两个网络段
让 busybox连接到新创建的my-net3里面
 
[root@king /]# docker network connect my-net3 51bcdea480fc
connect连接   网络  容器ID
这样这个容器就可以同时访问两个网络了
 
 
(8)使用--name指定启动容器名字,可以使用docker自带DNS通信,但只能 工作在user-defined 网络,默认的 bridge 网络是无法使用 DNS 的
启动容器时,你给他指定自己建立的网络模式,并且给这个容器起一个名字,这两个容器就可以通过容器的名字进行通信,就类似于hosts域名解析文件
 
#docker run -it --network=my_net2 --name=bbox1 busybox
#docker run -it --network=my_net2 --name=bbox2 busybox
 
 
(9)容器之间的网络互联
 
a). 首先创建一个 db 容器
 
b). 创建一个 web 容器,并使其连接到 db   
[root@king /]# docker run -itd --name db centos:latest  /bin/bash     启动容器
[root@king /]# docker run -itd --name web --link db:dbweb centos:latest /bin/bash
连接link 连接db:连接名字叫dbweb  指定镜像 centos
 
名字和这个链接的名字,也就是和 db 容器 建立一个叫做 link 的链接 
 
c). 查看链接的情况
docker ps -a
 
d). 使用 ping 命令来测试网络链接的情况
[root@king /]# docker exec -it web /bin/bash   进入容器
 
说明你让它连接它才能连谁,不能反向的来
 
 
 
(10)容器端口映射 在启动容器的时候,如果不指定参数,在容器外部是没有办法通过网络来访问容 器内部的网络应用和服务的
 
当容器需要通信时,我们可以使用 -P (大) &&-p (小)来指定端口映射
 
-P : Docker 会随机映射一个 49000 ~ 49900 的端口到容器内部开放的网络 端口
-p :则可以指定要映射的端口,并且在一个指定的端口上只可以绑定一个容器。(一个端口只能提供一个服务)
支持的格式有
IP : HostPort(宿主机的端口号) : ContainerPort(容器的端口号)
IP : (也可以不写): ContainerPort(容器的端口号)    它会在宿主机里随机开启一个端口,映射给容器你开启的端口
IP : HostPort :      这样就是反过来
 
查看映射
#docker port  容器名字
 
 
a)映射所有接口地址,此时绑定本地所有接口上的 5000 到容器的 5000 接口, 访问任何一个本地接口的 5000 ,都会直接访问到容器内部 (老师做的是5000 )
 
[root@king /]# docker run -itd -p 8080:80 centos:latest /bin/bash
8080:80的意思就是,访问宿主机的8080端口就是访问容器的80端口
0.0.0.0 是映射本地宿主机任何IP来开通了8080端口
 
b)多次使用可以实现多个接口的映射
 
[root@king /]# docker run -itd -p 8080:80 -p 8555:443 centos:latest /bin/bash
也可以这样,多个端口映射
 
c)映射到指定地址的指定接口 此时会绑定本地 192.168.4.169 接口上的 5000 到容器的 5000 接口
就是比如你宿主机有多块儿网卡,那它就有多个IP地址
也可以设置单个网卡访问它对应的端口才能访问到容器里面(就是你当你访问别的网卡同端口的时候它也访问不到容器里面的服务)
 
#docker run -dti -p 192.168.4.169:5000:5000 centos:7.0 /bin/bash
 
 
d) 映射到指定地址的任意接口 此时会绑定本地 192.168.4.169 接口上的任意一个接口到容器的 5000 接口
#docker run -dti -p 192.168.4.169::5000 centos:7.0 /bin/bash
 
 
 
e) 使用接口标记来指定接口的类型 (可以设置连接的类型,可以设置TCP还是UDP)
#docker run -dti -p 192.168.4.169::5000/UDP centos:7.0 /bin/bash
 
 
(11)实验:通过端口映射实现访问本地的 IP:PORT 可以访问到容器内的 web
 
 
 
a)将容器80端口映射到主机8899端口
 
注意这里映射的时候不加/bin/bash   不然后期会报错
[root@king /]# docker run -itd -p 9876:88 --name hehe nginx:latest
 
b) 查看刚运行docker
#docker ps
 
c) 进入容器
[root@king /]# docker exec -it hehe  /bin/bash
访问网页192.168.193.5:9876
 
d) 容器内部编辑网页文件 index.html
 
 
e)到宿主机上打开浏览器输入 IP:PORT 访问验证
访问网页192.168.193.5:9876   
 
 
网络排排查命令:
iptables -t nat -L
ip r
tcpdump -i docker0 -n icmp
tcpdump -i eth0 -n icmp
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

原文地址:https://www.cnblogs.com/hao6/p/12864182.html