在阿里云ECS上启动的nginx的docker镜像访问不到
1、环境
云服务器:Alibaba Cloud Linux 3.2104 LTS 64位
Docker:Docker version 26.1.4, build 5650f9b
Docker-nginx:DockerVersion: 20.10.7,NGINX_VERSION=1.21.5
2、访问链路
外网:8088–>ecs nginx–>ecs :8090–>docker : 80
3、Docker启动
docker run -d -p 8090:80 --name nginx02 nginx
4、配置安全组
由于当时一心想时候死宝塔面板,所以选择了Alibaba Cloud Linux 3。
现在ECS上有个静态页面,用了nginx直接代理到了静态页面。其实可以直接用路径访问,就是单纯玩一玩。所以把ECS和docker的映射端口也用nginx代理了一下。
在ECS的安全组中配置了8088端口,在nginx上配置了端口。
配置如下
server {
listen 8088;
server_name ip;
location / {
# 处理8088端口上的请求,并转发到127.0.0.1:8088
proxy_pass http://127.0.0.1:8090;
# 可根据需要添加其他代理设置
}
}
然后直接用ip:8088端口访问,出乎意料的不通。
5、检查
先ECS上测试调用
curl 127.0.0.1:8088
curl: (56) Recv failure: Connection reset by peer
额,访问不到,可能是nginx配置有问题,或者是8090映射的有问题,再试试
curl 127.0.0.1:8090
curl: (56) Recv failure: Connection reset by peer
这样看,估计问题还在下一层,进容器看看
docker exec -it 446221816a6a /bin/bash
先检查一下nginx的配置
whereis nginx
nginx: /usr/sbin/nginx /usr/lib/nginx /etc/nginx /usr/share/nginx
正常应该在/etc/nginx 中,看一下吧
cat /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log notice;
pid /var/run/nginx.pid;
events {
worker_connections 1024;
}
http {
include /etc/nginx/mime.types;
default_type application/octet-stream;
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
#tcp_nopush on;
keepalive_timeout 65;
#gzip on;
include /etc/nginx/conf.d/*.conf;
}
没有看到代理服务的配置,再看下include那个配置/etc/nginx/conf.d/*.conf
cd /etc/nginx/conf.d
cat default.conf
server {
listen 80;
listen [::]:80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}
应该是没有问题的,只能在docker看下监听的端口了
#查看下监听的端口
netstat -tuln
bash: netstat: command not found
#没有命令,再换个试试
lsof -i -P -n | grep LISTEN
bash: lsof: command not found
#还没有,top一下试试
top
bash: top: command not found
#还没有
#算了直接看下80端口
curl 127.0.0.1
curl: (7) Failed to connect to 127.0.0.1 port 80: Connection refused
#果然还不行,难道是没有启动?
#直接启动一下吧
nginx #我这里今天启动过了,所以报端口占用了
2024/08/03 14:33:50 [emerg] 52#52: bind() to 0.0.0.0:80 failed (98: Address already in use)
nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use)
#然后再试试
curl 127.0.0.1
#就可以看到,欢迎的信息了
...
<title>Welcome to nginx!</title>
...
docker容器中应该没有问题了,再来ECS上试试吧
curl 127.0.0.1:8088
#不出意料可以看到欢迎的信息
...
<title>Welcome to nginx!</title>
...
然后再去公网上试试,发现还是一直转圈,还是不通啊,检查了安全组配置的没有问题,切换了一个正在用的端口是可以访问通过的。那么还是端口配置有问题啊。
开始检查ECS的防火墙
sudo firewall-cmd --list-ports
20/tcp 21/tcp 22/tcp 80/tcp 443/tcp 8888/tcp 8998/tcp 39000-40000/tcp
果然是没有8088端口啊,是不是加一下就可以了,网上找一下命令
5.1 方案一:失败
sudo iptables -A INPUT -p tcp --dport 8088 -j ACCEPT
#加完保存一下
sudo iptables-save > /etc/sysconfig/iptables # 适用于CentOS、RHEL或Fedora
sudo iptables-save > /etc/iptables/rules.v4 # 适用于Ubuntu、Debian
####那么问题来了,我应该用哪个,我的系统不属于中两种啊
###看了一下这个路径,都没有这个文件
###试试吧
sudo iptables-save > /etc/sysconfig/iptables #执行成功
sudo systemctl restart iptables#重启刷新一下,报错了
Failed to restart iptables.service: Unit iptables.service not found.
sudo firewall-cmd --list-ports #再看一下还没有
20/tcp 21/tcp 22/tcp 80/tcp 443/tcp 8888/tcp 8998/tcp 39000-40000/tcp
5.2 方案二:成功
上个方案不行,于是又查询了阿里云的官方文档
最终发现了一个命令,执行后就成功了,不啰嗦了,直接来
sudo firewall-cmd --zone=public --add-port=8088/tcp --permanent
success
sudo firewall-cmd --reload
success
#然后查询了一下就有了
sudo firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: eth0
sources:
services: cockpit dhcpv6-client ssh
ports: 20/tcp 21/tcp 22/tcp 80/tcp 443/tcp 8888/tcp 39000-40000/tcp 8998/tcp 8088/tcp
protocols:
forward: no
masquerade: no
forward-ports:
source-ports:
icmp-blocks:
rich rules:
再去访问一下公网,就可以访问通了
5.3 命令区分
firewalld 和 firewall-cmd 命令:
sudo firewall-cmd --zone=public --add-port=8088/tcp --permanent 是用于 firewalld 防火墙的命令。
区别:
firewalld 是一种动态管理的防火墙,允许管理员在运行时更改防火墙规则,而不必重启服务。
firewall-cmd 命令是 firewalld 的命令行接口,用于添加、删除和管理防火墙规则。
--zone=public 指定了规则应用的区域,这里指定为 public 区域,可以根据具体需要修改为其他预定义或自定义的区域。
--add-port=8088/tcp 表示允许 TCP 协议的 8088 端口通过防火墙,--permanent 参数表示将规则永久保存,重启后依然有效。
iptables 命令:
sudo iptables -A INPUT -p tcp --dport 8088 -j ACCEPT 是用于 iptables 防火墙的命令。
区别:
iptables 是 Linux 内核中的防火墙规则管理工具,较为传统和静态。
-A INPUT 表示将规则添加到 INPUT 链中,即处理输入流量的链。
-p tcp 指定规则适用的协议为 TCP。
--dport 8088 指定规则应用的目标端口为 8088。
-j ACCEPT 表示如果流量匹配规则,将接受该流量。
总结:
firewalld 和 firewall-cmd 更加现代和灵活,支持动态管理规则,而且可以方便地基于区域管理规则集合,对网络环境的变化有更好的适应性。
iptables 则是传统的静态防火墙规则工具,更适合在系统启动时设置一次性的规则,需要手动保存规则以确保重启后生效。
在选择使用时,通常建议优先选择 firewall-cmd 和 firewalld,特别是在需要动态调整防火墙规则以及支持多区域配置的情况下。
6、总结
1、记得docker跑起来之后,要检查对应的服务是否启动了
2、ECS中时候直接加安全组策略可以直接访问,今天不知道为啥8088不行。如果也遇到类似问题,开一下防火墙策略试试。
3、尽量使用发行版的linux,社区完善一点的。