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

Cam*_*art 5 ssl lets-encrypt cert-manager envoyproxy

我在 Kubernetes 环境中使用https://github.com/jetstack/cert-manager自动加载https://letsencrypt.org/。它创建的证书将在 90 天后过期。在到期前30 天,cert-manager 更新证书并替换证书。证书存储在 k8s 机密中。

你如何让 Envoy Proxy自动重新加载证书?这些问题已关闭,似乎没有答案。有人提到可以帮助提供解决方案的 Secret Discovery Service (SDS),但我还没有弄清楚。

对于 nginx,可以通过将 k8s 机密添加到 k8s 卷,将卷挂载到文件系统以供 nginx 使用来配置 TLS。然后可以使用文件系统观察程序调用sudo nginx -s reload以在证书更改时重新加载配置。我看到 Envoy Proxy 支持hot restart,但我没有看到类似于 nginx 的命令来让它热重启。

有一个hot-restarter.py,但它不是文件观察器,我宁愿不在 envoyproxy/envoy:latest docker 镜像上安装 python。我认为该程序的某些功能可能会内置到一个也可以查看文件的 Rust 应用程序中,但是对于这种非常常见的场景,必须已经存在一些东西,对吧?

jet*_*eon 8

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

这就是他们所说的 xDS,它包含您可以编写的不同服务,这些服务生成配置的不同部分。该服务(您必须提供和运行)可以通过它公开的不同端点有效地提供所有其他服务(例如侦听器发现服务)。Envoy 允许您将其配置为轮询类似REST 的 API流式 gRPC 服务,甚至在特定位置观看文件(我怀疑这对您来说是赢家)。您实际上只需要实现 LDS 即可动态管理 TLS 证书。配置的其余部分可以保持静态。

如果您选择编写 Envoy 咨询配置的动态服务的路径,那么设置它并不复杂,它只读取磁盘上文件的内容,并为 Envoy 提供它在那里找到的任何内容。为此,您只需为Common TLS Context 对象提供内联字符串数据源。除非您有数千个证书和侦听器,否则响应正文不会接近您的带宽/内存限制。

我承认,我用尽了开始使用 Envoy 的时间,试图解释他们大量的面向机器的文档,所以我最终决定为我们的配置使用轮询 HTTP 服务。即使每隔几秒钟轮询一次,它也是唯一真正的流量,因此设置和继续运行非常容易。我将谈论这种方法,因为这是我最熟悉的方法。您可能已经开始使用类似于静态示例的内容,但是您需要做的就是使其更具动态性,只是进一步向下移动到动态配置。只需将 REST 替换为 gRPC,因为这更容易使用和实现REST 端点进一步记录下来。这需要一些试验和错误,但一个好的开始方法是让服务返回您已经在使用的配置的 JSON 版本。看出来的有一个问题是,你需要添加"type""version"顶层JSON对象引用的东西你返回类型,即应对LDS服务的原型可能是这样上的按键:

{
    "version_info": "0",
    "resources": [{
        "@type": "type.googleapis.com/envoy.api.v2.Listener",
        "name": "http_listener",
        "address": "{...}",
        "filter_chains": [{
            "filters": [
                "{...}"
            ]
        }]
    }]
}
Run Code Online (Sandbox Code Playgroud)

这并不像我希望在 Python 中工作那么容易。他们在使用 gRPC的xDS服务器的Go 中有一个很好的例子,但这对我几乎没有帮助我查看我在Github 上找到的其他一些实现xDS服务器的尝试。这个项目对我特别有帮助。此外,如果您已经在动态配置 Envoy,而不是像 Envoy 实例本身的集群标识符这样的稳定​​的东西,那么我还没有遇到任何实际上需要热重启的事情。