【问题标题】:How to issue letsencrypt certificate for k8s (AKS) using terraform resources?如何使用 terraform 资源为 k8s (AKS) 颁发 letencrypt 证书?
【发布时间】:2019-12-21 07:33:02
【问题描述】:

总结

我无法在 azure aks 上为我的 terraform kubernetes 集群颁发有效证书。域和证书创建成功(证书是根据crt.sh创建的),但是证书没有应用于我的域,我的浏览器报告“Kubernetes Ingress Controller Fake Certificate”作为应用的证书。

terraform 文件已从一组可用的 yaml 文件(可以很好地颁发证书)转换为我的最佳能力。请参阅我的 terraform 代码 here

更新!在最初的问题中,我也无法创建证书。这已通过使用来自here 的“tls_cert_request”资源修复。更改包含在下面我更新的代码中。

这是我检查过的一些东西,发现不是问题

  • acmeletsencrypt 颁发的证书数量不超过 staging 或 prod 的速率限制。
  • 我在使用暂存证书服务器或生产证书服务器时收到相同的“假证书”错误。

以下是我目前正在调查的一些潜在错误来源。

  • 我没有看到 letencrypt yaml 输入“privateKeySecretRef”的 terraform 等效项,因此我的部署入口“certmanager.k8s.io/cluster-issuer”的值应该是多少。

如果有人有任何其他建议,我真的很高兴听到他们(因为这已经困扰了我很长一段时间了)!

证书资源

provider "acme" {
  server_url = var.context.cert_server
}

resource "tls_private_key" "reg_private_key" {
  algorithm = "RSA"
}

resource "acme_registration" "reg" {
  account_key_pem = tls_private_key.reg_private_key.private_key_pem
  email_address = var.context.email
}

resource "tls_private_key" "cert_private_key" {
  algorithm = "RSA"
}

resource "tls_cert_request" "req" {
  key_algorithm   = "RSA"
  private_key_pem = tls_private_key.cert_private_key.private_key_pem
  dns_names       = [var.context.domain_address]

  subject {
    common_name = var.context.domain_address
  }
}

resource "acme_certificate" "certificate" {
  account_key_pem = acme_registration.reg.account_key_pem
  certificate_request_pem = tls_cert_request.req.cert_request_pem

  dns_challenge {
    provider = "azure"
    config = {
      AZURE_CLIENT_ID = var.context.client_id
      AZURE_CLIENT_SECRET = var.context.client_secret
      AZURE_SUBSCRIPTION_ID = var.context.azure_subscription_id
      AZURE_TENANT_ID = var.context.azure_tenant_id
      AZURE_RESOURCE_GROUP = var.context.azure_dns_rg
    }
  }
}

Pypiserver 入口资源

resource "kubernetes_ingress" "pypi" {
  metadata {
    name = "pypi"
    namespace = kubernetes_namespace.pypi.metadata[0].name

    annotations = {
      "kubernetes.io/ingress.class" = "inet"
      "kubernetes.io/tls-acme" = "true"
      "certmanager.k8s.io/cluster-issuer" = "letsencrypt-prod"
      "ingress.kubernetes.io/ssl-redirect" = "true"
    }
  }

  spec {
    tls {
      hosts = [var.domain_address]
    }
    rule {
      host = var.domain_address

      http {
        path {
          path = "/"

          backend {
            service_name = kubernetes_service.pypi.metadata[0].name
            service_port = "http"
          }
        }
      }
    }
  }
}

如果需要更多信息,请告诉我,我会用缺失的内容更新我的问题文本。最后,我会让 terraform 代码 git repo 保持运行并为他人提供帮助。

【问题讨论】:

  • 那么证书创建了吗?入口日志在哪里?入口是否配置为使用证书?
  • 感谢您的快速回复。该证书不是根据我所知道的创建的。通过检查crt.sh,看起来我上次创建证书是在我尝试使用 yaml 文件时。我现在正在获取入口日志,我还将在入口中添加与 pypiserver 部署相关的部分。随意查看 repo here 以了解 pypiserver 的 k8s 部署的入口设置。就像我提到的那样,我对所有这些都是新手,所以我可能错过了基本的东西:)
  • 好吧,你需要看看为什么没有创建证书。老实说,您可能应该只创建一个入口资源并让 cert-manager 处理证书部分。您只需要使用适当的提供者创建一个集群发行者。
  • 再次感谢您的评论。所以你建议我使用 helm cert-manager chart 之类的东西来处理证书?我已经看到在其他 terraform 示例中使用了这种方法,但是在阅读了来自 here 的“acme_certificate”(“acme_certificate 资源可用于创建和管理 ACME TLS 证书”)之后,我的印象是我可以使用该 terraform 资源成功注册并创建我的证书吗?还是掌舵图方法是成功颁发证书的唯一途径?
  • 我猜这两种方法都可以,从来没有尝试过这种方法,但我想将证书作为入口资源的一部分更方便

标签: kubernetes terraform lets-encrypt azure-aks terraform-provider-azure


【解决方案1】:

我的问题的答案是我必须在我的集群中包含一个证书管理器,据我所知,没有本地 terraform 资源来创建它。我最终使用 Helm 作为我的入口和证书管理器。

设置最终比我最初想象的要复杂一些,而且现在它需要运行两次。这是由于 kubeconfig 未更新(必须在第二次运行“terraform apply”之前应用“set KUBECONFIG=.kubeconfig”)。所以它并不漂亮,但它作为一个最低限度的“工作”示例来启动和运行您的部署。

确实有一些方法可以使用本机 terraform 资源来简化 pypi 部署部分,并且可能有一个简单的方法可以解决 kubeconfig 未更新的问题。但我没有时间进一步调查。

如果有人有关于 k8s 集群更优雅、更实用且(可能最重要的是)安全的最小 terraform 设置的提示,我很想听听!

无论如何,对于那些感兴趣的人,可以找到生成的 terraform 代码 here

【讨论】:

  • 很多“需要运行两次”的问题可以通过depends_on解决。
  • 很好地呼吁仅使用集群的 cert-manager 和 helm 来管理本机入口定义。比在 k8 部署之前必须使用 terraform 创建资源要干净得多。少一个依赖。
猜你喜欢
  • 2019-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-26
  • 2012-10-31
  • 1970-01-01
  • 2021-05-06
  • 1970-01-01
相关资源
最近更新 更多