Debug——主机无法访问虚拟机中Docker开启的容器
文章目录
- 问题阐述
- 解决方案
- 成长知识
- Linux中IP转发
- Linux防火墙设置
- 思:是不是这个防火墙防的是其他网络上的人对我虚拟机的访问,我虚拟机的宿主机其实没有这个限制?但是我后面解压Jenkins.war包过程中,主机访问虚拟机中端口时,即使已经设置了IP转发为1,仍然无法正常访问,需要设置防火墙开放8080端口才行,为什么呢?为什么访问Docker中容器不需要设置防火墙开放端口,而访问虚拟机中Jenkins就需要呢?
- 虚拟机与Docker容器的端口访问差异
问题阐述
明明已经正确设置了端口,也启动了虚拟机中的docker容器将docker中端口映射到虚拟机机器的端口上,主机也可以正确ping到虚拟机ip地址
在主机却仍然无法正确访问到虚拟机中的docker容器
解决方案
- 查看 Linux 系统中IP 转发的配置,结果0为未开启,1为开启
cat /proc/sys/net/ipv4/ip_forward
发现结果为0,测试发现确实如果为0则访问不到,若改为1才可能能够正常访问
改为1的命令
sysctl -w net.ipv4.ip_forward=1
然后便可访问成功
成长知识
Linux中IP转发
- IP 转发:当 IP 转发启用时(/proc/sys/net/ipv4/ip_forward 设置为 1),虚拟机可以将来自其他网络接口的流量转发到目标地址。这在桥接网络或 NAT 网络中非常重要,因为它允许流量从一个网络接口到达另一个网络接口。
- 禁用 IP 转发:当 IP 转发禁用时(/proc/sys/net/ipv4/ip_forward 设置为 0),虚拟机不会转发来自其他网络接口的流量。这意味着即使 Docker 容器的端口已经正确映射,宿主机也无法通过虚拟机的网络接口访问 Docker 容器。
Linux防火墙设置
事实上只改了IP转发配置,我便解决了问题,但我在解决问题的过程中还了解到了防火墙配置,虽然实践说明主机访问虚拟机一般并不会受到防火墙限制,但仍有必要多掌握一些知识!!!
虚拟机linux如何查看防火墙,设置防火墙开放端口?
在 Linux 虚拟机中,查看和设置防火墙规则的方法取决于你使用的防火墙工具。常见的防火墙工具包括 firewalld 和 iptables。以下是如何使用这两种工具查看和设置防火墙规则的详细步骤。
-
使用
firewalld
firewalld 是现代 Linux 发行版(如 CentOS 7、Fedora、RHEL 7 等)中常用的防火墙管理工具。 -
查看防火墙状态
运行以下命令查看 firewalld 的状态:
firewall-cmd --state
如果防火墙正在运行,输出将是 running。
- 查看防火墙规则
运行以下命令查看当前的防火墙规则:
firewall-cmd --list-all
这将显示当前活动的防火墙区域(如 public、internal 等)及其规则,包括开放的端口、允许的服务等。
- 开放特定端口
运行以下命令开放特定端口(例如开放 80/tcp 和 3306/tcp):
firewall-cmd --zone=public --add-port=80/tcp --permanent
firewall-cmd --zone=public --add-port=3306/tcp --permanent
--zone=public
:指定防火墙区域,public 是默认区域。
--add-port=80/tcp
:开放端口 80,协议为 TCP。
--permanent
:使规则永久生效,重启后仍然有效。
- 移除特定端口
运行以下命令移除已开放的端口(例如移除 80/tcp 和 3306/tcp):
firewall-cmd --zone=public --remove-port=80/tcp --permanent
firewall-cmd --zone=public --remove-port=3306/tcp --permanent
--zone=public
:指定防火墙区域,public 是默认区域。
--remove-port=80/tcp
:移除端口 80,协议为 TCP。
--permanent
:使规则永久生效,重启后仍然有效。
- 重新加载防火墙规则
运行以下命令重新加载防火墙规则,使更改生效:
firewall-cmd --reload
- 验证端口是否开放
运行以下命令验证端口是否已经开放:
firewall-cmd --list-all
你应该在输出中看到 ports: 80/tcp 3306/tcp
思:是不是这个防火墙防的是其他网络上的人对我虚拟机的访问,我虚拟机的宿主机其实没有这个限制?但是我后面解压Jenkins.war包过程中,主机访问虚拟机中端口时,即使已经设置了IP转发为1,仍然无法正常访问,需要设置防火墙开放8080端口才行,为什么呢?为什么访问Docker中容器不需要设置防火墙开放端口,而访问虚拟机中Jenkins就需要呢?
虚拟机与Docker容器的端口访问差异
- 访问虚拟机中服务(如Jenkins)需要开放防火墙端口的原因
- 虚拟机本质:独立的操作系统实例,拥有完整的网络栈和安全边界。
- 防火墙机制:
- 虚拟机操作系统(如Linux)自带防火墙(firewalld/ufw),默认拦截外部对非必要端口的访问(包括8080)。
- IP转发(
net.ipv4.ip_forward=1
)仅负责数据包转发,不替代防火墙规则。 - 外部访问(包括主机)必须通过虚拟机自身防火墙的明确允许。
- 核心逻辑:虚拟机防火墙是独立的安全屏障,默认拒绝所有未授权端口访问。
- 访问Docker容器通常无需手动开放主机防火墙端口的原因
- 容器网络模型:基于Linux内核的命名空间(Namespace)和桥接网络,属于主机内的进程级隔离。
- 自动配置机制:
- 使用
-p 主机端口:容器端口
映射时,Docker会自动在主机iptables中添加转发规则。 - 规则内容:允许外部访问主机映射端口,并转发到容器内部对应端口。
- 使用
- 容器内部特性:默认无独立防火墙(除非手动安装),端口对主机默认开放。
- 核心逻辑:Docker自动完成主机防火墙规则配置,省去手动操作步骤。
- 关键区别对比表
场景 | 网络隔离级别 | 防火墙规则来源 | 是否需要手动开放端口 |
---|---|---|---|
虚拟机(如Linux) | 独立操作系统级别 | 虚拟机自身的防火墙(firewalld/ufw) | 需要(默认拦截外部访问) |
Docker容器 | 进程级隔离(共享主机内核) | 主机的iptables(Docker自动配置) | 不需要(Docker自动添加转发规则) |
- 补充说明
- 若Docker容器内手动启用防火墙(如firewalld),则需在容器内开放端口。
- 虚拟机可配置防火墙默认允许所有访问(不推荐,存在安全风险),但与Docker的自动规则机制本质不同。