Gateway API + NGINX Gateway FabricでのTLS証明書の更新対応
以前のポストで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