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.
Prerequisites:
- You will need an Active Directory or LDAP server already configured.
- A running Kubernetes Cluster with role based access enable. You should have Administrative access
- An Ingress Controller installed in the cluster.
- A Certificate Manager if not using Custom Certificates. I will be using custom certificates for my deployment
- 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:
Click on “SIGN IN” to bring up the login page. Enter your username and AD password
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.
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