Friday, June 25, 2021

Kubernetes Dashboard SSO OIDC with keycloak-Part2

 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://192.168.56.162:8443/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

Make you have working ingress controller is also installed on your kubernetes cluster.you can install the same using helm or maually.

helm install stable/nginx-ingress \
    --name nginx-ingress \
    --namespace=nginx-ingress \
    --set rbac.create=true \
    --set controller.kind=DaemonSet \
    --set controller.hostNetwork=true \
    --set controller.daemonset.useHostPort=true \
    --set controller.stats.enabled=true \
    --set controller.metrics.enabled=true

kubectl --namespace nginx-ingress get services -o wide -w nginx-ingress-controller
kubectl create secret tls default-ingress-tls --key /path/to/private.pem --cert /path/to/cert.pem --namespace nginx-ingress

We need an authentication proxy before the dashboard. 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://192.168.56.162:8443/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.nrathi.io - --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.nrathi.io 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-group-rbac.yaml
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: devops-cluster-admin
  namespace: kubernetes-dashboard
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-admin
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: Group
  name: devopstales
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
subjects:
- kind: User
  name: "devopstales"
  namespace: "kube-system"
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name:  cluster-admin