En esta página, se muestra cómo usar el controlador de admisión Gatekeeper para aplicar controles de seguridad a nivel de Pod en los clústeres de Google Kubernetes Engine (GKE).
Descripción general
Gatekeeper es un controlador de admisión que valida las solicitudes para crear y actualizar Pods en los clústeres de Kubernetes con Open Policy Agent (OPA).
El uso de Gatekeeper permite que los administradores definan políticas con una restricción, que es un conjunto de condiciones que permiten o rechazan comportamientos de implementación en Kubernetes. Puedes aplicar estas políticas en un clúster mediante un ConstraintTemplate
. En este documento, se proporcionan ejemplos para restringir las capacidades de seguridad de las cargas de trabajo para garantizar la aplicación forzosa, prueba y auditoría de las políticas de seguridad mediante Gatekeeper.
Gatekeeper también puede hacer lo siguiente:
- Implementar políticas: Aplica la política de manera gradual y con alcance para limitar el riesgo de interrumpir las cargas de trabajo.
- Ejecutar cambios de políticas en modo de prueba: Proporciona mecanismos para probar el impacto y el rango de la política antes de la aplicación.
- Auditar las políticas existentes: Garantiza la aplicación de los controles de seguridad para las cargas de trabajo nuevas y existentes (controles de auditoría).
Conceptos
Gatekeeper presenta dos conceptos con el fin de proporcionarles a los administradores métodos potentes y flexibles para controlar sus clústeres: restricciones y plantillas de restricción, que son conceptos heredados del framework de restricciones de Open Policy Agent.
Las restricciones son la representación de tu política de seguridad, ya que definen los requisitos y el rango de aplicación. Las plantillas de restricción son declaraciones reutilizables (escritas en Rego) que aplican una lógica para evaluar campos específicos en objetos de Kubernetes, según los requisitos definidos en las restricciones.
Por ejemplo, podrías tener una restricción que declare perfiles de seccomp que se pueden aplicar a Pods en un espacio de nombres específico y una plantilla de restricción similar que proporciona la lógica para extraer estos valores y controlar la aplicación de manera forzosa.
En la siguiente plantilla de restricción, del repositorio de Gitkeeper, comprueba la existencia de securityContext.privileged
en una especificación de Pod:
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
name: k8spspprivilegedcontainer
spec:
crd:
spec:
names:
kind: K8sPSPPrivilegedContainer
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8spspprivileged
violation[{"msg": msg, "details": {}}] {
c := input_containers[_]
c.securityContext.privileged
msg := sprintf("Privileged container is not allowed: %v, securityContext: %v", [c.name, c.securityContext])
}
input_containers[c] {
c := input.review.object.spec.containers[_]
}
input_containers[c] {
c := input.review.object.spec.initContainers[_]
}
Para extender la plantilla de restricción anterior, la siguiente restricción define el permiso (kinds
) de la aplicación específica de esta plantilla de restricción en un modo dryrun
:
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sPSPPrivilegedContainer
metadata:
name: psp-privileged-container
spec:
enforcementAction: dryrun
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
Con Gatekeeper, puedes crear tus propias restricciones y plantillas de restricciones para satisfacer tus necesidades específicas. También puedes usar un conjunto estándar de restricciones y plantillas de restricciones en el repositorio de Gitkeeper que se definió para permitir la adopción rápida y la aplicación de la seguridad. Cada restricción también incluye configuraciones de Pod de ejemplo.
Google Cloud proporciona una versión administrada y compatible de forma oficial de Gatekeeper llamada Controlador de políticas. Google no admite oficialmente el proyecto de código abierto Gatekeeper.
Antes de comenzar
Antes de comenzar, asegúrate de haber realizado las siguientes tareas:
- Habilita la API de Google Kubernetes Engine. Habilitar la API de Google Kubernetes Engine
- Si deseas usar Google Cloud CLI para esta tarea, instala y, luego, inicializa gcloud CLI. Si ya instalaste gcloud CLI, ejecuta
gcloud components update
para obtener la versión más reciente.
Habilita el guardián de acceso en un clúster con el Controlador de políticas
El controlador de políticas es un motor de políticas compilado en el proyecto de código abierto guardián de acceso. Google recomienda el uso del Controlador de políticas porque incluye funciones adicionales para ayudar a aplicar la política a gran escala, incluida la política como código, la compatibilidad con varios clústeres, la integración con Cloud Logging y la habilidad de ver el estado de la política en la consola de Google Cloud. El controlador de políticas está disponible con una licencia de Google Kubernetes Engine (GKE) Enterprise Edition, pero en su lugar puedes instalar el guardián de acceso en tu clúster.
Para habilitar el Controlador de políticas en un clúster, sigue la Guía de instalación de Policy Controller.
Habilita las restricciones y las plantillas de restricciones
Gatekeeper y sus plantillas de restricciones se pueden instalar y habilitar sin afectar negativamente las cargas de trabajo nuevas o existentes. Por esta razón, se recomienda que todas las plantillas de restricción de seguridad de Pods aplicables se apliquen al clúster.
Además, las restricciones de Gatekeeper se pueden implementar para aplicar controles para objetos específicos, como espacios de nombres y Pods.
Observa el siguiente ejemplo que limita el alcance a los Pods ubicados en el espacio de nombres production y los define en la declaración de coincidencia de restricciones:
...
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Pod"]
namespaces:
- "production"
A fin de obtener más información sobre las opciones disponibles para los objetos Constraint
y ConstraintTemplate
, consulta Cómo usar Gatekeeper.
Prueba políticas
La introducción de políticas nuevas a los clústeres existentes puede tener un comportamiento adverso; por ejemplo, la restricción de las cargas de trabajo existentes. Uno de los beneficios de usar Gatekeeper para la seguridad de Pods es la capacidad de probar la eficacia y el impacto que tendrá una política sin realizar cambios reales con un modo de ejecución de prueba. Esto permite que se realice la prueba de la configuración de la política en clústeres en ejecución sin aplicación de políticas. Los incumplimientos de políticas se registran y se identifican sin interferir.
En los siguientes pasos, se demuestra cómo un desarrollador, operador o administrador puede aplicar plantillas de restricción y restricciones para determinar su eficacia o impacto potencial:
Aplica los archivos de configuración de Gatekeeper a fin de replicar datos para la auditoría y la ejecución de prueba:
kubectl create -f- <<EOF apiVersion: config.gatekeeper.sh/v1alpha1 kind: Config metadata: name: config namespace: "gatekeeper-system" spec: sync: syncOnly: - group: "" version: "v1" kind: "Namespace" - group: "" version: "v1" kind: "Pod" EOF
A continuación, se ejecuta una carga de trabajo con privilegios elevados sin aplicar restricciones:
kubectl create -f- <<EOF apiVersion: v1 kind: Pod metadata: name: nginx labels: app: nginx spec: containers: - name: nginx image: nginx securityContext: privileged: true EOF
Carga la plantilla de restricción
k8spspprivilegedcontainer
que se mencionó antes:kubectl create -f- <<EOF apiVersion: templates.gatekeeper.sh/v1beta1 kind: ConstraintTemplate metadata: name: k8spspprivilegedcontainer spec: crd: spec: names: kind: K8sPSPPrivilegedContainer targets: - target: admission.k8s.gatekeeper.sh rego: | package k8spspprivileged violation[{"msg": msg, "details": {}}] { c := input_containers[_] c.securityContext.privileged msg := sprintf("Privileged container is not allowed: %v, securityContext: %v", [c.name, c.securityContext]) } input_containers[c] { c := input.review.object.spec.containers[_] } input_containers[c] { c := input.review.object.spec.initContainers[_] } EOF
Ahora, creemos una restricción nueva para extender esta plantilla de restricción. Esta vez, estableceremos
enforcementAction
endryrun
:kubectl create -f- <<EOF apiVersion: constraints.gatekeeper.sh/v1beta1 kind: K8sPSPPrivilegedContainer metadata: name: psp-privileged-container spec: enforcementAction: dryrun match: kinds: - apiGroups: [""] kinds: ["Pod"] EOF
Con Gatekeeper sincronizando datos de objetos en ejecución y verificando de forma pasiva si hay incumplimientos, podemos confirmar si se encontraron infracciones mediante el
status
de la restricción:kubectl get k8spspprivilegedcontainer.constraints.gatekeeper.sh/psp-privileged-container -o yaml
apiVersion: constraints.gatekeeper.sh/v1beta1 kind: K8sPSPPrivilegedContainer metadata: ... name: psp-privileged-container ... spec: enforcementAction: dryrun match: kinds: - apiGroups: - "" kinds: - Pod status: auditTimestamp: "2019-12-15T22:19:54Z" byPod: - enforced: true id: gatekeeper-controller-manager-0 violations: - enforcementAction: dryrun kind: Pod message: 'Privileged container is not allowed: nginx, securityContext: {"privileged": true}' name: nginx namespace: default
Ejecutemos otro Pod con privilegios para confirmar que la política no interfiere con las implementaciones:
kubectl create -f- <<EOF apiVersion: v1 kind: Pod metadata: name: privpod labels: app: privpod spec: containers: - name: nginx image: nginx securityContext: privileged: true EOF
Este nuevo Pod se implementará correctamente.
Para limpiar los recursos creados en esta sección, ejecuta los siguientes comandos:
kubectl delete k8spspprivilegedcontainer.constraints.gatekeeper.sh/psp-privileged-container kubectl delete constrainttemplate k8spspprivilegedcontainer kubectl delete pod/nginx kubectl delete pod/privpod
Aplicar políticas
Ahora que podemos confirmar la validez y el impacto de una política sin afectar las cargas de trabajo existentes o nuevas, implementemos una política con aplicación completa.
Sobre la base de los ejemplos utilizados para validar la política anterior, los siguientes pasos demuestran cómo un desarrollador, operador o administrador puede aplicar plantillas de restricciones y restricciones para aplicar una política:
Carga la plantilla de restricción
k8spspprivilegedcontainer
que se mencionó antes:kubectl create -f- <<EOF apiVersion: templates.gatekeeper.sh/v1beta1 kind: ConstraintTemplate metadata: name: k8spspprivilegedcontainer spec: crd: spec: names: kind: K8sPSPPrivilegedContainer targets: - target: admission.k8s.gatekeeper.sh rego: | package k8spspprivileged violation[{"msg": msg, "details": {}}] { c := input_containers[_] c.securityContext.privileged msg := sprintf("Privileged container is not allowed: %v, securityContext: %v", [c.name, c.securityContext]) } input_containers[c] { c := input.review.object.spec.containers[_] } input_containers[c] { c := input.review.object.spec.initContainers[_] } EOF
Ahora, creemos una restricción nueva para extender esta plantilla de restricción. Esta vez, no configuraremos la clave
enforcementAction
. De forma predeterminada, la claveenforcementAction
se establece endeny
.kubectl create -f- <<EOF apiVersion: constraints.gatekeeper.sh/v1beta1 kind: K8sPSPPrivilegedContainer metadata: name: psp-privileged-container spec: match: kinds: - apiGroups: [""] kinds: ["Pod"] EOF
Intenta implementar un contenedor que declare permisos con privilegios:
kubectl create -f- <<EOF apiVersion: v1 kind: Pod metadata: name: nginx labels: app: nginx spec: containers: - name: nginx image: nginx securityContext: privileged: true EOF
Deberías recibir el siguiente mensaje de error:
Error from server ([denied by psp-privileged-container] Privileged container is not allowed: nginx, securityContext: {"privileged": true}): error when creating "STDIN": admission webhook "validation.gatekeeper.sh" denied the request: [denied by psp-privileged-container] Privileged container is not allowed: nginx, securityContext: {"privileged": true}
Para realizar una limpieza, ejecuta los siguientes comandos:
kubectl delete k8spspprivilegedcontainer.constraints.gatekeeper.sh/psp-privileged-container kubectl delete constrainttemplate k8spspprivilegedcontainer
Alternativas a Gatekeeper
Gatekeeper te permite declarar y aplicar políticas de seguridad a nivel del Pod personalizadas. También puedes usar el controlador de admisión PodSecurity
integrado de Kubernetes para aplicar políticas de seguridad predefinidas a nivel del Pod. Estas políticas predefinidas están alineadas con los niveles definidos por los Estándares de seguridad de Pods.
¿Qué sigue?
Gatekeeper proporciona un método extremadamente potente para aplicar y validar la seguridad en los clústeres de GKE mediante políticas declarativas. Sin embargo, el uso de Gatekeeper se extiende más allá de la seguridad y puede usarse en otros aspectos de la administración y las operaciones.