【问题标题】:How can I make authorized requests to secured API endpoint from cronjobs?如何从 cronjobs 向安全 API 端点发出授权请求?
【发布时间】:2022-12-09 18:34:27
【问题描述】:

我有一个 golang 应用程序,它通过 JWT token 获得 API 密钥授权

我正在使用 Kubernetes。所以,这个 golang 应用程序在一个 pod 中。

现在,我想为 cronjobs 创建另一个应用程序,每周一次访问 golang 端点。

我需要的:

如何做/跳过授权?

跳过:这里不需要入口,因为我可以简单地在内部调用它。这对这个案子有帮助吗?

我试过的:

我试着将 cronjobs 和 api 放在同一个应用程序中,这样我就可以简单地调用服务而不是端点,但这也有一个缺点。 我无法创建副本,因为它们也会复制 cronjobs 并且相同的端点将被命中 1*no of replicas

我想每周调用一次“abc.com”端点。它需要一个令牌,我不能简单地传递一个令牌。 我希望有办法解决这个问题。

【问题讨论】:

    标签: go kubernetes cron kubernetes-ingress


    【解决方案1】:

    如果您只需要在内部调用它们而不暴露它们,那肯定会有所帮助。
    如果两个 Pod(以及 Deployment)都在同一个集群下运行,您就可以使用 Kubernetes 的内部 DNS。

    K8s 会自动为您创建的服务创建 DNS 记录,这些记录可按照以下特定格式用于内部通信:<service-name>.<service-namespace>.svc.cluster.local

    来自官方文档的更多信息:DNS for Services and Pods

    如果这听起来很奇怪或者如果它可以帮助理解它的要点,请尝试将“端点”视为您添加到系统主机文件的规则:它归结为基本上添加一个规则,其中 <service-name>.<service-namespace>.svc.cluster.local 指向您的 pod IP 地址,除非它是自动完成的

    例如。

    • 您的 golang 应用程序在 Pod 中运行。
    • 您在命名空间go-apps 下创建了一个指向它的服务,名为go-api
    • 如果您的 cron-job worker 在同一集群内的 Pod 中运行,您可以使用 go-api.go-apps.svc.cluster.local[:<port>] 访问您的应用程序,而无需使用 Ingress

    授权由您决定,因为您通常直接或使用特定框架来处理它。 例如,您可以在您的应用程序中添加自定义端点路径,确保唯一接受的客户端来自集群的相同私有 IP 子网,没有令牌(不推荐)或具有特定的半固定一个你生成和控制的,这样你就可以从你的 crons 发送一个这样的请求:go-api.go-apps.svc.cluster.local:8080/api/v1/callWithNoAuth

    【讨论】:

    • 嗨 Leo,感谢您的回答。我假设这将表现为端点 go-api.go-apps.svc.cluster.local[:<port>] (尽管我跳过了入口)如何跳过授权?使用 mux 中间件进行授权的是 go 应用程序。
    • 编辑答案以根据您的要求完成它。希望应该足够了,除非你问如何规避另一个应用程序的(你不控制的)授权方案。这不是正确的地方。
    • 所以,你想让我的处理程序/控制器检查请求来自哪里?您能否详细说明“使用您生成和控制的特定半固定的”。在我的应用程序中,令牌有一个过期时间,所以你是说创建一个没有过期的令牌吗?
    • 我不“想要”,我只是提供一个你如何做到的例子。正如他们所说,“有多种方法可以给猫剥皮”,但这取决于您和您的应用程序必须满足的要求。永不过期的固定令牌(尽管不推荐)。您手动生成并定期更改的令牌。只接受“私有”IP 地址的网络过滤器。您交换的证书。像这样的“EaaS”框架可以工作link。以上任何一项都可以,以上的组合可以工作。
    【解决方案2】:

    我正在创建一个新的答案,因为我觉得我对此有更多的贡献。
    所以,我最终做的是为内部 API 调用创建一个中间件。在这个中间件中,我在中间件中授权调用者,即检查它是否来自“xyz-service:port”。

    我发现使用第 3 方身份验证器的需要有点矫枉过正,而且在代码中使用令牌风险更高。

    由于除了ingress之外的所有服务都是ClusterIP,所以没有人可以从外面直接访问它。

    感谢@LeoD 的answer。我使用这种方法获得了信心。

    附言简单地服务名称:端口就足够了 例如:http://myservice:4000/api

    【讨论】:

    • 太好了,您添加了额外的有用信息!最好编辑您的第一个答案并在其中添加额外的信息,这样可以得到一个单一而有力的答案。对将来可能用谷歌搜索这个问题的人有帮助:)
    猜你喜欢
    • 2015-10-15
    • 1970-01-01
    • 2019-11-18
    • 1970-01-01
    • 2018-12-10
    • 2017-05-05
    • 2015-03-03
    • 2018-01-05
    • 2022-11-18
    相关资源
    最近更新 更多