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

简介: 第 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网桥与外部网络互通。

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。 &nbsp; &nbsp; 相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
12月前
|
Java 数据库 数据安全/隐私保护
Spring Boot四层架构深度解析
本文详解Spring Boot四层架构(Controller-Service-DAO-Database)的核心思想与实战应用,涵盖职责划分、代码结构、依赖注入、事务管理及常见问题解决方案,助力构建高内聚、低耦合的企业级应用。
1939 1
|
Kubernetes Java 微服务
Spring Cloud 微服务架构技术解析与实践指南
本文档全面介绍 Spring Cloud 微服务架构的核心组件、设计理念和实现方案。作为构建分布式系统的综合工具箱,Spring Cloud 为微服务架构提供了服务发现、配置管理、负载均衡、熔断器等关键功能的标准化实现。本文将深入探讨其核心组件的工作原理、集成方式以及在实际项目中的最佳实践,帮助开发者构建高可用、可扩展的分布式系统。
962 0
|
存储 Java 数据库连接
简单学Spring Boot | 博客项目的三层架构重构
本案例通过采用三层架构(数据访问层、业务逻辑层、表现层)重构项目,解决了集中式开发导致的代码臃肿问题。各层职责清晰,结合依赖注入实现解耦,提升了系统的可维护性、可测试性和可扩展性,为后续接入真实数据库奠定基础。
926 0
|
Java 开发者 Spring
Spring框架 - 深度揭秘Spring框架的基础架构与工作原理
所以,当你进入这个Spring的世界,看似一片混乱,但细看之下,你会发现这里有个牢固的结构支撑,一切皆有可能。不论你要建设的是一座宏大的城堡,还是个小巧的花园,只要你的工具箱里有Spring,你就能轻松搞定。
587 9
|
Kubernetes Docker 容器
Kubernetes与Docker参数对照:理解Pod中的command、args与Dockerfile中的CMD、ENTRYPOINT。
需要明确的是,理解这些都需要对Docker和Kubernetes有一定深度的理解,才能把握二者的区别和联系。虽然它们都是容器技术的二个重要组成部分,但各有其特性和适用场景,理解它们的本质和工作方式,才能更好的使用这些工具,将各自的优点整合到生产环境中,实现软件的快速开发和部署。
677 25
|
负载均衡 Java API
基于 Spring Cloud 的微服务架构分析
Spring Cloud 是一个基于 Spring Boot 的微服务框架,提供全套分布式系统解决方案。它整合了 Netflix、Zookeeper 等成熟技术,通过简化配置和开发流程,支持服务发现(Eureka)、负载均衡(Ribbon)、断路器(Hystrix)、API网关(Zuul)、配置管理(Config)等功能。此外,Spring Cloud 还兼容 Nacos、Consul、Etcd 等注册中心,满足不同场景需求。其核心组件如 Feign 和 Stream,进一步增强了服务调用与消息处理能力,为开发者提供了一站式微服务开发工具包。
1140 0
|
Kubernetes Shell Windows
【Azure K8S | AKS】在AKS的节点中抓取目标POD的网络包方法分享
在AKS中遇到复杂网络问题时,可通过以下步骤进入特定POD抓取网络包进行分析:1. 使用`kubectl get pods`确认Pod所在Node;2. 通过`kubectl node-shell`登录Node;3. 使用`crictl ps`找到Pod的Container ID;4. 获取PID并使用`nsenter`进入Pod的网络空间;5. 在`/var/tmp`目录下使用`tcpdump`抓包。完成后按Ctrl+C停止抓包。
626 12
|
XML Java 开发者
Spring底层架构核心概念解析
理解 Spring 框架的核心概念对于开发和维护 Spring 应用程序至关重要。IOC 和 AOP 是其两个关键特性,通过依赖注入和面向切面编程实现了高效的模块化和松耦合设计。Spring 容器管理着 Beans 的生命周期和配置,而核心模块为各种应用场景提供了丰富的功能支持。通过全面掌握这些核心概念,开发者可以更加高效地利用 Spring 框架开发企业级应用。
563 18
|
搜索推荐 NoSQL Java
微服务架构设计与实践:用Spring Cloud实现抖音的推荐系统
本文基于Spring Cloud实现了一个简化的抖音推荐系统,涵盖用户行为管理、视频资源管理、个性化推荐和实时数据处理四大核心功能。通过Eureka进行服务注册与发现,使用Feign实现服务间调用,并借助Redis缓存用户画像,Kafka传递用户行为数据。文章详细介绍了项目搭建、服务创建及配置过程,包括用户服务、视频服务、推荐服务和数据处理服务的开发步骤。最后,通过业务测试验证了系统的功能,并引入Resilience4j实现服务降级,确保系统在部分服务故障时仍能正常运行。此示例旨在帮助读者理解微服务架构的设计思路与实践方法。
1143 17

推荐镜像

更多