【问题标题】:Multiple instances of Traefik in different kubernetes namespaces不同 kubernetes 命名空间中的多个 Traefik 实例
【发布时间】:2018-03-13 12:20:52
【问题描述】:

我们正在尝试运行具有三个命名空间的 Kubernetes 集群:

  • public 包含任何人都可以访问的服务
  • internal 包含只能由员工访问的服务
  • engineering 包含只有开发人员才能看到的服务

internalengineering 命名空间受到相互身份验证的保护,每个都使用不同的证书颁发机构。

我们使用 Traefik 来管理这些服务的入口,但是,按照 kubernetes guide 设置 Traefik,授予 Traefik 的每个实例查看所有命名空间的入口的权限。这意味着您可以通过在 public 命名空间中运行的 Traefik 实例使用 internal 命名空间中的服务,绕过相互身份验证。

我们正在通过在入口上设置主机来解决这个问题,但这意味着入口必须为每个环境单独定义(例如,host: engineering.example.comhost: engineering.staging.example.com 不同)。我们希望将主机排除在入口配置之外。

理论上,使用 RBAC,我们应该能够将允许 Traefik 看到的内容限制在它自己的入口中的资源,如 this guide on RBAC 中所建议的那样。

我的理解是它仍然需要 ClusterRole 权限,例如:

---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: traefik-ingress-controller
rules:
  - apiGroups:
      - ""
    resources:
      - services
      - endpoints
      - secrets
    verbs:
      - get
      - list
      - watch
  - apiGroups:
      - extensions
    resources:
      - ingresses
    verbs:
      - get
      - list
      - watch

但是使用 Role 绑定而不是 ClusterRole 绑定会将这些权限限制为仅限给定服务​​帐户命名空间中的权限。因此,如果服务帐户位于工程命名空间中:

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: traefik-ingress-controller
  namespace: engineering

那么角色绑定将是:

---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: traefik-ingress-controller
  namespace: engineering
roleRef:
  kind: ClusterRole
  apiGroup: rbac.authorization.k8s.io
  name: traefik-ingress-controller
subjects:
- kind: ServiceAccount
  name: traefik-ingress-controller

然后我们将服务帐户绑定到 Traefik 部署:

---
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: traefik-ingress-controller
  namespace: engineering
spec:
  replicas: 1
  template:
    spec:
      serviceAccountName: traefik-ingress-controller
      ...

我们还根据 kubernetes configuration guide 在配置中设置命名空间

[kubernetes]
namespaces = ["engineering"]

但是,当 Traefik 启动时,我们会收到错误:

E0313 11:15:57.971237 1 reflector.go:199] github.com/containous/traefik/vendor/k8s.io/client-go/tools/cache/reflector.go:94: Failed to list *v1.Endpoints: endpoints is forbidden: User "system:serviceaccount:engineering:traefik-ingress-controller" cannot list endpoints at the cluster scope: Unknown user "system:serviceaccount:engineering:traefik-ingress-controller"

Unknown user 令人困惑,因为这显然是绑定 ServiceAccount 而不是用户。此外,我们可以看到 ServiceAccount 是通过 kubectl 创建的。

我在这里有点死胡同。

如何让 Traefik 只在它自己的命名空间中获取 Ingress?

【问题讨论】:

    标签: kubernetes traefik kubernetes-ingress


    【解决方案1】:

    当 Traefik 认为没有配置命名空间时,可能会出现此错误;也就是你概述的TOML配置

    [kubernetes]
    namespaces = ["engineering"]
    

    没有生效。

    我能想到两个原因:

    1. 除了 TOML 配置文件,您还向 Traefik 传递了一个 --kubernetes 命令行参数(通过部署清单中的 args 条目)。这将禁用 namespaces 选项。
    2. 文件未正确挂载到Deployment,导致默认namespaces值(空列表)生效。为了判断这是否真的如此,我们需要查看您的完整 ConfigMap 以及您的部署清单的相关卷部分。

    【讨论】:

    • 啊,好吧,所以我们确实有--kubernetes 开关,所以我拉了它,没有更多的错误......但根本没有日志,也没有来自 Traefik 本身的响应(只是超时)。我们的 GKE 控制面板显示应用程序运行良好。 ? 很确定正在读取配置,因为它的位置没有改变,并且(除了这个问题)我们所有的 MA 证书、acme 等都正常工作。
    • 默认情况下,Traefik 只记录警告。将日志级别增加到 INFO 甚至 DEBUG 以查看它的作用。检查 Traefik 仪表板以查看前端/后端是否已正确注册。最后,您是否有 Traefik 的 Service 对象,允许您通过 NodePort、LoadBalancer 或类似的东西访问 Traefik pod?
    • ??‍♂️ 在某些时候(所有重新启动等等)我们的 IP 地址发生了变化。不幸的是,我们仍然能够使用 Traefik 跨命名空间。
    • 拆掉整个东西,从头开始,它现在可以工作了。摆脱旧的ClusterRoleBindings 可能很难(我们确实删除了它们,但似乎没有帮助)。无论如何,谢谢你! ??‍♂️
    猜你喜欢
    • 1970-01-01
    • 2018-05-01
    • 1970-01-01
    • 2021-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多