借助docker展现的nginx反向代理实例

概述

这节其实是上一篇nginx教程的补充,因为有朋友看了之后对于反向代理那块还有点疑问.所以这边就举一个简单的例子(负载均衡).顺便加上了一些docker的知识。所以废话不说,进入正题吧~

nginx反向代理

上一篇文章提到了反向代理的概念.概念其实很简单,但是实际上有什么应用呢?
有个最简单也是很实用的例子,也就是负载均衡.作为反向代理的nginx在收到请求后按照一定规则再分发给下游的服务器.在这里对服务端而言客户端是明确的,并且通常配置的时候会带上realip.但是对于客户端来讲却不知道请求最后落到了哪台机器,这就是一个常见的反向代理的场景.这里并没有其他可以补充的知识,在nginx的官网上都是有相关介绍的.
这就着重以一个例子来实现.

这边会借助docker来实现这个例子.
最简单的一个例子就是两个服务容器一个nginx容器.
nginx容器就是直接使用官方镜像即可.

首先是server的代码,go语言编写

package main

import (
    "fmt"
    "log"
    "net/http"
    "os"
)

func main() {
    http.HandleFunc("/test", func(w http.ResponseWriter, r *http.Request) {
        log.Println(r)
        hostName, _ := os.Hostname()
        w.Write([]byte(fmt.Sprintf("server:%s\n", hostName)))
        return
    })

    log.Println("start...")

    log.Panic(http.ListenAndServe(":8081", nil))
}

本身没什么难度,主要是会输出自己的hostname,这个在后面帮助我们区分实际访问的服务器.

然后go build 编译即可,根据自己的实际需求选择编译条件.这里我提供了现成的docker镜像,地址为(https://cloud.docker.com/u/evanshao/repository/docker/evanshao/lbserver),

就不多赘述了.
然后是Dockerfile

FROM debian
MAINTAINER evan
COPY server /
ENTRYPOINT ["./server"]

这个也很简单,就是借助debian基础镜像运行编译好的server.

然后是nginx配置(已经提供了镜像,地址是:https://cloud.docker.com/u/evanshao/repository/docker/evanshao/lbnginx).

这里可以参考上一篇文章的基础配置:

#user nobody;
worker_processes 4; # 按照机器情况定

events {
    worker_connections 10240; # 按照机器情况定
}

http{
    include  mime.types;
    default_type  application/json;  # 按照自己服务设置
    error_page 500 502 503 504 /50x.html;
    error_page 404 /404.html; # 这个自己写了放到html目录下,不然应该是nginx代码里写死的
     resolver 114.114.114.114;
    # 定义日志格式  这个别名是main
    log_format main '$remote_addr - $remote_user [$time_local] "$request"  $status $body_bytes_sent "$http_referer" "$http_user_agent" "$http_x_forwarded_for"';

  sendfile on;
 keepalive_timeout 30;

 include sites/*.http.conf;  # 具体的server放在这里

}

重点是sites下需要两个新建的配置文件,
一个是ups.http.upstream:

upstream test_server{
    server serverA:8081;
    server serverB:8081;
}

这里其实是有两个注意点的,一个是serverA 这个是配合后面的dockerDNS使用的,还有个自然是端口号,和server程序监听的端口号一致.

另外一个文件是 ups.http.conf,这里在开头引用了upsream文件,并利用proxy_pass实现了转发.

include sites/ups.http.upstream;
server{
    listen 80 default_server;
    server_name localhost;
    access_log logs/ups.log main;
    
    location /{
        set $upstream_host $host;
        proxy_pass http://test_server;
        
    }
}

这边是Dockerfile,myconf下就是上面的文件nginx.conf以及sites文件夹,sites里是其他两个文件.另外还创建了一个空的logs文件夹

FROM nginx
MAINTAINER evan
COPY myconf/  /etc/nginx
EXPOSE 80
ENTRYPOINT ["nginx","-g","daemon off;"]

到这里实验环境就准备好了,下面其实就是docker部分了,时间有限,这里仅仅提下使用方法.如果docker没有安装的话可以参考官方文档进行操作,后面有机会我也会开始写一些docker的简单教程~

上文提到的dockerDNS其实是docker提供的一种容器间通信的方法.具体的就不赘述了,如果有兴趣的话可以自行搜索或者等我的blog哦.
首先我们要创建自己的docker子网

docker network create --driver bridge --subnet 172.22.16.0/24 --gateway 172.22.16.1 my_net

这里相当于创建了一个局域网,网段是172.22.16.然后在运行server和nginx容器的时候我会把他们都指定到这个网段,这样才能保证局域网内各容器的网络通信.
接下来首先启动两台server容器

docker run -itd --rm --name serverA --hostname serverA --network=my_net evanshao/lbserver
docker run -itd --rm --name serverB --hostname serverB --network=my_net evanshao/lbserver

这里用--hostname 指定机器的host配合server的取值,--name相当于指定局域网内的通信域名,这里需要注意的是--name 指定的才是我们访问的域名,这里我顺手写成和hostname一样的了,不要混淆.

然后我们需要启动nginx

docker run -itd --rm --name lbnginx -p 80:80 --network=my_net evanshao/lbnginx

这时候实验环境就已经搭建完成了,我们通过浏览器访问http://192.168.31.147/test就可以看到效果了:

lbserverA.png

刷新就变成

lbserverB.png

这边配置默认应该是轮询,当你停掉一个容器的时候就会只访问到活着的那台机器了.
这里如果没时间自己操作的话,直接按照我上面的三条docker run命令执行即可.
后面可以慢慢还原.

这里写的有些粗略了,因为上一篇文章已经有提到一些nginx关键字的用法,官方也写得很详细了.主要还是展示下如果通过docker展现这一场景,后续我也会慢慢补充一些docker的知识,希望到时候能对你们有所帮助.

你可能感兴趣的:(借助docker展现的nginx反向代理实例)