我们正在尝试运行具有三个名称空间的kubernetes集群:
-
public
包含任何人都可以访问的服务 -
internal
包含只应由工作人员访问的服务 -
engineering
包含只应对开发人员可见的服务
internal
和 engineering
名称空间受相互身份验证保护,每个名称空间使用不同的证书颁发机构 .
我们使用Traefik来管理这些服务的入口,然而,在设置Traefik之后,授予每个Traefik权限实例以查看所有命名空间中的入口 . 这意味着您可以通过在 public
命名空间中运行的Traefik实例在 internal
命名空间中使用服务,从而绕过mututal身份验证 .
我们通过在入口处设置主机来解决这个问题,但这意味着必须为每个环境单独定义入口(例如, host: engineering.example.com
与 host: engineering.staging.example.com
不同) . 我们宁愿让主机退出入口配置 .
从理论上讲,使用RBAC我们应该能够限制Traefik允许在_1595865中建议的内容中看到的资源 .
我的理解是它仍然需要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只在它自己的命名空间中获取Ingresses?
1 回答
当Traefik认为没有配置名称空间时,可能会发生此错误;也就是你概述的TOML配置
没有变得有效 .
我可以想到两个原因:
除了TOML配置文件之外,您还将一个
--kubernetes
命令行参数传递给Traefik(通过部署清单中的args
条目) . 这将禁用namespaces
选项 .文件未正确装入Deployment,导致默认
namespaces
值(空列表)生效 . 要确定是否真的如此,我们需要查看完整的ConfigMap以及部署清单的相关卷部分 .