nginx-proxy 自动反向代理

2016/8/19 posted in  Docker

docker 使得部署应用非常的方便,真正的让在单机部署多个应用成为一键化操作。然而,如果单机中有多个应用需要对外提供服务,用 docker 有时候感觉并不是那么优雅。

如果在单机中需要部署多个应用,而这些应用需要占用同一个端口,比如多个 web 应用同时需要 80/443 端口,或者希望对于来自同一个域名的流量进行 load balance,希望这些流量可以被分发到不同的容器上。这些常见的场景,目前操作起来并不方便。

对于上述场景,常见的做法就是在本地部署一个 nginx,每当有 docker 容器更新的时候,便修改 nginx 的配置文件,使满足需求。

方法很简单,但是繁琐,如果有工具可以把这些操作自动化,那么在使用 docker 的时候,是不是可以节省很多精力。在 daocloud hub 里,的确有这么一样工具,即是 nginx-proxy。这是一个会自动获取容器配置并做好反向代理和负责均衡的 nginx。

部署 nginx-proxy

首先需要把共享使用的端口预留给 proxy,比如 80、443 端口,这样,就可以让打在这两个端口上的流量由 proxy 来分配。其次,因为 proxy 需要获取 docker 容器的配置进行对 nginx 的配置文件修改,因此,需要把 docker.sock 映射到容器中。

docker 启动命令

docker run -d -p 80:80 -v /var/run/docker.sock:/tmp/docker.sock:ro daocloud.io/daocloud/nginx-proxy

建议使用 compose 来配置,yml文件如下:

proxy:
  image: daocloud.io/daocloud/nginx-proxy:0.3.6
  privileged: false
  restart: always
  ports:
  - 443:443
  - 80:80
  volumes:
  - /var/run/docker.sock:/tmp/docker.sock:ro

反向代理

对于配置好 proxy 的主机,每当在主机上启动一个容器的时候,proxy 都会自动检查该容器是否含有 VIRTUAL_HOST 这个环境变量,当检查到某个刚启动的容器含有这个环境变量时,便会自动修改配置文件,使得这个来自 环境变量描述的域名 的流量会被打在这个容器上。

那么,在启动容器的时候,只需要添加一个环境变量,比如:

hypo_blog:
  image: daocloud.io/cmss/hypo-blog:master-796038f
  privileged: false
  restart: always
  ports:
  - '4000'
  environment:
  - VIRTUAL_HOST=blog.ihypo.net

负载均衡

当有多个容器含有相同的 VIRTUAL_HOST 的时候,proxy 便会自动做好负载均衡,如果使用 daocloud 的话:

只需要在容器界面调整容器个数,proxy 会自动做好 load balance。

如果进入 proxy 容器中查看的话,也可以看到生成的配置文件:

upstream blog.ihypo.net {
           # dao_hypo_blog_2
           server 192.168.0.6:4000;
           # dao_hypo_blog_1
           server 192.168.0.4:4000;
}

其他

nginx-proxy 的使用非常简单,还支持多域名,多端口,https 等,可以参考镜像的 README

参考

https://github.com/jwilder/nginx-proxy

http://jasonwilder.com/blog/2014/03/25/automated-nginx-reverse-proxy-for-docker/