Kubewarden
Kubewarden es un motor de políticas de Kubernetes. Su objetivo es ser el motor de políticas universal para Kubernetes.
- Puede reutilizar políticas de otros motores de políticas sin tener que reescribirlas.
- Puede escribir sus propias políticas en cualquier lenguaje de programación que genere archivos binarios de WebAssembly, reutilizando sus bibliotecas y herramientas de lenguaje.
- Puede ejecutar políticas tanto fuera del clúster como como parte de sus procesos de CI/CD.
- Kubewarden también proporciona un escáner de auditoría para comprobar de forma activa y continua el cumplimiento de las políticas a lo largo del tiempo.
Kubewarden es un proyecto CNCF Sandbox, creado originalmente por SUSE Rancher .
Componentes de Kubewarden
Se compone de varios tipos de recursos y componentes que trabajan juntos para proporcionar una gestión avanzada y segura de políticas en Kubernetes. ClusterAdmissionPolicy y AdmissionPolicy definen las políticas a diferentes niveles, PolicyServer evalúa y ejecuta estas políticas, y el kubewarden-controller coordina y asegura el funcionamiento adecuado de todo el sistema.
Recursos ClusterAdmissionPolicy: Estos recursos definen cómo se implementan las políticas para los clústeres de Kubernetes. Cada ClusterAdmissionPolicy especifica una política que se aplica a nivel de clúster, proporcionando una forma centralizada de gestionar las reglas de seguridad y comportamiento que deben seguir los recursos dentro del clúster.
Recursos PolicyServer: Representan una implementación de un PolicyServer de Kubewarden. Los PolicyServer son responsables de cargar y evaluar las políticas definidas por el administrador. Estas políticas se ejecutan en el contexto del PolicyServer, que actúa como un entorno seguro y aislado para la evaluación de las políticas.
Recursos AdmissionPolicy: Definen políticas específicas para un namespace determinado. Mientras que ClusterAdmissionPolicy aplica políticas a nivel de clúster, AdmissionPolicy permite definir y aplicar políticas específicas dentro de un namespace, proporcionando un control más granular sobre los recursos y las reglas dentro de ese ámbito.
Implementación de un kubewarden-controller: Este controlador monitorea los recursos ClusterAdmissionPolicy y AdmissionPolicy, e interactúa con los componentes del PolicyServer de Kubewarden. El kubewarden-controller asegura que las políticas se carguen y apliquen correctamente, gestionando la comunicación entre Kubernetes y los servidores de políticas de Kubewarden.
Un listado de políticas las puede encontrar en el siguiente enlace: ArtifactHub
Instalación en Rancher Kubernetes Engine
- Ingresar como usuario administrador al cluster de Kubernetes con el siguiente comando:
export KUBECONFIG=/home/student/rke2_conn/cluster1/cluster1_kubeconfig.yaml - Instalar Kubewarden stack usando helm charts de la siguiente forma:
Primero se deben agregar los repositorios de los helm charts desde el servidor bastion
helm repo add kubewarden https://charts.kubewarden.iohelm repo update kubewarden - Instalar los CRDS
helm install --wait -n kubewarden --create-namespace kubewarden-crds kubewarden/kubewarden-crds - Instalar kubewarden-controller:
helm install --wait -n kubewarden kubewarden-controller kubewarden/kubewarden-controller - Instalar kubewarden-defaults, que creará un recurso de PolicyServer llamado default. También puede instalar un conjunto de políticas recomendadas para proteger su clúster aplicando algunas de las mejores prácticas conocidas.
helm install --wait -n kubewarden kubewarden-defaults kubewarden/kubewarden-defaults
Ejemplo: Implementando una Politica para prevenir crear recursos en el sistema sin definición de recursos de computo.
El siguiente ejemplo aplicará una Politica que restringe la creación de Pods sin recursos definidos. Esto ayuda a mantener la capacidad del cluster controlada.
- Ingresar como usuario administrador al cluster de Kubernetes con el siguiente comando:
export KUBECONFIG=/home/student/rke2_conn/cluster1/cluster1_kubeconfig.yaml -
Crearemos un namespace con el nombre
test-kw-policy1.kubectl create ns test-kw-policy1 -
Usaremos el siguiente comando para crear la política de tipo AdmissionPolicy llamada container-resources-policy, en el nuevo namespace test-kw-policy1. Necesitamos evitar la creación de pods sin recursos (requests,limits) definidos o dentro de los valore permitidos por esta política.
Puede obtener información acerca de la política en este enlace.
Recurso Parámetro Valor Memoria defaultRequest128M defaultLimit256M maxLimit2G CPU defaultRequest100m defaultLimit150m maxLimit500m kubectl apply -f - <<EOF apiVersion: policies.kubewarden.io/v1 kind: AdmissionPolicy metadata: name: container-resources-policy namespace: test-kw-policy1 spec: module: registry://ghcr.io/kravciak/policies/container-resources:latest rules: - apiGroups: [""] apiVersions: ["v1"] resources: ["pods"] operations: - CREATE - UPDATE mutating: false settings: memory: defaultRequest: 128M defaultLimit: 256M maxLimit: 2G cpu: defaultRequest: 100m defaultLimit: 150m maxLimit: 500m EOF -
Cuando el recurso AdmissionPolicy se crea, el estado se establece en pending y forzará una implementación del en PolicyServer. En nuestro ejemplo, es el PolicyServer llamado default. Puede monitorear el lanzamiento ejecutando el siguiente comando:
watch kubectl get admissionpolicy.policies -n test-kw-policy1 -
Crearemos la definición de un pod en un archivo llamado
simple-pod.yaml.kubectl run simple-pod --image=docker.io/redis:latest\ -n test-kw-policy1 -o yaml --dry-run=client > simple-pod.yaml -
Consultamos la definición del recurso.
Salida ejemplo:cat simple-pod.yamlNote que por defecto no cuenta con recursos definidos.apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: simple-pod name: simple-pod namespace: test-kw-policy1 spec: containers: - image: docker.io/redis:latest name: simple-pod resources: {} dnsPolicy: ClusterFirst restartPolicy: Always status: {} -
Trate de aplicar el cambio en el cluster.
Deberá fallar con el siguiente mensaje:kubectl apply -f simple-pod.yamlLo que indica que no tiene recuros definidos y no se forza a modificar el recurso para asigarne valores por defecto.Error from server: error when creating "simple-pod.yaml": admission webhook "namespaced-test-kw-policy1-container-resources-policy. kubewarden.admission" denied the request: Request rejected by policy namespaced-test-kw-policy1-container-resources-policy. The policy attempted to mutate the request, but it is currently configured to not allow mutations -
Modicaremos el recurso para incluir la definición de los recursos de la siguiente manera:
Note que hemos definido como valor máximo de memoria 8G.apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: simple-pod name: simple-pod namespace: test-kw-policy1 spec: containers: - image: docker.io/redis:latest name: simple-pod resources: requests: cpu: 100m memory: 100M limits: cpu: 150m memory: 8G dnsPolicy: ClusterFirst restartPolicy: Always status: {} -
Trate de aplicar el cambio en el cluster.
Deberá fallar con el siguiente mensaje:kubectl apply -f simple-pod.yamlError from server: error when creating "simple-pod.yaml": admission webhook "namespaced-test-kw-policy1-container-resources-policy. kubewarden.admission" denied the request: memory limit '8G' exceeds the max allowed value '2G' -
Modifique la definición de recursos y ajuste los parámetros de resources.limits.memory a 1G.
apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: simple-pod name: simple-pod namespace: test-kw-policy1 spec: containers: - image: docker.io/redis:latest name: simple-pod resources: requests: cpu: 100m memory: 100M limits: cpu: 150m memory: 1G dnsPolicy: ClusterFirst restartPolicy: Always status: {} -
Trate de aplicar el cambio en el cluster.
El comando deberá ser exitoso y se creará el pod en el namespace deseado.kubectl apply -f simple-pod.yaml
Ejemplo: Modificación de una Politica para ajustar los recursos de un pod en su definición de recursos de computo.
El siguiente ejemplo aplicará una Politica que modificar la creación de Pods sin recursos definidos y coloca los valores predeterminados. Esto ayuda a mantener la capacidad del cluster controlada.
-
Modifique la politica creada previamete.
Note el cambio en mutating, esto permitirá que el recurso sea modificado en tiempo de ejecución con los valores de la política.kubectl apply -f - <<EOF apiVersion: policies.kubewarden.io/v1 kind: AdmissionPolicy metadata: name: container-resources-policy namespace: test-kw-policy1 spec: module: registry://ghcr.io/kravciak/policies/container-resources:latest rules: - apiGroups: [""] apiVersions: ["v1"] resources: ["pods"] operations: - CREATE - UPDATE mutating: true settings: memory: defaultRequest: 128M defaultLimit: 256M maxLimit: 2G cpu: defaultRequest: 100m defaultLimit: 150m maxLimit: 500m EOF -
Puede monitorear el lanzamiento ejecutando el siguiente comando:
Espere a que esta activa.watch kubectl get admissionpolicy.policies -n test-kw-policy1 -
Crearemos la definición de un pod en un archivo llamado
simple-pod2.yaml.kubectl run simple-pod2 --image=docker.io/redis:latest\ -n test-kw-policy1 -o yaml --dry-run=client > simple-pod2.yaml -
Consultamos la definición del recurso.
Salida ejemplo:cat simple-pod2.yamlNote que por defecto no cuenta con recursos definidos.apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: simple-pod name: simple-pod namespace: test-kw-policy1 spec: containers: - image: docker.io/redis:latest name: simple-pod resources: {} dnsPolicy: ClusterFirst restartPolicy: Always status: {} -
Trate de aplicar el cambio en el cluster.
Deberá set exitoso.kubectl apply -f simple-pod2.yamlpod/simple-pod2 created -
Inspeccione el pod en ejecución.
Salida ejemplo:kubectl get -o yaml pod/simple-pod2 -n test-kw-policy1 |yq .spec.containers[0].resourcesNote que se ha modificado en tiempo de ejecución con los valores definidos en la política.limits: cpu: 150m memory: 256M requests: cpu: 100m memory: 128MRecurso Parámetro Valor Memoria defaultRequest128M defaultLimit256M CPU defaultRequest100m defaultLimit150m
Ejemplo: Implementando una Politica Nivel de Cluster
El siguiente ejemplo aplicará una Politica que restringe la creación de Pods con securityContext privileged, la configuración securityContext: privileged: true en un POD proporciona a los contenedores permisos extendidos en el host, lo que puede ser necesario para ciertas aplicaciones pero conlleva riesgos significativos de seguridad.
NO DEBE DEJAR ESTA POLITICA ACTIVA EN ESTE CLUSTER, ASEGURESE DE ELIMINAR LOS RECURSOS EN LA SECCION "Limpieza del ambiente" AL FINALIZAR
- Usaremos el siguiente comando para crear la política pod-privileged. Necesitamos evitar la creación de contenedores privilegiados dentro de nuestro clúster de Kubernetes aplicando esta política.
Esto produce el siguiente resultado:
kubectl apply -f - <<EOF apiVersion: policies.kubewarden.io/v1 kind: ClusterAdmissionPolicy metadata: name: privileged-pods spec: module: registry://ghcr.io/kubewarden/policies/pod-privileged:v0.2.2 rules: - apiGroups: [""] apiVersions: ["v1"] resources: ["pods"] operations: - CREATE - UPDATE mutating: false EOFclusteradmissionpolicy.policies.kubewarden.io/privileged-pods created - Cuando el recurso ClusterAdmissionPolicy se crea, el estado se establece en pending y forzará una implementación del objetivo PolicyServer. En nuestro ejemplo, es el PolicyServer llamado default. Puede monitorear el lanzamiento ejecutando el siguiente comando:
Y se debe mostrarse en estado active para comenzar a funcionar:
kubectl get clusteradmissionpolicy.policies.kubewarden.io/privileged-pods[student@student-0-aio ~]$ kubectl get clusteradmissionpolicy.policies.kubewarden.io/privileged-pods NAME POLICY SERVER MUTATING BACKGROUNDAUDIT MODE OBSERVED MODE STATUS AGE privileged-pods default false true protect protect active 103s -
Una vez que ClusterAdmissionPolicy esté activo, puede probar la política. Creemos un Pod con un Contenedor que no está en modo privileged:
Esto producirá el siguiente resultado:kubectl apply -f - <<EOF apiVersion: v1 kind: Pod metadata: name: unprivileged-pod spec: containers: - name: nginx image: nginx:latest EOFEl Pod se creó exitosamente, con lo que comprobamos que contenedores que NO esten en modo privilegiado se crearan sin ningún inconveniente.pod/unprivileged-pod created -
Ahora, creemos un Pod con securityContext en privileged con valor true, la configuración securityContext: privileged: true proporciona a los contenedores permisos extendidos en el host, lo que puede ser necesario para ciertas aplicaciones pero conlleva riesgos significativos de seguridad.
La política ha denegado la creación del Pod y debería ver el siguiente mensaje:kubectl apply -f - <<EOF apiVersion: v1 kind: Pod metadata: name: privileged-pod spec: containers: - name: nginx image: nginx:latest securityContext: privileged: true EOFLo anterior comprueba que la politica creada anteriormente esta funcionando correctamente, ya que NO permite crear contnedores en modo privilegedError from server: error when creating "STDIN": admission webhook "clusterwide-privileged-pods.kubewarden.admission" denied the request: Privileged container is not allowed
Limpieza del ambiente
- Puede eliminar los recursos creados desinstalando los helm charts de la siguiente manera::
helm uninstall --namespace kubewarden kubewarden-defaultshelm uninstall --namespace kubewarden kubewarden-controllerhelm uninstall --namespace kubewarden kubewarden-crdskubectl delete namespace kubewarden test-kw-policy1