Dashboard authentication with Keycloak and gatekeeper
In this post I will show you how to add a keycloak gatekeeper authentication proxy for Kubernetes Dashboard.
Parts of the Kubernetes series
- Part1a: Install K8S with ansible
- Part1b: Install K8S with kubeadm
- Part1c: Install K8S with kubeadm and containerd
- Part1d: Install K8S with kubeadm and allow swap
- Part1e: Install K8S with kubeadm in HA mode
- Part2: Intall metal-lb with K8S
- Part2: Intall metal-lb with BGP
- Part3: Install Nginx ingress to K8S
- Part4: Install cert-manager to K8S
- Part5a: Use local persisten volume with K8S
- Part5b: Use ceph persisten volume with K8S
- Part5c: Use ceph CSI persisten volume with K8S
- Part5d: Kubernetes CephFS volume with CSI driver
- Part5e: Use Project Longhorn as persisten volume with K8S
- Part5f: Use OpenEBS as persisten volume with K8S
- Part5f: vSphere persistent storage for K8S
- Part6: Kubernetes volume expansion with Ceph RBD CSI driver
- Part7a: Install k8s with IPVS mode
- Part7b: Install k8s with IPVS mode
- Part8: Use Helm with K8S
- Part9: Tillerless helm2 install
- Part10: Kubernetes Dashboard SSO
- Part11: Kuberos for K8S
- Part12: Gangway for K8S
- Part13a: Velero Backup for K8S
- Part13b: How to Backup Kubernetes to git?
- Part14a: K8S Logging And Monitoring
- Part14b: Install Grafana Loki with Helm3
Kubernetes does not have its own user management and relies on external providers like Keycloak. First we need to integrate an OpeniD prodiver (for me keycloak) with the kubernetes api server.
nano /etc/kubernetes/manifests/kube-apiserver.yaml
...
command:
- /hyperkube
- apiserver
- --advertise-address=10.10.40.30
...
- --oidc-issuer-url=https://keycloak.devopstales.intra/auth/realms/mydomain
- --oidc-client-id=k8s
- --oidc-username-claim=email
- --oidc-groups-claim=groups
# for self sign cert or custom ca
#- --oidc-ca-file=/etc/kubernetes/pki/rootca.pem
...
systemctl restart docker kubelet
We need an authentication proxy before the dasboard. I will use keycloak-gatekeeper for that purpose.
nano proxy-deplayment.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: dasboard-proxy
labels:
app.kubernetes.io/name: dasboard-proxy
namespace: kubernetes-dashboard
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: dasboard-proxy
template:
metadata:
labels:
app.kubernetes.io/name: dasboard-proxy
spec:
containers:
- name: dasboard-proxy
image: "keycloak/keycloak-gatekeeper:latest"
command:
- /opt/keycloak-gatekeeper
- --discovery-url=https://keycloak.devopstales.intra/auth/realms/mydomain/.well-known/openid-configuration
- --client-id=k8s
- --client-secret=43219919-0904-4338-bc0f-c986e1891a7a
- --listen=0.0.0.0:3000
- --encryption-key=AgXa7xRcoClDEU0ZDSH4X0XhL5Qy2Z2j
- --redirection-url=https://dashboard.devopstales.intra
- --enable-refresh-tokens=true
- --upstream-url=https://kubernetes-dashboard
# debug:
#- --upstream-url=http://echo:8080
# for self sign cert or custom ca
#- --skip-upstream-tls-verify
#- --skip-openid-provider-tls-verify
ports:
- name: http
containerPort: 3000
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: dasboard-proxy
labels:
app.kubernetes.io/name: dasboard-proxy
namespace: kubernetes-dashboard
spec:
type: ClusterIP
ports:
- port: 3000
targetPort: http
protocol: TCP
name: http
selector:
app.kubernetes.io/name: dasboard-proxy
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: dasboard-proxy
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/proxy-buffer-size: "64k"
cert-manager.io/cluster-issuer: ca-issuer
namespace: kubernetes-dashboard
spec:
tls:
- hosts:
- dashboard.devopstales.intra
secretName: dasboard-proxy-tls
rules:
- host: dashboard.devopstales.intra
http:
paths:
- backend:
serviceName: dasboard-proxy
servicePort: 3000
Now you can login at dashboard.devopstales.intra but you haven’t got any privileges so lets create. some.
nano devops-team_ClusterRoleBinding.yaml
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: cluster-admin-it-afdeling
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: Group
name: devops-team
nano user_ClusterRoleBinding.yaml
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: devopstales-admin
subjects:
- kind: User
apiGroup: rbac.authorization.k8s.io
name: devopstales
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin