Traefik的多个实例在不同的kubernetes名称空间中

Dan*_*elM 4 kubernetes traefik kubernetes-ingress

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

  • public 包含任何人都可以访问的服
  • internal 包含只应由工作人员访问的服务
  • engineering 包含只应对开发人员可见的服务

internalengineering命名空间与相互认证保护,各自使用不同的证书颁发机构.

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

我们通过在入口处设置主机来解决这个问题,但这意味着必须为每个环境单独定义入口(例如,host: engineering.example.com不同host: engineering.staging.example.com).我们宁愿让主机退出入口配置.

从理论上讲,使用RBAC我们应该能够限制Traefik允许在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
Run Code Online (Sandbox Code Playgroud)

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

---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: traefik-ingress-controller
  namespace: engineering
Run Code Online (Sandbox Code Playgroud)

那么角色绑定将是:

---
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
Run Code Online (Sandbox Code Playgroud)

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

---
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
  name: traefik-ingress-controller
  namespace: engineering
spec:
  replicas: 1
  template:
    spec:
      serviceAccountName: traefik-ingress-controller
      ...
Run Code Online (Sandbox Code Playgroud)

我们还根据kubernetes 配置指南在配置中设置命名空间

[kubernetes]
namespaces = ["engineering"]
Run Code Online (Sandbox Code Playgroud)

然而,当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只在它自己的命名空间中获取Ingresses?

Tim*_*ann 7

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

[kubernetes]
namespaces = ["engineering"]
Run Code Online (Sandbox Code Playgroud)

没有变得有效.

我可以想到两个原因:

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