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