ingress-nginx-helm/examples/rbac/nginx/README.md
Jan Weitz 3ad6fa80d4 Fix #798 - RBAC for leader election
Using gcr.io/google_containers/nginx-ingress-controller:0.9.0-beta.7
the nginx-controller needs to handle leader-election via configmaps.

To perform the leader-election the nginx-controller needs to have the
appropiate RBAC permissions.

Previously to this fix, the following errors occured:

-  cannot get configmaps in the namespace "NAMESPACE_PLACEHOLDER". (get configmaps ingress-controller-leader-nginx)
- initially creating leader election record: User "system:serviceaccount:NAMESPACE_PLACEHOLDER" cannot create configmaps in the namespace "NAMESPACE_PLACEHOLDER". (post configmaps)
2017-06-01 21:30:21 +02:00

4.8 KiB

Role Based Access Control

This example demontrates how to apply role based access control

Overview

This example applies to nginx-ingress-controllers being deployed in an environment with RBAC enabled.

Role Based Access Control is comprised of four layers:

  1. ClusterRole - permissions assigned to a role that apply to an entire cluster
  2. ClusterRoleBinding - binding a ClusterRole to a specific account
  3. Role - permissions assigned to a role that apply to a specific namespace
  4. RoleBinding - binding a Role to a specific account

In order for RBAC to be applied to an nginx-ingress-controller, that controller should be assigned to a ServiceAccount. That ServiceAccount should be bound to the Roles and ClusterRoles defined for the nginx-ingress-controller.

Service Accounts created in this example

One ServiceAccount is created in this example, nginx-ingress-serviceaccount.

Permissions Granted in this example

There are two sets of permissions defined in this example. Cluster-wide permissions defined by the ClusterRole named nginx-ingress-clusterrole, and namespace specific permissions defined by the Role named nginx-ingress-role.

Cluster Permissions

These permissions are granted in order for the nginx-ingress-controller to be able to function as an ingress across the cluster. These permissions are granted to the ClusterRole named nginx-ingress-clusterrole

  • configmaps, endpoints, nodes, pods, secrets: list, watch
  • services, ingresses: get, list, watch
  • events: create, patch
  • ingresses/status: update

Namespace Permissions

These permissions are granted specific to the nginx-ingress namespace. These permissions are granted to the Role named nginx-ingress-role

  • configmaps, pods, secrets: get
  • endpoints: create, get, update

Furthermore to support leader-election, the nginx-ingress-controller needs to have access to a configmap using the resourceName ingress-controller-leader-nginx

  • configmaps: create, get, update (for resourceName ingress-controller-leader-nginx)

This resourceName is the concatenation of the election-id and the ingress-class as defined by the ingress-controller, which default to:

  • election-id: ingress-controller-leader
  • ingress-class: nginx
  • resourceName : <election-id>-<ingress-class>

Please adapt accordingly if you overwrite either parameter when launching the nginx-ingress-controller.

Bindings

The ServiceAccount nginx-ingress-serviceaccount is bound to the Role nginx-ingress-role and the ClusterRole nginx-ingress-clusterrole.

Namespace created in this example

The Namespace named nginx-ingress is defined in this example. The namespace name can be changed arbitrarily as long as all of the references change as well.

Usage

  1. Create the Namespace, Service Account, ClusterRole, Role, ClusterRoleBinding, and RoleBinding.
kubectl create -f ./nginx-ingress-controller-rbac.yml
  1. Create the nginx-ingress-controller

For this example to work, the Service must be in the nginx-ingress namespace:

apiVersion: v1
kind: Service
metadata:
  name: nginx-ingress
  namespace: nginx-ingress #match namespace of service account and role
spec:
  type: LoadBalancer
  ports:
    - port: 80
      name: http
    - port: 443
      name: https
  selector:
    k8s-app: nginx-ingress-lb

The serviceAccountName associated with the containers in the deployment must match the serviceAccount from nginx-ingress-controller-rbac.yml The namespace references in the Deployment metadata, container arguments, and POD_NAMESPACE should be in the nginx-ingress namespace.

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: nginx-ingress-controller
  #match namespace of service account and role
  namespace: nginx-ingress 
spec:
  replicas: 2
  template:
    metadata:
      labels:
        k8s-app: nginx-ingress-lb
    spec:
      #match name of service account
      serviceAccountName: nginx-ingress-serviceaccount
      containers:
        - name: nginx-ingress-controller
          image: gcr.io/google_containers/nginx-ingress-controller:version
          #namespace matching is required in some arguments
           args:
            - /nginx-ingress-controller
            - --default-backend-service=default/default-http-backend
            - --default-ssl-certificate=$(POD_NAMESPACE)/tls-certificate
         env:
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            #match namespace of service account and role
            - name: POD_NAMESPACE 
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace	  
          ports:
            - containerPort: 80
            - containerPort: 443