如何自动为Envoy代理加载新的TLS证书?

时间:2019-01-04 00:03:20

标签: ssl lets-encrypt envoyproxy cert-manager

我在Kubernetes环境中使用https://github.com/jetstack/cert-manager自动加载https://letsencrypt.org/。它创建的证书将在90天内过期。 30 days在到期之前,证书管理器会续订证书并替换证书。证书存储在k8s秘密中。

如何将Envoy代理获取到automatically reload the certificates?问题已关闭,似乎无法解决。有一些mention的秘密发现服务(SDS)可以帮助提供一种解决方案,但我还无法弄清楚。

对于nginx,可以通过将k8s秘密添加到k8s卷,然后将该卷安装到文件系统中以供nginx使用来配置TLS。然后,当证书更改时,可以使用文件系统监视程序来调用sudo nginx -s reload以重新加载配置。我看到Envoy代理支持hot restart,但是没有看到类似于nginx的命令来使其热重启。

有一个hot-restarter.py,但它不是文件监视程序,因此我不希望在envoyproxy / envoy:latest docker映像上安装python。我以为该程序的某些功能可以内置到也可以进行文件监视的rust应用程序中,但是在这种非常常见的情况下必须已经存在一些东西,对吗?

1 个答案:

答案 0 :(得分:1)

看起来您正在使用静态配置来配置(或计划配置)Envoy,而Envoy真正发挥作用的地方在于您提供动态生成的配置时。两者之间的主要区别在于,您拥有一个将Envoy配置为定期查询更新的服务,但是该服务必须发送回的内容与静态配置非常相似。

这就是他们所说的xDS,它包含您可以编写的,生成配置的不同部分的不同服务。一项服务(您必须提供并运行)可以通过其公开的不同端点有效地提供所有其他服务(例如Listener Discovery Service)。 Envoy允许您将其配置为在特定位置轮询REST-like APIstreaming gRPC service甚至watch a file(我怀疑这是您的赢家)。实际上,您只需要实现LDS即可动态管理TLS证书。配置的其余部分可以保持不变。

如果您选择编写由Envoy咨询以获取config的动态服务的途径,那么对其进行设置并不复杂,因此它仅读取磁盘上文件的内容并向Envoy提供在其中找到的所有内容。为此,您只需为inline string data source提供一个Common TLS Context object。除非您有成千上万的证书和侦听器,否则响应主体将无法获得带宽/内存限制附近的任何信息。

我会坦白说,我花了很多时间来承担起起使Envoy尝试解释他们大量的面向机器的文档的负担,因此我最终选择了针对我们的配置的轮询HTTP服务。即使每隔几秒钟进行一次轮询,它也是唯一的实际流量,因此设置和继续运行非常容易。我将介绍这种方法,因为这是我最熟悉的一种方法。 您可能从static example之类的东西开始,但是要使其更具动态性,您需要做的就是将其移至dynamic configuration再向下一点。只需将REST替换为gRPC,就可以轻松实现并实现后面记录的REST endpoints。这需要一些试验和错误,但是开始的一个好方法是简单地使服务返回您已经使用的配置的JSON版本。需要注意的一个陷阱是,您需要在顶级JSON对象上添加"type""version"键,这些键引用要返回的事物类型的原型,即对LDS服务可能看起来像这样:

{
    "version_info": "0",
    "resources": [{
        "@type": "type.googleapis.com/envoy.api.v2.Listener",
        "name": "http_listener",
        "address": "{...}",
        "filter_chains": [{
            "filters": [
                "{...}"
            ]
        }]
    }]
}

这几乎不像我希望开始使用Python那样容易。他们在使用gRPC的 xDS 服务器的Go语言中有一个很好的例子,但它对我的帮助几乎不及其他实现 xDS 我在Github上找到的服务器。 This project对我特别有帮助。另外,如果您已经在动态配置envoy而不是诸如Envoy实例本身的群集标识符之类的稳定内容,那么我还没有遇到任何实际上需要热重启的事情。