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.
- 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.
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.
More guides on Kubernetes: