当前位置: 首页 > 科技观察

使用Nginx实现服务器中多容器共存

时间:2023-03-14 11:30:08 科技观察

使用Nginx实现多个容器在服务器共存,分别映射到宿主机(云主机)的同一个端口(即80、443、3306)。在ServiceDocker中安装了XAMPP,并在此基础上部署了扫码签到小程序的服务端。ServiceDocker的80和443端口分别提供http和https服务,3306端口是MySQL数据库的端口。ServiceDocker绑定域名sign.famend.cn。目标云主机中的一个ServiceDocker占用了80和443端口,如果要在宿主机中部署另外一台服务器对外服务,则不能使用80和443端口。我们的目标是在宿主机中部署多个ServiceDocker,每个ServiceDocker绑定自己的域名对外提供服务,保证80和443端口可用。思路是修改ServiceDocker的端口映射,将ServiceDocker的80、443端口映射到宿主机的89、449端口,从而释放宿主机的80、443端口。释放的80和443端口被Nginx使用。用Nginx安装docker(简称NginxDocker,命名为mynginx,下同)。NginxDocker内部使用80和443端口,分别映射到宿主机的80和443端口。NginxDocker用作反向代理。当有访问请求时,读取Nginx的配置后,将不同的URL指向其对应的Dockers。例如:访问http://sign.famend.cn:80,会自动映射到http://sign.famend.cn:89。实现步骤1、修改ServiceDocker的端口映射,释放80和443端口,Docker没有提供修改端口的命令。从网上找了2个方法。方法一:先停止容器,然后将容器打包成一个镜像,再运行新的镜像。运行新映像时指定新端口。使用的命令如下:#首先停止容器dockerstopcontainerA#将容器提交到镜像dockercommitcontainerAnewImageB#运行容器dockerrun-p8080:8080-p8081:8081-v/home/data/:/home/data/-dtnewImageB方法二:先停止Container,再停止容器服务,再修改容器配置文件,最后启动容器服务,启动容器。步骤如下:① 停止ServiceDocker(ServiceDocker的名字是sign),停止docker服务。sudodockerstopsignsudoservicedockerstop② 使用dockerps-a命令找到要修改的容器的CONTAINERID。③ 运行dockerinspect[CONTAINERID]|grep标识命令。④ 执行cd/var/lib/docker/containers命令进入,找到与Id相同的目录。如果执行cd命令时提示permissiondenied,可以先执行sudo-s。进入id对应的目录后,打开文件hostconfig.json。找到80端口的映射,如下:"80/tcp":[{"HostIp":"0.0.0.0","HostPort":"80"}]将"HostPort":"80"改为"HostPort":"89",如下"80/tcp":[{"HostIp":"0.0.0.0","HostPort":"89"}]修改前,ServiceDocker内部的80端口映射到宿主机的80端口;修改后,ServiceDockerInternal80端口映射到宿主机的89端口。稍微说明一下,有些文章(参考资料中的2、3)提到需要修改config.v2.json,个人测试不需要。启动ServiceDocker时会自动修改此文件。⑤ 启动docker服务,然后启动ServiceDocker(命名标志)。sudoservicedockerstartsudodockerstartsign方法(一)和方法(二)都可以,我选择方法(二)。执行方法(2)后,打开浏览器验证,提示“无法访问该网站”。初步估计是docker中的server没有启动。运行命令:sudo/opt/lampp/lamppstopsudo/opt/lampp/lamppstart运行stop时发现apache没有启动,可能是80端口被修改了,执行start后打开浏览器即可验证http://sign.famend.cn:89和https://sign.famend.cn:449,访问成功。修改Docker端口的方法并不复杂。如果以后的docker版本能提供相应的命令,相信会方便很多。顺便运行crontab-l查看ServiceDocker中的定时任务是否启动。如果没有,运行servicecronstart启动定时任务。接下来配置NginxDocker反向代理,使http://sign.famend.cn:80和https://sign.famend.cn:443也能访问成功。2.配置NginxDocker反向代理。① 下载nginx并运行。dockercontainerrun\-d\-p80:80\-p443:443\--rm\--namemynginx\nginx② 配置nginx配置文件。mkdirnginx-filesdockercontainercpmynginx:/etc/nginx.mvnginxconfviconf/nginx.conf在nginx.conf中添加如下反向代理信息。服务器{listen443ssl;server_namesign.famend.cn;ssl_certificate/etc/nginx/ssl/sign.famend.cn/1_sign.famend.cn_bundle.crt;ssl_certificate_key/etc/nginx/ssl/sign.famend.cn/2_sign.famend.cn.key;location/{proxy_set_headerHOST$host;proxy_set_headerX-Real-IP$remote_addr;proxy_set_headerX-Forwarded-For$proxy_add_x_forwarded_for;proxy_set_headerX-Forwarded-Proto$scheme;proxy_passhttp://sign.famend.cn:89/;}}服务器{listen80;server_namefamend.cnsign.famend.cn;location/{proxy_set_headerHOST$host;proxy_set_headerX-Real-IP$remote_addr:89;proxy_set_headerX-Forwarded-For$proxy_add_x_forwarded_for;proxy_set_headerX-Forwarded-Proto$scheme;proxy_passhttp://sign.famend.cn:89/;}}443端口需要使用ssl_certificate和ssl_certificate_key。ServiceDocker中证书使用的LetsEncryptSSL证书每90天更新一次。SSL证书的来源:一种允许他们从LetsEncrypt共享SSL证书的方法。另外,在腾讯注册的域名,腾讯免费提供SSL证书,有效期一年。为了简单起见,我直接使用了腾讯的SSL证书。当然,在一年之内,证书必须在到期前更新。③ 停止mynginx,然后重启。dockercontainerrun\--namemynginx\--volume"$PWD/conf":/etc/nginx\-p80:80\-p443:443\-d\nginx这次去掉--rm参数,这样会保留当它停止运行容器时。至此,配置完成。验证sign.famend.cn:80sign.famend.cn:89sign.famend.cn:449sign.famend.cn:443是否可以在浏览器中正常访问。当然打开449和443可以发现这两个网址使用的证书是不一样的。449由LetsEncrypt提供,有效期为90天;443来自腾讯(发行机构TrustAsia),有效期1年。当然,也可以访问ServiceDocker中的另一个网站famed.cn:famed.cn:80famend.cn:89成功。