要重新再获得被分配IP地址,可以在客户端主机的DOC下(在[开始]-[运行]里输入“cmd”或点击附件里的[命令提示符]就可以进入)
输入命令 ipconfig/release (释放掉你获得的IP)
然后 ipconfig/renew(重新到DHCP服务器那里获得IP)
A类是第1段1-126,B类第1段是128-191,C类第1段就是192-223
A、B类被作为外网地址,C类被用做局域网地址。
你要连通外网后A、B类的都是网络经营商拥有的,你得花钱租的。
DHCP有一定的记忆性,如果只连一台计算机,肯定经常出现总分配同1个地址,或差不多的地址,以求网络的稳定,并节省消耗。
Docker搭建了lnmp环境后,如果需要访问安装在宿主机上的数据库或中间件,是不能直接使用127001这个ip的,这个ip在容器中指向容器自己,那么应该怎么去访问宿主机呢:
例如你的docker环境的虚拟IP是19216899100,那么宿主机同样会托管一个和19216899100同网段的虚拟IP,并且会是主IP:192168991,那么就简单了,在容器中访问192168991这个地址就等于访问宿主机,问题解决注意,通过192168991访问宿主机,等于换了一个ip,如果数据库或中间件限制了本机访问或者做了ip段限制,要记得添加192168991到白名单
如上红字所描述:同一个宿主机上的不同容器之间的网络如何互通的???
我们安装完docker之后,docker daemon会为我们自动创建3个网络,如下:
其实docker有4种网络通信模型,分别是:bridge、host、none、container
默认的使用的网络模型是bridge,也是我们生产上会使用到的网络模型。
下文中跟大家分享docker容器互通原理到时候呢,用到的也是bridge网络模型
另外,当我们安装完docker之后,docker会为我们创建一个叫docker0的网络设备
通过ifconfig命令可以查看到它,看起来它貌似和eth0网络地位相当,像是一张网卡。然而并不是,docker0其实是一个Linux网桥
何以见得?可以通过下面的命令查看 *** 作系统上的网桥信息
那大家怎么理解Linux网桥的概念呢?
其实大家可以把docker0理解成一台虚拟的交换机!然后像下面这样类比着理解,就会豁然开朗
1、它好比是大学在机房上课时,老师旁边的那个大大的交换机设备。
2、把机房里的电脑都连接在交换机上,类比成docker 容器作为一台设备都连接着宿主机上的docker0。
3、把交换机和机房中的机器的ip在同一个网段,类比成docker0、和你启动的docker容器的ip也同属于172网段。
类比成这样:
我们刚才做类比理解docker0的时候说:把机房里的电脑都连接在交换机上,类比成docker 容器作为一台设备都连接着宿主机上的docker0。那具体的实现落地实现用的是啥技术呢?
答案是:veth pair
veth pair的全称是:virtual ethernet,就是虚拟的以太网卡。
说到以太网卡大家都不陌生呀,不就是我们常见的那种叫eth0或者是ens的网络设备吗?
那这个veth pair是怎么玩的呢?有啥用呢?大家可以看下面这张图
veth-pair设备总是会成对的出现,用于连接两个不同network-namespace
就上图来说,从network-namespace1的veth0中发送的数据会出现在 network-namespace2的veth1设备中。
虽然这种特性很好,但是如果出现有多个容器,你就会发现组织架构会越来越复杂,越来越乱
不过好在我们已经循序渐进的了解Linux网桥(docker0),以及这里的veth-pair设备,于是我们可以把整体的架构图重新绘制成下面这样
因为不同容器有自己隔离后的network-namespace所以他们都有自己的网络协议栈
那我们能不能找到容器里面的网卡和物理机上的哪张卡是一对网络vethpair设备呢?
如下:
回到宿主机
意思是就是说,容器545ed62d3abf的eth0网卡和宿主机通过ip addr命令查看的网络设备标号55的设备组成一对vethpair设备,彼此流量互通!
先看个简单的,同一个局域网中的不同主机A、B之间是如何互联交换数据的。如下图
那,既然是同一个局域网中,说明A、B的ip地址在同一个网段,如上图就假设它们都在19216810网段。
还得再看下面这张OSI 7层网络模型图。
主机A向主机B发送数据,对主机A来说数据会从最上层的应用层一路往下层传递。比如应用层使用的>
电脑左下角圆形的图标开始,然后在打开菜单中选择运行,就打开运行对话框,在运行对话框的的输入框中输入cmd,之后点下面的,确定,按钮,打开cmd命令提示符,在打开的cmd命令提示符中输入下面的命令就可以查看自己的ip地址了ipconfig /all。
点击电脑右下角的开始,网络连接图标,再打开连接信息对话框,选择,打开网络和共享中心,打开网络和共享中心页面,选择本地连接,在打开的本地连接状态对话框中点击详细信息按钮,再打开网络连接详细信息对话框,可以看到除了ip地址之外的更多信息。
利用Net Namespace可以为Docker容器创建隔离的网络环境,容器具有完全独立的网络栈,与宿主机隔离。也可以使Docker容器共享主机或者其他容器的网络命名空间,基本可以满足开发者在各种场景下的需要。
Docker支持 4种网络模式 :
1)host模式,--net=host指定,不支持多主机。
2)container模式,--net = container : name_or_id指定,不支持多主机。
3)none模式,--net=none指定,不支持多主机。
4)bridge模式,--net=bridge指定,默认设置,不支持多主机。
启动容器的时候使用Host模式,那么该容器与宿主机共用一个Network Namespace,因此容器将不会虚拟自己的网卡、配置自己的IP等,而是使用宿主机的IP和端口。
采用Host模式的容器,可以直接使用宿主机的IP地址与外界进行通信,无需额外进行NAT转换。由于容器通信时,不再需要通过Linux Bridge等方式转发或者数据包的拆封,性能上有很大优势。当然, Host模式有利也有弊 ,主要包括以下缺点:
1)容器没有隔离、独立的网络栈。容器因与宿主机共用网络栈而争抢网络资源,并且容器崩溃也可能导致宿主机崩溃,这在生产环境中是不允许发生的。
2)容器不再拥有所有的端口资源,因为一些端口已经被宿主机服务、Bridge模式的容器端口绑定等其他服务占用了。
需要补充说明的是,Host模式下的容器仅仅是网络命名空间与主机相同,但容器的文件系统、进程列表等还是和与宿主机隔离的。
Container模式是一种特殊的网络模式。该模式下的容器使用其他容器的网络命名空间,网络隔离性会处于Bridge模式与Host模式之间。当容器与其他容器共享网络命名空间时,这两个容器间不存在网络隔离,但它们与宿主机及其他容器又存在网络隔离。
在Kubernetes体系架构下引入Pod概念,Kubernetes为Pod创建一个基础设施容器, 同一Pod下的其他容器都以Container模式 共享这个基础设施容器的网络命名空间,相互之间以localhost访问,构成一个统一的整体。
与前两种不同,None模式的Docker容器拥有自己的Network Namespace,但并不为Docker容器进行网络配置。该Docker容器没有网卡、IP、路由等信息。需要用户为Docker容器添加网卡、配置IP等。
Bridge模式是Docker默认的网络模式,也是开发者最常使用的网络模式。在这种模式下,Docker为容器创建独立的网络栈,保证容器内的进程使用独立的网络环境,实现容器之间、容器与宿主机之间的网络栈隔离。同时,通过宿主机上的Docker0网桥,容器可以与宿主机乃至外界进行网络通信。
同一宿主机上,容器之间都是连接在Docker0这个网桥上,Docker0作为虚拟交换机使容器间相互通信 。但是, 由于宿主机的IP地址与容器veth pair的IP地址均不在同一个网段 ,故仅仅依靠 veth pair和NameSpace的技术 并不足以使宿主机以外的网络主动发现容器的存在。Docker采用了 端口绑定的方式(通过iptables的NAT) ,将宿主机上的端口流量转发到容器内的端口上,这样一来,外界就可以与容器中的进程进行通信。 iptables的介绍,请点我点我 。
创建容器,并将宿主机的3306端口绑定到容器的3306端口:docker run -tid --name db -p 3306:3306 mysql
在宿主机上,可以通过“iptables -t nat -L -n”,查到一条DNAT规则:DNAT tcp --0000/0 0000/0 tcp dpt:3306 to:1721705:3306
Bridge模式的容器与外界通信时,必定会占用宿主机上的端口,从而与宿主机竞争端口资源,这会造成对宿主机端口管理很复杂。同时,由于容器与外界通信是基于三层上iptables NAT,性能和效率损耗是显而易见的。
NAT将地址空间分段的做法引入了额外的复杂度。比如容器中应用所见的IP并不是对外暴露的IP, 因为网络隔离,容器中的应用实际上只能检测到容器的IP,但是需要对外宣称的则是宿主机的IP,这种信息的不对称将带来诸如破坏自注册机制等问题 。
摘抄自陆平的《基于Kubernetes的容器云平台实战》一书的第10章Kubernetes网络
最近解决docker与宿主机同网段通信的问题,写此文章记录一下整个过程。
例如
宿主机A 和宿主机B是网络联通关系,在宿主机A上面创建了多个容器组成集群,但是我希望通过宿主机B也可以访问到宿主机A的容器,当然,你也可能会说,端口映射非常方便,如果我需要的端口比较多,或者着如果我临时需要增加某些端口,可能设置起来比较麻烦,那么如果我们将宿主机A里面的容器的IP与宿主机的IP在同一个网络,不就可以直接来进行互联互通了么。
安装 Docker
安装 pipework 这个工具可以使用一条命令就可以实现更改容器的IP,更准确来说为容器IP添加一个新的网卡。
编辑默认ip配置文件,eth0或者ens33(不同 *** 作系统,名称不一致,例如我 *** 作的这台机器的名称为ifcfg-ens33)
输入 i 进入到编辑模式,将下面的内容复制到文件中
并且将配置内容复制到配置文件中
重启虚拟机网络服务
修改docker的配置文件 /etc/sysconfig/
修改内容如下
修改完之后:
--net=none 代表容器的网卡都是为空的,需要通过 pipework 进行自定义指定
修改主机ip,网段与宿主机A网桥IP段保持一致。设置后,宿主机A,B之间可以互相ping通
到这里,就完成了Docker网络之间的通信。
前面介绍了: Docker容器网络-基础篇
前文说到容器网络对Linux虚拟化技术的依赖,这一篇章我们将一探究竟,看看Docker究竟是怎么做的。通常,Linux容器的网络是被隔离在它自己的Network Namespace中,其中就包括:网卡(Network Interface)、回环设备(Loopback Device)、路由表(Routing Table)和iptables规则。对于一个进程来说,这些要素,就构成了它发起和响应网络请求的基本环境。
我们在执行 docker run -d --name xxx 之后,进入容器内部:
并执行 ifconfig:
我们看到一张叫eth0的网卡,它正是一个Veth Pair设备在容器的这一端。
我们再通过 route 查看该容器的路由表:
我们可以看到这个eth0是这个容器的默认路由设备。我们也可以通过第二条路由规则,看到所有对 16925411/16 网段的请求都会交由eth0来处理。
而Veth Pair 设备的另一端,则在宿主机上,我们同样也可以通过查看宿主机的网络设备来查看它:
在宿主机上,容器对应的Veth Pair设备是一张虚拟网卡,我们再用 brctl show 命令查看网桥:
可以清楚的看到Veth Pair的一端 vethd08be47 就插在 docker0 上。
我现在执行docker run 启动两个容器,就会发现docker0上插入两个容器的 Veth Pair的一端。如果我们在一个容器内部互相ping另外一个容器的IP地址,是不是也能ping通?
容器1:
容器2:
从一个容器ping另外一个容器:
我们看到,在一个容器内部ping另外一个容器的ip,是可以ping通的。也就意味着,这两个容器是可以互相通信的。
我们不妨结合前文时所说的,理解下为什么一个容器能访问另一个容器?先简单看如一幅图:
当在容器1里访问容器2的地址,这个时候目的IP地址会匹配到容器1的第二条路由规则,这条路由规则的Gateway是0000,意味着这是一条直连规则,也就是说凡是匹配到这个路由规则的请求,会直接通过eth0网卡,通过二层网络发往目的主机。而要通过二层网络到达容器2,就需要1271703对应的MAC地址。所以,容器1的网络协议栈就需要通过eth0网卡来发送一个ARP广播,通过IP找到MAC地址。
所谓ARP(Address Resolution Protocol),就是通过三层IP地址找到二层的MAC地址的协议。这里说到的eth0,就是Veth Pair的一端,另一端则插在了宿主机的docker0网桥上。eth0这样的虚拟网卡插在docker0上,也就意味着eth0变成docker0网桥的“从设备”。从设备会降级成docker0设备的端口,而调用网络协议栈处理数据包的资格全部交给docker0网桥。
所以,在收到ARP请求之后,docker0就会扮演二层交换机的角色,把ARP广播发给其它插在docker0网桥的虚拟网卡上,这样,1271703就会收到这个广播,并把其MAC地址返回给容器1。有了这个MAC地址,容器1的eth0的网卡就可以把数据包发送出去。这个数据包会经过Veth Pair在宿主机的另一端veth26cf2cc,直接交给docker0。
docker0转发的过程,就是继续扮演二层交换机,docker0根据数据包的目标MAC地址,在CAM表查到对应的端口为veth8762ad2,然后把数据包发往这个端口。而这个端口,就是容器2的Veth Pair在宿主机的另一端,这样,数据包就进入了容器2的Network Namespace,最终容器2将响应(Ping)返回给容器1。在真实的数据传递中,Linux内核Netfilter/Iptables也会参与其中,这里不再赘述。
CAM就是交换机通过MAC地址学习维护端口和MAC地址的对应表
这里介绍的容器间的通信方式就是docker中最常见的bridge模式,当然此外还有host模式、container模式、none模式等,对其它模式有兴趣的可以去阅读相关资料。
好了,这里不禁问个问题,到目前为止只是单主机内部的容器间通信,那跨主机网络呢?在Docker默认配置下,一台宿主机的docker0网桥是无法和其它宿主机连通的,它们之间没有任何关联,所以这些网桥上的容器,自然就没办法多主机之间互相通信。但是无论怎么变化,道理都是一样的,如果我们创建一个公共的网桥,是不是集群中所有容器都可以通过这个公共网桥去连接?
当然在正常的情况下,节点与节点的通信往往可以通过NAT的方式,但是,这个在互联网发展的今天,在容器化环境下未必适用。例如在向注册中心注册实例的时候,肯定会携带IP,在正常物理机内的应用当然没有问题,但是容器化环境却未必,容器内的IP很可能就是上文所说的1721702,多个节点都会存在这个IP,大概率这个IP是冲突的。
如果我们想避免这个问题,就会携带宿主机的IP和映射的端口去注册。但是这又带来一个问题,即容器内的应用去意识到这是一个容器,而非物理机,当在容器内,应用需要去拿容器所在的物理机的IP,当在容器外,应用需要去拿当前物理机的IP。显然,这并不是一个很好的设计,这需要应用去配合配置。所以,基于此,我们肯定要寻找其他的容器网络解决方案。
在上图这种容器网络中,我们需要在我们已有的主机网络上,通过软件构建一个覆盖在多个主机之上,且能把所有容器连通的虚拟网络。这种就是Overlay Network(覆盖网络)。
关于这些具体的网络解决方案,例如Flannel、Calico等,我会在后续篇幅继续陈述。
以上就是关于docker 容器如何固定ip有几种方式全部的内容,包括:docker 容器如何固定ip有几种方式、宿主机telnet不通docker容器内的ip地址怎么解决、Docker容器间网络互联原理,讲不明白算我输等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)