docker网络
docker网络
目录
[toc]
docker网络
1、docker网络模型
•vethpair:成对出现的一种虚拟网络设备,数据从一端进,从另一端出。用于解决网络命名空间之间隔离。(相当于一根网线)•docker0:网桥是一个二层网络设备,通过网桥可以将Linux支持的不同的端口连接起来,并实现类似交换机那样的多对多的通信。引入网桥(docker0)的作用:1.解决容器之间的通信(2层之间的通信)2.解决宿主机和容器命名空间隔离问题;
2、Docker使用iptables实现网络通信
Docker使用iptables实现网络通信。外部访问容器:# iptables -t nat -vnL DOCKER容器访问外部:# iptables -t nat -vnL POSTROUTING#注意:这里的虚线代表一个隔离的网络命名空间!
3、实例测试
我们先来创建一个容器:
[root@docker ~]# docker run -d --name nginx -p 88:80 nginx994c016655ef16ee64adf748c17e6256c1ed31c2237dabdc2b1d8fc8c57549ee[root@docker ~]# docker psCONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMES994c016655efnginx"/docker-entrypoint.…"AboutaminuteagoUpAboutaminute0.0.0.0:88->80/tcp,:::88->80/tcpnginx[root@docker ~]#
现在在笔记本浏览器上输入http:<!DOCTYPEhtml><html><head><title>Welcome to nginx!</title><style>html{color-scheme:lightdark;}body{width:35em;margin:0auto;font-family:Tahoma,Verdana,Arial,sans-serif;}</style></head><body><h1>Welcome to nginx!</h1><p>If you see this page,the nginx web server is successfully installed andworking.Furtherconfigurationisrequired.</p><p>For online documentation and support please refer to<a href="http:Commercialsupportisavailableat<a href="http:<p><em>Thank you forusing nginx.</em></p></body></html>[root@docker ~]#
我们再来看看容器映端口的映射情况:
[root@docker ~]# ss -antlp|grep88LISTEN01024*:88*:*users:(("docker-proxy",pid=20252,fd=4))LISTEN01024[::]:88 [::]:*users:(("docker-proxy",pid=20257,fd=4))[root@docker ~]#
查看下当前系统下的网卡ip情况:
[root@docker ~]# ifconfig docker0:flags=4163<UP,BROADCAST,RUNNING,MULTICAST>mtu1500inet172.17.0.1netmask255.255.0.0broadcast172.17.255.255inet6fe80::42:c5ff:fe1c:5bd3prefixlen64scopeid0x20<link>ether02:42:c5:1c:5b:d3txqueuelen0(Ethernet)RXpackets117bytes16377(15.9 KiB)RXerrors0dropped0overruns0frame0TXpackets161bytes15411(15.0 KiB)TXerrors0dropped0overruns0carrier0collisions0ens33:flags=4163<UP,BROADCAST,RUNNING,MULTICAST>mtu1500inet172.29.9.32netmask255.255.0.0broadcast172.29.255.255inet6fe80::20c:29ff:fe56:3f5prefixlen64scopeid0x20<link>ether00:0c:29:56:03:f5txqueuelen1000(Ethernet)RXpackets6828bytes3659631(3.4 MiB)RXerrors0dropped0overruns0frame0TXpackets3599bytes583426(569.7 KiB)TXerrors0dropped0overruns0carrier0collisions0lo:flags=73<UP,LOOPBACK,RUNNING>mtu65536inet127.0.0.1netmask255.0.0.0inet6::1prefixlen128scopeid0x10<host>looptxqueuelen1000(Local Loopback)RXpackets24343bytes42494064(40.5 MiB)RXerrors0dropped0overruns0frame0TXpackets24343bytes42494064(40.5 MiB)TXerrors0dropped0overruns0carrier0collisions0veth8a8c209:flags=4163<UP,BROADCAST,RUNNING,MULTICAST>mtu1500inet6fe80::5cb6:bdff:fe47:be9eprefixlen64scopeid0x20<link>ether5e:b6:bd:47:be:9etxqueuelen0(Ethernet)RXpackets19bytes3534(3.4 KiB)RXerrors0dropped0overruns0frame0TXpackets31bytes2877(2.8 KiB)TXerrors0dropped0overruns0carrier0collisions0[root@docker ~]#
(1)我们看下外部网络访问容器
[root@docker ~]# iptables -t nat -vnL DOCKER
走的是路由表:
[root@docker ~]# ip routedefaultvia172.29.0.254devens33169.254.0.0/16devens33scopelinkmetric1002172.17.0.0/16devdocker0protokernelscopelinksrc172.17.0.1172.29.0.0/16devens33protokernelscopelinksrc172.29.9.32
docker0又是一个二层的网桥设备,它会基于arp发送广播,然后与相应的容器进行通信。
(2)那么容器与外部网络如何进行通信呢?
创建并进入容器,进行ping测试:
[root@docker ~]# docker run -it --name=test--rmbusybox:1.28.3#我们ping百度进行测试/# ping baidu.comPINGbaidu.com(220.181.38.148):56 data bytes64bytesfrom220.181.38.148:seq=0ttl=127time=32.968ms64bytesfrom220.181.38.148:seq=1ttl=127time=30.789ms^C---baidu.compingstatistics---2packetstransmitted,2packetsreceived,0%packetlossround-tripmin/avg/max=30.789/31.878/32.968ms/# #看下自己容器当前eth0的ip是172.17.0.2/# ifconfig eth0Linkencap:EthernetHWaddr02:42:AC:11:00:02inetaddr:172.17.0.2Bcast:172.17.255.255Mask:255.255.0.0UPBROADCASTRUNNINGMULTICASTMTU:1500Metric:1RXpackets:14errors:0dropped:0overruns:0frame:0TXpackets:6errors:0dropped:0overruns:0carrier:0collisions:0txqueuelen:0RXbytes:1149(1.1 KiB) TX bytes:418 (418.0B)loLinkencap:LocalLoopbackinetaddr:127.0.0.1Mask:255.0.0.0UPLOOPBACKRUNNINGMTU:65536Metric:1RXpackets:0errors:0dropped:0overruns:0frame:0TXpackets:0errors:0dropped:0overruns:0carrier:0collisions:0txqueuelen:1000RXbytes:0(0.0 B) TX bytes:0 (0.0B)/# #在看下当前容器的路由表:/# ip route defaultvia172.17.0.1deveth0172.17.0.0/16deveth0scopelinksrc172.17.0.2
再看下宿主机的路由表:
[root@docker ~]# ip routedefaultvia172.29.0.254devens33#走的是默认路由169.254.0.0/16devens33scopelinkmetric1002172.17.0.0/16devdocker0protokernelscopelinksrc172.17.0.1172.29.0.0/16devens33protokernelscopelinksrc172.29.9.32[root@docker ~]# ifconfig docker0:flags=4099<UP,BROADCAST,MULTICAST>mtu1500inet172.17.0.1netmask255.255.0.0broadcast172.17.255.255inet6fe80::42:c5ff:fe1c:5bd3prefixlen64scopeid0x20<link>ether02:42:c5:1c:5b:d3txqueuelen0(Ethernet)RXpackets123bytes16711(16.3 KiB)RXerrors0dropped0overruns0frame0TXpackets167bytes15904(15.5 KiB)TXerrors0dropped0overruns0carrier0collisions0ens33:flags=4163<UP,BROADCAST,RUNNING,MULTICAST>mtu1500inet172.29.9.32netmask255.255.0.0broadcast172.29.255.255inet6fe80::20c:29ff:fe56:3f5prefixlen64scopeid0x20<link>ether00:0c:29:56:03:f5txqueuelen1000(Ethernet)RXpackets10211bytes4864742(4.6 MiB)RXerrors0dropped0overruns0frame0TXpackets5719bytes847549(827.6 KiB)TXerrors0dropped0overruns0carrier0collisions0lo:flags=73<UP,LOOPBACK,RUNNING>mtu65536inet127.0.0.1netmask255.0.0.0inet6::1prefixlen128scopeid0x10<host>looptxqueuelen1000(Local Loopback)RXpackets34888bytes60503678(57.7 MiB)RXerrors0dropped0overruns0frame0TXpackets34888bytes60503678(57.7 MiB)TXerrors0dropped0overruns0carrier0collisions0[root@docker ~]#
注意下:这里的docker0--eth0有做一次的SNAT转换
[root@docker ~]# iptables -t nat -vnL POSTROUTING ChainPOSTROUTING(policy ACCEPT372packets,23096bytes)pktsbytestargetprotoptinoutsourcedestination3194MASQUERADEall--*!docker0172.17.0.0/160.0.0.0/0[root@docker ~]#
测试结束。
4、不同宿主机之间,docker容器网络通信有几种方式?
容器跨宿主机容器通信问题。
这是一种需求;
数据包封装实现︰overlay(隧道方案)和路由方案
技术∶flannel、weave、calico
实战-docker配置静态ip(已成功测试-已博客输出-mk老师)-20210525
实验涉及软件百度云链接
链接:https:提取码:3q06
实验环境
一个还原到之前安装了 docker 的虚拟机快照:centos7.7 1908虚机。如何在centos7上安装docker环境,可以在我的博客查找文章:3-实战-centos上安装docker-(过程超详细-已测试成功)-20210522
前言
(1)Docker 的 4 种网络模式
Docker有以下4种网络模式︰
host模式,使用--net=host指定。
container模式,使用--net=container:NAME_or_ID指定。
none模式,使用--net=none指定。
bridge模式,使用--net=bridge指定,默认就是bridge模式。
默认选择bridge的情况下,容器启动后会通过DHCP 获取一个地址,这可能不是我们想要的,在centos7系统上,docker环境下可以使用**pipework脚本(官方提供的脚本)**对容器分配固定IP(这个IP可以是和物理机同网段IP)
注:docker 默认是bridge (--net=bridge )模式,相当于VMware 中NAT模式。docker环境下可以使用pipework脚本对容器分配固定IP,相当于VMware中桥接模式。注:Pipework有个缺陷,容器重启后IP设置会自动消失,需要重新设置。
扩展∶--privileged=true #允许开启特权功能
privileged ['prrvalrdgd]有特权的
在docker 0.6版以后,privileged 被引入docker。使用该参数,container内的root拥有真正的root权限。否则,container内的root只是外部物理机的一个普通用户权限。使用privileged启动的容器,可以看到很多host上的设备,并且可以执行mount。甚至允许你在docker容器中启动docker容器。不启用privileged,容器中root用户不能执行mount。
(2)扩展:测试 privileged 特权功能
1、未设置 privileged 特权的容器:
[root@docker ~]# docker run -it centos bash[root@80a9f7e36df2 /]# ls /dev/ #可以看到的设备文件比较少consolecorefdfullmqueuenullptmxptsrandomshmstderrstdinstdoutttyurandomzero[root@80a9f7e36df2 /]# mount /dev/sda1 /opt/ #不可以挂载成功, mount命令执行失败mount:/opt:permissiondenied.[root@80a9f7e36df2 /]# mount -o bind /etc/ /optmount:/opt:permissiondenied.[root@80a9f7e36df2 /]# exit
2、使用 privileged 特权的容器
[root@docker ~]# docker run -it --privileged centos bash[root@fac986b64e15 /]# ls /dev/ #可以看到很多设备文件[root@fac986b64e15 /]# mount /dev/sda1 /opt/ #可以挂载物理机上的 sda1 分区[root@fac986b64e15 /]# umount /opt[root@fac986b64e15 /]# mount -o bind /etc/ /opt #可以挂载成功[root@fac986b64e15 /]# umount /opt/[root@fac986b64e15 /]# exitexit[root@docker ~]#[root@docker ~]# docker run -it --privileged centos bash[root@906b0421babd /]# init 0 #不能使用 init 0 关机,还是使用 exit 退出 dockerCouldn't find an alternative telinit implementation to spawn.
0、基础环境配置
一个还原到之前安装了 docker 的虚拟机快照:centos7.7 1908虚机。如何在centos7上安装docker环境,可以在我的博客查找文章。
1、配置桥接网络
桥接本地物理网络的目的,是为了局域网内用户方便访问docker实例中服务,不要需要各种端口映射即可访问服务。但是这样做又违背了docker 容器的安全隔离的原则,工作中辩证的选择。
- 创建桥设备 br0:
安装包:
[root@docker ~]# yum install -y bridge-utils
- 把 ens33 绑到 br0 桥设备上:
配置前网卡配置如下:
#开始配置[root@docker ~]# cd /etc/sysconfig/network-scripts/[root@docker network-scripts]# cp ifcfg-ens33 /opt/ #备份ifcfg-ens33[root@docker network-scripts]# vim ifcfg-ens33 #编辑配置文件为以下内容TYPE=EthernetPROXY_METHOD=noneBROWSER_ONLY=noBOOTPROTO=staticDEFROUTE=yesIPV4_FAILURE_FATAL=noIPV6INIT=yesIPV6_AUTOCONF=yesIPV6_DEFROUTE=yesIPV6_FAILURE_FATAL=noIPV6_ADDR_GEN_MODE=stable-privacyNAME=ens33#UUID=3bff16f1-d739-485c-9e02-197c4678f51cDEVICE=ens33ONBOOT=yesBRIDGE="br0"
- 生成桥设备 br0 的配置文件:
[root@docker network-scripts]# vim ifcfg-br0 #创建 ifcfg-br0 文件,并写入以下内容DEVICE="br0"NM_CONTROLLED="yes"ONBOOT="yes"TYPE="Bridge"BOOTPROTO=noneIPADDR=172.29.9.11NETMASK=255.255.0.0GATEWAY=172.29.0.254DNS1=114.114.114.114注:TYPE="Bridge"
- 重启网络并测试,
[root@docker ~]# systemctl restart network
配置桥接网络后,查看ip:
2、使用 pipework 脚本配置静态 IP
方法 1:直接下载 pipework zip 包
3、使用静态 IP 启动一个 docker 实例
例:以none模式,使用--net=none启动一个容器,并且开启docker 特权模式。
[root@docker ~]# docker run -itd --net=none--privileged=truecentosbashe5ca1cc49de1db462ebf405a5735a2dc1ee43f28b2887bd00559c2ae22b4b505[root@docker ~]#
- 扩展结束,接着给容器配置表态 IP 地址
[root@docker ~]# docker psCONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMESe5ca1cc49de1centos"bash"12minutesagoUp12minutestrusting_rosalind[root@docker ~]#可以看到容器启动的 ID ,比如是e5ca1cc49de1
给此容器配置地址:
pipework语法:pipework 网桥名 容器实例ID 分配给容器的IP/掩码@网关
[root@docker ~]# pipework br0 e5ca1cc49de1 172.29.9.21/16@172.29.0.254 #注:容器的 DNS 地址,会直接使用物理机的 dns
注意用pipwork脚本配置ip后,不需要重启网络,容器ip马上就会生效的。
- 测试 IP:#可以看到 docker 实例的 IP 已经可以使用
[root@docker ~]# docker psCONTAINERIDIMAGECOMMANDCREATEDSTATUSPORTSNAMESe5ca1cc49de1centos"bash"16minutesagoUp16minutestrusting_rosalind[root@docker~]#dockerinspecte5ca1cc49de1#查看容器的详细情况
- 进入入容器,测试网络:
[root@docker ~]# docker ps[root@docker ~]# docker exec -it e5ca1cc49de1 bash #进入容器[root@e5ca1cc49de1 /]# yum install -y net-tools #安装ifconfig命令[root@e5ca1cc49de1 /]# cat /etc/resolv.conf [root@e5ca1cc49de1 /]# ifconfig[root@e5ca1cc49de1 /]# route -n
到此,docker 实例配置静态 IP 成功。
4、小案例: 使用静态 IP 启动的 docker 实例运行,一个 web 服务器
[root@c8f88d9bf76e /]# yum install -y httpd[root@c8f88d9bf76e /]# systemctl start httpdSystemhasnotbeenbootedwithsystemdasinitsystem(PID 1). Can't operate.Failed to connect to bus:Host is down[root@c8f88d9bf76e /]#[root@c8f88d9bf76e /]# /usr/sbin/httpd -DFOREGROUND &[root@c8f88d9bf76e /]# netstat -antup|grep 80[root@c8f88d9bf76e /]# cd /var/www/html/[root@c8f88d9bf76e html]# ls[root@c8f88d9bf76e html]# echo Linux-k8s >index.html
5、总结
关于如何给docker配置静态ip,配置步骤总结如下:
1、创建一个 br0 桥接设备
2、下载 pipework 包并安装
3、安装并运行 docker
4、拉取一个 centos docker 镜像
5、启动一个 docker 实例 注意加参数: --net=none --privileged=true
6、使用 pipework 给 docker 实例配置 IP
7、小案例:使用静态 IP 启动的 docker 实例运行,一个 web 服务器
关于我
我的博客主旨:
- 排版美观,语言精炼;
- 文档即手册,步骤明细,拒绝埋坑,提供源码;
- 本人实战文档都是亲测成功的,各位小伙伴在实际操作过程中如有什么疑问,可随时联系本人帮您解决问题,让我们一起进步!
🍀 微信二维码
x2675263825 (舍得), qq:2675263825。
🍀 微信公众号
《云原生架构师实战》
🍀 csdn