docker基础4——网络配置

文章目录

  • 一、虚拟化网络
  • 二、Linux内核名称空间
    • 2.1 基本命令
    • 2.2 转移设备veth
    • 2.3 不同名称空间通信原理测试
  • 三、docker容器通信原理
    • 3.1 单节点同网段容器间通信
    • 3.2 单节点不同网段容器间通信
    • 3.3 不同节点容器间通信
  • 四、docker网络模式
    • 4.1 bridge模式
    • 4.2 container模式
    • 4.3 host模式
    • 4.4 none模式
  • 五、容器常用操作
    • 5.1 容器主机名操作
    • 5.2 开放容器端口
    • 5.3 docker0网桥设置
    • 5.4 新建docker网桥

一、虚拟化网络

基本了解:

  • Network Namespace 是 Linux 内核提供的功能,是实现网络虚拟化的重要功能,它能创建多个隔离的网络空间,它们有独自网络栈信息。
  • 不管是虚拟机还是容器,运行的时候仿佛自己都在独立的网络中。不同Network Namespace的资源相互不可见,彼此之间无法通信。
  1. 假如我的物理机有4块物理网卡,需要创建4个名称空间,这些设备是可以单独关联到某个单独的名称空间使用。
  2. 下图所示,把第一块网卡分配给第一个名称空间,第二块分给第二个名称空间,以此类推。此时其它名称空间都是看不见当前所在名称空间的,因为一个设备只能属于一个名称空间。这种方式使得每一个名称空间都能配置IP地址,并且与外部网络直接通信,因为它们使用的是物理网卡,物理机可以对外上网。
  • 问:但如果我们所拥有的名称空间数量超过物理网卡数量呢?
  • 答:此时可以使用虚拟网卡设备,用纯软件的方式来模拟一组设备来使用。

docker基础4——网络配置_第1张图片

  1. Linux内核级支持2种级别设备的模拟,一种是二层设备,一种是三层设备。
  2. Linux内核模拟的二层设备,每个网络接口设备是成对出现的,可以模拟为一根网线的两端,其中一端模拟主机的虚拟网卡,另一端模拟虚拟交换机,就相当于让一个主机连到一个交换机上去。Linux内核原生支持二层虚拟网桥设备,即用软件虚拟交换机的功能。如下图所示。

docker基础4——网络配置_第2张图片

  1. 那么此时如果再有一个名称空间,它又创建了一对虚拟网卡,一端连接名称空间,一端连接虚拟交换机,此时就相当于两个名称空间连接到了同一个虚拟交换机网络中,若两个名称空间的网卡地址配置在同一网段,那么它们之间是可以互相通信的,如下图所示。

docker基础4——网络配置_第3张图片

  • 总结:从网络通信的物理设备到网卡都是用纯软件的方式来实现,这种实现方式就叫做虚拟化网络。

二、Linux内核名称空间

2.1 基本命令

  • 物理机使用ip netns命令对linux内核的Network Namespace 进行操作。
  • 每个 Network Namespace 都有自己独立的网卡、路由表、ARP 表、iptables 等和网络相关的资源。
  • ip netns命令来自于iproute安装包,一般系统会默认安装。
命令 释义
ip netns list 列出名称空间
ip netns add NAME 添加名称空间
ip netns attach NAME PID 进入名称空间
ip netns set NAME NETNSID 设置名称空间
ip [-all] netns delete [NAME] 删除
ip netns monitor 监控

1.linux系统默认没有名称空间。新创建Network Namespace 会出现在/var/run/netns/目录下。
在这里插入图片描述
2.创建Network Namespace,名为qingjun0。

ip netns add qingjun0

docker基础4——网络配置_第4张图片
3.查看qingjun0名称空间的网卡信息。

ip netns exec qingjun0 ip a

docker基础4——网络配置_第5张图片

4.启用qingun0名称空间的lo回环网卡。

ip netns exec qingjun0 ip link set lo up

docker基础4——网络配置_第6张图片

2.2 转移设备veth

  • 不同名称空间的通信时通过一对veth网卡实现的,所以我们先来了解下什么时veth。

veth pair概念:

  • 全称为Virtual Ethernet Pair,是一个成对的端口,所有从这对端口一端进入的数据包都将从另一端出来,反之也是一样。
  • 引入veth pair是为了在不同的 Network Namespace 直接进行通信,利用它可以直接将两个 Network Namespace 连接起来。
  • 我们可以在不同的 Network Namespace 之间转移设备(如veth)。一个设备只能属于一个 Network Namespace ,所以转移后在这个 Network Namespace 内就看不到这个设备了。
  • veth设备属于可转移设备,而很多其它设备(如lo、vxlan、ppp、bridge等)是不可以转移的。

概念图:
docker基础4——网络配置_第7张图片

1.创建2个名称空间。

ip netns add qingjun0
ip netns add baimu0

在这里插入图片描述
2.启动两名称空间的lo网卡。

ip netns exec qingjun0 ip link set lo up
ip netns exec baimu0 ip link set lo up

docker基础4——网络配置_第8张图片
3.创建veth网卡对。
docker基础4——网络配置_第9张图片
4.修改网卡名称。

ip link set dev veth0 name eth0
ip link set dev veth1 name eth1

docker基础4——网络配置_第10张图片

2.3 不同名称空间通信原理测试

1.接上文,此时已经存在两个名称空间,一对veth。
2.将eth0加入到qingjun0。

ip link set eth0 netns qingjun0

docker基础4——网络配置_第11张图片

3.分别给两个veth网卡配置IP。

ip netns exec qingjun0 ip addr add 192.168.10.1/24 dev eth0
ip addr add 192.168.10.2/24 dev eth1

docker基础4——网络配置_第12张图片
docker基础4——网络配置_第13张图片
4.启动两个veth网卡。

ip netns exec qingjun0 ip link set eth0 up
ip link set eth1 up

docker基础4——网络配置_第14张图片
5.测试两veth网卡通信情况。
docker基础4——网络配置_第15张图片
6.把本机的veth网卡移到baimu0名称空间,测试两名称空间通信。

ip link set eth1 netns baimu0
ip netns exec baimu0 ip addr add 192.168.10.3/24 dev eth1
ip netns exec baimu0 ip link set eth1 up

docker基础4——网络配置_第16张图片
docker基础4——网络配置_第17张图片

三、docker容器通信原理

3.1 单节点同网段容器间通信

  1. 同一台物理机上的两个容器的通信,是通过在这台主机上建立一个虚拟交换机来实现的。让这两个容器各自用纯软件的方式创建一对虚拟网卡,一半在容器上,一半在虚拟交换机上,从而实现通信,如下图所示。

docker基础4——网络配置_第18张图片

3.2 单节点不同网段容器间通信

  1. 如下图所示,当同一台物理机上的两个容器需要跨交换机通信时,两个交换机上各自连接不同的容器,这时可以通过名称空间创建一对网卡,一端连SW1,另一端连SW2,这样一来两个交换机就连起来了,C1和C3这两个处于不同交换机的容器就可以实现通信。

docker基础4——网络配置_第19张图片

  1. 如下图所示,当不在同一网络我们就必须要通过路由转发才能使其通信,也就是我们得在两台交换机之间加一个路由器,其实Linux内核本身就是支持路由转发的,只需要我们将路由转发功能打开即可。此时我们可以再启动一个容器,这个容器里面就跑一个内核,并将其转发功能打开,这样一来就模拟了一台路由器,通过这台路由器来实现路由转发。

docker基础4——网络配置_第20张图片

3.3 不同节点容器间通信

  1. 如下图所示,若C1需要与C5进行通信,不能使用桥接模式,容易产生广播风暴。
  2. 只能使用NAT模式,通过DNAT将容器的端口暴露到宿主机上,通过访问宿主机的端口来实现访问容器内部的目的。

docker基础4——网络配置_第21张图片

  1. 上图说的那种方式有个弊端,就是在请求端我们需要做SNAT将数据包通过宿主机的真实网卡转发出去,需要进行两次NAT转换,效率低。此时可以采用Overlay Network(叠加网络)技术来实现不同节点间容器的相互通信功能。
  2. Overlay Network会将报文进行隧道转发,也就是在报文发出去之前要为其添加一个IP首部,也就是下图的1.1和1.2这部分,1.1是源,1.2是目标,当宿主机2收到报文后解封装发现要找的目标容器是C2,于是把包转发给C2。

docker基础4——网络配置_第22张图片

四、docker网络模式

网络模式 配置 说明
host –network host 容器和宿主机共享Network namespace
container –network container:NAME_OR_ID 容器和另外一个容器共享Network namespace
none –network none 容器有独立的Network namespace,
但并没有对其进行任何网络设置,
如分配veth pair 和网桥连接,配置IP等
bridge –network bridge 默认模式

基本了解:

  1. docker共有四种网络模式,host、container、none、bridge。
  2. docker在安装后自动提供3种网络,host、none、bridge。
  3. docker使用Linux桥接,在宿主机虚拟一个docker容器网桥,名为docker0,这个docker0的作用就是上面提到的虚拟交换机。局域网交换机功能和网桥功能是一样的。
  4. docker启动一个容器时,会根据docker0的网段分配给容器一个IP地址,称为Container-IP,同时docker0是每个容器的默认网关。因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信。

docker基础4——网络配置_第23张图片

4.1 bridge模式

  1. 当docker守护进程启动时,会在主机上创建一个名为docker0的虚拟网桥。
  2. 主机上启动的docker容器会连接到docker0虚拟网桥上,虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。
  3. 从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关。
  4. 在主机上创建一对虚拟网卡veth pair设备,docker将veth pair设备的一端放在新创建的容器中,作为容器网卡命名为eth0。另一端放在主机中,以vethxxx这样类似的名字命名,并将这个网络设备加入到docker0网桥中。
  5. bridge模式是docker的默认网络模式。使用docker run -p时,docker实际是在iptables做了DNAT规则,实现端口转发功能。可以使用iptables -t nat -vnL查看。
  6. docker0是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,这也意味着外部网络无法通过直接Container-IP访问到容器。若容器希望外部访问能够访问到,可以通过端口映射,即docker run创建容器时候通过 -p 或 -P 参数来启用,访问容器的时候就通过[宿主机IP]:[容器端口]访问容器。

bridge模式概念图:
docker基础4——网络配置_第24张图片

1.创建一个nginx容器,将内部的容器端口80映射成外部端口8080,这样外部就可以通过8080端口访问到nginx容器了。

docker run -d -p 8080:80  --name qingjun  nginx 

docker基础4——网络配置_第25张图片
2.参数-P是生成随机端口并创建容器。

docker run -d -P  --name baimu  nginx

docker基础4——网络配置_第26张图片

4.2 container模式

  1. container模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。
  2. 新创建的容器不会创建自己的网卡、配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。所以这两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。
  3. 两个容器的进程可以通过 lo 网卡设备通信。

container模式概念图:
docker基础4——网络配置_第27张图片

1.此时有个已存在的容器baimu,容器ip为172.17.0.3。
在这里插入图片描述
2.创建新容器,根据–network参数指定要共享的容器。

docker run -it --network container:baimu busybox /bin/sh

docker基础4——网络配置_第28张图片

4.3 host模式

  1. 容器使用host模式时,该容器不会获得一个独立的Network Namespace,是和宿主机共用一个Network Namespace。容器不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。
  2. 使用host模式的容器可以直接使用宿主机的IP地址与外界通信,容器内部的服务端口也可以使用宿主机的端口,不需要进行NAT,host最大的优势就是网络性能比较好,但是docker host上已经使用的端口就不能再用了,网络的隔离性不好。

Host模式概念图:
docker基础4——网络配置_第29张图片

1.创建容器时,使用–network参数指定host模式。容器里可以查看真机网卡信息,容器内的操作不会影响到真机。

docker run -it --rm --network host busybox /bin/sh

docker基础4——网络配置_第30张图片
2.使用host模式创建容器,可以直接通过真机ip访问到容器里。不需要再像桥接模式那样还需要指定映射端口。

docker run -d --network host nginx

docker基础4——网络配置_第31张图片

4.4 none模式

  1. 使用none模式,docker容器拥有自己的Network Namespace,它的网络不被docker容器进行任何网络配置。所以这个docker容器没有网卡、IP、路由等信息,需要手动配置网卡、配置IP等。
  2. 这种网络模式下容器只有lo回环网络,没有其他网卡。
  3. 这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性。
  4. 应用场景:启动一个容器处理数据,比如转换数据格式;一些后台的计算和处理任务。

none模式概念图:
docker基础4——网络配置_第32张图片

1.创建容器时,使用–network参数指定none模式。

docker run -it --rm --network none centos /bin/bash

docker基础4——网络配置_第33张图片

五、容器常用操作

5.1 容器主机名操作

1.查看容器主机名。

docker container run -it --rm busybox /bin/sh

docker基础4——网络配置_第34张图片

2.自定义容器主机名,在容器启动时注入主机名。

docker container run -it --rm --hostname=qingjun busybox /bin/sh

docker基础4——网络配置_第35张图片
3.手动指定容器主机IP映射关系。

docker container run -it --rm --hostname=qingjun  --add-host=www.text.com:1.1.1.1 busybox /bin/sh

docker基础4——网络配置_第36张图片
4.手动指定容器主机DNS。容器主机默认指定的DNS时本机的DNS,是否能与外通信决定于容器本身,而不是用的哪个DNS,DNS只是与外界通信的一种方式。

docker container run -it --rm --hostname=qingjun  --dns=8.8.8.8 busybox /bin/sh

在这里插入图片描述

5.2 开放容器端口

端口暴露方式 释义
-p (containerPort) 将指定的容器端口映射成主机所有地址的一个动态端口
-p (hostPort):(containerPort) 将容器端口映射成指定主机端口
-p (ip)::(containerPort) 将指定的容器端口映射成主机指定ip的动态端口
-p (ip):(hostPort):(containerPort) 将指定的容器端口映射至主机指定ip的指定端口

1.映射成动态端口,可用对应主机上的所有IP访问。

docker container run -d -p 80 httpd

docker基础4——网络配置_第37张图片
2.映射成指定端口,可用对应主机上的所有IP访问。

docker container run -d -p 8080:80 httpd

docker基础4——网络配置_第38张图片
3.映射成随机端口,可用对应主机上的对应IP访问。

//只能用192.168.161.129:32769访问,当这台主机存在多个ip时,其他ip:32769访问不了。
docker container run -d -p 192.168.161.129::80 httpd

4.映射成指定端口,可用对应主机上的对应IP访问。

docker container run -d -p 192.168.161.129:8080:80 httpd

docker基础4——网络配置_第39张图片

5.3 docker0网桥设置

  • docker0网桥信息也可以自定义,需要修改配置文件/etc/docker/daemon.json 。
  • 官方文档相关配置。
cat /etc/docker/daemon.json 
{
  "bip": "192.168.1.1/24",
  "fixed-cidr": "192.168.1.0/25",
  "fixed-cidr-v6": "2001:db8::/64",
  "mtu": 1500,
  "default-gateway": "192.168.1.254",
  "default-gateway-v6": "2001:db8:abcd::89",
  "dns": ["10.20.1.2","10.20.1.3"]
}

1.自定义docker0的IP。

//修改docker配置文件,添加bip参数,指定docker0的IP,之后创建的容器IP从192.168.100.2开始。
vim /etc/docker/daemon.json 
{
     "bip":"192.168.100.1/24",     ##添加此行。
     "registry-mirrors": ["https://registry.docker-cn.com","https://11vuihex.mirror.aliyuncs.com"]
}


//重启。
systemctl  daemon-reload
systemctl  restart docker

docker基础4——网络配置_第40张图片

2.设置容器的默认dns。

//修改docker配置文件,指定要创建
vim /etc/docker/daemon.json 
{
     "bip":"192.168.100.1/24",
     "dns":["114.114.114.114","8.8.8.8"],    ##添加此行。
     "registry-mirrors": ["https://registry.docker-cn.com","https://11vuihex.mirror.aliyuncs.com"]
}


//重启。
systemctl  daemon-reload
systemctl  restart docker

docker基础4——网络配置_第41张图片

5.4 新建docker网桥

1.创建第二个docker网桥,区别默认的docker0

docker network create -d bridge --subnet 192.168.150.1/24 --gateway 192.168.150.1 qingjun

docker基础4——网络配置_第42张图片
2.使用新创建的网桥创建容器,对比与默认网桥创建的容器ip,发现网段不一致,所以两个容器网络是不通的,需要再运行一个容器充当虚拟路由器,这就涉及到docker存储卷挂载知识。

docker container run --rm --network qingjun -it busybox /bin/sh

docker基础4——网络配置_第43张图片

你可能感兴趣的:(docker,docker,php,容器,linux,运维)