0x00 背景
最近呢在用golang进行开发,在前人的基础上维护一个后端的项目。
项目启动了一个web server,放在daocloud上使用容器化的部署方式,写一个Dockerfile去serve。
根据前人的Dockerfile,步骤主要如下:
1. 用apt-get下载nginx
2. 用go get下载govendor(golang的一个包管理器)
3. 使用govendor下载vendor.json下的所有依赖
4. 在容器内启动server
5. 将项目中写好的nginx配置文件拷贝到/etc/nginx/目录下,覆盖了sites-enabled/default文件
6. 启动nginx反向代理
0x01 引入grpc
因为有2套业务系统,目前系统间通信用的是RESTful接口,想用一种更高效的通信方式。
于是让新来的同事研究了grpc,并且实现了一个原来的接口,grpc基于HTTP2,可以实现更高性能的服务。
当grpc server完成后,我看到nginx也支持配置grpc的代理,所以想尝试一下。
搜索到了一个文档是这样配置的。
server {
listen 80 http2;
access_log logs/access.log main;
location / {
grpc_pass grpc://localhost:50051;
}}
于是我加进了项目中的配置文件,push到库上
但是发现nginx挂了,报出错误说没有grpc_pass这个指令。
于是我又查了错误信息,原来nginx是从1.13版本开始支持grpc这个功能的,
输入nginx -v查看容器中的nginx版本,为1.10
0x02 在容器中安装新版nginx
到nginx官网上寻找支持,找到了一篇文章,可以配置一些源,安装nginx
于是我在Dockerfile里在安装nginx前加上了以下语句
RUN wget http://nginx.org/keys/nginx_signing.key; apt-key add nginx_signing.key;
RUN echo 'deb http://nginx.org/packages/debian/ stretch nginx' >> /etc/apt/sources.list
RUN echo 'deb-src http://nginx.org/packages/debian/ stretch nginx' >> /etc/apt/sources.list
注: stretch是Debian 9 的codename,我使用的golang1.9.4的镜像操作系统是Debian 9,
我一开始以为是Ubuntu16.04,写的是xenial,结果一直在安装时报错,说libssl不符合要求,依赖无法安装之类的报错。
0x03 反向代理失效的解决
修改完上一步之后,非常完美,容器没有报错,nginx没有报错,服务的程序没有报错,但就是API服务访问不了。。。
一直以为是自己程序上的错误,所以检查了又检查,甚至回滚到了没有grpc前的版本,依然连不上。
在容器内访问对应端口,ok,代理出去的端口访问,失败了。
于是我在google上搜索proxy pass doesn’t work,找到个stackoverflow的问题,给了我一点启发。
为什么简单的proxy pass不生效?
这个链接的答案是说要删除掉一些nginx.conf中的include语句,使得一些默认的80端口不生效。
这使我想到要仔细查nginx的配置文件,从nginx.conf文件开始查,果然发现1.10版本nginx和1.14版本nginx默认的配置不一样,
1.10会默认带上sites-enabled/default这个文件,
而1.14版本却不会带上这个文件,所以我复制的文件根本不在生效的配置里,反向代理自然没有生效。
于是我在nginx.conf中增加了include sites-enabled/default,整个问题终于解决。