docker镜像有自己的ip的原因是docker属于容器。根据查询相关信息资料,docker容器可以分配并指定ip,尤其是搭建集群时,可以防止容器ip混乱,在启动docker容器的时候,使用默认网络是不支持指派固定ip的,因此要创建自定义网络,设置固定ip。
Nacos(注册中心)是通过 IP+PORT 的形式调用其他服务。
问题:
Docker 容器使用虚拟 IP,当 Docker 中的服务 A,向 Nacos 注册的时候,Nacos 获取到了 Docker 的内部 IP,导致另外一个服务 B,想通过注册中心调用服务 A,但由于服务 B从 nacos 注册中心获取到的是服务 A 的内部 IP,这样导致了两个处于公网的微服务之间无法互相访问。
当然,配置了上述网络类型后,nacos 是可以拿到宿主机的 IP,但是此时拿到的是宿主机的内网 IP,解决办法如下:
启动 Docker 的时候,用 --network 参数,可以指定网络类型
在使用weave之前,你需要在所有宿主机上安装Docker环境,参考这些教程,在Ubuntu或CentOS/Fedora发行版中安装Docker。Docker环境部署完成后,使用下面的命令安装weave:$wget/zettio/weave/releases/download/latest_release/weave$chmoda+xweave$sudocpweave/usr/local/bin注意你的PATH环境变量要包含/usr/local/bin这个路径,请在/etc/profile文件中加入一行(LCTT译注:要使环境变量生效,你需要执行这个命令:source/etc/profile):exportPATH="$PATH:/usr/local/bin"在每台宿主机上重复上面的 *** 作。Weave在TCP和UDP上都使用6783端口,如果你的系统开启了防火墙,请确保这两个端口不会被防火墙挡住。在每台宿主机上启动Weave路由器当你想要让处于在不同宿主机上的容器能够互相通信,第一步要做的就是在每台宿主机上启动weave路由器。第一台宿主机,运行下面的命令,就会创建并开启一个weave路由器容器(LCTT译注:前面说过了,weave路由器也是一个容器):$sudoweavelaunch第一次运行这个命令的时候,它会下载一个weave镜像,这会花一些时间。下载完成后就会自动运行这个镜像。成功启动后,终端会输出这个weave路由器的ID号。下面的命令用于查看路由器状态:$sudoweavestatus第一个weave路由器就绪了,目前为止整个peer对等网络中只有一个peer成员。你也可以使用docker的命令来查看weave路由器的状态:$dockerps第二台宿主机部署步骤稍微有点不同,我们需要为这台宿主机的weave路由器指定第一台宿主机的IP地址,命令如下:$sudoweavelaunch当你查看路由器状态,你会看到两个peer成员:当前宿主机和第一个宿主机。当你开启路由器,这个peer成员列表会更长。当你新开一个路由器时,要指定前一个宿主机的IP地址,请注意不是第一个宿主机的IP地址(LCTT译注:链状结构)。现在你已经有了一个weave网络了,它由位于不同宿主机的weave路由器组成。把不同宿主机上的容器互联起来接下来要做的就是在不同宿主机上开启Docker容器,并使用虚拟网络将它们互联起来。假设我们创建一个私有网络10000/24来互联Docker容器,并为这些容器随机分配IP地址。如果你想新建一个能加入weave网络的容器,你就需要使用weave命令来创建,而不是docker命令。原因是weave命令内部会调用docker命令来新建容器然后为它设置网络。下面的命令是在宿主机hostA上建立一个Ubuntu容器,然后将它放到10000/24网络中,分配的IP地址为10001:hostA:~$sudoweaverun10001/24-t-iubuntu成功运行后,终端会显示出容器的ID号。你可以使用这个ID来访问这个容器:hostA:~$dockerattach在宿主机hostB上,也创建一个Ubuntu容器,IP地址为10002:hostB:~$sudoweaverun10002/24-t-iubuntu访问下这个容器的控制台:hostB:~$dockerattach这两个容器能够互相ping通,你可以通过容器的控制台检查一下。如果你检查一下每个容器的网络配置,你会发现有一块名为“ethwe”的网卡,你分配给容器的IP地址出现在它们那里(比如这里分别是10001和10002)。Weave的其他高级用法weave提供了一些非常巧妙的特性,我在这里作下简单的介绍。应用分离使用weave,你可以创建多个虚拟网络,并为每个网络设置不同的应用。比如你可以为一群容器创建10000/24网络,为另一群容器创建101000/24网络,weave会自动帮你维护这些网络,并将这两个网络互相隔离。另外,你可以灵活地将一个容器从一个网络移到另一个网络而不需要重启容器。举个例子:首先开启一个容器,运行在10000/24网络上:$sudoweaverun10002/24-t-iubuntu然后让它脱离这个网络:$sudoweavedetach10002/24最后将它加入到101000/24网络中:$sudoweaveattach101002/24现在这个容器可以与101000/24网络上的其它容器进行通信了。这在当你创建一个容器而网络信息还不确定时就很有帮助了。将weave网络与宿主机网络整合起来有时候你想让虚拟网络中的容器能访问物理主机的网络。或者相反,宿主机需要访问容器。为满足这个功能,weave允许虚拟网络与宿主机网络整合。举个例子,在宿主机hostA上一个容器运行在10000/24中,运行使用下面的命令:hostA:~$sudoweaveexpose1000100/24这个命令把IP地址1000100分配给宿主机hostA,这样一来宿主机hostA也连到了10000/24网络上了。显然,你在为宿主机选择IP地址的时候,需要选一个没有被其他容器使用的地址。现在hostA就可以访问10000/24上的所有容器了,不管这些容器是否位于hostA上。好巧妙的设定啊,32个赞!
你没有确定什么用VISTA
进行配置我用的网络配置管理来解释:!
我们知道,在微软的Vista系统中的网络功能得到了显著的改善,特别是在之前版本的系统设置已经非常不同的,这让许多刚刚安装了Vista系统的新手亏损,感觉设置是非常困难的。在这里,我教你如何创建和Vista下管理虚拟专用网(***)。
一,创建一个连接
第一次启动Vistat系统,然后单击“开始/连接到”菜单,在当前系统中显示所有可用的网络连接,然后点击下面的“设置连接或网络“链接,就会d出”网络连接“窗口,在其中的四个选项列表,连接到网络,因为它是建立一个***连接,选择”连接到工作区“,然后单击“下一步”按钮。
然后选择“使用我的Internet连接(***)”项,单击“下一步”按钮,然后输入***的IP地址登录和目标名称,在这里可以设置是否使用智能卡,允许其他人使用此连接,并立即连接到***。分配给您的用户名和密码
最后输入时,它会自动连接到点击“下一步”按钮,***,然后创建***连接。
二,***日常维护
***建立的时候,通常你需要连接,你可以用同样的方法拨号连接,然后单击“开始/连接到”菜单中,然后,您可以看到所有可用的侧从中挑选合适的***连接,您可以双击该***网络连接列表后,立即连接。
但管理选项“连接到网络”中的拨号连接实在有限,无法建立连接更多的管理,甚至删除现有的连接都无法使用。因此,如何管理***连接它的“网络连接”?
首先在“网络连接”对话框中,单击“打开网络和共享中心”链接,进入“网络和共享中心”窗口。在这里,您可以网上的“网络连接”的管理,其中包括“重命名”,“删除”,“创建快捷方式”,“创建副本”,等你甚至可以改变连接的连接设置。
如果你觉得***链接放置在桌面上,只需选择在“网络连接”窗口中所需的***连接,然后单击“创建快捷方式”按钮,系统会自动d出“Windows可以不能在当前位置创建快捷方式,使桌面上的快捷方式?“的提示,点击”是“按钮后,就可以在桌面上创建***的快捷方式。
前一篇 基于docker部署的微服务架构(一):服务注册中心 已经成功创建了一个服务注册中心,现在我们创建一个简单的微服务,让这个服务在服务注册中心注册。然后再创建一个调用者,调用此前创建的微服务。
新建一个maven工程,修改pomxml引入 spring cloud 依赖:
在 resources 目录中创建 applicationyml 配置文件,在配置文件内容:
这里eureka的注册地址为上一篇中设置的defaultZone。
在 java 目录中创建一个包 demo ,在包中创建启动入口 AddServiceApplicationjava
在demo包下新建一个子包controller,在controller子包下创建一个controller对外提供接口。
在服务注册中心已经运行的情况下,运行 AddServiceApplicationjava 中的 main 方法,启动微服务。
访问服务注册中心页面 >
Docker 是一个开源的 应用容器引擎 ,让 开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows 机器上,也可以实现虚拟化 。容器是完全使用沙箱机制,相互之间不会有任何接口。
由于本地开发好的程序往往都需要部署到服务器上进行运行,这就导致了程序需要运行在不同的环境上,这通常是一个令人头痛的事情。在过去,开发团队需要清楚的告诉运维部署团队,其所使用的全部配置文件+所有软件环境。不过,即便如此,仍然常常发生部署失败的状况。
于是乎, 虚拟化 技术应运而生。开发团队将开发好的程序在虚拟机上运行,这样就能解决运维的问题。但是由于虚拟机技术过重的特性导致了其 资源占用多、冗余步骤多以及启动慢的缺陷 。而这个时候 一种新的虚拟化技术搭配上容器化的思想 的产品便出现了,而它就是Docker。
下图是虚拟机技术和容器化技术架构的对比。我们可以得出以下总结:
[上传失败(image-efadd2-1643314980201)]
]( >
1创建一个网络(子网掩码设置大一点,这样就有用不完的私网IP了)
docker network create --subnet=17217200/16 my_docker_net
2启动容器的时候 指定网络和IP地址,感觉容器名字包含IP的信息会好记一点,如:
redis:
docker run -itd --name myRedis_0_5 --net my_docker_net --ip 17217205 -p 6379:6379 redis
rabbitMq:
docker run -d --hostname myRabbit --name myRabbit --net my_docker_net --ip 17217206 -p 15672:15672 -p 5672:5672 rabbitmq
docker exec -it myRabbit rabbitmq-plugins enable rabbitmq_management
指定MQ版本:
docker run -d --hostname myRabbit310 --name myRabbit310 --net my_docker_net --ip 17217207 -p 15672:15672 -p 5672:5672 rabbitmq:310-rc-management
docker exec -it myRabbit310 rabbitmq-plugins enable rabbitmq_management
docker exec -it myRabbit310 rabbitmq-plugins enable rabbitmq_shovel rabbitmq_shovel_management
mysql:
docker run -itd --name mysql-local --net my_docker_net --ip 17217202 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root mysql
xxl-job-admin
docker run -e PARAMS="--springdatasourceurl=jdbc:mysql://17217202:3306/xxl_jobuseUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai --springdatasourceusername=root --springdatasourcepassword=root" --net my_docker_net --ip 17217209 -p 8089:8080 -v /tmp:/data/applogs --name xxl-job-admin -d xuxueli/xxl-job-admin:231
3这样容器就有固定的IP了,会形成如下状态:
容器外面可以使用映射出的端口访问,但是不能通过指定的IP访问
容器内部容器之间可以使用指定的端口访问,但无法通过容器的主机IP+映射的端口访问
这样似乎还是不方便:一个应用在容器外本来可以访问,可是丢到容器内,因为服务地址配置问题会导致不能访问,切换配置也非常麻烦,如果解决
一个好的办法是为容器配置一个环境变量,这样容器中的应用会自动读取环境变量
4通常容器如RIDIS,默认一般没有ifconfig和 ping命令,导致无法查看本机IP地址和PING通对方IP地址,使用如下命令安装:
apt-get update 先升级apt-get,
然后安装
apt install iputils-ping
apt install net-tools
ifconfig 或者 ip addr查看的虚拟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镜像为什么有自己的ip全部的内容,包括:docker镜像为什么有自己的ip、Nacos微服务注册地址为Docker内网IP的解决办法、如何配置docker共享宿主机ip等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)