docker部署ng实现反向代理

发布时间:2024年01月12日

场景

按规定尽可能减少开放到外网的端口,所以需要将多个服务部署到一个ip一个端口上。

方案

使用ng实现请求转发。根据http请求中的host与ng配置文件中的server_name匹配,转发到对应的机器上。
在docker上部署三个容器,每个容器中启动一个ng服务(这仨ng服务的欢迎页面不同,用以区分不同服务)。其中一个ng作为反向代理,另外ng作为http服务(之后这俩ng会被替换成其他服务,比如gitlab服务)。

实现

定制镜像

官方ng镜像中没有vim,而公司生产环境的电脑又不能直连互联网,所以需要在本地开发环境将ng镜像修改下然后部署到生产环境。

使用Dockerfile定制镜像。

FROM nginx:latest
RUN apt-get update && \
    apt-get install -y vim && \
    rm -rf /var/lib/apt/lists/*

在Dockerfile所在目录下执行如下命令

docker build -t nginx_wjl

不要使用docker commit定制镜像。具体原因参见《Docker从入门到实践 第三版》

成功定制镜像
在这里插入图片描述

部署

// 创建网络
docker network create ng_net


// 反向代理
docker run --name mynginx0 --network ng_net -p 1080:80 -d nginx_wjl

// 服务1
docker run --name mynginx1 --network ng_net -p 1081:80 -d nginx_wjl

// 服务2
docker run --name mynginx2 --network ng_net -p 1082:80 -d nginx_wjl

修改文件

修改欢迎页面

vim /usr/share/nginx/html/index.html

修改反向代理的配置文件

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log debug;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  'wjl $host wjl$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;
    server {
        listen 80;
        server_name server1.com;

        location / {
                proxy_pass http://mynginx1:80;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
        }
    }
    server {
        listen 80;
        server_name server2.com;

        location / {
                proxy_pass http://mynginx2:80;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
        }
    }
}

host

SwichHosts做如下配置

127.0.0.1 server1.com
127.0.0.1 server2.com

效果

反向代理欢迎页面
在这里插入图片描述

server1欢迎页面
在这里插入图片描述

server2欢迎页面
在这里插入图片描述

通过反向代理访问server1欢迎页面。虽然访问的是"server1.com",但由于之前修改了host,所以实际访问的ip是回环地址。
在这里插入图片描述

通过反向代理访问server2欢迎页面

在这里插入图片描述

其他

遇到的问题

host无效

用switchhosts配置完之后,命令行中可以发现功能都正常运行,但是在浏览器上就是无法访问相应服务。就好像浏览器没有将"server1.com"这个地址解析成回环地址。
询问ChatGPT,他告诉我可能是开了代理导致的。关闭代理后问题解决了。
在这里插入图片描述

docker网络

容器好像必须在一个docker网络下才能相互访问。docker网络这部分内容不太了解,有机会要学习下。

ng关键文件 欢迎页面 配置文件 日志

ng容器中的关键文件存储位置可能与平时本机或者win下的不一样。以下路径都是ChatGPT告诉我的,亲测有效。

// 欢迎页面
vim /usr/share/nginx/html/index.html

// 配置文件
vim /etc/nginx/nginx.conf

// 日志
vim /var/log/nginx/error.log
vim /var/log/nginx/access.log

日志无效

日志文件打开之后啥也没有,原因是ng镜像中的日志文件是链接,重定向到"stdout"和"stderr"。
在这里插入图片描述
若要通过文件形式查看日志,可以把镜像中自带的这俩文件删除,删除之后运行"nginx -s reload"。之后的日志就会显示到这俩文件中了。

这个问题原因的发现比较偶然,手一抖打出"ls -l"的命令,然后发现这是链接。

server_name

最开始的方案中没打算通过域名进行流量分发,想通过不同的uri实现流量分发。比如访问反向代理的"/server1/add",server1就会接收到一个"/add"请求。
实现过程中发现ng配置未生效,最后发现是因为server_name没配置回环地址,但我访问的时候用的是回环地址,所以导致配置文件没提供我想要的功能。

user  nginx;
worker_processes  auto;

error_log  /var/log/nginx/error.log debug;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024;
}


http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  'wjlwjl$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;
    server {
        listen 80;
        server_name mynginx0 127.0.0.1;# 这里追加了回环地址。mynginx0这个是容器名,应该没啥用。

        location /n1 {
                proxy_pass http://mynginx1:80/;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
        }
        location /n2 {
                proxy_pass http://mynginx2:80/;
                proxy_set_header Host $host;
                proxy_set_header X-Real-IP $remote_addr;
        }

    }
}

实现了"通过uri进行请求转发"的功能后,突然意识到可以按照server_name进行请求转发,所以本篇博客才以server_name作为请求转发的依据。

"server_name需要加回环地址"这个发现也是突然来的灵感。可能是在某个地方听说过这部分知识。

win&curl

排查问题的过程中,我尝试在容器内,在powershell,在cmd上使用curl测试请求。

curl -H "Host: server1.com" http://127.0.0.1

在反向代理容器中使用curl
在这里插入图片描述

但是curl在powershell中没法修改header,所以在powershell中使用了另一个指令

Invoke-WebRequest -Uri "http://127.0.0.1:1080" -Headers @{"Host" = "server1.com"}

在这里插入图片描述

待解决问题

反应慢

通过反向代理访问另外俩服务时反应比较慢。这个问题先delay,本篇博客实现的功能只是一个大项目中的小环节,等整个大项目完成差不多之后再性能调优。

文章来源:https://blog.csdn.net/m1f2c3/article/details/135550805
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。