切换语言为:繁体

在阿里云ECS上启动的nginx的docker镜像访问不到

  • 爱糖宝
  • 2024-08-04
  • 2091
  • 0
  • 0

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:

再去访问一下公网,就可以访问通了 

在阿里云ECS上启动的nginx的docker镜像访问不到

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,社区完善一点的。

0条评论

您的电子邮件等信息不会被公开,以下所有项均必填

OK! You can skip this field.