【问题标题】:Let's Encrypt with Kubernetes results in block mixed contentLet's Encrypt with Kubernetes 导致块混合内容
【发布时间】:2021-01-15 16:08:48
【问题描述】:

我有一个 nginx 入口控制器,让我们使用 helm 部署加密 + cert-manager。访问前端工作正常,问题是前端pod调用clusterIP服务上的后端pod但失败并出现块混合内容错误?

Angular 中的前端,其中 api_url: 'http://backend/api'

如果我在没有 nginx-ingress-let's encrypt 的情况下运行工作负载 > 没有问题,则调用成功。

所以我假设由于入口上的 https 和 http 客户端调用导致该错误。

我该如何解决这个问题?如果我更改了前端代码 api_url: https://backend/api,它也不会工作,因为服务上缺少 TLS 证书。

如何在前端和后端之间的 clusterIP 服务上使用 TLS??

我的前端设置为:

this.http.post<any>(`${environment.apiUrl}/auth/login`, {email, password})

在哪里apiUrl: 'http://backend/api'

我在一个容器中构建了前端并将其暴露给负载均衡器服务,我试图通过 ClusterIP 服务将它连接到端口 3000 上的后端。

前端 YAML:

apiVersion: v1
kind: Service
metadata:
  name: frontend
spec:
  selector:
    tier: frontend
  ports:
    - port: 80
      targetPort: 80
  type: LoadBalancer
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
spec:
  selector:
    matchLabels:
      tier: frontend
  replicas: 1
  template:
    metadata:
      labels:
        tier: frontend
    spec:
      containers:
      - name: frontend
        image: <Image>
        imagePullPolicy: Always
        ports:
        - containerPort: 80

后端 YAML:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend
spec:
  selector:
    matchLabels:
      app: app
      tier: backend
  replicas: 1
  template:
    metadata:
      labels:
        app: app
        tier: backend
    spec:
      containers:
      - name: frontend-container
        image: <Image>
        ports:
        - containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
  name: backend
spec:
  selector:
    app: app
    tier: backend
  ports:
  - protocol: TCP
    port: 80
    targetPort: 3000

如文档 here 中所述。

但是当我尝试从浏览器访问它时它不起作用,我收到未知错误!

这里是前端内部的屏幕截图,确保它能够在内部到达后端。

我不明白我在哪里出错了。我认为设置为 http://backend 的 apiUrl var 未正确转换,因为如果我将其更改为负载均衡器 IP 并重建映像,则将后端暴露给 LB 服务而不是 ClusterIP。它确实有效。

但显然我不想将我的后端暴露给 LB 服务。

有什么想法吗?

【问题讨论】:

    标签: kubernetes


    【解决方案1】:

    您可以在入口层执行 TLS 终止,入口规则包含对此的规定。

    nginx 服务将通过一个公共 IP 暴露给外部世界,它只运行在 LoadBalancer 的级别,终止只需要在一个级别完成,一旦流量进入你的 kubernetes 集群的 VPN,就不需要保持内部加密。

    你可以关注this stack overflow post ,我猜应该会有帮助。 TLS 证书将由 cert-manager 自动创建,您只需在 DNS 中进行相应的设置即可。

    【讨论】:

    • 感谢 Tushar,Ingress 层的终止工作正常我在prod.example.com 中加载没有问题,问题是当我使用应用程序并通过前/端之间的 clusterIP 服务调用 API 时我不明白为什么如果在 docker 中运行调用有效,但在 K8s 中不会。我尝试隔离并发现当前端通过 clusterIP 服务发送“加密”请求时出现了问题。你建议我应该在哪里调查?
    • 您是否尝试过对该服务名称进行 nslookup 以获取 FQDN,当您从 clusterIP 访问该服务时尝试添加 FQDN
    • 是的,我做到了,我什至在前端使用的辅助容器中使用的 api_url var 上进行了 curl,它能够很好地进行调用。但是在我提交时在浏览器中,它会抛出“未知”错误”,打开网络选项卡,请求失败并出现错误“阻止混合内容”。这仅适用于上述 kubernetes 设置。如果我在本地主机上的 docker 中运行前端/后端容器,则提交工作!
    • 这有点难以理解,因为在内部运行时将只是 docker 容器,而 k8s 只是编排,您可以尝试在节点中执行 ssh,然后尝试在使用 docker 命令的类似方式,就像您使用 docker / docker-compose
    • 你也可以在问题中分享服务和部署文件
    【解决方案2】:

    对我有用的解决方案是路由到两个服务的 Ingress;前端和后端在 / 和 /api 路径上。

    将前端中的 apiUrl 变量以及从服务“后端”的名称更改为入口控制器地址:https://ADDRESS/api 正如其他人指出的那样,调用将无法从浏览器解析,因为 https: //后端无法从K8s外部路由,导致Unknown Error。

    【讨论】:

      猜你喜欢
      • 2020-08-30
      • 2020-04-25
      • 2019-05-17
      • 1970-01-01
      • 2017-08-26
      • 1970-01-01
      • 2020-12-31
      • 1970-01-01
      • 2018-03-19
      相关资源
      最近更新 更多