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,社羣完善一點的。