Esta página mostra como gravar um modelo de restrição personalizado e usá-lo para estender o Policy Controller se você não encontrar um modelo de restrição pré-gravado que se adapte às suas necessidades.
As políticas do controlador de políticas são descritas usando a biblioteca de restrições de OPA e são programadas em Rego (links em inglês). Uma política pode avaliar qualquer campo de um objeto Kubernetes.
Escrever políticas usando o Rego é uma habilidade especializada. Por esse motivo, uma biblioteca de modelos de restrição comuns é instalada por padrão. Você provavelmente pode invocar esses modelos de restrição ao criar restrições. Se você tiver necessidades especializadas, poderá criar seus próprios modelos de restrição.
Os modelos de restrição permitem separar a lógica de uma política dos requisitos específicos para reutilização e delegação. É possível criar restrições usando modelos de restrição desenvolvidos por terceiros, como projetos de código aberto, fornecedores de software ou especialistas em regulamentação.
Antes de começar
- Instalar o Policy Controller
Modelo de restrição de exemplo
Veja a seguir um modelo de restrição de exemplo que nega todos os recursos cujo nome corresponde a um valor fornecido pelo criador da restrição. O restante desta página discute o conteúdo do modelo, destacando conceitos importantes.
Se você estiver usando o Config Sync com um
repositório hierárquico,
recomendamos criar suas restrições no diretório 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])
}
Restrição de exemplo
Veja a seguir uma restrição de exemplo que pode ser implementada para negar todos os
recursos chamados policy-violation
:
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sDenyName
metadata:
name: no-policy-violation
spec:
parameters:
invalidName: "policy-violation"
Partes de um modelo de restrição
Os modelos de restrição têm duas partes importantes:
O esquema da restrição que você quer que os usuários criem. O esquema de um modelo de restrição é armazenado no campo
crd
.O código-fonte Rego que é executado quando a restrição é avaliada. O código fonte Rego para um modelo é armazenado no campo
targets
.
Esquema (campo crd
)
O campo CRD é um modelo para criar a Definição de Recurso Personalizado do Kubernetes que define o recurso de restrição para o servidor da API Kubernetes. Você só precisa preencher os seguintes campos:
Campo | Descrição |
---|---|
spec.crd.spec.names.kind |
O tipo da restrição. Quando em minúsculas, o valor
desse campo precisa ser igual a metadata.name . |
spec.crd.spec.validation.openAPIV3Schema |
O esquema do campo |
Prefixo do modelo de restrição com nome K8s
é uma convenção que
permite evitar conflitos com outros tipos de modelos de restrição, como
modelos do Forseti que segmentam recursos do Google Cloud.
Código-fonte original (campo targets
)
As seções a seguir fornecem mais informações sobre o código-fonte do Rego.
Local
O código-fonte do Rego é armazenado no campo spec.targets
, em que targets
é uma matriz de objetos no seguinte formato:
{"target": "admission.k8s.gatekeeper.sh","rego": REGO_SOURCE_CODE, "libs": LIST_OF_REGO_LIBRARIES}
target
: informa ao Controlador de Políticas qual sistema estamos conferindo (neste caso, Kubernetes); apenas uma entrada emtargets
é permitida.rego
é o código-fonte da restrição.libs
: uma lista opcional de bibliotecas do código do Rego que é disponibilizada para o modelo de restrição. Ele foi desenvolvido para facilitar o uso de bibliotecas compartilhadas e está fora do escopo deste documento.
Código-fonte
Veja a seguir o código-fonte do Rego para a restrição 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])
}
Observe o seguinte:
package k8sdenynames
é requerido pelo OPA (ambiente de execução do Rego). O valor é ignorado.- A regra Rego que o Policy Controller chama para verificar se há alguma
violação é chamada
violation
. Se essa regra tiver correspondências, ocorreu uma violação da restrição. - A regra
violation
tem a assinaturaviolation[{"msg": "violation message for the user"}]
, onde o valor de"msg"
é a mensagem de violação retornada ao usuário. - Os parâmetros fornecidos à restrição são disponibilizados sob a palavra-chave
input.parameters
. - O
request-under-test
é armazenado sob a palavra-chaveinput.review
.
A palavra-chave input.review
tem os campos a seguir.
Campo | Descrição |
---|---|
uid |
O ID exclusivo dessa solicitação. Não fica disponíveis durante a auditoria. |
kind |
As informações de Tipo de
|
name |
O nome do recurso. É possível que ela esteja vazia se o usuário depende do servidor de API para gerar o nome em uma solicitação CREATE. |
namespace |
O namespace do recurso (não fornecido para recursos com escopo no cluster). |
operation |
A operação solicitada (por exemplo, CREATE ou UPDATE). Não ficam disponíveis durante a auditoria. |
userInfo |
As informações do usuário solicitante. Não é possível fazer isso durante a auditoria. Ele tem o seguinte formato:
|
object |
O objeto que o usuário está tentando modificar ou criar |
oldObject |
O estado original do objeto. Está disponível somente nas operações UPDATE. |
dryRun |
Se esta solicitação foi invocada com kubectl --dry-run
Ela não estará disponível durante a auditoria. |
Escrever modelos de restrição referencial
Modelos de restrição referencial são modelos que permitem ao usuário restringir um objeto em relação a outros objetos. Um exemplo disso pode ser "não permita que um pod seja criado antes que se saiba que existe uma entrada correspondente". Outro exemplo pode ser "não permitir que dois serviços tenham o mesmo nome de host".
O Policy Controller permite que você escreva restrições referenciais observando o
servidor de API para conseguir um conjunto de recursos fornecidos pelo usuário. Quando um recurso é modificado,
o Policy Controller o armazena em cache localmente, para que possa ser facilmente referenciado pelo
código-fonte Rego. O Policy Controller disponibiliza esse cache com a
palavra-chave data.inventory
.
Os recursos com escopo definido em cluster são armazenados em cache no seguinte local:
data.inventory.cluster["GROUP_VERSION"]["KIND"]["NAME"]
Por exemplo, um nó chamado my-favorite-node
pode ser encontrado em
data.inventory.cluster["v1"]["Node"]["my-favorite-node"]
Recursos com namespace são armazenados em cache aqui:
data.inventory.namespace["NAMESPACE"]["GROUP_VERSION"]["KIND"]["NAME"]
Por exemplo, um ConfigMap chamado production-variables
no namespace shipping-prod
pode ser encontrado em
data.inventory.namespace["shipping-prod"]["v1"]["ConfigMap"]["production-variables"]
O conteúdo completo do objeto é armazenado nesse local de cache e pode ser referenciado no seu Rego da maneira que você achar melhor.
Mais informações sobre Rego
As informações anteriores fornecem os recursos exclusivos do Policy Controller que facilitam a gravação de restrições nos recursos do Kubernetes no Rego. Um tutorial completo sobre como programar no Rego está fora do escopo deste guia. No entanto, a documentação do agente de política aberta tem informações sobre a sintaxe e os recursos da própria linguagem Rego.
Instalar seu modelo de restrição
Depois de criar o modelo de restrição, use kubectl apply
para aplicá-lo.
O Policy Controller cuidará do processamento. Verifique o campo status
do seu modelo de restrição para garantir que não haja erros ao
instancia-lo. Na ingestão bem-sucedida, o campo status
precisa mostrar
created: true
e o observedGeneration
anotado no campo status
precisa
ser igual ao campo metadata.generation
.
Depois que o modelo é ingerido, você pode aplicar restrições, conforme descrito em Como criar restrições.
Remover um modelo de restrição
Para remover um modelo de restrição, siga estas etapas:
Verifique se nenhuma restrição que você quer preservar está usando o modelo de restrição:
kubectl get TEMPLATE_NAME
No caso de um conflito de nomenclatura entre o nome do modelo de restrição e um objeto diferente no cluster, use o seguinte comando:
kubectl get TEMPLATE_NAME.constraints.gatekeeper.sh
Remova o modelo de restrição:
kubectl delete constrainttemplate CONSTRAINT_TEMPLATE_NAME
Quando você remove um modelo de restrição, não é mais possível criar restrições que o referenciem.
A seguir
- Saiba mais sobre o Policy Controller.
- Veja a documentação de referência da biblioteca de modelos de restrição.
- Saiba como usar restrições em vez de PodSecurityPolicies.