3. 自动轮换控制平面 TLS 凭证

Linkerd自动 mTLS 功能 使用一组 TLS 凭据为代理生成 TLS 证书信任锚(trust anchor)颁发者证书(issuer certificate)私钥(private key)。 虽然 Linkerd24 小时自动轮换数据平面代理的 TLS 证书, 但它不会轮换用于颁发这些证书的 TLS 凭据。 在本文档中,我们将描述如何使用外部解决方案 自动轮换颁发者证书私钥

(请注意,Linkerd信任锚仍然必须在 long-lived 集群上 手动轮换。)

Cert manager

Cert-manager 是一个流行的项目,用于使来自外部来源的 TLS 凭证 可用于 Kubernetes 集群。

第一步,在您的集群上安装 cert-manager

Cert manager 作为集群上的证书颁发机构(CA)

在这种情况下,我们不会从外部来源获取凭据, 而是将其配置为集群上的 CA, 并让它定期重新颁发 Linkerd颁发者证书私钥

首先,创建 cert-manager 将用来存储其 Linkerd 相关资源的命名空间。 为简单起见,我们建议使用默认的 Linkerd 控制平面命名空间:

kubectl create namespace linkerd

将签名密钥对保存为 Secret

接下来,使用 step 工具, 创建一个签名密钥对(signing key pair)并将其存储在上面创建的 命名空间中的 Kubernetes Secret 中:

step certificate create root.linkerd.cluster.local ca.crt ca.key \
  --profile root-ca --no-password --insecure &&
  kubectl create secret tls \
    linkerd-trust-anchor \
    --cert=ca.crt \
    --key=ca.key \
    --namespace=linkerd

对于寿命更长(longer-lived)的信任锚证书,将 --not-after 参数传递 给具有所需值的 step 命令(例如 --not-after=87600h)。

创建引用密钥的颁发者

有了 Secret,我们可以创建一个引用它的 cert-manager "Issuer" 资源:

cat <<EOF | kubectl apply -f -
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
  name: linkerd-trust-anchor
  namespace: linkerd
spec:
  ca:
    secretName: linkerd-trust-anchor
EOF

颁发证书并将它们写入一个 secret

最后,我们可以创建一个 cert-manager "Certificate" 资源, 它使用这个 Issuer 来生成所需的证书:

cat <<EOF | kubectl apply -f -
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: linkerd-identity-issuer
  namespace: linkerd
spec:
  secretName: linkerd-identity-issuer
  duration: 48h
  renewBefore: 25h
  issuerRef:
    name: linkerd-trust-anchor
    kind: Issuer
  commonName: identity.linkerd.cluster.local
  dnsNames:
  - identity.linkerd.cluster.local
  isCA: true
  privateKey:
    algorithm: ECDSA
  usages:
  - cert sign
  - crl sign
  - server auth
  - client auth
EOF

(在上面的 YAML 清单中,duration key 指示 cert-manager 将 证书视为有效 48 小时,而 renewBefore key 指示 cert-manager 将尝试在当前证书到期前 25 小时颁发新证书。 这些值可以根据您的喜好定制。)

此时,cert-manager 现在可以使用此证书资源获取 TLS 凭据, 该凭据将存储在名为 linkerd-identity-issuersecret 中。 要验证您新颁发的证书,您可以运行:

kubectl get secret linkerd-identity-issuer -o yaml -n linkerd

现在我们只需要通知 Linkerd 使用这些凭据。

替代 CA 提供商

您可以将 Cert Manager 配置为依赖于许多其他解决方案, 例如 Vault, 而不是使用 Cert Manager 作为 CA。 可以在此处找到 有关如何设置现有证书管理器 以使用不同类型的颁发者的更多详细信息。

第三方证书管理解决方案

需要注意的是,Linkerd 提供的机制也可以在 cert-manager 之外使用。 Linkerd 将读取 linkerd-identity-issuer Secret, 如果它是 kubernetes.io/tls 类型,将使用内容作为其 TLS 凭证。 这意味着任何能够通过将 TLS 证书写入此 Secret 来轮换它们的解决方案都可用于提供动态 TLS 证书管理

您可以使用以下命令生成该 secret

kubectl create secret tls linkerd-identity-issuer --cert=issuer.crt --key=issuer.key --namespace=linkerd

其中,issuer.crtissuer.key 将是以上述信任根ca.crt)为根的中间证书证书私钥 (请查看此 指南 以了解如何生成它们)。

请注意,根证书(ca.crt)也需要包含在该 Secret 中。 您只需编辑生成的 Secret 中包含带有 base64 编码文件内容的 ca.crt 字段。

设置完 linkerd-identity-issuer Secret 后,继续按照以下说明安装和配置 Linkerd 以使用它。

在 CLI 安装中使用这些凭据

对于 CLI 安装,Linkerd 控制平面应该 与 --identity-external-issuer 标志一起安装, 该标志指示 Linkerdlinkerd-identity-issuer secret 读取证书。 每当更新存储在 secret 中的 certificatekey 时, identity 服务将自动检测此更改并重新加载新凭据。

瞧!我们已经设置了 Linkerd 控制平面 TLS 凭据的自动轮换。 如果你想监控更新过程,你可以检查服务发出的 IssuerUpdated 事件:

kubectl get events --field-selector reason=IssuerUpdated -n linkerd

使用 Helm 安装

对于 Helm 安装,而不是运行 linkerd install, 将 identityTrustAnchorsPEM 设置为 linkerd-identity-issuer Secret 中 ca.crt 的值:

helm install linkerd2 \
  --set-file identityTrustAnchorsPEM=ca.crt \
  --set identity.issuer.scheme=kubernetes.io/tls \
  --set installNamespace=false \
  linkerd/linkerd2 \
  -n linkerd

有关如何对 webhook TLS 凭据执行类似操作,请参阅 自动轮换 Webhook TLS 凭据