kubernetes Spring Cloud 微服务架构—(9)Kubernetes spring cloud 微服务-Docker 高级网络操作

本文涉及的产品
注册配置 MSE Nacos/ZooKeeper,118元/月
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
云原生网关 MSE Higress,422元/月
简介: 第 9 章 Docker 高级网络操作 在 Docker 的网络模式章节讲述了 Docker 支持的四中网络模式: host、container、none、 bridge 以及图形解释了在这几种网络模式下, Dokcer IP 的配置情况。那么在本章节主要讲解容器之间通信的原理,Dokcer0 网桥详解,以及在None 模式下怎样添加自定义网卡,并且还要实现添加正在运行容器的 IP 地址。注:本章节有一定难度,可以选修。

 

9.1 网络通信基础

在网络通信中,两台主机的唯一标识为IP 地址(V4/V6), (类似身份证号码) 基于 IP 地址实现全世界的网络互联。

计算机通信 初发展,并未实现系统化与标准化,不同厂商产出各自的网络来实现通信, 这样导致了计算机缺乏灵活性和可扩展性, 为了解决该问题,ISO(国际标准化组织)制定了一个国际标准 OSI(开放式通信系统互联参考模型), (IETF(国际互联网工程任务组)TCP/IP 模型)

OSI 模型

 

9.2 局域网互联技术

9.2.1 以太网发展

1973 , 美国加利福尼亚州的 Xerox 公司实现了 初的以太网(3Mbps)

1980 , Xerox DECIntel 实现了10Mbps 以太网

1983 , IEEE 标准委员会通过第一个 802.3 标准

1990 , IEEE 通过了使用双绞线介质的以太网标准传输 10Mbps

 

9.2.2 局域网通信设备

集线器(HUB),物理层的设备

网桥又称桥接器,(Network Bridge),数据链路层设备  

交换机 Switch,数据链路层设备(网管 snmp/telnet 与非网管)

 

9.2.3 局域网(二层)数据转发原理

192.168.1.10 192.168.1.11 发送邮件, 根据 OSI 七层模型, 数据转发是需要封装数据包(1500 字节/分片重组 MTU

1.  192.168.1.10 查询本机的地址缓存表(arp -a, 是否有 IP 地址对应的 mac 地址, 如果有直接发送数据包,如果没有则发送ARP 广播

2. 192.168.1.10 向网络发送 ARP 广播, 询问 192.168.1.11 MAC 地址是多少?

3. 在未隔离广播域的交换机上的端口都会接收到这个广播.

4. 192.168.1.11 接收到请求以后,比对目标网络地址, 是否是地址, 然后再回应给192.168.1.10

5. 192.168.1.10 收到 mac 地址以后, 封装数据包,发送到交换机, 交换机根据目标 mac 转发数据到

192.168.1.11

 

 

9.3 容器通信基础

Linux系统中Namespace (> 2.6.x 内核版本) 主要用于资源的隔离。在有了Namespace功能之后,在Linux系统中就可以抽象出多个网络子系统,并且各子系统间都有自己的网络设备,协议栈等,彼此之间互不影响。

如果相互隔离的Namespace之间需要通信时,则用veth-pair来做连接作为连接桥梁,使原

本互不相干的容器之间能够相互通信。

根据网络连接的方式与规模,可分为直接相连“Bridge 相连 “OVS 相连。下面会详细讲解几种模式的实现方式。

 

9.3.1 直接连接

直接相连是 简单的方式,如下图,一对veth-pair 直接将两个 namespace 连接在一起。

#同一宿主机

 

9.3.1.1配置不同NS, 相同网段的直接连接互通

 

9.3.1.2 创建不同的Namespace

# 创建 namespace 
[root@docker01 ~]# ip netns a ns1 
[root@docker01 ~]# ip netns a ns2

 

9.3.1.3 创建veth-pairveth0/veth1

#创建一对 veth-pair veth0 veth1 
#创建 veth0 类型为 veth, 对端的地址为 veth1 
[root@docker01 ~]# ip l a veth0 type veth peer name veth1

9.3.1.4 添加veth0/veth1至两个不同的NS


/

[root@docker01 ~]# ip l s veth0 netns ns1 
[root@docker01 ~]# ip l s veth1 netns ns2

9.3.1.5 配置veth IP 地址

#给两个 veth0 veth1 配上 IP 并启用, 必须为一个网段 
[root@docker01 ~]# ip netns exec ns1 ip a a 10.1.1.2/24 dev veth0 
[root@docker01 ~]# ip netns exec ns1 ip l s veth0 up 
[root@docker01 ~]# ip netns exec ns2 ip a a 10.1.1.3/24 dev veth1 
[root@docker01 ~]# ip netns exec ns2 ip l s veth1 up

9.3.1.6 测试veth 连通性

#给两个 veth0 veth1 配上 IP 并启用, 必须为一个网段 
[root@docker01 ~]# ip netns exec ns1 ip a a 10.1.1.2/24 dev veth0 
[root@docker01 ~]# ip netns exec ns1 ip l s veth0 up 
[root@docker01 ~]# ip netns exec ns2 ip a a 10.1.1.3/24 dev veth1 
[root@docker01 ~]# ip netns exec ns2 ip l s veth1 up
rtt min/avg/max/mdev = 0.068/0.084/0.201/0.032 ms

9.3.2 Linux Bridge连接

Linux Bridge 相当于一个网桥,可以中转两个namespace的流量。如下图,两对 veth-pair 分别将两个 namespace 连到 Bridge 上。

 

9.3.2.1 配置不同NS, 相同网络通过网桥的互通

# 创建 namespace 
[root@docker01 ~]# ip netns a ns1 
[root@docker01 ~]# ip netns a ns2

9.3.2.2 创建网桥br0

[root@docker01 ~]# ip l a br0 type bridge 
[root@docker01 ~]# ip l s br0 up 
创建两对 veth-pair 
[root@docker01 ~]# ip l a veth01 type veth peer name br-veth0 
[root@docker01 ~]# ip l a veth11 type veth peer name br-veth1

 

9.3.2.3 配置veth pair, 并且加入到独立的NS与相同的br0

9.3.2.3.1 #配置veth01namespacens1, 设置br-veth0的桥接器为br0

[root@docker01 ~]# ip l s veth01 netns ns1 
[root@docker01 ~]# ip l s br-veth0 master br0 
[root@docker01 ~]# ip l s br-veth0 up

 

9.3.2.3.2 配置veth11namespacens2, 设置br-veth1的桥接器为br0

[root@docker01 ~]# ip l s veth11 netns ns2

[root@docker01 ~]# ip l s br-veth1 master br0

[root@docker01 ~]# ip l s br-veth1 up

 

9.3.2.4 配置veth01veth11 IP 地址

# 给两个 ns 中的 veth 配置 IP 并启用 
[root@docker01 ~]# ip netns exec ns1 ip a a 11.1.1.2/24 dev veth01 
[root@docker01 ~]# ip netns exec ns1 ip l s veth01 up 
[root@docker01 ~]# ip netns exec ns2 ip a a 11.1.1.3/24 dev veth11 
[root@docker01 ~]# ip netns exec ns2 ip l s veth11 up

 

9.3.2.5 测试连通性

#veth01 ping veth11 
[root@localhost ~]# ip netns exec ns1 ping 11.1.1.3 PING 11.1.1.3 (11.1.1.3) 56(84) bytes of data. 
64 bytes from 11.1.1.3: icmp_seq=1 ttl=64 time=0.060 ms 
64 bytes from 11.1.1.3: icmp_seq=2 ttl=64 time=0.105 ms 
--- 11.1.1.3 ping statistics --- 
2 packets transmitted, 2 received, 0% packet loss, time 999ms rtt min/avg/max/mdev = 0.060/0.082/0.105/0.024 ms

9.3.3 通过OVS 连接

OVS 是第三方开源的 Bridge,功能比 Linux Bridge 要更强大

 

 

9.3.3.1 安装OVS

[root@localhost ~]# yum install wget   openssl-devel  \  python-sphinx gcc make python-devel   openssl-devel kernel-devel graphviz kernel-debug-devel \ autoconf automake   rpm-build redhat-rpm-config libtool python-twisted-core python-zope-interface   \ 
PyQt4 desktop-file-utils   libcap-ng-devel groff checkpolicy python-six selinux-policy-devel -y 
[root@localhost ~]# mkdir -p   /root/rpmbuild/SOURCES 
[root@localhost ~]# cd /root/rpmbuild/SOURCES   
[root@localhost ~]# wget   http://openvswitch.org/releases/openvswitch-2.9.2.tar.gz 
[root@localhost ~]# tar xvf   openvswitch-2.9.2.tar.gz 
[root@localhost ~]# rpmbuild -bb   --nocheck openvswitch-2.9.2/rhel/openvswitch-fedora.spec 
[root@localhost ~]# yum localinstall   /root/rpmbuild/RPMS/x86_64/openvswitch-2.9.2-1.el7.centos.x86_64.rpm -y 
[root@demo SOURCES]# systemctl start   openvswitch.service 
[root@demo SOURCES]#   systemctl enable openvswitch.service

9.3.4 配置veth通过OVS连接通信

9.3.4.1 通过OVS命令创建一个bridge

[root@localhost ~]# ovs-vsctl add-br ovs-br

  

9.3.4.2 创建两对veth-pair  

[root@localhost ~]# ip l a veth011 type veth peer name ovs-veth0 
[root@localhost ~]# ip l a veth111 type veth peer name ovs-veth1

 

9.3.4.3 配置veth-pair添加到NSOVS Bridge


/

#操作 veth011 
#添加 veth011 到 ns1 
[root@localhost ~]# ip l s veth011 netns ns1 
#将 ovs-veth0 添加到 ovs-br 桥接器 
[root@localhost ~]# ovs-vsctl add-port ovs-br ovs-veth0 
[root@localhost ~]# ip l s ovs-veth0 up 
#操作 veth1 
#添加 veth1 到 ns2 
[root@localhost ~]# ip l s veth111 netns ns2 
#将 ovs-veth1 添加到 ovs-br 桥接器 
[root@localhost ~]# ovs-vsctl add-port ovs-br ovs-veth1 
[root@localhost ~]# ip l s ovs-veth1 up

9.3.4.4 配置veth IP 地址

[root@localhost ~]# ip netns exec ns1 ip a a 12.1.1.2/24 dev veth011 
[root@localhost ~]# ip netns exec ns1 ip l s veth011 up 
[root@localhost ~]# ip netns exec ns2 ip a a 12.1.1.3/24 dev veth111 
[root@localhost ~]# ip netns exec ns2 ip l s veth111 up


/

 

9.3.4.5 测试连通性

# veth011 ping veth111

 

[root@localhost ~]# ip netns exec ns1   ping 12.1.1.3 PING 12.1.1.3 (12.1.1.3) 56(84) bytes of data. 
64 bytes from 12.1.1.3: icmp_seq=1   ttl=64 time=0.311 ms 
64 bytes from 12.1.1.3: icmp_seq=2   ttl=64 time=0.087 ms 
--- 12.1.1.3 ping statistics --- 
2 packets transmitted, 2 received, 0% packet   loss, time 999ms rtt min/avg/max/mdev = 0.087/0.199/0.311/0.112 ms

 

9.4 Docker0 网桥详解

Docker 服务默认会创建一个 docker0 网桥(其上有一个 docker0 内部接口),它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和宿主机都在同一个物理网络。

 

 

Docker 默认指定了 docker0 接口 的 IP 地址和子网掩码,让主机和容器之间可以通过网桥相互通信,它还给出了 MTU(接口允许接收的    大传输单元),以太网通常是 1500

Bytes,或宿主机网络路由上支持的默认值。这些值都可以在服务启动的时候进行配置。

 

--bip=CIDR -- IP 地址加掩码格式,例如192.168.100.5/24

--mtu=BYTES -- 覆盖默认的 Docker mtu 配置

也可以在配置文件中配置DOCKER_OPTS,然后重启服务。 由于目前 Docker 网桥是 Linux 网桥,用户可以使用 brctl show 来查看网桥和端口连接信息。


 

9.4.1 查看docker0网桥

9.4.2 安装网络工具

/

#如果已经安装 Docker CE 则无需要再安装 
[root@node-2 ~]#  yum install -y yum-utils device-mapper-persistent-data lvm2 
[root@node-2 ~]#  yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo [root@node-2 ~]#  yum install docker-ce-19.03.6 docker-ce-cli-19.03.6 containerd.io -y 
#安装网络查看工具 
[root@node-2 ~]#  yum install bridge-utils

 

9.4.3 查看网络

#查看系统网络接口 
[root@node-2 ~]# ip a 
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     inet6 ::1/128   scope host         valid_lft forever   preferred_lft forever 
2:   ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast   state UP group default qlen
1000 
      link/ether 00:0c:29:14:38:91 brd ff:ff:ff:ff:ff:ff     inet 192.168.91.136/24 brd 192.168.91.255   scope global noprefixroute ens32          valid_lft forever preferred_lft forever     inet6 fe80::7dfd:e7a3:7683:20e7/64 scope   link noprefixroute         valid_lft   forever preferred_lft forever 
3: docker0:   <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN   group default      link/ether   02:42:2f:4c:4a:2b 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

9.4.4 查看网桥

[root@node-2 ~]# brctl show bridge name     bridge id               STP enabled     interfaces docker0         8000.02422f4c4a2b       no

9.4.5 启动nginx demo容器

#运行 nginx demo 
[root@node-2 ~]# docker run --name nginx-demo -p 8081:80 -d nginx

9.4.6 获取容器进程id

#系统所支持的网络命名空间(在内核中根据进程号隔离) 
[root@node-2 ~]# ll /proc/1370/ns/ total 0 lrwxrwxrwx 1 root root 0 Nov  6 11:51 ipc -> ipc:[4026532449] lrwxrwxrwx 1 root root 0 Nov  6 11:51 mnt -> mnt:[4026532447] lrwxrwxrwx 1 root root 0 Nov  6 11:50 net -> net:[4026532443] lrwxrwxrwx 1 root root 0 Nov  6 11:51 pid -> pid:[4026532450] lrwxrwxrwx 1 root root 0 Nov  6 11:51 user -> user:[4026531837] lrwxrwxrwx 1 root root 0 Nov  6 11:51 uts -> uts:[4026532448]

9.4.7 查看命名空间

#系统所支持的网络命名空间(在内核中根据进程号隔离) 
[root@node-2 ~]# ll /proc/1370/ns/ total 0 lrwxrwxrwx 1 root root 0 Nov  6 11:51 ipc -> ipc:[4026532449] lrwxrwxrwx 1 root root 0 Nov  6 11:51 mnt -> mnt:[4026532447] lrwxrwxrwx 1 root root 0 Nov  6 11:50 net -> net:[4026532443] lrwxrwxrwx 1 root root 0 Nov  6 11:51 pid -> pid:[4026532450] lrwxrwxrwx 1 root root 0 Nov  6 11:51 user -> user:[4026531837] lrwxrwxrwx 1 root root 0 Nov  6 11:51 uts -> uts:[4026532448]

9.4.8 通过进程id 获取到网络命名空间

[root@demo ~]# ll /proc/1370/ns/net 
lrwxrwxrwx 1 root root 0 Mar 23 23:35 /proc/1370/ns/net -> net:[4026532443]

9.4.9 查看系统网络接口

#查看网络结构, 多了一块网卡 
[root@node-2 ~]# ip a 
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     inet6 ::1/128   scope host         valid_lft forever   preferred_lft forever 
2:   ens32:   <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP   group default qlen
1000 
      link/ether 00:0c:29:14:38:91 brd ff:ff:ff:ff:ff:ff     inet 192.168.91.136/24 brd   192.168.91.255 scope global noprefixroute ens32        valid_lft forever preferred_lft   forever     inet6   fe80::7dfd:e7a3:7683:20e7/64 scope link noprefixroute         valid_lft forever preferred_lft   forever 
3: docker0:   <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group   default      link/ether 02:42:2f:4c:4a:2b   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:2fff:fe4c:4a2b/64 scope link           valid_lft forever preferred_lft forever 
5:   veth7ebd9ef@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue   master docker0 state   UP group default      link/ether b2:12:dc:e7:a5:17 brd   ff:ff:ff:ff:ff:ff link-netnsid 0       inet6 fe80::b012:dcff:fee7:a517/64 scope link         valid_lft forever preferred_lft forever

9.4.9.1 查看网卡桥接

[root@demo ~]# brctl show bridge name     bridge id               STP enabled     interfaces docker0         8000.0242c736b32f       no              veth7ebd9ef

 

9.4.9.2 查看Iptables

#iptables 存在有地址转换

[root@node-2 ~]# iptables -L -n -t nat   Chain DOCKER (2 references) 
target     prot opt source               destination          
RETURN     all    --  0.0.0.0/0            0.0.0.0/0            
DNAT       tcp    --  0.0.0.0/0            0.0.0.0/0            tcp dpt:8081 to:172.17.0.2:80

 

9.5 创建 Docker 自定义网桥

Docker 自定义网桥除了默认的 docker0 网桥,用户也可以指定网桥来连接各个容器。在启动 Docker 服务的时候,使用 -b BRIDGE--bridge=BRIDGE 来指定使用的网桥。如果Docker服务已经运行,那需要先停止服务。

 

9.5.1 自定义网桥逻辑架构图容器通过自定义的网桥bridge0访问外网

 

 

9.5.2 停止docker 服务

[root@node-2 ~]# service docker stop

 

9.5.3 建立自定义网桥bridge0

#设置bridge0网段为192.168.6.0/24 
#添加网桥 
[root@node-2 ~]# brctl addbr bridge0 
#设置网桥 IP 地址段 
[root@node-2 ~]# ip addr add 192.168.6.1/24 dev bridge0 
#设置网桥状态 UP 
[root@node-2 ~]# ip link set dev bridge0 up

9.5.4 查看网络

#查看系统增加桥接器bridge0

 

[root@node-2 ~]# ip a 
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     inet6 ::1/128   scope host         valid_lft forever   preferred_lft forever 
2:   ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast   state UP group default qlen
1000 
      link/ether 00:0c:29:14:38:91 brd ff:ff:ff:ff:ff:ff     inet 192.168.91.136/24 brd   192.168.91.255 scope global noprefixroute ens32        valid_lft forever preferred_lft   forever     inet6   fe80::7dfd:e7a3:7683:20e7/64 scope link noprefixroute         valid_lft forever preferred_lft   forever 
3: docker0:   <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN   group default      link/ether   02:42:2f:4c:4a:2b 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:2fff:fe4c:4a2b/64 scope link           valid_lft forever preferred_lft forever 
6:   bridge0:   <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN   group default qlen 1000     link/ether   12:e7:be:6c:aa:1c brd ff:ff:ff:ff:ff:ff       inet 192.168.6.1/24 scope global bridge0        valid_lft forever preferred_lft   forever     inet6   fe80::10e7:beff:fe6c:aa1c/64 scope link tentative         valid_lft forever preferred_lft   forever

9.5.5 查看系统所有桥接器

[root@node-2 ~]# brctl show bridge name     bridge id               STP enabled     interfaces bridge0         8000.000000000000       no docker0         8000.02422f4c4a2b       no

9.5.6 查看网桥状态

[root@node-2 ~]# ip addr show bridge0 
6: bridge0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default qlen 1000     link/ether 12:e7:be:6c:aa:1c brd ff:ff:ff:ff:ff:ff    inet 192.168.6.1/24 scope global bridge0        valid_lft forever preferred_lft forever
    inet6 fe80::10e7:beff:fe6c:aa1c/64 scope link         valid_lft forever preferred_lft forever

9.5.7 配置Docker使用新网桥bridge0

[root@node-2 ~]# cat /etc/docker/daemon.json     
{ 
  "bridge": "bridge0" 
} 
#完整配置 
{ 
   "bridge": "bridge0", 
  "registry-mirrors": ["https://plqjafsr.mirror.aliyuncs.com"], 
   "data-root": "/data/docker", 
    "storage-driver": "overlay2", 
    "storage-opts": [ 
     "overlay2.override_kernel_check=true", 
      "overlay2.size=1G" 
    ] 
}

 

9.5.8 重启docker 服务

#重载

[root@node-2 ~]# systemctl daemon-reload

[root@node-2 ~]# service docker restart

 

9.5.8.1 启动容器

#启动一个已经退出的容器

[root@demo ~]# docker ps -a 
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS               NAMES 
400fb9f1f415 centos              "/bin/bash"              27 hours ago        Exited (1) 26 hours ago                        happy_lumiere 
#启动容器 
[root@demo ~]# docker start   400fb9f1f415 
#进入终端 
[root@demo ~]# docker exec -it   400fb9f1f415 /bin/bash 
[root@400fb9f1f415 /]# ip a 
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

 

9.5.9 运行容器,是否可以使用新网桥

9.5.9.1 重新运行容器

[root@node-2 ~]#  docker run -it --name centos-d1 centos /bin/bash

 

9.5.9.2 使用 ping 测试网络连通性

/ # ping www.baidu.com

PING www.baidu.com (163.177.151.109): 56 data bytes

64 bytes from 163.177.151.109: seq=0 ttl=127 time=9.102 ms

64 bytes from 163.177.151.109: seq=1 ttl=127 time=9.358 ms

64 bytes from 163.177.151.109: seq=2 ttl=127 time=9.284 ms

 

9.5.9.3 查看容器ip

#新容器使用bridge0网段192.168.6.0/24, docker0172.17.0.0/16 网段

[root@node-2 ~]# docker run -ti   centos 
/ # ip a 
1: lo: <LOOPBACK,UP,LOWER_UP>   mtu 65536 qdisc noqueue 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 
30: eth0@if31:   <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue      link/ether 02:42:c0:a8:06:03 brd   ff:ff:ff:ff:ff:ff     inet 192.168.6.3/24 brd 192.168.6.255 scope   global eth0        valid_lft forever   preferred_lft forever

9.5.9.4 查看系统Iptables 转发规则 MASQUERADE:  

 通过MASQUERADE自动实现SNAT,把192.168.6.0网段的地址, 转换发送到外网。  也就是说在自定义添加了网桥以后, docker 会自动添加网桥的网段到iptables SNAT 的规则中,实现容器启动以后能够自动的连接到外网。

[root@node-2 ~]# iptables -L -n -t nat 
……….省略 
Chain POSTROUTING (policy ACCEPT) 
target     prot opt source               destination          
MASQUERADE  all --  192.168.6.0/24   0.0.0.0/0

9.6 容器 None 网络模式添加网卡

Docker 的网络实现其实就是利用了 Linux 上的网络名字空间隔离技术和虚拟网络设备(veth pair)连接技术,实现容器对外部网络的访问。

 

9.6.1 创建容器流程回顾(桥接模式)

Docker 创建一个容器的时候,会执行如下操作:

 

创建一对虚拟接口(veth pair),分别放到本地主机和新容器中;本地主机一端桥接到默认的 docker0 或指定网桥上,并具有一个唯一的名字,比如 veth65f9;容器一端放到新容器中,并修改名字作为 eth0,这个接口只在容器的名字空间可见;从网桥可用地址段中获取一个空闲地址分配给容器的 eth0,并配置默认路由到桥接网卡 veth65f9。完成这些之后,容器就可以使用 eth0 虚拟网卡来连接其他容器和其他网络。

 

9.6.1.1 本案例实现的效果为容器busybox容器添加自定义的网卡,容器可以通过网卡连接到外部网络。

 

 

9.6.2 操作过程

9.6.2.1 创建一个容器, 设置网络模式是none

#启动一个 /bin/bash 容器,指定--net=none 参数。

[root@demo ~]# docker run -it --name=demo-none  --net=none busybox

 

9.6.3 查看容器IP

#此时的容器是没有任何IP

/ # ip a

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue 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

  

9.6.4 获取容器id

#在本地主机查找容器的进程 id

[root@node-2 ~]# docker ps

CONTAINER ID  IMAGE  COMMAND    CREATED       STATUS              PORTS               NAMES

38078e9a638d busybox  "sh" 13 minutes ago Up 13 minutes                          youthful_chandrasekhar

 

9.6.5 获取到容器的进程id

[root@node-2 ~]# docker inspect -f '{{.State.Pid}}' demo-none 
13034 
9.6.6 创建网络命名空间挂载点 
[root@node-2 ~]# pid=13034 
#创建网络空间挂载点(本地文件目录) 
[root@node-2 ~]# mkdir -p /var/run/netns 
#绑定网络命名空间到挂载点 
[root@node-2 ~]# ln -s /proc/$pid/ns/net  /var/run/netns/$pid

9.6.7 查看需要添加的桥接器的网段与桥接器名称

#检查桥接网卡的 IP 和子网掩码信息。 
[root@node-2 ~]# ip addr show bridge0   
6: bridge0:   <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN   group default qlen 1000     link/ether   00:00:00:00:00:00 brd ff:ff:ff:ff:ff:ff 
    inet 192.168.6.1/24 scope global bridge0                #容器网关地址        valid_lft forever   preferred_lft forever     inet6   fe80::10e7:beff:fe6c:aa1c/64 scope link         valid_lft forever preferred_lft forever

9.6.8 建立veth-pair  

namespace之间需要通信,用veth-pair 来做桥梁创建一对 “veth pair” 接口 A 和 B,绑定 A 到网桥 bridge0,并启用。 
A 为: veth 接口(宿主机), B 为容器网卡 
[root@node-2 ~]# ip link add A type veth peer name B 
#设置 A veth 桥接到 bridge0 
[root@node-2 ~]# brctl addif bridge0 A 
#启动 veth A 
[root@node-2 ~]# ip link set A up

9.6.9 设置网络与ip

#将B放到容器的网络命名空间,命名为 eth10,启动它并配置一个可用 IP(桥接网段)和默认网关。 
#添加网卡 B 到网络命名空间 13034 
[root@node-2 ~]# ip link set B netns $pid 
#设置容器网卡的名称为 eth10 
[root@node-2 ~]# ip netns exec $pid ip link set dev B name eth10 
#设置网卡的状态为 up 
[root@node-2 ~]# ip netns exec $pid ip link set eth10 up 
#设置容器网卡的 ip 地址 
[root@node-2 ~]# ip netns exec $pid ip addr add 192.168.6.100/24 dev eth10 
#设置默认路由 
[root@node-2 ~]# ip netns exec $pid ip route add default via 192.168.6.1

9.6.9.1 查看容器ip

#查看容器是否有 eth10 
/ # ip a 
1: lo: <LOOPBACK,UP,LOWER_UP>   mtu 65536 qdisc noqueue 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 
20: eth10@if21:   <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue qlen   1000     link/ether 8e:6b:02:17:36:0a   brd ff:ff:ff:ff:ff:ff     inet 192.168.6.100/24 scope global eth10        valid_lft forever preferred_lft   forever

9.6.9.2 查看宿主机网桥

[root@node-2 ~]# brctl show bridge name     bridge id               STP enabled     interfaces bridge0         8000.1651b5e3adba       no              A docker0         8000.02422f4c4a2b       no

 

9.6.9.3 查看系统网卡

[root@node-2 ~]# ip a 
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     inet6 ::1/128   scope host         valid_lft forever   preferred_lft forever 
2:   ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast   state UP group default qlen
1000 
      link/ether 00:0c:29:14:38:91 brd ff:ff:ff:ff:ff:ff     inet 192.168.91.136/24 brd 192.168.91.255   scope global noprefixroute ens32          valid_lft forever preferred_lft forever     inet6 fe80::7dfd:e7a3:7683:20e7/64 scope   link noprefixroute
valid_lft forever preferred_lft forever 
3: docker0:   <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN   group default      link/ether   02:42:2f:4c:4a:2b 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:2fff:fe4c:4a2b/64 scope   link         valid_lft forever preferred_lft forever 
6:   bridge0:   <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group   default qlen
1000 
      link/ether 16:51:b5:e3:ad:ba brd ff:ff:ff:ff:ff:ff     inet 192.168.6.1/24 scope global bridge0        valid_lft forever preferred_lft   forever     inet6   fe80::10e7:beff:fe6c:aa1c/64 scope link         valid_lft forever preferred_lft   forever 
21: A@if20: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue   master bridge0 state UP group default qlen 1000     link/ether 16:51:b5:e3:ad:ba brd   ff:ff:ff:ff:ff:ff link-netnsid 0       inet6 fe80::1451:b5ff:fee3:adba/64 scope link         valid_lft forever preferred_lft   forever

9.7 运行容器 IP 添加地址

#拉取镜像 CentOS 
[root@ demo ~]# docker pull centos 

9.7.1 运行容器

#前台运行centos

[root@demo ~]# docker run --name=centos-IP1 -it centos /bin/bash

 

9.7.2 获取到容器启动进程号

[root@ demo ~]# docker inspect -f '{{.State.Pid}}' centos-IP1  

13575

9.7.3 容器修改之前的ip  

[root@95d78806950d /]# ip a 
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 
28: eth0@if29:   <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group   default      link/ether   02:42:c0:a8:06:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 192.168.6.3/24 brd 192.168.6.255 scope global eth0        valid_lft forever preferred_lft forever

9.7.4 创建容器网络命名空间挂载点

[root@ demo ~]# pid=13575 
#无法直接操作必须要有网络空间挂载点 
[root@demo ~]# ip netns exec $pid ip a 
Cannot open network namespace "13575": No such file or directory 
[root@ demo ~]# mkdir -p /var/run/netns 
#创建网络空间挂载点 
[root@ demo ~]# ln -s /proc/$pid/ns/net  /var/run/netns/$pid 
#查看现在容器 IP 
[root@ demo ~]# ip netns exec $pid ip a 
9.7.5 设置容器新IP 
#设置容器的ip 地址 
[root@ demo ~]# ip netns exec $pid ip addr add 192.168.6.10/24 dev eth0 
9.7.6 容器内部检验IP 
#检验新的ip 地址是否添加 
[root@ demo ~]# ip netns exec $pid ip a

9.8 总结 Docker 实现原理

1)   底层硬件支撑, 也可以用虚拟机运行Docker

2)   在硬件或虚拟机内安装支持容器运行的操作系统

3) Docker 通过NSCgroupsOverlayFs技术实现容器的加载启动.

4)容器通过利用系统中的Docker0网桥与外部网络互通。

相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
7天前
|
运维 Kubernetes Docker
利用Docker和Kubernetes构建微服务架构
利用Docker和Kubernetes构建微服务架构
|
5天前
|
安全 持续交付 Docker
微服务架构和 Docker 容器化部署的优点是什么?
微服务架构和 Docker 容器化部署的优点是什么?
|
7天前
|
Docker 微服务 容器
使用Docker Compose实现微服务架构的快速部署
使用Docker Compose实现微服务架构的快速部署
17 1
|
21天前
|
Kubernetes 负载均衡 Docker
构建高效微服务架构:Docker与Kubernetes的完美搭档
本文介绍了Docker和Kubernetes在构建高效微服务架构中的应用,涵盖基本概念、在微服务架构中的作用及其实现方法。通过具体实例,如用户服务、商品服务和订单服务,展示了如何利用Docker和Kubernetes实现服务的打包、部署、扩展及管理,确保微服务架构的稳定性和可靠性。
74 7
|
20天前
|
Kubernetes 负载均衡 Docker
构建高效微服务架构:Docker与Kubernetes的完美搭档
【10月更文挑战第22天】随着云计算和容器技术的快速发展,微服务架构逐渐成为现代企业级应用的首选架构。微服务架构将一个大型应用程序拆分为多个小型、独立的服务,每个服务负责完成一个特定的功能。这种架构具有灵活性、可扩展性和易于维护的特点。在构建微服务架构时,Docker和Kubernetes是两个不可或缺的工具,它们可以完美搭档,为微服务架构提供高效的支持。本文将从三个方面探讨Docker和Kubernetes在构建高效微服务架构中的应用:一是Docker和Kubernetes的基本概念;二是它们在微服务架构中的作用;三是通过实例讲解如何使用Docker和Kubernetes构建微服务架构。
55 6
|
21天前
|
Docker 容器
docker swarm启动服务并连接到网络
【10月更文挑战第16天】
20 5
|
21天前
|
调度 Docker 容器
docker swarm创建覆盖网络
【10月更文挑战第16天】
14 5
|
18天前
|
存储 监控 Linux
Docker技术架构概述
【10月更文挑战第22天】Docker采用CS架构,Client与Daemon交互,Compose管理多容器应用。
|
22天前
|
负载均衡 网络协议 关系型数据库
docker swarm 使用网络启动服务
【10月更文挑战第15天】
19 4
|
22天前
|
数据安全/隐私保护 Docker 容器
docker swarm创建网络
【10月更文挑战第15天】
10 1