|
Este documento foi traduzido usando tecnologia de tradução automática de máquina. Sempre trabalhamos para apresentar traduções precisas, mas não oferecemos nenhuma garantia em relação à integridade, precisão ou confiabilidade do conteúdo traduzido. Em caso de qualquer discrepância, a versão original em inglês prevalecerá e constituirá o texto official. |
|
Esta é uma documentação não divulgada para Admission Controller 1.34-dev. |
Migrando Políticas do Gatekeeper para SUSE Security Admission Controller
Este guia mostra como converter uma política existente do Gatekeeper em uma política SUSE Security Admission Controller. Este processo envolve duas etapas principais: . Compile o programa Rego em um módulo WebAssembly (Wasm). . Distribua o módulo WebAssembly como uma política Admission Controller.
O tutorial de políticas Rego cobre a maior parte do processo de construção para compilar o código Rego em um módulo WebAssembly. Este guia foca no processo passo a passo de extrair as Definições de Recursos Personalizados (CRDs) do Gatekeeper e migrá-las para uma política Admission Controller funcional. Ele utiliza uma política de demonstração básica do Gatekeeper.
Pré-requisitos
-
opa: você usa esta ferramenta para compilar o código em wasm. Este guia foi escrito usando a versão
v1.5.1. -
kwctl: ferramenta que você usa para preparar e executar o módulo de WebAssembly Admission Controller. -
bats: ferramenta usada para executar testes de ponta a ponta. Se você decidir escrever esse tipo de teste -
yq: ferramenta usada para extrair dados de arquivos yaml.
Antes de migrar suas políticas
Antes de iniciar o processo de migração das políticas do Gatekeeper, considere usar políticas já disponíveis no Admission Controller catalog. Algumas das políticas são políticas OPA e Gatekeeper publicamente disponíveis migradas para Admission Controller.
Além disso, dê uma olhada na nossa documentação de comparação entre Admission Controller e Gatekeeper.
Etapa 1: Inicialize seu projeto de política Admission Controller
Primeiro, use o Gatekeeper Admission Controller modelo para criar uma estrutura básica de projeto de política. Isso fornece alvos Makefile para construir e testar sua política. Após criar o código da política a partir do modelo, execute os comandos do Makefile para verificar se a política é construída e os testes são executados com sucesso:
$ make policy.wasm test
opa build -t wasm -e policy/violation -o bundle.tar.gz policy.rego
tar xvf bundle.tar.gz /policy.wasm
tar: Removing leading `/' from member names
/policy.wasm
rm bundle.tar.gz
touch policy.wasm # opa creates the bundle with unix epoch timestamp, fix it
opa test *.rego
PASS: 2/2
Etapa 2: Migrar o código da política do Gatekeeper
Agora, comece a migrar a política do Gatekeeper. Isso envolve converter um
ConstraintTemplate e seus recursos associados Constraint em uma política Admission Controller. Em um contexto Admission Controller, considere o ConstraintTemplate como o código kernel da política, enquanto as instâncias Constraint se traduzem em instâncias de política executando dentro de Admission Controller.
Primeiro, copie o código Rego do seu ConstraintTemplate para o arquivo policy.rego que foi gerado pelo template Admission Controller. Para este exemplo, você deve usar a seguinte política de demonstração demo policy do repositório do Gatekeeper.
YAML da política do Gatekeeper
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
name: k8srequiredlabels
spec:
crd:
spec:
names:
kind: K8sRequiredLabels
validation:
# Schema for the `+parameters+` field
openAPIV3Schema:
type: object
properties:
labels:
type: array
items:
type: string
targets:
- target: admission.k8s.gatekeeper.sh
rego: |
package k8srequiredlabels
violation[{"msg": msg, "details": {"missing_labels": missing}}] {
provided := {label | input.review.object.metadata.labels[label]}
required := {label | label := input.parameters.labels[_]}
missing := required - provided
count(missing) > 0
msg := sprintf("you must provide labels: %v", [missing])
}
Copie o trecho de código Rego do campo rego para o seu arquivo policy.rego:
cat gatekeeper/demo/basic/templates/k8srequiredlabels_template.yaml | yq ".spec.targets[0].rego" > policy.rego
Adaptar o código Rego para Admission Controller
Você precisa garantir que o nome package usado dentro do código Rego seja policy.
Este é o valor esperado em muitos lugares pelo modelo do Gatekeeper Admission Controller.
Se você não alterá-lo, terá erros ao construir a política e executar seus testes de ponta a ponta.
Por exemplo, a política de demonstração que estamos convertendo está definida dentro do pacote k8srequiredlabels, esse valor deve ser alterado para policy.
É assim que o conteúdo do arquivo policy.rego deve ser:
package policy
violation[{"msg": msg, "details": {"missing_labels": missing}}] {
provided := {label | input.review.object.metadata.labels[label]}
required := {label | label := input.parameters.labels[_]}
missing := required - provided
count(missing) > 0
msg := sprintf("you must provide labels: %v", [missing])
}
Tentar construir o código após essa alteração pode revelar novos erros de compilação:
opa build -t wasm -e policy/violation -o bundle.tar.gz policy.rego
error: load error: 2 errors occurred during loading:
policy.rego:3: rego_parse_error: `+if+` keyword is required before rule body
policy.rego:3: rego_parse_error: `+contains+` keyword is required for partial set rules
make: *** [Makefile:4: policy.wasm] Error 1
O autor da política deve corrigir esses erros para permitir que o CLI opa construa o
código com sucesso. As mudanças específicas podem variar dependendo da versão opa e do código de política original. Como estamos migrando uma política rego anterior ao OPA v1, precisamos atualizar o código para ser compatível com a v1. O código final policy.rego fica assim:
package policy
violation contains {"msg": msg, "details": {"missing_labels": missing}} if {
provided := {label | input.review.object.metadata.labels[label]}
required := {label | label := input.parameters.labels[_]}
missing := required - provided
count(missing) > 0
msg = sprintf("you must provide labels: %v", [missing])
}
Depois de ajustar o código, construa a política:
$ make policy.wasm
opa build -t wasm -e policy/violation -o bundle.tar.gz policy.rego
tar xvf bundle.tar.gz /policy.wasm
tar: Removing leading `/' from member names
/policy.wasm
rm bundle.tar.gz
touch policy.wasm # opa creates the bundle with unix epoch timestamp, fix it
Há mais informações sobre como construir políticas do Gatekeeper em nosso tutorial.
Código da política Rego e compatibilidade com OPA v1.0.0
Com o lançamento do OPA (Agente de Política Aberta) v1.0.0 em dezembro de 2024, uma mudança significativa foi introduzida em relação à sintaxe da política Rego.
Anteriormente, if para todas as definições de regras e contains para regras de múltiplos valores eram opcionais; agora, são obrigatórios. Essa mudança afeta a maioria das políticas mais antigas.
Aqui está um resumo do que você precisa saber:
-
OPA v1.0.0 Syntax: O OPA v1.0.0 exige o uso de
ifpara todas as definições de regras econtainspara regras de múltiplos valores. Políticas que não aderirem a essa sintaxe irão falhar. -
Compatibilidade Retroativa: Se você precisar construir políticas mais antigas que não utilizam a nova sintaxe v1.0.0, deve fornecer a flag
--v0-compatibleao comandoopa build. -
Integração do Gatekeeper: O Gatekeeper atualizou sua dependência do OPA para v1.0.0 em sua versão v3.19.0.
-
Versão do Rego nos templates do Gatekeeper: O Gatekeeper assume que a sintaxe
v0é utilizada, a menos que o template especifique explicitamenteversion: "v1"no camposourcesobcode.engine: Rego.
Veja esta seção da documentação do Gatekeeper para mais detalhes sobre como as versões v0 e v1 do Rego são tratadas.
O que isso significa para você:
-
Se o Gatekeeper CR não especificar uma versão do Rego, isso implica que
v0será usado. Você deve construir a política usando o comandoOPA_V0_COMPATIBLE=true make. -
Se o Gatekeeper CR especificar explicitamente
version: "v1", você deve construir a política sem nenhuma variável de ambiente definida.
Etapa 3: Atualizar e executar os testes
Embora seja altamente recomendado, os autores de políticas podem pular a criação de testes para a versão inicial de uma política. Se isso se aplica a você, precisará desativar os alvos do Makefile usados para executar os testes. Você não pode remover esses alvos completamente, pois os trabalhos padrão de CI esperam que eles estejam definidos. Em vez disso, você deve substituir os comandos que chamam opa e bats por uma operação "no-op". Por exemplo, você pode usar um comando echo para imprimir uma explicação do porquê os testes não estão sendo executados.
O template Admission Controller do Gatekeeper inclui tanto testes unitários de Rego quanto testes de ponta a ponta (e2e) usando Bats e kwctl. Se você planeja incluir testes, ambos os conjuntos precisam ser adaptados para sua política.
Se sua política do Gatekeeper já possui testes de Rego, você pode copiá-los para o arquivo policy_test.rego. Esses são executados automaticamente quando você executa o comando make test.
|
Tenha em mente que quaisquer testes de Rego que você escrever em |
A política que você está migrando neste guia não possui testes; precisamos adicioná-los nós mesmos. Portanto, vamos atualizar o arquivo de teste policy_test.rego com alguns testes básicos:
package policy
review_required_labels := {
"parameters": {"labels": ["test"]},
"review": {"object": {"metadata": {"labels": {"test": "value"}}}},
}
review_missing_labels := {
"parameters": {"labels": ["test"]},
"review": {"object": {"metadata": {"labels": {"other": "value"}}}},
}
test_accept if {
r = review_required_labels
res = violation with input as r
count(res) = 0
}
test_reject if {
r = review_missing_labels
res = violation with input as r
count(res) = 1
}
Agora, executar make test deve validar sua política:
$ make policy.wasm test
opa build -t wasm -e policy/violation -o bundle.tar.gz policy.rego
tar xvf bundle.tar.gz /policy.wasm
tar: Removing leading `/' from member names
/policy.wasm
rm bundle.tar.gz
touch policy.wasm # opa creates the bundle with unix epoch timestamp, fix it
opa test *.rego
PASS: 2/2
Em seguida, atualize o arquivo de testes e2e (e2e.bats):
#!/usr/bin/env bats
@test "accept because required label is present" {
run kwctl run -e gatekeeper annotated-policy.wasm --settings-path test_data/settings.json --request-path test_data/accept_deploy_request.json
# this prints the output when one the checks below fails
echo "output = ${output}"
# request accepted
[ "$status" -eq 0 ]
[ $(expr "$output" : '.*allowed.*true') -ne 0 ]
}
@test "reject because required label is missing" {
run kwctl run -e gatekeeper annotated-policy.wasm --settings-path test_data/settings.json --request-path test_data/reject_deploy_request.json
# this prints the output when one the checks below fails
echo "output = ${output}"
# request rejected
[ "$status" -eq 0 ]
[ $(expr "$output" : '.*allowed.*false') -ne 0 ]
[ $(expr "$output" : '.*message.*you must provide labels: \[test\]') -ne 0 ]
}
Você precisará criar os arquivos test_data/settings.json, test_data/accept_deploy_request.json e test_data/reject_deploy_request.json para suportar esses testes.
test_data/settings.json
{
"labels": ["test"]
}
Não incluiremos o conteúdo completo de accept_deploy_request.json e reject_deploy_request.json aqui, pois AdmissionRequest JSON pode ser bastante longo, e queremos manter este guia conciso. No entanto, você pode usar o comando kwctl scaffold para gerar esses arquivos. A chave para este guia é que uma solicitação deve estar sem o rótulo necessário, enquanto a outra deve ter o rótulo definido.
Verifique se os testes e2e estão passando:
$ make e2e-tests
bats e2e.bats
e2e.bats
✓ accept because required label is present
✓ reject because required label is missing
|
Os parâmetros da política (por exemplo, rótulos neste exemplo) originam-se das configurações da política. Isso permite que você implante várias instâncias da mesma política com diferentes parâmetros/configurações, semelhante a como Constraints funcionam no Gatekeeper. |
Etapa 4: Prepare metadata.yml para distribuição
Agora que você tem uma política funcional, prepare o arquivo metadata.yml para distribuição. Este arquivo define anotações com a descrição da política, autor, licença e outras informações essenciais. Crucialmente, ele define o rules que especifica quais recursos e verbos a política pode validar. Esta informação direciona o comando kwctl scaffold para gerar o manifesto para implantar a política em seu cluster.
Os CRDs Constraints do Gatekeeper, que são instâncias de políticas definidas em ConstraintTemplates, especificam quais recursos uma instância de política avalia.
Portanto, se você tiver Constraints existentes que aplicam um ConstraintTemplate, eles oferecem uma boa referência para os recursos que você deve definir em seu arquivo metadata.yml. Por exemplo, no exemplo do Gatekeeper usado anteriormente, o K8sRequiredLabels Constraint criado a partir do k8srequiredlabels ConstraintTemplate se aplica a Namespaces:
apiVersion: constraints.gatekeeper.sh/v1beta
kind: K8sRequiredLabels
metadata:
name: ns-must-have-gk
spec:
match:
kinds:
- apiGroups: [""]
kinds: ["Namespace"]
parameters:
labels: ["gatekeeper"]
Com base nisso, atualize a seção rules do seu metadata.yml para incluir um novo rule para validar namespaces durante as operações de CREATE e UPDATE:
rules:
- apiGroups: ["apps"]
apiVersions: ["v1"]
resources: ["deployments"]
operations: ["CREATE", "UPDATE"]
- apiGroups: [""]
apiVersions: ["v1"]
resources: ["namespaces"]
operations: ["CREATE", "UPDATE"]
mutating: false
contextAware: false
executionMode: gatekeeper
backgroundAudit: true
annotations:
io.artifacthub.displayName: Policy Name
io.artifacthub.resources: Pod
io.artifacthub.keywords: pod, cool policy, kubewarden
io.kubewarden.policy.ociUrl: ghcr.io/yourorg/policies/policy-name
io.kubewarden.policy.title: policy-name
io.kubewarden.policy.version: 0.0.1-unreleased
io.kubewarden.policy.description: Short description
io.kubewarden.policy.author: "Author name <author-email@example.com>"
io.kubewarden.policy.url: https://github.com/yourorg/policy-name
io.kubewarden.policy.source: https://github.com/yourorg/policy-name
io.kubewarden.policy.license: Apache-2.0
io.kubewarden.policy.severity: medium
io.kubewarden.policy.category: Resource validation
Agora, sua política está pronta para distribuição e implantação. Consulte a seção Publicando a política do tutorial para aprender como enviá-la para um registro remoto.
Você pode criar o manifesto da política usando kwctl:
$ kwctl scaffold manifest --type ClusterAdmissionPolicy annotated-policy.wasm
apiVersion: policies.kubewarden.io/v1
kind: ClusterAdmissionPolicy
metadata:
annotations:
io.kubewarden.policy.category: Resource validation
io.kubewarden.policy.severity: medium
name: policy-name
spec:
module: file:///home/jvanz/SUSE/mygatekeeperpolicy/annotated-policy.wasm
settings: {}
rules:
- apiGroups:
- apps
apiVersions:
- v1
resources:
- deployments
operations:
- CREATE
- UPDATE
- apiGroups:
- ''
apiVersions:
- v1
resources:
- namespaces
operations:
- CREATE
- UPDATE
mutating: false
Defina Configurações da Política
Esta política tem parâmetros, que o Gatekeeper define dentro do Constraint. Você precisa atualizar a seção settings no manifesto de política gerado Admission Controller para incluir esses parâmetros obrigatórios. No exemplo a seguir, além de definir as configurações, você pode testar a política a partir do registro OCI:
apiVersion: policies.kubewarden.io/v1
kind: ClusterAdmissionPolicy
metadata:
annotations:
io.kubewarden.policy.category: Resource validation
io.kubewarden.policy.severity: medium
name: policy-name
spec:
module: registry://ghcr.io/jvanz/policies/mygatekeeperpolicy:latest
settings:
labels:
- "gatekeeper"
rules:
- apiGroups:
- apps
apiVersions:
- v1
resources:
- deployments
operations:
- CREATE
- UPDATE
- apiGroups:
- ""
apiVersions:
- v1
resources:
- namespaces
operations:
- CREATE
- UPDATE
mutating: false
Tente implantar um namespace sem o rótulo obrigatório gatekeeper:
kubectl apply -f - <<EOF
apiVersion: v1
kind: Namespace
metadata:
name: your-namespace-name
labels:
purpose: demo
EOF
Error from server: error when creating "STDIN": admission webhook "clusterwide-policy-name.kubewarden.admission" denied the request: you must provide labels: [gatekeeper]
E outro namespace com o rótulo obrigatório:
kubectl apply -f - <<EOF
apiVersion: v1
kind: Namespace
metadata:
name: your-namespace-name
labels:
purpose: demo
gatekeeper: test
EOF
namespace/your-namespace-name created