Opensourcetechブログ

OpensourcetechによるNGINX/Zabbix/Neo4j/Linuxなどオープンソース技術に関するブログです。

nginx 1.17.0で gRPC proxyを設定する

 

こんにちは、LinuCエバンジェリストこと、鯨井貴博@opensourcetechです。

igore sysoevさんと一緒

 

今回は、nginx 1.13.10から実装されてgRPC proxy機能を試してみようと思います。

なお、gRPC環境についてはこちらで構築したものを使用しています。

gRPCを触ってみる - Opensourcetechブログ

 

 

 

nginxの設定

使用するnginxは、CentOS7にyumでインストールしたものです。

ここでは、gRPC proxyをするために必要な「http_ssl_module」と「http_v2_module」があるか確認しておきます。

[root@localhost ~]# nginx -V
nginx version: nginx/1.17.0
built by gcc 4.8.5 20150623 (Red Hat 4.8.5-36) (GCC)
built with OpenSSL 1.0.2k-fips 26 Jan 2017
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -m64 -mtune=generic -fPIC' --with-ld-opt='-Wl,-z,relro -Wl,-z,now -pie'

 

 続いて、nginxの設定(/etc/nginx/conf.d/default.conf)を編集します。

1〜6行目を追記しています。

[root@localhost ~]# vi /etc/nginx/conf.d/default.conf
[root@localhost ~]# cat -n /etc/nginx/conf.d/default.conf
1 server {
2 listen 8080 http2;
3 location / {
4 grpc_pass grpc://localhost:50051;
5 }
6 }
7 server {
8 listen 80;
9 server_name localhost;
10 root /usr/share/nginx/html/zabbix/zabbix;
11 #root /usr/share/nginx/html;
12
13 #charset koi8-r;
14 #access_log /var/log/nginx/host.access.log main;
15
16 #location / {
17 # root /usr/share/nginx/html;
18 # root /usr/share/nginx/html/zabbix;
19 # index index.html index.htm;
20 #}
21
22 #error_page 404 /404.html;
23
24 # redirect server error pages to the static page /50x.html
25 #
26 error_page 500 502 503 504 /50x.html;
27 location = /50x.html {
28 root /usr/share/nginx/html;
29 }
30
31 # proxy the PHP scripts to Apache listening on 127.0.0.1:80
32 #
33 #location ~ \.php$ {
34 # proxy_pass http://127.0.0.1;
35 #}
36
37 # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
38 #
39 location ~ \.php$ {
40 #root html;
41 fastcgi_pass 127.0.0.1:9000;
42 fastcgi_index index.php;
43 #fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
44 fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
45 include fastcgi_params;
46 }
47
48 # deny access to .htaccess files, if Apache's document root
49 # concurs with nginx's one
50 #
51 #location ~ /\.ht {
52 # deny all;
53 #}
54 }
55

 

 

 

nginxの再起動

編集した設定を読み込むため、nginxを再起動します。

再起動後、8080/TCPをnginxがlistenしています。

[root@localhost ~]# systemctl restart nginx
[root@localhost ~]# systemctl status nginx
● nginx.service - nginx - high performance web server
Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
Active: active (running) since 日 2019-05-26 17:21:35 JST; 7s ago
Docs: http://nginx.org/en/docs/
Process: 3770 ExecStop=/bin/kill -s TERM $MAINPID (code=exited, status=0/SUCCESS)
Process: 3773 ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf (code=exited, status=0/SUCCESS)
Main PID: 3774 (nginx)
CGroup: /system.slice/nginx.service
├─3774 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf...
└─3775 nginx: worker process

5月 26 17:21:35 localhost.localdomain systemd[1]: Starting nginx - high perfo....
5月 26 17:21:35 localhost.localdomain systemd[1]: PID file /var/run/nginx.pid....
5月 26 17:21:35 localhost.localdomain systemd[1]: Started nginx - high perfor....
Hint: Some lines were ellipsized, use -l to show in full.
[root@localhost ~]# ss -tanl | grep 8080
LISTEN 0 128 *:8080 *:*
[root@localhost ~]# ss -tanlp | grep 8080
LISTEN 0 128 *:8080 *:* users:*1

 

 

 

gRPCクライアントの準備

以前の記事で使用したクライアント用のPythonコードの一部(31行目)を環境にあわせて編集します。

YakinikuTabetai:~ beatmania$ vi /Users/beatmania/GitHub/beatmania/grpc/examples/python/helloworld/greeter_client.py
YakinikuTabetai:~ beatmania$ cat -n /Users/beatmania/GitHub/beatmania/grpc/examples/python/helloworld/greeter_client.py
1 # Copyright 2015 gRPC authors.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14 """The Python implementation of the GRPC helloworld.Greeter client."""
15
16 from __future__ import print_function
17 import logging
18
19 import grpc
20
21 import helloworld_pb2
22 import helloworld_pb2_grpc
23
24
25 def run():
26 # NOTE(gRPC Python Team): .close() is possible on a channel and should be
27 # used in circumstances in which the with statement does not fit the needs
28 # of the code.
29 #with grpc.insecure_channel('localhost:50051') as channel:
30 #with grpc.insecure_channel('192.168.10.61:50051') as channel:
31 with grpc.insecure_channel('192.168.10.61:8080') as channel:
32 stub = helloworld_pb2_grpc.GreeterStub(channel)
33 response = stub.SayHello(helloworld_pb2.HelloRequest(name='submattnesk'))
34 print("Greeter client received: " + response.message)
35
36
37 if __name__ == '__main__':
38 logging.basicConfig()
39 run()

 

編集後、実行すれば「Hello,ユーザー名!」と応答があればOKです。

YakinikuTabetai:~ beatmania$ python /Users/beatmania/GitHub/beatmania/grpc/examples/python/helloworld/greeter_client.py
Greeter client received: Hello, submattnesk!

 

 

 

パケットキャプチャ

クライアント(greeter_client.py)---フロントエンド(nginx)---バックエンド(greeter_server.py)の通信をキャプチャーして確認してみます。

※tcpdumpで「-i any」とインターフェイス指定すると、loopbackを含めた全インターフェイスをキャプチャできるんですね!

[root@localhost ~]#tcpdump -i any tcp port 8080 or tcp port 50051 -w /tmp/grpc.pcap

 

まず、フロントエンド側のキャプチャ。

フロントエンド側のキャプチャ画像

 

そして、バックエンド側のキャプチャ。

バックエンド側のキャプチャ画像

 

当然ですが、どちらもHTTP/2.0でgRPC通信をしています。

Wiresharkの影響かもしれませんが バックエンド側のProtocolがgRPCにならないんですね。ちょっと不思議。

 

 

参考リンク

Introducing gRPC Support with NGINX 1.13.10 - NGINX

Module ngx_http_grpc_module

アフィリエイトのアクセストレード

 

 

 

 

 

 

www.slideshare.net

github.com

www.facebook.com

twitter.com

www.instagram.com

 

 

にほんブログ村 IT技術ブログ Linuxへ
Linux

にほんブログ村 IT技術ブログ オープンソースへ
オープンソース

 

 

*1:"nginx",pid=3775,fd=6),("nginx",pid=3774,fd=6

Opensourcetech by Takahiro Kujirai