記事概要
Kubernetes上に構築したサービスをクラスタ外に公開するためには一般的に「IngressController」を利用する。
Nginx IngressControllerをよく使うが、これのタイムアウト設定についてあまり詳しく書かれていなかったので補足していく。
Nginx IngressControllerの設定値
筆者が構築する場合は以下のようにhelmでyamlを生成している。
RELEASE_NAME=<test等任意の名前>
CHART_VERSION=<helmchartのバージョン>
INSTALL_NAMESPACE=<インストール先のネームスペース>
helm template ${RELEASE_NAME} ingress-nginx/ingress-nginx --version ${CHART_VERSION} --namespace ${INSTALL_NAMESPACE} --values helm.values.yaml > helm.yaml
helm.values.yaml にはhelm実行時の引数をまとめて記載しておくことができる。
設定できる値はドキュメントに記載されている。
IngressControllerに対して何かしら設定する場合は以下のようにhelm.values.yamlを設定する。
controller:
config:
# https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/
hsts: "false"
enable-modsecurity: "false"
custom-http-errors: '403,413,404'
enable-access-log-for-default-backend: "false"
このようにhelm template
でyamlを生成して管理する利点としては、helm chartのバージョンアップで変わった部分があればhelm.yamlの比較でわかることである。
生成したyamlはGitOpsで管理しているため、間違いが起こりにくい。
ここで設定した値はIngressリソースのannotationsで上書きできるものも多々ある。
タイムアウトの設定
バックエンドからN秒以内にレスポンスがなかった場合にIngressControllerから504を返すように実装したいとする。
このときどうするべきかAKS上で下図のような構成を構築して検証してみた。
検証結果
今回の場合はリクエストを受け付けた後、時間がかかる処理を実行中にタイムアウトしてしまうという想定でサンプルを実装した。
結果としてproxy-read-timeout
の時間でタイムアウトした。
ただし小さい値で設定するとタイムアウト時間が数秒ずれていた。
proxy-connect-timeout | proxy-send-timeout | proxy-read-timeout | proxy-next-upstream-timeout | 結果 |
---|---|---|---|---|
5 | 50 | 55 | 5 | 55秒で504発生 |
5 | 50 | 90 | 5 | 90秒で504発生 |
ネットワークポリシーを使ってネットワーク的に遮断した場合はproxy-next-upstream-timeout
の値でタイムアウトが発生した。
proxy-connect-timeout | proxy-send-timeout | proxy-read-timeout | proxy-next-upstream-timeout | 結果 |
---|---|---|---|---|
5 | 50 | 55 | 10 | 10秒で504発生 |
5 | 50 | 55 | 0 | 10分以上応答なし |
デフォルト値
ドキュメントによるとそれぞれの項目のデフォルト値は下表のようになっている。
proxy-next-upstream-timeout
はデフォルト値0のまま応答がないと何も返ってこないのできちんと設定したほうが良いだろう。
設定 | 値 |
---|---|
proxy-connect-timeout | 5 |
proxy-send-timeout | 60 |
proxy-read-timeout | 60 |
proxy-next-upstream-timeout | 0(設定なし) |
まとめ
- タイムアウトのデフォルト値はConfigMapで設定する。
- Ingressリソースのannotationsで上書きできる。
proxy-next-upstream-timeout
のデフォルト値は0なので5等の値に設定しておいたほうが良い。