Esta página mostra-lhe como escrever um modelo de restrição personalizado e usá-lo para expandir o Policy Controller se não conseguir encontrar um modelo de restrição pré-escrito que se adeque às suas necessidades.
Esta página destina-se a administradores de TI e operadores que querem garantir que todos os recursos executados na plataforma de nuvem cumprem os requisitos de conformidade da organização, fornecendo e mantendo a automatização para auditar ou aplicar, e usar modelos de configuração declarativa. Para saber mais sobre as funções comuns e as tarefas de exemplo que referimos no conteúdo, consulte o artigo Funções e tarefas comuns do utilizador do GKE. Google Cloud
As políticas do Policy Controller são descritas através da estrutura de restrições do OPA e são escritas em Rego. Uma política pode avaliar qualquer campo de um objeto Kubernetes.
Escrever políticas com o Rego é uma competência especializada. Por este motivo, é instalada uma biblioteca de modelos de restrições comuns por predefinição. É provável que possa invocar estes modelos de restrições quando criar restrições. Se tiver necessidades especializadas, pode criar os seus próprios modelos de restrições.
Os modelos de restrições permitem-lhe separar a lógica de uma política dos respetivos requisitos específicos para reutilização e delegação. Pode criar restrições através de modelos de restrições desenvolvidos por terceiros, como projetos de código aberto, fornecedores de software ou especialistas regulamentares.
Antes de começar
- Instale o Policy Controller.
Exemplo de modelo de restrição
Segue-se um exemplo de um modelo de restrição que nega todos os recursos cujo nome corresponda a um valor fornecido pelo criador da restrição. O resto desta página aborda o conteúdo do modelo, destacando conceitos importantes ao longo do processo.
Se estiver a usar a sincronização de configuração com um repositório hierárquico, recomendamos que crie as 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])
}
Exemplo de restrição
Segue-se um exemplo de uma restrição que pode implementar para recusar todos os recursos denominados 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ções têm duas partes importantes:
O esquema da restrição que quer que os utilizadores 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 de um modelo é armazenado no campo
targets
.
Esquema (campo crd
)
O campo CRD é um modelo para criar a definição de recursos personalizados do Kubernetes que define o recurso de restrição para o servidor da API Kubernetes. Só tem de preencher os seguintes campos.
Campo | Descrição |
---|---|
spec.crd.spec.names.kind |
O tipo de restrição. Quando convertido em minúsculas, o valor
deste campo tem de ser igual a metadata.name . |
spec.crd.spec.validation.openAPIV3Schema |
O esquema do campo |
Adicionar o prefixo K8s
ao modelo de restrição é uma convenção que lhe permite evitar colisões com outros tipos de modelos de restrições, como modelos do Forseti que segmentam recursos Google Cloud .
Código-fonte Rego (campo targets
)
As secções seguintes fornecem mais informações sobre o código fonte do Rego.
Localização
O código fonte Rego é armazenado no campo spec.targets
, onde targets
é uma matriz de objetos do seguinte formato:
{"target": "admission.k8s.gatekeeper.sh","rego": REGO_SOURCE_CODE, "libs": LIST_OF_REGO_LIBRARIES}
target
: indica ao Policy Controller o sistema que estamos a analisar (neste caso, o Kubernetes); só é permitida uma entrada emtargets
.rego
: o código-fonte da restrição.libs
: uma lista opcional de bibliotecas de código Rego que é disponibilizada ao modelo de restrição; destina-se a facilitar a utilização de bibliotecas partilhadas e está fora do âmbito deste documento.
Código fonte
Segue-se o código-fonte 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])
}
Tenha em conta o seguinte:
- O campo
package k8sdenynames
é obrigatório para o OPA (tempo de execução do Rego). O valor é ignorado. - A regra Rego que o Policy Controller invoca para verificar se existem violações chama-se
violation
. Se esta regra tiver correspondências, ocorreu uma violação da restrição. - A regra
violation
tem a assinaturaviolation[{"msg": "violation message for the user"}]
, em que o valor de"msg"
é a mensagem de violação devolvida ao utilizador. - Os parâmetros fornecidos à restrição são disponibilizados na palavra-chave
input.parameters
. - O
request-under-test
é armazenado na palavra-chaveinput.review
.
A palavra-chave input.review
tem os seguintes campos.
Campo | Descrição |
---|---|
uid |
O ID exclusivo deste pedido específico. Não está disponível durante a auditoria. |
kind |
As informações de tipo para o
|
name |
O nome do recurso. Pode estar vazio se o utilizador estiver a usar o servidor da API para gerar o nome num pedido CREATE. |
namespace |
O espaço de nomes do recurso (não fornecido para recursos com âmbito de cluster). |
operation |
A operação pedida (por exemplo, CREATE ou UPDATE) não está disponível durante a auditoria. |
userInfo |
As informações do utilizador que está a fazer o pedido. Não estão disponíveis durante a auditoria. Tem o seguinte formato:
|
object |
O objeto que o utilizador está a tentar modificar ou criar. |
oldObject |
O estado original do objeto; só está disponível em operações UPDATE. |
dryRun |
Se este pedido foi invocado com kubectl --dry-run ;
não está disponível durante a auditoria. |
Escreva modelos de restrições referenciais
Os modelos de restrições referenciais são modelos que permitem ao utilizador restringir um objeto relativamente a outros objetos. Um exemplo disto pode ser "não permitir a criação de um Pod antes de se saber que existe um Ingress correspondente". Outro exemplo pode ser "não permitir que dois serviços tenham o mesmo nome de anfitrião".
O Policy Controller permite-lhe escrever restrições referenciais monitorizando o servidor de API para um conjunto de recursos fornecido pelo utilizador. Quando um recurso é modificado, o Policy Controller armazena-o em cache localmente para que possa ser facilmente referenciado pelo código fonte Rego. O Policy Controller disponibiliza esta cache através da palavra-chave data.inventory
.
Os recursos com âmbito de cluster são colocados em cache na seguinte localização:
data.inventory.cluster["GROUP_VERSION"]["KIND"]["NAME"]
Por exemplo, um nó com o nome my-favorite-node
pode ser encontrado em
data.inventory.cluster["v1"]["Node"]["my-favorite-node"]
Os recursos com âmbito do espaço de nomes são colocados em cache aqui:
data.inventory.namespace["NAMESPACE"]["GROUP_VERSION"]["KIND"]["NAME"]
Por exemplo, um ConfigMap denominado production-variables
no espaço de nomes shipping-prod
pode ser encontrado em
data.inventory.namespace["shipping-prod"]["v1"]["ConfigMap"]["production-variables"]
O conteúdo completo do objeto é armazenado nesta localização da cache e pode ser referenciado no seu código-fonte Rego da forma que considerar mais adequada.
Mais informações sobre o Rego
As informações anteriores fornecem as funcionalidades únicas do Policy Controller que facilitam a escrita de restrições em recursos do Kubernetes no Rego. Um tutorial completo sobre como escrever em Rego está fora do âmbito deste guia. No entanto, a documentação do Open Policy Agent tem informações sobre a sintaxe e as funcionalidades da própria linguagem Rego.
Instale o modelo de restrição
Depois de criar o modelo de restrição, use kubectl apply
para o aplicar e o Policy Controller encarrega-se de o carregar. Certifique-se de que verifica o campo status
do modelo de restrição para se certificar de que não ocorreram erros
na respetiva instanciação. Após a carregamento bem-sucedido, o campo status
deve apresentar created: true
e o valor observedGeneration
indicado no campo status
deve ser igual ao valor do campo metadata.generation
.
Depois de o modelo ser carregado, pode aplicar restrições ao mesmo, conforme descrito no artigo Criar restrições.
Remova um modelo de restrição
Para remover um modelo de restrição, conclua os seguintes passos:
Verifique se não existem restrições que queira preservar a usar o modelo de restrição:
kubectl get TEMPLATE_NAME
Se existir 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 remove um modelo de restrição, deixa de poder criar restrições que façam referência ao mesmo.
O que se segue?
- Saiba mais acerca do Policy Controller.
- Veja a documentação de referência da biblioteca de modelos de restrições.
- Saiba como usar restrições em vez de PodSecurityPolicies.