title: Multiple instances of Traefik in different kubernetes namespaces
body: <p>We're trying to run a kubernetes cluster with three namespaces:</p>
  
  <ul>
  <li><code>public</code> contains services accessible to anyone</li>
  <li><code>internal</code> contains services that should only be accessed by members of staff</li>
  <li><code>engineering</code> contains services that should only be visible to developers</li>
  </ul>
  
  <p>The <code>internal</code> and <code>engineering</code> namespaces are protected with mutual authentication, each using a different certificate authority.</p>
  
  <p>We're using Traefik as to manage ingresses to these services however, following the <a href="https://docs.traefik.io/user-guide/kubernetes/" rel="noreferrer">kubernetes guide</a> to set up Traefik, grants each instance of Traefik permissions to see ingresses across all namespaces. This means you could use a service in the <code>internal</code> namespace via the Traefik instance running in the <code>public</code> namespace, bypassing the mututal authentication.</p>
  
  <p>We're working around this by setting hosts on the ingresses, but this means ingresses must be defined seperately for each environment (eg, <code>host: engineering.example.com</code> is different to <code>host: engineering.staging.example.com</code>). We'd prefer to leave the host out of the ingress configuration.</p>
  
  <p>In theory, using RBAC we, should be able to restrict what Traefik is allowed to see to just resources in it's own ingresses as suggested in <a href="https://kubernetes.io/docs/admin/authorization/rbac/#rolebinding-and-clusterrolebinding" rel="noreferrer">this guide on RBAC</a>.</p>
  
  <p>My understanding is that it still needs ClusterRole permissions such as this:</p>
  
  <pre><code>---
  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
  </code></pre>
  
  <p>But using a Role binding instead of a ClusterRole binding will then restrict those permissions to just the ones in the given service accounts namespace. So if the service account is in the engineering namespace:</p>
  
  <pre><code>---
  apiVersion: v1
  kind: ServiceAccount
  metadata:
    name: traefik-ingress-controller
    namespace: engineering
  </code></pre>
  
  <p>Then the role binding would be:</p>
  
  <pre><code>---
  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
  </code></pre>
  
  <p>We then tie the service account to the Traefik deployment with:</p>
  
  <pre><code>---
  kind: Deployment
  apiVersion: extensions/v1beta1
  metadata:
    name: traefik-ingress-controller
    namespace: engineering
  spec:
    replicas: 1
    template:
      spec:
        serviceAccountName: traefik-ingress-controller
        ...
  </code></pre>
  
  <p>We also set the namespaces in the config as per the kubernetes <a href="https://docs.traefik.io/configuration/backends/kubernetes/" rel="noreferrer">configuration guide</a></p>
  
  <pre><code>[kubernetes]
  namespaces = ["engineering"]
  </code></pre>
  
  <p>However, when Traefik starts we get the error:</p>
  
  <p><code>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"</code></p>
  
  <p>The <code>Unknown user</code> is confusing as this is obviously binding a <code>ServiceAccount</code> not a user. Additionally, we can see the <code>ServiceAccount</code> has been created via kubectl.</p>
  
  <p>I'm at a bit of a dead end here. </p>
  
  <p>How do I make Traefik only pick up Ingresses in it's own namespace?</p>