Kube-LEGO からの移行
kube-lego は、Let's Encrypt(または他のACMEサーバー)からTLS証明書を取得するための、Jetstackの古いプロジェクトです。
cert-managerのリリース以降、kube-legoは段階的に廃止され、このプロジェクトが推奨されています。両者にはいくつかの重要な違いがあります。
機能 | kube-lego | cert-manager |
---|---|---|
設定 | Ingressリソースへのアノテーション | CRD |
CAs | ACME | ACME、署名キーペア |
Kubernetes | v1.2 - v1.8 | v1.7以上 |
デバッグ | ログを確認する | Kubernetes Events API |
マルチテナント | サポートされていません | サポートされています |
証明書ごとに異なる発行元 | サポートされていません | サポートされています |
Ingressコントローラーのサポート (ACME) | GCE、NGINX | すべて |
このガイドでは、サービスを中断することなく、kube-legoのインストールをcert-managerに安全に移行する方法を説明します。
ガイドの最後に、次の状態になっているはずです。
-
kube-legoのスケールダウンと削除
-
cert-managerのインストール
-
ACME秘密鍵のcert-managerへの移行
-
この秘密鍵を使用して、クラスタ全体で証明書を発行するためのACME
ClusterIssuer
の作成 -
kubernetes.io/tls-acme: "true"
アノテーションが付いたすべてのIngressリソースに対して、作成したClusterIssuer
を使用して、cert-managerのingress-shim
を構成してCertificateリソースを自動的にプロビジョニングする -
cert-managerのインストールが機能していることを確認する
1. kube-legoのスケールダウン
cert-managerのデプロイを開始する前に、kube-legoデプロイメントをレプリカ数0にスケールダウンすることをお勧めします。これにより、2つのコントローラーが互いに競合するのを防ぎます。公式のデプロイYAMLを使用してkube-legoをデプロイした場合は、次のようなコマンドで実行できます。
$ kubectl scale deployment kube-lego \--namespace kube-lego \--replicas=0
その後、kube-lego podが実行されていないことを次のようにして確認できます。
$ kubectl get pods --namespace kube-lego
2. cert-managerのデプロイ
cert-managerは、公式のインストールガイドに従ってHelmを使用してデプロイする必要があります。特別な手順は必要ありません。このガイドの最後に、このデプロイに戻り、cert-managerをデプロイする際に使用するいくつかのCLIフラグをアップグレードします。
Helmとcert-managerをデプロイする際には、RBACが正しく構成されていることを十分に確認してください。デプロイに関するドキュメントにいくつかのニュアンスが記載されています!
3. ACMEアカウント秘密鍵の取得
ユーザーの代わりに証明書の発行と更新を続けるためには、kube-legoが作成したユーザーアカウント秘密鍵をcert-managerに移行する必要があります。
ACMEユーザーアカウントのIDは、秘密リソースに保存されている秘密鍵です。デフォルトでは、kube-legoはkube-lego Deploymentと同じ名前空間にあるkube-lego-account
という名前の秘密にこのキーを保存します。LEGO_SECRET_NAME
環境変数の値を使用する場合は、kube-legoをデプロイする際にこの値を上書きしている可能性があります。
この秘密リソースのコピーをダウンロードして、ローカルディレクトリに保存する必要があります。
$ kubectl get secret kube-lego-account -o yaml \--namespace kube-lego \--export > kube-lego-account.yaml
保存したら、このファイルを開き、metadata.name
フィールドをcert-managerに関連する名前に変更します。このガイドの残りの部分では、letsencrypt-private-key
を選択したと仮定します。
完了したら、この新しいリソースをcert-manager
名前空間に作成する必要があります。デフォルトでは、cert-managerはClusterIssuers
のサポートリソースを実行している名前空間に保存し、上記のcert-managerのデプロイ時にはcert-manager
を使用しました。cert-managerを別の名前空間にデプロイした場合は、これを変更する必要があります。
$ kubectl create -f kube-lego-account.yaml \--namespace cert-manager
4. 古いACMEアカウントを使用してACME ClusterIssuer
を作成する
以前kube-legoで登録したACMEアカウントに関する情報を保持するClusterIssuer
を作成する必要があります。そのためには、古いkube-legoデプロイメントからさらに2つの情報が必要です。ACMEサーバーのサーバーURLと、アカウント登録に使用したメールアドレスです。
これらの情報はどちらも、kube-lego ConfigMap
に保存されています。
それらを取得するには、kubectl
を使用してConfigMap
をget
できます。
$ kubectl get configmap kube-lego -o yaml \--namespace kube-lego \--export
メールアドレスは.data.lego.email
フィールドに、ACMEサーバーのURLは.data.lego.url
フィールドに表示されます。
このガイドでは、メールアドレスがuser@example.com
で、URLがhttps://acme-staging-v02.api.letsencrypt.org/directory
であると仮定します。
秘密鍵を新しいSecretリソースに移行し、ACMEメールアドレスとURLを取得したので、ClusterIssuer
リソースを作成できます!
cluster-issuer.yaml
という名前のファイルを作成します。
apiVersion: cert-manager.io/v1kind: ClusterIssuermetadata:# Adjust the name here accordinglyname: letsencrypt-stagingspec:acme:# The ACME server URLserver: https://acme-staging-v02.api.letsencrypt.org/directory# Email address used for ACME registrationemail: user@example.com# Name of a secret used to store the ACME account private key from step 3privateKeySecretRef:name: letsencrypt-private-key# Enable the HTTP-01 challenge providersolvers:- http01:ingress:ingressClassName: nginx
次に、このファイルをKubernetesクラスタに送信します。
$ kubectl create -f cluster-issuer.yaml
ACMEアカウントが正常に検証されたことを確認できます。
$ kubectl describe clusterissuer letsencrypt-staging...Status:Acme:Uri: https://acme-staging-v02.api.letsencrypt.org/acme/acct/7571319Conditions:Last Transition Time: 2019-01-30T14:52:03ZMessage: The ACME account was registered with the ACME serverReason: ACMEAccountRegisteredStatus: TrueType: Ready
5. 新しいClusterIssuer
をデフォルトで使用するようにingress-shimを構成する
ClusterIssuer
が証明書を発行できるようになったので、最後に1つの作業が残っています。ingress-shim
(cert-managerの一部としてデプロイされる)を再構成して、適切なアノテーションが付いたすべてのIngressリソースに対してCertificateリソースを自動的に作成する必要があります。
ingress-shimの役割に関する詳細はドキュメントを参照できますが、ここではいくつかの追加フラグを追加するためにhelm upgrade
を実行するだけです。ClusterIssuer
にletsencrypt-staging
という名前を付けた(上記のように)と仮定して、実行します。
$ helm upgrade cert-manager \jetstack/cert-manager \--namespace cert-manager \--set ingressShim.defaultIssuerName=letsencrypt-staging \--set ingressShim.defaultIssuerKind=ClusterIssuer
cert-manager podが再作成され、起動すると、以前kube-legoが有効になっていたすべてのingressに対してCertificateリソースが自動的に作成されます。
6. 各Ingressに対応するCertificateが存在することを確認する
終了する前に、以前kube-legoを有効にした各IngressリソースにCertificateリソースが作成されていることを確認する必要があります。
次を実行して確認できます。
$ kubectl get certificates --all-namespaces
クラスタ内のkube-legoアノテーションが付いた各Ingressのエントリが表示されます。
cert-managerのログを表示することで、cert-managerが古いTLS証明書を「採用」したことも確認できます。
$ kubectl logs -n cert-manager -l app=cert-manager -c cert-manager...I1025 21:54:02.869269 1 sync.go:206] Certificate my-example-certificate scheduled for renewal in 292 hours
ここでは、cert-managerが既存のTLS証明書を検証し、292時間後に更新するようにスケジュールされたことがわかります。