Openunison - Gestión de identidades en Kubernetes

Publicado por Francisco Ortiz Sarria el

DevOpsKubernetesOpenunisonGobiernoManagement

Kubernetes es un orquestador de contenedores, usado ampliamente en organizaciones y compañías en sus diferentes versiones. Los administradores del clúster tienen medios por los cuales administran el mismo, estos son proporcionados por los propios proveedores o configurados desde el aprovisionamiento.

cabecera - Enmilocalfunciona - Gestión de identidades - 1400x400px.jpg

En muchas ocasiones es realmente útil que el acceso a Kubernetes no sea solamente para administradores, sino también a desarrolladores o terceros que quieran consultar algún tipo de información. Por ejemplo, un desarrollador podría consultar el estado en que se encuentra su aplicación, los dominios expuestos, la configuración establecida o los logs en tiempo real para propósitos de depuración.

La mayoría de compañías disponen de una gestión centralizada de usuarios, incluyendo servicios como LDAP o Active Directory. Estos usuarios pueden pertenecer a grupos para poder clasificarlos y ayudar a su identificación en los diferentes sistemas. Por ejemplo, el grupo developer, donde todos los usuarios desarrolladores son añadidos al entrar en la compañía.

Una de las grandes ventajas de un SSO (o inicio de sesión único) es que permite a los usuarios autenticarse a través de un único punto sin tener que gestionar diferentes accesos.

Openunison es la pieza de software que permitirá el funcionamiento de un sistema de identidad y Kubernetes. Actuará de “puente” permitiendo que el usuario pueda autenticarse y pueda realizar diferentes acciones según el alcance de las mismas (RBAC).

Aunque el artículo comprende varias tecnologías y operativas, para su entendimiento es necesario que se tenga experiencia en Kubernetes a nivel de administración/configuración y por supuesto también de la herramienta helm.

La finalidad del artículo es realizar la instalación y de configuración de Openunison en un clúster de Kubernetes. Demostraremos un inicio de sesión usando el SSO de github, que nos permitirá una conexión al dashboard de Kubernetes y a la api de Kubernetes mediante un token temporal.

Para mejor entendimiento del mismo aclaremos algunos conceptos, aunque no entraremos en detalles profundos.

Single Sign On (SSO)

Es un método de autenticación que permite a los usuarios autenticarse contra diferentes aplicaciones y servicios usando solamente una credencial (por ejemplo, usuario y contraseña). Es muy común el uso web del mismo en los que la autenticación se realiza mediante diferentes mecanismos como SAML.

Proveedor de identidad (IDP)

Es un sistema que gestiona los datos de usuario y proporciona diferentes vías, mecanismos y protocolos para acceder a ellos. Estos servicios pueden tener su propio sistema de almacenamiento o bien conectarse a un tercero para la obtención de los mismos, como LDAP o Active Directory. Un ejemplo de idp open source sería Keycloak.

Helm

Permite instalar los charts en el clúster de Kubernetes. Los charts son definiciones de las diferentes aplicaciones, servicios, configuraciones, y objetos de Kubernetes que conlleva el paquete de software. Podemos instalar una aplicación de forma directa indicando previamente una configuración establecida en un fichero yaml. Sin usar este empaquetado, tardaríamos muchísimo más tiempo en leer toda la documentación para escribir la configuración y conectar todas las piezas.

El concepto es similar a un gestor de paquetes de Kubernetes. No entramos en detalles en este artículo, puedes leer estos artículos de nuetro blog para su mejor compresión: helm - despliga tus aplicaciones y su continuación.

Kubernetes: autenticación y roles

Uno de los componentes principales en un clúster de Kubernetes es la API (kube-api-server). Este componente expone una api HTTP para usuarios finales, en los que se puede consultar y manipular el estado de los objetos, como pods, configmaps, etc.

Kubernetes presenta diferentes formas para la autenticación: certificados, tokens, usuarios y contraseñas. Una de las funcionalidades en cuestión de permisos RBAC, o gestión de permisos basados en roles.

Documentación oficial Mecanismos de autenticación

RBAC

Permite establecer una serie de reglas para gestionar los permisos que tiene una entidad referente a los objetos de api.
Para ello existen 4 tipos de objetos:

  • Role. Definicción de permisos sobre los recursos de una apigroup, en un determinado namespace.
  • ClusterRole. Misma idea de role pero a nivel de clúster, sin tener en cuenta el namespace.
  • RoleBinding. Concede los permisos a una entidad a nivel de namespace.
  • ClusterRoleBinding. Concede los permisos a una entidad a nivel de clúster.

Implementación de la api de Kubernetes: ApiVersion:rbac.authorization.k8s.io/v1

Documentación oficial RBAC

Openunison

Openunison es un software desarrollado por Tremolo Security y que tiene una licencia Apache License 2.0. Está publicado en github.

Proporciona SSO y autenticación para los clusters de Kubernetes, independientemente de su localización y proveedor. Aunque puede funcionar de forma standalone, sin el contexto de Kubernetes, no es objetivo de este artículo. Nos centraremos exclusivamente en su versión conjunta para Kubernetes.

Dispone de otras funcionalidades no cubiertas en este artículo, como alta disponibilidad con AMQ, integraciones con azuread, googlws, kiali, etc.

Componentes

La mayoría de las funcionalidades propias del IDP residen en su principal componente, openunison. Dispone de numerosos plugins/componentes adicionales para añadir funcionalidades y realizar integraciones con terceros.
En referencia al helm y su instalación en Kubernetes, podemos decir que está formado por tres componentes principales, disponiendo cada uno de un chart.
Para su completo funcionamiento, necesitamos tener instalado Kubernetes dashboard, si deseamos esta funcionalidad, aunque no es obligatorio.

Kubernetes dashboard

Es un software con licencia Apache 2.0 y suele ser utilizado en clusters para visualizar de forma gráfica e interactuar con el mismo. Aunque no es un producto de Tremolo, es necesario instalarlo para su uso y ver la funcionalidad que queremos mostrar en este artículo.
Internamente utiliza un service account para conectar con la api y obtener toda la información. Es una aplicación realizada las tecnologías Angular y Go.

Orchestra (openunison)

Realiza las funciones de gestión de identidad necesarias para la mayoría de las aplicaciones: sso, aprovisionamiento de los usuarios, federación y servicios web. Es la aplicación base o core del sistema.

Portal de login de orchestra (orchestra-login-portal)

El portal web permite a los usuarios auntenticación y interactuar con Kubernetes.
Existen dos posibles vías principalmente:

  • Kubernetes dashboard
  • Token para usar con kubectl

Operador de kuberentes (openunison-operator)

Proporciona mecanismos para la automatización de operaciones para las instancias de OpenUnison que corran en el clúster. El operador generará la configuración necesaria para que Openunison funcione:

  • Certificados y generación de claves
  • Creación de secrets, deployments, services e ingress
  • Configuración para OpenShift
  • Importación de metadatos de SAML desde una url o xml
  • Inicialización de la base de datos para realizar el seguimiento de datos de auditoría
  • Despliegue de ActiveMQ para alta disponibilidad

Openunison helm charts

Unas de las opciones disponibles para instalar el software es en formato helm chart.

Puedes consultar el listado de chart disponibles aunque nos centraremos mayormente en los siguientes para su instalación:

  • openunison-operator
  • openunison-orchestra
  • openunison-orchestra-login-portal

Instalación

Existen disponibles diferentes métodos para la instalación:

  • ArgoCD
  • ouctl: herramienta propia creada por tremolo para facilitiar la instalación.
  • Despliegue manual con helm

El artículo actual se ha realizado utilizando el método tres, usando minikube con docker en una máquina linux.

Documentación de instalación centrada en la versión de helm

Documentación detallada más técnica a nivel de instalación aislada

Requisitos

Clúster de Kubernetes

Para poder instalar la herramienta, necesitamos el elemento fundamental, un clúster de Kubernetes. Existen muchas maneras de conseguir un clúster básico de un nodo de forma rápida.

Es recomendable tener la funcionalidad de ingress activada para poder visualizar el portal de forma más cómoda, o bien utilizaremos la funcionalidad de port-fowarding para publicar temporalmente la aplicación.

Windows

En el blog disponemos de este artículo para su instalación en Windows 10.

Linux

Puedes tener un clúster de un nodo de manera muy fácil, teniendo docker instalado y minikube.
En la documentación oficial explican al detalle su instalación: docker y minikube

Docker será instalado a través de la paquetería usando su repositorio propio y minikube puede ser descargado e instalado en tu local. Además, debes de instalar kubectl.

Macos

La aplicación Docker desktop permite instalar docker y entre sus opciones activar un clúster de un nodo de Kuberentes.

Arquitectura ARM

Lamentablemente openunision no dispone de imágenes en arquitectura arm64.
Puedes construirla desde tu local para que posteriormente estén disponibles en la cache de imágenes del clúster y que no sean descargadas del registry público. Puedes consultar los dockerfile en los diferentes repositorios. Éste es el dockerfile de openunison-kubernetes-operator.

Algunas imágenes:

  • docker.io/library/openunison-kubernetes-operator:1.0.6
  • ghcr.io/tremolosecurity/python3:1.0.0
  • ghcr.io/openunison/openunison-k8s:1.0.40
  • ghcr.io/openunison/openunison-kubernetes-operator:1.0.6
  • docker.io/tremolosecurity/kubernetes-artifact-deployment:1.1.0

Si utilizas minikube, puedes añadir estas imágenes en la cache del clúster

# Guardamos la imagen en local
docker save ghcr.io/openunison/openunison-kubernetes-operator > myimage.tar openunison

# Añadimos en la cache del clúster
minikube image load myimage.tar

Proveedor de identidad

Para poder probar la funcionalidad es necesario contar con un IDP.
Diferentes fuentes de identidad:

  • Active directory/LDAP
  • OpenId Connect
  • GitHub
  • SAML2
Github

Lo utilizaremos en la prueba actual. Para que sea lo más fácil y menos complejo, creamos una cuenta en github y además la activaremos para que contemple una organización.

  • Creamos una cuenta de github, para ello necesitamos una cuenta de correo electrónico
  • Una vez creada y activada, necesitaremos crear una organización. En la sección opciones de github (disponible en el menú hamburguesa del perfil), en la sección de acceso podemos localizar "Organizaciones". Podemos crear desde aquí una nueva organización, que será clave para poder configurar los roles a los miembros de la organización.
  • También será necesario crear una github app. Este apartado se especifica más adelante en la instalación.

Instalación de Kubernetes dashboard

Una vez revisados los requisitos mínimos, podemos empezar a realizar las instalaciones de los charts.

Procedemos a instalar el componente y sus configuraciones por defecto en el namespace kubernetes-dashboard

kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml

Este deployment no contempla ninguna ingress. La ingress es ya gestionada por Openunison al activar el valor en values.yaml

Añadir el repositorio de helm charts de Openunison

helm repo add tremolo https://nexus.tremolo.io/repository/helm/
helm repo update

Podemos ver las versiones últimas

helm search repo

Para esta instalación usaremos las veriones de chart y app

  • tremolo/openunison-operator 3.0.11 y 1.0.40
  • tremolo/orchestra 2.10.48 y 1.0.40

Github

Utilizaremos el proveedor github, pues el más rápido sin tener que disponible de un SSO local. El mecanismo consiste en proporcionar una url de retorno de autorización (Authorization callback URL)

Creación de una Github app

Necesitamos disponer de una cuenta github activa.
Registramos una github app que controlará la integración.
Aquí debemos tener en cuenta la siguiente información:

  • Client id y client secret
  • Homepage URL: Página principal donde redirecciona tras iniciar sesión.
  • Authorization callback URL: Endpoint que implementa el esquema de autenticación.

Para esta prueba se ha configurado https://k8sou.apps.ou.tremolo.dev/ como homepage url y https://k8sou.apps.ou.tremolo.dev/auth/github como Authorization callback URL. Recordar que tenéis que añadir estos dominios en vuestro fichero host para que os funcione correctamente.

Nos centraremos en los valores mínimos para que la aplicación funcione correctamente.

Ficheros de configuración

Creación de un namespace para instalación

kubectl create ns openunision

Configuración RBAC para otorgar a los miembros de la organización github los permisos definidos del rol cluster-admin.
Realizaremos la instalación de las siguientes configuraciones:

kubectl apply -f fichero.yaml

rbac_github.yaml

Configura name con el nombre de tu org o org/team

kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
    name: github-cluster-admins
subjects:
- kind: Group
    name: **** # Sustituye aqui el nombre de tu github org
roleRef:
    kind: ClusterRole
    name: cluster-admin
    apiGroup: rbac.authorization.k8s.io

Por defecto la aplicación utiliza una serie de credenciales, creamos un secreto, además añadiremos el valor GITHUB_SECRET_ID

Los valores de K8S_DB_SECRET y unisonKeystorePassword deben de ser generados de nuevo para producción.
Configura GITHUB_SECRET_ID con tu github app secret id

orchestra-secrets-source.yaml

apiVersion: v1
type: Opaque
metadata:
  name: orchestra-secrets-source
  namespace: openunison
data:
  K8S_DB_SECRET: ********
  unisonKeystorePassword: ********
  GITHUB_SECRET_ID: ********
kind: Secret

Instalación de openunison-operador

helm install openunison tremolo/openunison-operator --namespace openunison

Si necesitas ver la salida final que aplica, recuerda que puedes hacerlo con template render

Verificamos que el pod está ya corriendo

k get pods -n openunison

NAME                                   READY   STATUS    RESTARTS   AGE
openunison-operator-6855ff588d-mw4w6   1/1     Running   0          84s

Instalación de openunison-orchestra

Fichero de configuración values.yaml.
Realizaremos una configuración mínima viable para su funcionamiento.

Configura los valores

  • github.client_id
  • github.teams
  • k8s_url
network:
  openunison_host: "k8sou.apps.ou.tremolo.dev" # Dominio del portal login de orquestra
  dashboard_host: "k8sdb.apps.ou.tremolo.dev" # Dominio del dashboard de Kubernetes
  api_server_host: "k8sapi.apps.ou.tremolo.dev" # Api orquestra
  session_inactivity_timeout_seconds: 900
  k8s_url: https://192.168.49.2:6443 # Dirección y puerto del api server
  force_redirect_to_tls: false
  createIngressCertificate: true
  ingress_type: nginx
  ingress_annotations: {}

cert_template:
  ou: "Kubernetes"
  o: "MyOrg"
  l: "My Cluster"
  st: "State of Cluster"
  c: "MyCountry"

myvd_config_path: "WEB-INF/myvd.conf"
k8s_cluster_name: openunison-cp
enable_impersonation: false

impersonation:
  use_jetstack: true
  explicit_certificate_trust: true

dashboard:
  namespace: "kubernetes-dashboard"
  cert_name: "kubernetes-dashboard-certs"
  label: "k8s-app=kubernetes-dashboard"
  service_name: kubernetes-dashboard
  require_session: true
  enabled: true

certs:
  use_k8s_cm: false

trusted_certs: []

monitoring:
  prometheus_service_account: system:serviceaccount:monitoring:prometheus-k8s

github:
  client_id: ************** # CLIENT ID DE LA APLICACION DE GIT
  teams: ********/ # NOMBRE DE LA ORG GITHUB
#saml:
#  idp_url: "https://portal.apps.tremolo.io/idp-test/metadata/dfbe4040-cd32-470e-a9b6-809c8f857c40"

network_policies:
  enabled: false
  ingress:
    enabled: true
    labels:
      app.kubernetes.io/name: ingress-nginx
  monitoring:
    enabled: true
    labels:
      app.kubernetes.io/name: monitoring
  apiserver:
    enabled: false
    labels:
      app.kubernetes.io/name: kube-system

services:
  enable_tokenrequest: false
  token_request_audience: api
  token_request_expiration_seconds: 600
  node_selectors: []
openunison:
  replicas: 1
  non_secret_data:
    K8S_DB_SSO: oidc
    PROMETHEUS_SERVICE_ACCOUNT: system:serviceaccount:monitoring:prometheus-k8s
    SHOW_PORTAL_ORGS: "false"
  secrets: []
  enable_provisioning: false
  use_standard_jit_workflow: true
  #imagePullPolicy: Never


helm install orchestra tremolo/orchestra --namespace openunison -f values.yaml

Comprobamos que se han creado pods y están corriendo

k get pods -n openunison

NAME                                    READY   STATUS    RESTARTS   AGE
openunison-operator-6855ff588d-mw4w6    1/1     Running   0          14m
openunison-orchestra-79dff6b774-72hp8   1/1     Running   0          70s

Instalación de orchestra-login-portal

Reutilizamos el fichero values.yaml de la sección anterior

helm install orchestra-login-portal tremolo/orchestra-login-portal --namespace openunison -f values.yaml
k get pods -n openunison

NAME                                             READY   STATUS    RESTARTS   AGE
openunison-operator-6855ff588d-mw4w6             1/1     Running   0          17m
openunison-orchestra-79dff6b774-72hp8            1/1     Running   0          4m39s
ouhtml-orchestra-login-portal-5547759cdc-47smn   1/1     Running   0          17s

Tras la instalación se ejecuta un pod para realizar algunos tests

Resolución de ingress

Openunison por defecto instala ingress configuradas con los valores de red proporcionados en el fichero de values.yaml
Depende del proveedor de Kubernetes que estemos usando habrá que realizar un procedimiento para que las ingress resuelva.

En el caso de minikube recuerda tener activado el addon de ingress

minikube addons enable ingress
kubectl get ingress -n openunision

Comprobamos que se han creado las ingress, y que resuelve correctamente

NAME                   CLASS    HOSTS                                                 ADDRESS        PORTS     AGE
openunison-orchestra   <none>   k8sou.apps.ou.tremolo.dev,k8sdb.apps.ou.tremolo.dev   192.168.49.2   80, 443   19m

Como véis, la ip 192.168.49.2 no esta en la red actual si no que pertence a la red de Kubernetes (es la actual ip del cluster de minikube)

minikube ip
192.168.49.2

En caso de que el sistema no tenga ingress podemos usar minikube tunnel para exponer los servicios de tipo load balancer y que estén accesibles desde el host.
También podemos usar port-forward para exponer una aplicación en concreto

Ejemplos: kubectl port-forward -n kubernetes-dashboard service/kubernetes-dashboard 8443:443 --address 0.0.0.0

Acceso al portal

Configurarmos el fichero host de nuestro sistema para que pueda resolver correctamente
(/etc/hosts en macos y linux, c:\Windows\System32\Drivers\etc\hosts windows)

192.168.1.165 k8sou.apps.ou.tremolo.dev k8sdb.apps.ou.tremolo.dev

Accedemos al portal web nos aparecerá una advertencia de que la autoridad certificadora y le diremos que proceder.

Una vez dentro, al no tener session nos redirecciona a la página de github

Tras conceder permiso a la aplicación de github, nos redireccion de nuevo al portal orquestra

Podemos acceder al dashboard de kuberentes

O bien obtener un token temporal para interactuar con la api kube server

Actualización/Desinstalación

Si durante la instalación encontramos problemas o queremos cambiar la configuración recordar que podemos usar el comando

helm upgrade

Para actualizar el helm sin desinstalar.

Conclusión

La adopción de Kubernetes ha supuesto que muchas compañías descubran la importancia de tener una plataforma que cubra gran parte de las necesidades, facilitando el día a día y proporcionado herramientas ágiles para ser más productivos.
Openunison permite la integración de kubernetes entre diferentes comunidades, no enfocadas especialmente a su administración, como los desarolladores, que podrán consultar y depurar sin tener conocimientos profundos de kubernetes gracias al dashboard de Kubernetes.