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 acerca das funções comuns e das tarefas de exemplo que referimos no Google Cloud conteúdo, consulte o artigo Funções e tarefas comuns de utilizadores do GKE.
As políticas do Policy Controller são descritas através da estrutura de restrições da 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 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ção, 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 em- targets.
- 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 violationtem 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.