En esta página, se muestra cómo escribir una plantilla de restricciones personalizada y usarla para extender el controlador de políticas si no puedes encontrar una plantilla de restricciones escrita previamente que se adapte a tus necesidades.
Esta página está destinada a los administradores de TI y operadores que desean asegurarse de que todos los recursos que se ejecutan dentro de la plataforma en la nube cumplan con los requisitos de cumplimiento de la organización. Para ello, deben proporcionar y mantener la automatización para auditar o aplicar el cumplimiento, y usar plantillas de configuración declarativa. Para obtener más información sobre los roles comunes y las tareas de ejemplo a las que hacemos referencia en el contenido de Google Cloud , consulta Tareas y roles comunes de los usuarios de GKE Enterprise.
Las políticas del controlador de políticas 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 mediante el uso de Rego es una habilidad especializada. Por esta razón, se instala una biblioteca de plantillas de restricciones comunes de forma predeterminada. Es probable que puedas invocar estas plantillas de restricciones cuando crees 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 su reutilización y delegación. Puedes crear restricciones si usas plantillas de restricciones desarrolladas por terceros, como proyectos de código abierto, proveedores de software o expertos en las normativas.
Antes de comenzar
- Instala Policy Controller.
Plantilla de restricciones de ejemplo
A continuación, se muestra una plantilla de restricciones de ejemplo que niega todos los recursos cuyo nombre coincide con un valor proporcionado por el creador de la restricción. En el resto de esta página, se analiza el contenido de la plantilla y se destacan los conceptos importantes.
Si usas el Sincronizador de configuración 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])
}
Restricción de ejemplo
A continuación, se muestra una restricción de ejemplo que puedes 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 restricciones
Las plantillas de restricciones tienen dos piezas importantes:
El esquema de la restricción que deseas que creen los usuarios. El esquema de una plantilla de restricciones 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 modelo para crear la definición de recursos personalizados de Kubernetes que define el recurso de restricción para el servidor de la API de Kubernetes. Solo debes propagar los siguientes campos.
Campo | Descripción |
---|---|
spec.crd.spec.names.kind |
Es el tipo de la restricción. Cuando está en minúsculas, el valor de este campo debe ser igual a metadata.name . |
spec.crd.spec.validation.openAPIV3Schema |
El esquema para el campo |
Prefijar la plantilla de restricciones con el nombre K8s
es una convención que te permite evitar colisiones con otros tipos de plantillas de restricciones, como las plantillas de Forseti dirigidas a recursos de Google Cloud .
Código fuente de Rego (campo targets
)
En las siguientes secciones, se proporciona 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
, en el que targets
es un arreglo de objetos con el siguiente formato:
{"target": "admission.k8s.gatekeeper.sh","rego": REGO_SOURCE_CODE, "libs": LIST_OF_REGO_LIBRARIES}
target
: Le indica a Policy Controller qué sistema observamos (en este caso, Kubernetes). Solo se permite una entrada entargets
.rego
: Es el código fuente de la restricción.libs
: Es una lista opcional de bibliotecas de código de Rego que está disponible para la plantilla de restricciones. Tiene como objetivo facilitar el uso de las bibliotecas compartidas y está fuera del alcance de este documento.
Código fuente
A continuación, se muestra el código fuente de Rego para 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 requerido por OPA (entorno de ejecución de Rego). Se ignora el valor.- La regla de Rego que invoca el controlador de políticas para ver si hay alguna infracción se llama
violation
. Si esta regla tiene coincidencias, se produjo una infracción de la restricción. - La regla
violation
tiene la firmaviolation[{"msg": "violation message for the user"}]
, en la que el valor de"msg"
es el mensaje de infracción que se muestra al usuario. - Los parámetros proporcionados a la restricción están disponibles con la palabra clave
input.parameters
. request-under-test
se almacena con la palabra claveinput.review
.
La palabra clave input.review
tiene los siguientes campos.
Campo | Descripción |
---|---|
uid |
Es el ID único para esta solicitud específica. No está disponible durante la auditoría. |
kind |
Es la información del tipo para
|
name |
Es el nombre del recurso. Puede estar vacío si el usuario depende del servidor de la API para generar el nombre en una solicitud CREATE. |
namespace |
Es el espacio de nombres del recurso (no se proporcionado para los recursos con permisos para clústeres). |
operation |
Es la operación solicitada (por ejemplo, CREATE o UPDATE). No está disponible durante la auditoría. |
userInfo |
Es la información del usuario solicitante. No está disponible durante la auditoría. Tiene el siguiente formato:
|
object |
Es el objeto que el usuario intenta modificar o crear. |
oldObject |
Es el estado original del objeto. Solo está disponible en las operaciones UPDATE. |
dryRun |
Indica si esta solicitud se invoca con kubectl --dry-run . No está disponible durante la auditoría. |
Escribe plantillas de restricciones referenciales
Las plantillas de restricciones referenciales son plantillas que permiten al usuario restringir un objeto con respecto a otros. Un ejemplo de esto podría ser “no permitir que se cree un Pod antes de que se sepa que existe una entrada coincidente”. Otro ejemplo podría ser “no permitir que dos servicios tengan el mismo nombre de host”.
El controlador de políticas te permite escribir restricciones referenciales si miras el servidor de la API para un conjunto de recursos proporcionado por el usuario. Cuando se modifica un recurso, el controlador de políticas lo almacena en caché de forma local para que el código fuente de Rego pueda hacer referencia a él con facilidad. El controlador de políticas hace que esta caché esté disponible con la palabra clave data.inventory
.
Los recursos con permisos de clústeres se almacenan en caché en la siguiente ubicación:
data.inventory.cluster["GROUP_VERSION"]["KIND"]["NAME"]
Por ejemplo, se puede encontrar un nodo llamado my-favorite-node
en esta ubicación:
data.inventory.cluster["v1"]["Node"]["my-favorite-node"]
Los recursos con permisos de espacios 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
podría encontrarse en la siguiente ubicación:
data.inventory.namespace["shipping-prod"]["v1"]["ConfigMap"]["production-variables"]
El contenido completo del objeto se almacena en esta ubicación de caché y se puede hacer referencia a él en el código fuente de Rego como creas necesario.
Más información sobre Rego
En la información anterior, se proporcionan las características únicas del controlador de políticas que facilitan la escritura de restricciones en los recursos de Kubernetes en Rego. Está fuera del alcance de esta guía, proporcionar un instructivo completo sobre cómo escribir en Rego. Sin embargo, en la documentación del agente de políticas abiertas, se incluye información sobre la sintaxis y las funciones del lenguaje de Rego.
Instala tu plantilla de restricciones
Después de crear la plantilla de restricción, usa kubectl apply
para aplicarla y el controlador de políticas se encargará de transferirla. Asegúrate de verificar el campo status
de la plantilla de restricciones para asegurarte de que no haya errores durante la creación de instancias. En una transferencia exitosa, el campo status
debe mostrar created: true
y el observedGeneration
anotado en el campo status
debe ser igual al campo metadata.generation
.
Después de que se haya transferido la plantilla, puedes aplicarle restricciones como se describe en Crea restricciones.
Quita una plantilla de restricciones
Para quitar una plantilla de restricciones, completa los siguientes pasos:
Verifica que ninguna restricción que desees conservar use la plantilla de restricciones:
kubectl get TEMPLATE_NAME
Si hay un conflicto de nomenclatura entre el nombre de la plantilla de restricciones y un objeto diferente en el clúster, puede usar el siguiente comando en su lugar:
kubectl get TEMPLATE_NAME.constraints.gatekeeper.sh
Quita la plantilla de restricciones a continuación:
kubectl delete constrainttemplate CONSTRAINT_TEMPLATE_NAME
Cuando quitas una plantilla de restricciones, ya no podrás crear restricciones que hagan referencia a ella.
¿Qué sigue?
- Obtén más información sobre el Controlador de políticas.
- Consulta la documentación de referencia de la biblioteca de plantillas de restricciones.
- Aprende cómo usar restricciones en lugar de PodSecurityPolicies.