Kubernetes supports various authentication strategies for users. For Cluster Administrators to do better User and Password Management, Integration of Kubernetes to Active Directory proves to be useful. This is a better approach as compared to using Service accounts tokens to authenticate users.

Most developers and cluster administrators prefer using a command line interface in their operations. Therefore, this tutorial will look at how we can authenticate users using Active Directory on Kubernetes CLI. We will use gangway to achieve this.

Gangway is an application that can be used to enable authentication flows using OpenID Connect. Kubernetes support OIDC Tokens as a way to identify users who access the cluster. The authenticator uses ID tokens rather than access token to identify these users.

When using OIDC to authenticate with Kubernetes, the client (e.g. kubectl) sends the ID token alongside all requests to the API server. The Kubernetes API server verifies the token to ensure it is valid. Once verified, the API server extracts the username and group membership information from the token, and continues processing the request.


Gangway is configured as a client of an upstream Identity Service ( In our case is Active Directory). To obtain the ID token, the user accesses Gangway, initiates the OIDC flow by clicking the “Log In” button, and completes the flow by authenticating with the upstream Identity Service. Once the authentication flow is complete, the user is redirected to a Gangway page that provides instructions on how to configure kubectl to use the ID token.


The diagram below show the authentication sequence a user must go during the authentication process.

Authentication Flow

 Prerequisites:

  1. You will need an Active Directory or LDAP server already configured.
  2. A running Kubernetes Cluster with role based access enable. You should have Administrative access
  3. An Ingress Controller installed in the cluster.
  4. A Certificate Manager if not using Custom Certificates. I will be using custom certificates for my deployment
  5. You will also need a domain name that supports wildcard DNS entry. I will use the wildcard DNS “*.kubernetes.mydomain.com” to route external traffic to my Kubernetes cluster.

Assuming all prerequisites are in place, let’s look at how to deploy Gangway in our cluster. We will require to deploy Dex and Gangway. Dex will serve as the identity provider that will validate our credentials with the Active Directory (ldap) identity store. Dex uses OpenID Connect to perform this validation. Gangway will enable the end users to self-configure their kubectl configuration using the OpenID Connect Token provided by Dex after successful authentication.

STEP 1. Deploy DEX on Kubernetes

To do this, Follow Step One of guide below on deployment of Dex in kubernetes cluster.

Authenticate Kubernetes Dashboard Users With Active Directory

STEP 2: Configure the Kubernetes API to access Dex as OpenID connect provider

Dex requires that the Kubernetes API server is configured for OIDC. There are several flags that need to be passed to the API server.

Edit the Kubernetes api-server manifest file in each master node as follows:

$ sudo vim /etc/kubernetes/manifests/kube-apiserver.yaml
...
    command:
    - /hyperkube
    - apiserver
    - --advertise-address=10.10.40.30 
## ADD these lines

    - --oidc-issuer-url=https://auth.kubernetes.mydomain.com/
    - --oidc-client-id=oidc-auth-client  ##ENSURE THE WILDCARD CERTIFICATES ARE PRESENT IN THIS FILE PATH IN ALL MASTER NODES: 
    - --oidc-ca-file=/etc/ssl/kubernetes/kubernetes.mydomain.com.crt    
    - --oidc-username-claim=email
    - --oidc-groups-claim=groups
...

Once saved, The api-server service will restart to pick the changes.

STEP 3: Deploy Gangway

Once Dex is deployed and running well, we are read to deploy Gangway. We will deploy Gangway in the same namespace as dex.

A. Deploy Configmap

We will first deploy a configmap that holds our gangway configurations. You need to modify the cluster name, apiserverURL, authorizeURL, tokenURL and redirectURL accordingly.

$ vim gangway_configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: gangway
  namespace: auth-system
data:
  gangway.yaml: |
    clusterName: "Kubernetes"
    apiServerURL: "https://172.28.120.125:6443"
    authorizeURL: "https://auth.kubernetes.mydomain.com/auth"  
    tokenURL: "https://auth.kubernetes.mydomain.com/token"
    clientID: "oidc-auth-client"
    # API client secret as indicated by the identity provider: This should match the Dex key
    clientSecret: "secret"
    # Where to redirect back to. This should be a URL where gangway is reachable.
    # Typically this also needs to be registered as part of the oauth application
    # with the oAuth provider.
    # Env var: GANGWAY_REDIRECT_URL
    redirectURL: "https://kubectl.kubernetes.mydomain.com/callback"
    # Used to specify the scope of the requested Oauth authorization.
    scopes: ["openid", "profile", "email", "offline_access"]
    usernameClaim: "email"
    emailClaim: "email"

Apply the configmap

$ kubectl apply -f gangway_configmap.yaml

B. Deploy Gangway

$ vim gangway.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: gangway
  name: gangway
  namespace: auth-system
spec:
  replicas: 1
  selector:
    matchLabels:
      app: gangway
  template:
    metadata:
      labels:
        app: gangway
    spec:
      containers:
      - command:
        - gangway
        - -config
        - /gangway/gangway.yaml
        env:
        - name: GANGWAY_SESSION_SECURITY_KEY
          valueFrom:
            secretKeyRef:
              key: sesssionkey
              name: gangway-key
        image: gangway:v2.0.0
        imagePullPolicy: Always
        name: gangway
        ports:
        - containerPort: 8080
          name: http
          protocol: TCP
        resources:
          limits:
            cpu: 100m
            memory: 100Mi
          requests:
            cpu: 100m
            memory: 100Mi
        volumeMounts:
        - mountPath: /etc/ssl/certs
          name: certs
        - mountPath: /gangway/
          name: gangway
      dnsPolicy: ClusterFirst
      restartPolicy: Always0
      volumes:
      - configMap:
          defaultMode: 420
          name: gangway
        name: gangway
      - name: certs
        secret:
          defaultMode: 420
          secretName: secret

Apply the above configuration to deploy gangway.

$ kubectl apply -f gangway.yaml

Confirm that pods have been deployed and are running:

$ kubectl get pods -n auth-system 
NAME                            READY   STATUS    RESTARTS   AGE
dex-6cdc6dbbf9-fdlv2            1/1     Running   0          13m

gangway-5c95f5db79-6jjdr        1/1     Running   0          3m


Lastly, Deploy the gangway service :

$ vim gangway-svc.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: gangway
  name: gangway-svc
  namespace: auth-system
spec:
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: http
  selector:
    app: gangway

  type: ClusterIP

Apply the configuration:

$ kubectl apply -f gangway-svc.yaml

C. Configure an Ingress Rule

We will then create an ingress rule to allow communication to our service.

Since I use custom certificates, We first have to create a TLS certificate for our ingress. Make sure the certificate data for the cluster is at the location specified or change this path to point to it.

$ kubectl create secret tls gangway --key /data/Certs/ kubernetes.kubernetes.mydomain.com.key --cert /data/Certs/ kubernetesuat.kubernetes.mydomain.com.crt -n auth-system

Create an gangway-ingress.yaml file. Modify the certificate manager issuer and the host parameters accordingly.

$ vim gangway-ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    ingress.kubernetes.io/force-ssl-redirect: "true"
#Add the line below if you have a certificate manager deployed in your kubernetes cluster
   #cert-manager.io/cluster-issuer: "letsencrypt" #your cert-manager issuer here 
  name: gangway
  namespace: auth-system
spec:
  rules:
  - host: kubectl.kubernetes.mydomain.com
    http:
      paths:
      - backend:
          serviceName: gangway-svc
          servicePort: http
  tls:
  - hosts:
    - kubectl.kubernetes.mydomain.com
    secretName: gangway

Apply the above configuration.

$ kubectl apply -f gangway-ingress.yaml

Once all components are up and running, you should be able to obtain credentials for your cluster using a browser to access gangway.

Lets try to login with a user in our AD group that should have permissions to the cluster. Navigate to your gangway URL which in my case is at https://kubectl.kubernetes.mydomain.com/

The login page should look like this:

gamgway login page

Click on “SIGN IN” to bring up the login page. Enter your username and AD password gamgway login pages

Once logged in, we are redirected back to a gangway page with instructions on configuring kubectl for the command line. These instructions involve installation of the kubectl and the second part has commands that can be executed to configure your kubeconfig file. You should be able to execute Kubectl commands once done.

gangway

Run the commands from the screen to install kubectl and configure kubectl for interacting with Kubernetes as an AD user.

You should now be able to interact with your cluster with ease.

More guides on Kubernetes:

Install Kubernetes Cluster on Debian 10 with Kubespray

Kubectl Cheat Sheet for Kubernetes Admins & CKA Exam Prep

Forward Kubernetes Logs to Elasticsearch (ELK) using Fluentbit

Install Ambassador API Gateway/Ingress Controller on Kubernetes

Your support is our everlasting motivation,
that cup of coffee is what keeps us going!


As we continue to grow, we would wish to reach and impact more people who visit and take advantage of the guides we have on our blog. This is a big task for us and we are so far extremely grateful for the kind people who have shown amazing support for our work over the time we have been online.

Thank You for your support as we work to give you the best of guides and articles. Click below to buy us a coffee.

LEAVE A REPLY

Please enter your comment!
Please enter your name here