🌟

Gateway API + NGINX Gateway FabricでのTLS証明書の更新対応

2023/11/24に公開

以前のポストでKubernetesの新たにv1を迎えたGateway APIを、
NGINX Gateway Fabric、NGFをコントローラーとして導入した手順をカバーしました。

今回のポストでは、その構築の中でSecretとして用意したTLS証明書を更新した際の流れを紹介します。

以下が以前のポストとなります。よろしければご覧ください。

Gateway APIとNGINX Gateway Fabricを自前のKubernetesクラスタで

セットアップの紹介

セットアップは次の通りです。

  • NGINX Gateway Fabricのworkerは、TCP 80と443の両方でlistenする
  • Gatewayは、
    • TCP 80と443の両方について、特定のnamespaceからのみ利用できるようにselectorでlabel条件を指定する
    • また、TCP 443についてはsecretを証明書として利用し、TLS terminateモードで動作するように設定する
  • アプリはdeploymentでpodがサーブされており、それらに接続するserviceも立っている
  • HTTPRouteマニフェストで指定のhostname/SNI宛の通信について、
    • TCP 80宛はHTTPSへリダイレクトするルールを定義する
    • TCP 443宛はprefix matchルールで指定のserviceへ通信を流すように設定する

なおkubernetesクラスタの管理にGitLabとFluxを利用している関係で、
TLSのsecretマニフェストファイルもレポジトリに載せています。
その時、レポジトリにはSOPSで暗号化したマニフェストファイルを載せ、
fluxにはそれらを複合化して、kubernetesクラスタに渡してもらうという形で動かしています。

結論

同じ名前のSecretで新しい証明書データをkubernetesクラスタ上に作ったら、それだけで新しい証明書で動作してくれるようになりました。

流れ

まずは証明書の更新ですが、letsencryptのワイルドカード証明書をcertbot/dns-cloudflareで一度作成しているので、
systemdのタイマーで定期的にdocker run certbot/dns-cloudflare renewを実行させていました。

というわけでfullchain.pemファイルとprivkey.pemファイルはあるところから進めていきます。

SOPS暗号化用レポジトリ上で、kubectl create secretで作成したマニフェストファイルを作成し、sopsコマンドで暗号化します。
あとはfluxがkubernetesクラスタ上に新しいsecretを作ってくれるのを待つだけです。

# create secret yaml from cert and key pem files
kubectl create secret tls tls-secret \
  --cert=fullchain.pem \
  --key=privkey.pem \
  --namespace=certificate \
  --dry-run=client \
  -o yaml > tls-secret.yaml

# encrypt
sops --encrypt -i tls-secret.yaml

# push to the repository and let flux create/renew the secret

# watch the secret being recreated with the new timestamp
kubectl get secret tls-secret -n certificate -o jsonpath='{.items[0].metadata.creationTimestamp}'

おしまい

以上です!

Dockerコンテナで他に動かしているサービスなどではコンテナリスタートなどが必要なので、
Kubernetesクラスタ上のGateway+TLS Secretではどうなのだろうと確認したく、
ちょうど証明書更新のタイミングがあったので確認した次第です。

GatewayなりNGFのworkerなり、何かしらリスタートする必要があるのかと思っていましたが何もなかったです!

Discussion