En esta página se explica cómo escribir una plantilla de restricción personalizada y usarla para ampliar Policy Controller si no encuentras una plantilla de restricción predefinida que se adapte a tus necesidades.
Esta página está dirigida a administradores de TI y operadores que quieran asegurarse de que todos los recursos que se ejecutan en la plataforma en la nube cumplen los requisitos de cumplimiento de la organización. Para ello, deben proporcionar y mantener la automatización para auditar o aplicar, y usar plantillas de configuración declarativa. Para obtener más información sobre los roles habituales y las tareas de ejemplo a las que hacemos referencia en el contenido, consulta Roles y tareas habituales de los usuarios de GKE. Google Cloud
Las políticas de Policy Controller se describen mediante el framework de restricciones de OPA y se escriben en Rego. Una política puede evaluar cualquier campo de un objeto de Kubernetes.
Escribir políticas con Rego es una habilidad especializada. Por este motivo, se instala de forma predeterminada una biblioteca de plantillas de restricciones comunes. Probablemente puedas invocar estas plantillas de restricciones al crear restricciones. Si tienes necesidades especializadas, puedes crear tus propias plantillas de restricciones.
Las plantillas de restricciones te permiten separar la lógica de una política de sus requisitos específicos para reutilizarla y delegarla. Puedes crear restricciones con plantillas de restricciones desarrolladas por terceros, como proyectos de código abierto, proveedores de software o expertos en normativas.
Antes de empezar
- Instala Policy Controller.
Plantilla de restricción de ejemplo
A continuación, se muestra un ejemplo de plantilla de restricción que deniega todos los recursos cuyo nombre coincida con un valor proporcionado por el creador de la restricción. En el resto de esta página se explica el contenido de la plantilla y se destacan conceptos importantes.
Si usas Config Sync con un repositorio jerárquico, te recomendamos que crees las restricciones en el directorio cluster/
.
apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
name: k8sdenyname
spec:
crd:
spec:
names:
kind: K8sDenyName
validation:
# Schema for the `parameters` field
openAPIV3Schema:
properties:
invalidName:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8sdenynames
violation[{"msg": msg}] {
input.review.object.metadata.name == input.parameters.invalidName
msg := sprintf("The name %v is not allowed", [input.parameters.invalidName])
}
Ejemplo de restricción
A continuación, se muestra un ejemplo de restricción que puede implementar para denegar todos los recursos llamados policy-violation
:
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sDenyName
metadata:
name: no-policy-violation
spec:
parameters:
invalidName: "policy-violation"
Partes de una plantilla de restricción
Las plantillas de restricciones tienen dos partes importantes:
El esquema de la restricción que quieres que creen los usuarios. El esquema de una plantilla de restricción se almacena en el campo
crd
.El código fuente de Rego que se ejecuta cuando se evalúa la restricción. El código fuente de Rego de una plantilla se almacena en el campo
targets
.
Esquema (campo crd
)
El campo CRD es un plano para crear la definición de recurso personalizado de Kubernetes que define el recurso de restricción del servidor de la API de Kubernetes. Solo tienes que rellenar los siguientes campos.
Campo | Descripción |
---|---|
spec.crd.spec.names.kind |
Tipo de restricción. Cuando se escriba en minúsculas, el valor de este campo debe ser igual a metadata.name . |
spec.crd.spec.validation.openAPIV3Schema |
Esquema del campo |
Añadir el prefijo K8s
a la plantilla de restricción es una convención que te permite evitar colisiones con otros tipos de plantillas de restricción, como las plantillas de Forseti que se dirigen a recursos Google Cloud .
Código fuente de Rego (campo targets
)
En las siguientes secciones se ofrece más información sobre el código fuente de Rego.
Ubicación
El código fuente de Rego se almacena en el campo spec.targets
, donde targets
es una matriz de objetos con el siguiente formato:
{"target": "admission.k8s.gatekeeper.sh","rego": REGO_SOURCE_CODE, "libs": LIST_OF_REGO_LIBRARIES}
target
: indica a Policy Controller qué sistema estamos consultando (en este caso, Kubernetes). Solo se permite una entrada entargets
.rego
: el código fuente de la restricción.libs
: lista opcional de bibliotecas de código Rego que se pone a disposición de la plantilla de restricción. Su objetivo es facilitar el uso de bibliotecas compartidas y no se incluye en este documento.
Código fuente
A continuación, se muestra el código fuente de Rego de la restricción anterior:
package k8sdenynames
violation[{"msg": msg}] {
input.review.object.metadata.name == input.parameters.invalidName
msg := sprintf("The name %v is not allowed", [input.parameters.invalidName])
}
Ten en cuenta lo siguiente:
package k8sdenynames
es obligatorio para OPA (el tiempo de ejecución de Rego). Se ignora el valor.- La regla de Rego que invoca Policy Controller para comprobar si hay alguna infracción se llama
violation
. Si esta regla tiene coincidencias, se ha producido una infracción de la restricción. - La regla
violation
tiene la firmaviolation[{"msg": "violation message for the user"}]
, donde el valor de"msg"
es el mensaje de infracción que se devuelve al usuario. - Los parámetros proporcionados a la restricción están disponibles en la palabra clave
input.parameters
. - El
request-under-test
se almacena en la palabra claveinput.review
.
La palabra clave input.review
tiene los siguientes campos.
Campo | Descripción |
---|---|
uid |
El ID único de esta solicitud en concreto. No está disponible durante la auditoría. |
kind |
Información de tipo de
|
name |
Nombre del recurso. Puede estar vacío si el usuario utiliza el servidor de la API para generar el nombre en una solicitud CREATE. |
namespace |
El espacio de nombres del recurso (no se proporciona para los recursos con permisos de clúster). |
operation |
La operación solicitada (por ejemplo, CREATE o UPDATE). No está disponible durante la auditoría. |
userInfo |
Información del usuario que envía la solicitud. No está disponible durante la auditoría. Tiene el siguiente formato:
|
object |
El objeto que el usuario intenta modificar o crear. |
oldObject |
El estado original del objeto. Solo está disponible en las operaciones UPDATE. |
dryRun |
Indica si se ha invocado esta solicitud con kubectl --dry-run ;
no está disponible durante la auditoría. |
Escribir plantillas de restricciones referenciales
Las plantillas de restricciones referenciales son plantillas que permiten al usuario restringir un objeto con respecto a otros objetos. Por ejemplo, "no permitir que se cree un pod antes de que se sepa que existe un Ingress coincidente". Otro ejemplo podría ser "no permitir que dos servicios tengan el mismo nombre de host".
Policy Controller te permite escribir restricciones referenciales monitorizando el servidor de APIs para un conjunto de recursos proporcionado por el usuario. Cuando se modifica un recurso, Policy Controller lo almacena en caché localmente para que el código fuente de Rego pueda hacer referencia a él fácilmente. Policy Controller hace que esta caché esté disponible con la palabra clave data.inventory
.
Los recursos con permisos de clúster se almacenan en caché en la siguiente ubicación:
data.inventory.cluster["GROUP_VERSION"]["KIND"]["NAME"]
Por ejemplo, un nodo llamado my-favorite-node
se podría encontrar en
data.inventory.cluster["v1"]["Node"]["my-favorite-node"]
Los recursos con permisos de espacio de nombres se almacenan en caché aquí:
data.inventory.namespace["NAMESPACE"]["GROUP_VERSION"]["KIND"]["NAME"]
Por ejemplo, un ConfigMap llamado production-variables
en el espacio de nombres shipping-prod
se puede encontrar en
data.inventory.namespace["shipping-prod"]["v1"]["ConfigMap"]["production-variables"]
El contenido completo del objeto se almacena en esta ubicación de la caché y se puede hacer referencia a él en el código fuente de Rego como consideres oportuno.
Más información sobre Rego
La información anterior proporciona las funciones únicas de Policy Controller que facilitan la escritura de restricciones en recursos de Kubernetes en Rego. Esta guía no incluye un tutorial completo sobre cómo escribir en Rego. Sin embargo, en la documentación de Open Policy Agent se incluye información sobre la sintaxis y las funciones del lenguaje Rego.
Instalar una plantilla de restricción
Una vez que hayas creado tu plantilla de restricción, usa kubectl apply
para aplicarla y Policy Controller se encargará de insertarla. Asegúrate de comprobar el campo status
de tu plantilla de restricción para verificar que no haya habido errores
al instanciarla. Si la ingestión se realiza correctamente, el campo status
debe mostrar created: true
y el valor observedGeneration
indicado en el campo status
debe ser igual al valor del campo metadata.generation
.
Una vez que se haya insertado la plantilla, podrá aplicarle restricciones tal como se describe en el artículo Crear restricciones.
Eliminar una plantilla de restricción
Para eliminar una plantilla de restricción, siga estos pasos:
Verifica que ninguna de las restricciones que quieras conservar use la plantilla de restricciones:
kubectl get TEMPLATE_NAME
Si hay un conflicto de nomenclatura entre el nombre de la plantilla de restricción y otro objeto del clúster, utilice el siguiente comando:
kubectl get TEMPLATE_NAME.constraints.gatekeeper.sh
Elimina la plantilla de restricción:
kubectl delete constrainttemplate CONSTRAINT_TEMPLATE_NAME
Cuando eliminas una plantilla de restricción, ya no puedes crear restricciones que hagan referencia a ella.
Siguientes pasos
- Consulta más información sobre Policy Controller.
- Consulta la documentación de referencia de la biblioteca de plantillas de restricciones.
- Consulta cómo usar restricciones en lugar de PodSecurityPolicies.