最新:在TwitterMastodon 上获取项目更新。

从 Kube-LEGO 迁移

kube-lego 是 Jetstack 的一个较旧的项目,用于从 Let's Encrypt(或其他 ACME 服务器)获取 TLS 证书。

自从 cert-managers 发布以来,kube-lego 逐渐被弃用,取而代之的是这个项目。两者之间存在一些关键区别。

功能kube-legocert-manager
配置Ingress 资源上的注释CRD
CAACMEACME、签名密钥对
Kubernetesv1.2 - v1.8v1.7+
调试查看日志Kubernetes 事件 API
多租户不支持支持
每个证书的唯一发行源不支持支持
入口控制器支持 (ACME)GCE、NGINX全部

本指南将逐步介绍如何安全地将您的 kube-lego 安装迁移到 cert-manager,而不会中断服务。

在本指南结束时,我们应该:

  1. 缩减并删除 kube-lego

  2. 安装 cert-manager

  3. 将 ACME 私钥迁移到 cert-manager

  4. 使用此私钥创建 ACME ClusterIssuer,以在整个集群中颁发证书

  5. 配置 cert-manager 的 ingress-shim,以自动为所有带有 kubernetes.io/tls-acme: "true" 注释的 Ingress 资源配置 Certificate 资源,使用我们创建的 ClusterIssuer

  6. 验证 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 getConfigMap

$ 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/v1
kind: ClusterIssuer
metadata:
# Adjust the name here accordingly
name: letsencrypt-staging
spec:
acme:
# The ACME server URL
server: https://acme-staging-v02.api.letsencrypt.org/directory
# Email address used for ACME registration
email: user@example.com
# Name of a secret used to store the ACME account private key from step 3
privateKeySecretRef:
name: letsencrypt-private-key
# Enable the HTTP-01 challenge provider
solvers:
- 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/7571319
Conditions:
Last Transition Time: 2019-01-30T14:52:03Z
Message: The ACME account was registered with the ACME server
Reason: ACMEAccountRegistered
Status: True
Type: 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 小时后进行续订。