はじめに
最初にIngressについて説明する必要があるだろう。誤解を恐れずにいろいろと端折って文章にするならば、Kubernetesというコンテナーオーケストレーションシステムが用意しているIngressは、Kubernetesクラスタ内で稼働しているHTTPベースのサービスに対して、クラスタ外部からアクセスする手段を提供するものである。Kubernetesが定義するIngressは、ただのリソースであり、HTTPにおけるホストとパスでどのサービスへリクエストをフォワードすればよいかのルールを記述する。実際にリクエストをIngressリソースの通りにフォワードする機能は、Kubernetes本体では提供されていない。この隙間機能、すなわち、Ingressリソースを読んでいい感じにL7ロードバランサーを設定してリクエストが期待通りにフォワードされるようにする機能を提供するものこそが、Ingress controllerなのである。nghttpx Ingress controllerとは、L7ロードバランサーにnghttpxを採用した、Ingress controllerである。
Kubernetesについて知りたい方は、 http://qiita.com/advent-calendar/2016/kubernetes をどうぞ。
nghttpxについて知りたい方は、少し古いですが http://qiita.com/tatsuhiro-t/items/99a2fd61d0fb16d7241b をどうぞ。合わせて読みたい公式マニュアル、nghttpx - HTTP/2 proxy - HOW-TOもどうぞ。
https://github.com/kubernetes/contrib/tree/master/ingress/controllers にはnginxを使ったIngress controller実装が公開されている。nghttpx Ingress controllerは、nginx Ingress controllerをベースに開発した。
どこがHTTP/2と関係あるのか?
もちろん関係がありますとも。nghttpxはHTTP/2をサポートしたL7ロードバランサーである。nghttpxはフロント、およびバックエンドの接続の両方でHTTP/2をサポートしているため、gRPCのロードバランスにも使うことができる。ただしnghttpxはバックエンドの接続では、HTTP/1もしくはHTTP/2のどちらを使うのかを事前に指定しておく必要がある。ところが、Ingressにはその指定するようなフィールドは存在しない。nghttpx Ingress controllerでは、Ingressリソースのannotationsにバックエンド接続に関する追加設定を書くことにして問題を回避した。以下の例では、greeterというサービスのport 50051に対する接続については、h2、すなわちHTTP/2プロトコルを使うように設定している:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: greeter
annotations:
ingress.zlab.co.jp/backend-config: '{"greeter": {"50051": {"proto": "h2"}}}'
spec:
rules:
- http:
paths:
- path: /helloworld.Greeter/
backend:
serviceName: greeter
servicePort: 50051
詳しくは、https://github.com/zlabjp/nghttpx-ingress-lb#additional-backend-connection-configuration を読んでほしい。