nginx代理docker容器中运行的服务

文章目录
  1. 1. 部署步骤
    1. 1.1. 前置条件
    2. 1.2. 制作nginx镜像
    3. 1.3. 准备nginx配置文件
  2. 2. 运行容器

云服务器上运行了很多的docker服务,大多数服务都是没有验证的,可以通过nginx做集中的代理,并在nginx上配置用户名密码验证,避免非授权访问。

遇到的问题如下:
Q1 容器的IP是不固定的,如何配置nginx的代理?
A1 通过创建docker网络,使nginx容器与业务容器在同一个网络中,这样就可以通过容器名称进行代理,不需要关注容器的IP地址

Q2 新上线的业务容器/修改了业务容器端口,要修改nginx代理文件,又要重新加载nginx配置,有没有便捷的方式?
A2 通过挂在的方式,将代理的配置文件放在宿主机,容器内运行检测脚本,当发现配置文件发生变化时,自动重载

部署步骤

前置条件

1
2
3
4
# 创建docker网络
docker network create docker-net
# 所有的业务容器运行是使用--net参数使用该网络
--net docker-net

制作nginx镜像

  • 新建检测脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
cat monitor.sh 
#!/bin/bash
while true
do
md5=`md5sum /etc/nginx/conf.d/port-to-domain.conf | awk '{print $1}'`
grep ${md5} /tmp/md5result &>/dev/null
if [ $? -ne 0 ];then
echo `date` 'Config File Change'
echo `date` 'Command nginx -t exec'
nginx -t
if [ $? -eq 0 ];then
echo `date` 'Command nginx -t exec success'
nginx -s reload
echo `date` 'Command nginx -s reload exec'
else
echo `date` 'Command nginx -t exec failed'
fi

echo ${md5} > /tmp/md5result
echo `date` 'Change md5result'
fi
sleep 5
done
  • 因为要运行检测脚本,所以要修改一下nginx默认的cmd

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 新建一个启动服务的脚本
$ cat start-nginx-server.sh
#!/bin/bash
nohup bash /opt/monitor.sh &>/var/log/monitor.log &
nginx -g 'daemon off;'

# 修改文件权限
chmod +x start-nginx-server.sh monitor.sh

# 新建Dockerfile
$ cat Dockerfile
FROM nginx:latest
ADD monitor.sh /opt/
ADD start-nginx-server.sh /usr/local/bin/
CMD ["/usr/local/bin/start-nginx-server.sh"]

# 构建镜像
docker build -t nginx_pass:v1 .

准备nginx配置文件

在宿主机准备配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/opt/etc/nginx/conf.d# more port-to-domain.conf 
server {
listen 80;
server_name vscode.xxxx.com;
location ^~ / {
proxy_pass http://vscode:8086; # 转发,vscode为业务容器的名称
proxy_set_header X-Real-IP $remote_addr; #获取客户端真实IP
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}
server {
listen 80;
server_name cmd.xxx.com;
location ^~ / {
proxy_pass http://cmd:88; # 转发,cmd为业务容器的名称
proxy_set_header X-Real-IP $remote_addr; #获取客户端真实IP
proxy_set_header REMOTE-HOST $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}

运行容器

运行nginx容器

1
2
# 挂载的目录要根据实际的进行修改
docker run -d --name nginx_pass -p 80:80 -v /opt/etc/nginx/conf.d:/etc/nginx/conf.d --net docker-net --restart=always nginx_pass:v1