こんにちは!Summer Internship 2018 にて Microservices Platform Team でインターンをしていた @everysick です*1。この記事ではインターン期間中に実装を行い、OSS として公開した Certificate Expiry Monitor Controller の紹介をします。
背景
有効期限監視の限界
TLS 証明書の運用では有効期限が来る前に TLS 証明書を更新をする必要があります。 これまでのメルカリでは mackerel.io の URL 外形監視機能に登録したエンドポイントの TLS 証明書を監視することで、有効期限が切れる前に通知をする運用を行っていました。
しかしながら、Microservices Platform 環境では日々新しいサービスが立ち上がっているため、従来の運用を適用するのであれば下図のように全ての TLS 証明書の発行を認知して監視対象に追加する必要があります。
Microservices Platform 環境での TLS 証明書
メルカリで全社的に取り組まれている Microservices 化に伴い、各 Microservice がそれぞれで異なるドメインを持つようになったため、TLS 証明書も同様に用意する必要がでてきました。その課題に対応するため、Microservices Platform Team では Kubernetes のクラスタに対して jetstack/kube-lego や jetstack/cert-manager を導入することにより、Let’s Encrypt を用いて TLS 証明書の発行と更新のオペレーションを自動化する仕組みを提供しています。
そのため、現在の Microservices Platform 環境では、Let’s Encrypt から発行した TLS 証明書と外部の CA から発行した TLS 証明書の二種類が存在しており、それらの運用・管理を下図のように行っています。
TLS 証明書の発行・更新におけるオペレーションは、各 Microservice 管理者が Ingress resoruce に ACME を有効にするアノテーションを付与することよって半自動化することができました。
しかし、この状態でも監視対象への追加のオペレーションが必要であったり、アノテーションの付け忘れによって TLS 証明書が自動更新されないなどの課題が解決されていません。この課題に対処するため、インターン期間中に Certificate Expiry Monitor Controller というソフトウェアの実装を行いました。
Certificate Expiry Monitor Controller
Certificate Expiry Monitor Controller は Kubernetes の Custom Controller として実装されました。Kubernetes クラスタ上の Ingress に登録されている TLS が有効なエンドポイントへ一定の間隔でリクエストを送ります。
その際、もしTLS 証明書の有効期限が切れている、もしくは閾値に達していた場合、予め設定した通知先へ警告メッセージを送信します。
これにより、従来の運用方法で課題となっていたエンドポイント登録の問題、及びアノテーションの付け忘れといったヒューマンエラーを回避することが可能になりました。
クラスタへのデプロイ
Certificate Expiry Monitor Controller は Docker Hub 上で Docker イメージを配布しています。ローカルの ~/.kube/config
を読み込んで動作させることも可能ですが、下のような Deployment の定義を追加して適用するのが最も簡単です。
# deployment.yml apiVersion: apps/v1 kind: Deployment metadata: name: certificate-expiry-monitor-controller namespace: kube-system spec: replicas: 1 selector: matchLabels: app: certificate-expiry-monitor-controller template: metadata: labels: app: certificate-expiry-monitor-controller spec: containers: - name: certificate-expiry-monitor-controller image: mercari/certificate-expiry-monitor-controller:<VERSION>
この定義を kubectl
コマンドを用いて適用するだけ(必要であれば権限等を付与する)でデプロイが可能です。
$ kubectl apply -n <YOUR_NAME_SPACE> -f deployment.yml
初期状態では有効期限の監視結果が stderr
に出力されるため、同じく kubectl
コマンドでログを取得して動作を確認することができます。
$ kubectl logs -n <YOUR_NAME_SPACE> <POD_NAME> {"level":"info","ts":1535617901.5555878,"caller":"controller/controller.go:58","msg":"Starting controller..."} ...
まとめ
インターン期間中に実装・公開した Certificate Expiry Monitor Controller について、その実装背景と動作概要を説明しました。
より詳しい設定や仕様に関してはREADME を参照してください。
記事公開現在のバージョンは 0.0.1
です。今後も様々なケースに対応するため、OSS として積極的に機能追加をしていく予定です。
*1:8/31をもってインターン終了