Como criar restrições

Este tópico mostra como definir restrições do Policy Controller.

Visão geral

O Policy Controller permite impor a política para um cluster Kubernetes definindo um ou mais objetos de restrição. Depois que uma restrição é instalada, as solicitações ao servidor da API são comparadas com a restrição e serão rejeitadas se não estiverem em conformidade. Recursos não compatíveis pré-existentes serão relatados no tempo de auditoria.

Cada restrição é apoiada por um modelo de restrição que define o esquema e a lógica da restrição. Os modelos de restrição podem ser originários do Google, de terceiros ou você pode escrever seus próprios. Consulte Como escrever um modelo de restrição para mais informações sobre a criação de novos modelos.

Antes de começar

Como usar a biblioteca de modelos de restrição

Quando você define uma restrição, especifica o modelo de restrição que ela estende. Uma biblioteca de modelos de restrição comuns desenvolvidos pelo Google é instalada por padrão e muitas organizações não precisam criar modelos de restrição personalizados diretamente no Rego. Os modelos de restrição fornecidos pelo Google têm o rótulo configmanagement.gke.io/configmanagement. Para listá-los, use o seguinte comando:

kubectl get constrainttemplates \
  -l="configmanagement.gke.io/configmanagement=config-management"

Para descrever um modelo de restrição e verificar seus parâmetros necessários:

kubectl describe constrainttemplate [CONSTRAINT-TEMPLATE-NAME]

Você pode ver todos os modelos de restrição na biblioteca.

Como definir uma restrição

Você define uma restrição usando o YAML e não precisa entender ou escrever o Rego. Em vez disso, uma restrição chama um modelo de restrição e fornece parâmetros específicos para a restrição.

  • O kind em minúsculas corresponde ao nome de um modelo de restrição.
  • O metadata.name é o nome da restrição.
  • O campo match define a quais objetos a restrição se aplica. Todas as condições especificadas precisam ser correspondidas antes que um objeto esteja no escopo de uma restrição. As condições match são definidas pelos seguintes subcampos:
    • kinds são os tipos de recursos aos quais a restrição se aplica, determinados por dois campos: apiGroups é uma lista de grupos de APIs do Kubernetes que corresponderão e kinds é uma lista de tipos que corresponderão. "*" corresponde a tudo. Se pelo menos uma entrada de apiGroup e uma kind corresponder, a condição kinds será atendida.
    • namespaces é uma lista de nomes de namespace aos quais o objeto pode pertencer. O objeto precisa pertencer a pelo menos um desses espaços para nome. Os recursos de namespace são tratados como se pertencessem a eles mesmos.
    • excludedNamespaces é uma lista de namespaces aos quais o objeto não pode pertencer.
    • labelSelector é um seletor de rótulo do Kubernetes que o objeto precisa atender.
    • namespaceSelector é um seletor de rótulo no namespace ao qual o objeto pertence. Se o namespace não atender ao objeto, ele não corresponderá. Os recursos de namespace são tratados como se pertencessem a eles mesmos.
  • O campo parameters define os argumentos para a restrição, com base no que o modelo de restrição espera.

A restrição a seguir, chamada ns-must-have-geo, chama um modelo de restrição chamado K8sRequiredLabels, incluído na biblioteca de modelos de restrição fornecida pelo Google. A restrição define parâmetros que o modelo de restrição usa para avaliar se os namespaces têm o rótulo geo definido com algum valor.

# ns-must-have-geo.yaml

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
  name: ns-must-have-geo
spec:
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Namespace"]
  parameters:
    labels:
      - key: "geo"

Para criar a restrição, aplique-a usando kubectl apply -f:

kubectl apply -f ns-must-have-geo.yaml

Como auditar uma restrição

Se a restrição estiver configurada e instalada corretamente, seu campo status.byPod[].enforced será definido como true, se a restrição estiver configurada para forçar ou testar a restrição.

As restrições são impostas por padrão, e uma violação de uma restrição impede uma determinada operação de cluster. Você pode definir spec.enforcementAction como dryrun de uma restrição para relatar violações no campo status.violations sem impedir a operação.

Para saber mais sobre auditoria, consulte Como fazer auditoria usando restrições

Advertências ao sincronizar restrições

Lembre-se das seguintes advertências ao sincronizar restrições.

Consistência eventual

Você pode confirmar restrições ao repo e pode limitar seus efeitos usando ClusterSelectors ou NamespaceSelectors. Como a sincronização é eventualmente consistente, lembre-se das seguintes advertências:

  • Se uma operação de cluster acionar uma restrição cujo NamespaceSelector se refira a um namespace que não foi sincronizado, a restrição será aplicada e a operação será evitada. Em outras palavras, um namespace ausente "falha ao fechar".
  • Se você alterar os rótulos de um namespace, o cache poderá conter dados desatualizados por um breve período.

Minimize a necessidade de renomear um namespace ou alterar os respectivos rótulos e teste as restrições que afetam um namespace renomeado ou remarcado para garantir que funcionem conforme o esperado.

Configurar o Policy Controller para restrições referenciais

Antes de habilitar restrições referenciais, você precisa criar um Config que informe ao Policy Controller quais tipos de objetos precisam ser observados, como namespaces.

Salve o seguinte manifesto YAML em um arquivo e aplique-o com kubectl. O manifesto configura o Policy Controller para assistir a namespaces e entradas. Crie uma entrada com group, version e kind em spec.sync.syncOnly, com os valores para cada tipo de objeto que você quer assistir.

apiVersion: config.gatekeeper.sh/v1alpha1
kind: Config
metadata:
  name: config
  namespace: "gatekeeper-system"
spec:
  sync:
    syncOnly:
      - group: ""
        version: "v1"
        kind: "Namespace"
      - group: "extensions"
        version: "v1beta1"
        kind: "Ingress"

Como ativar restrições referenciais

Uma restrição referencial refere-se a outro objeto na definição. Por exemplo, você pode criar uma restrição que exija que os objetos do Ingress em um cluster tenham nomes de host exclusivos. A restrição é referencial se o modelo de restrição contiver a cadeia data.inventory no Rego.

Restrições referenciais são desativadas por padrão no Policy Controller. Restrições referenciais só são garantidas como com consistência posterior e isso cria riscos:

  • Em um servidor de API sobrecarregado, o conteúdo do cache do Policy Controller pode ficar desatualizado, causando uma restrição referencial de "falha ao abrir", o que significa que a ação de imposição parece estar funcionando quando não está. Por exemplo, você pode criar Ingresses com nomes de host duplicados muito rapidamente para permitir que o controlador de admissão detecte as duplicatas.

  • A ordem na qual as restrições são instaladas e a ordem na qual o cache é atualizado são aleatórias.

Se você entende esses riscos e ainda quer ativar o suporte a restrições referenciais, defina policyController.referentialRulesEnabled como true no objeto Operator:

apiVersion: configmanagement.gke.io/v1
kind: ConfigManagement
metadata:
  name: config-management
  namespace: config-management-system
spec:
  clusterName: my-cluster
  channel: dev
  policyController:
    enabled: true
    referentialRulesEnabled: true

Como listar todas as restrições

Para listar todas as restrições instaladas em um cluster, use kubectl.

kubectl get constraint

Como remover uma restrição

Para localizar todas as restrições usando um modelo de restrição, liste todos os objetos com o mesmo kind que o metadata.name do modelo de restrição:

kubectl get [CONSTRAINT-TEMPLATE-NAME]

Para remover uma restrição, especifique kind e name:

kubectl delete [CONSTRAINT-TEMPLATE-NAME] [CONSTRAINT-NAME]

Se você quer excluir o modelo de restrição que a restrição estava usando, anote o kind da restrição.

Quando você remove uma restrição, ela deixa de ser aplicada assim que o servidor da API marca a restrição como excluída.

Como remover todos os modelos de restrição

Defina spec.policyController.templateLibraryInstalled como false. Isso impede que o Operator reinstale automaticamente a biblioteca.

Para remover todos os modelos de restrição e todas as restrições:

kubectl delete constrainttemplate --all

Como restaurar a biblioteca de modelos de restrições

Se você desabilitou a biblioteca de modelos de restrição ou desinstalou todos os modelos de restrição, é possível restaurá-la definindo spec.policyController.templateLibraryInstalled como true na configuração do Operator.

A seguir