从 Kube-LEGO 迁移
kube-lego 是 Jetstack 的一个较旧的项目,用于从 Let's Encrypt(或其他 ACME 服务器)获取 TLS 证书。
自从 cert-managers 发布以来,kube-lego 逐渐被弃用,取而代之的是这个项目。两者之间存在一些关键区别。
功能 | kube-lego | cert-manager |
---|---|---|
配置 | Ingress 资源上的注释 | CRD |
CA | ACME | ACME、签名密钥对 |
Kubernetes | v1.2 - v1.8 | v1.7+ |
调试 | 查看日志 | Kubernetes 事件 API |
多租户 | 不支持 | 支持 |
每个证书的唯一发行源 | 不支持 | 支持 |
入口控制器支持 (ACME) | GCE、NGINX | 全部 |
本指南将逐步介绍如何安全地将您的 kube-lego 安装迁移到 cert-manager,而不会中断服务。
在本指南结束时,我们应该:
-
缩减并删除 kube-lego
-
安装 cert-manager
-
将 ACME 私钥迁移到 cert-manager
-
使用此私钥创建 ACME
ClusterIssuer
,以在整个集群中颁发证书 -
配置 cert-manager 的
ingress-shim
,以自动为所有带有kubernetes.io/tls-acme: "true"
注释的 Ingress 资源配置 Certificate 资源,使用我们创建的ClusterIssuer
-
验证 cert-manager 安装是否正常工作
1. 缩减 kube-lego
在开始部署 cert-manager 之前,最好将我们的 kube-lego 部署缩减为 0 个副本。这样可以防止两个控制器可能相互“竞争”。如果您使用官方部署 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 用户帐户标识是一个私钥,存储在 Secret 资源中。默认情况下,kube-lego 会将此密钥存储在与 kube-lego Deployment 相同命名空间中的名为 kube-lego-account
的 Secret 中。您可能在部署 kube-lego 时覆盖了此值,在这种情况下,要使用的 Secret 名称将是 LEGO_SECRET_NAME
环境变量的值。
您应该下载此 Secret 资源的副本并将其保存到本地目录中
$ 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
我们需要创建一个 ClusterIssuer
,它将保存之前通过 kube-lego 注册的 ACME 帐户的信息。为此,我们需要从旧的 kube-lego 部署中获取另外两条信息:ACME 服务器的服务器 URL 和用于注册帐户的电子邮件地址。
这两条信息都存储在 kube-lego ConfigMap
中。
要检索它们,您应该能够使用 kubectl
get
该 ConfigMap
$ 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. 默认情况下配置 ingress-shim 以使用新的 ClusterIssuer
现在我们的 ClusterIssuer
准备签发证书,还有一件事要做:我们必须重新配置 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 小时后进行续订。