Pare de sofrer com REGO, vá de YAML
A criação de políticas de Segurança no Kubernetes é uma busca incessante da área de Segurança para evitar que incidentes exponham os negócios a riscos, como o de vazamento de dados.Até aí, a gente sabe que o negócio é aplicar políticas de segurança nos clusters Kubernetes para impedir ao máximo qualquer exposição a riscos e, no mercado, há várias alternativas de Security Policies para isso: OPA, Gatekeeper, Syra, AWS Opa, Azure Policy e etc.No entanto, o desafio para nós, kuberneteiros de plantão, está em implementar e manter essas políticas na linguagem em que estão escritas, REGO. Por estarmos acostumados a trabalhar com YAML, ferramentas que usam uma nova linguagem, nesse caso REGO, só dificultam a nossa vida! É como dar um passo para trás no que que estamos fazendo para aprender uma nova linguagem e, daí, aplicá-la nas políticas de segurança do cluster K8s.Cansado de sofrer com isso, fui atrás de uma saída e achei o Kyverno. O Kyverno é um controller de Kubernetes capaz de criar a sua própria política de segurança com YAML.Ainda, se mudar de cloud provider, as suas regras já farão parte de seu CI/CD ou de um backup velero ou, no pior cenário, nos YAMLS files do seu diretório escondido no seu drive. Em resumo, é fácil de escrever, entender, ficam num único lugar e podem migrar de cloud provider ou, até mesmo, para on-premise, evitando o lock-in com as operadoras cloud.Você consegue quase tudo com o Kyverno, veja só:
Bloquear remoção de resources, principalmente, o próprio Kyverno;
Rastrear o que estão executando que possa infringir na segurança dos nós;
Automatizar e policiar a criação de labels pra cobrar $$ dos times, quando for um K8s multi tenant;
Automatizar a criação de Network Policy e quem pode mexer nelas;
Bloquear o uso de recursos específicos, por exemplo, só quero que subam Ingress usando meu ingress-nginx ou o meu kong e o traefik são só do time X;
Automagicamente saber que qualquer deploy tem que ter um mínimo de:. recursos de cpu/memória. labels. réplicas
Distribuir secrets e configmaps para qualquer namespace criado;
Restringir uso de services LoadBalancer e/ou NodePort;
Impossibilitar a galera de subir coisas no namespace Default;
Forçar todo recurso a usar tag nas imagens e sempre do mesmo registry;
Aplicar NetworkPolicy quando um novo namespace é criado;
Criar um namespace, gerar todas as políticas e gerar um report do que é aplicado.
Ainda, dá para gerar relatórios de infração, inspeção e aplicação — tudo em YAML — para você extrair com aquele “-o json” e brincar de converter pra HTML. Tem CLI pra quem gosta também.Instalando o Kyverno
Quer instalar o Kyverno, brincar com políticas iniciais e ver como funciona?
A instalação não é intrusiva! Nada vai parar, nenhum erro vai ser gerado pela instalação e não há regra default que force qualquer política. Isso é, pode aplicar o Kyverno no seu cluster de produção, pois ele vai gerar no máximo policies reports indicando onde existe problema a ser tratado, com base nas regras default que não interferem, só aferem. Quer instalar o Kyverno, brincar com políticas iniciais e ver como funciona?Apenas atente-se para o fato de que quanto mais workloads você tem em seu cluster, mais recursos de cpu e memória seu Kyverno vai precisar para analisar, gerar e manter políticas e reports. Se for seu caso, aumente esses valores no deploy do Kyverno.Vamos ao que interessa!Você vai precisar:
* kubectl
* helm => 3.23
* 1 cluster k8s
* git
* kyverno cli, https://kyverno.io/docs/kyverno-cli/ (opcional, só se quiser mesmo, para validar politicas, etc)$ helm repo add kyverno https://kyverno.github.io/kyverno/
Verifique se o pod do Kyverno está instalado:
A partir desse momento, o “get cpol” vai trazer as políticas aplicadas ao cluster, no âmbito de cluster.O “get polr -A” trará os reports por namespaces, se você tiver namespaces criados e com workloads em execução.Veja que todas as políticas criadas por default estão em audit na coluna action, ou seja, só auditam os workloads. A partir do momento em que se deseja que se apliquem e impeçam alguma execução ou configuração, basta alterar a regra validationFailureAction: enforce e isso impedirá o próximo pod de seguir “quebrando a política”.
Aplique essa política:
Verifique nos logs do pod do Kyverno e nos objetos de ClusterPolicy:
Aqui, já se observa que nossa regra exigindo as labels informadas sejam aplicadas a qualquer workload em qualquer namespace, com exceção dos namespaces app1, kube-system e workloads-x.
Crie um deploy de teste:
Perceba aqui que só criei uma label app.kubernetes.io/name: web, o que não satisfaz na íntegra minha política recém-criada.
Para visualizar as auditorias FAIL dos reports, execute:
(...)O policyReport vai mostrar o service kubernetes e o namespace default com a mesma falta de labels que indicamos na política. Se essa política estiver enforce, então será obrigatória a adição dessas labels nesses resources e o pod não será criado até ser resolvida essa pendência.
Existem dezenas de outras políticas que podem ser aplicadas no quesito cluster, o que não te impede de aplicá-las somente a um namespace específico, usando o kind: ClusterPolicy ou para namespace, usando o Kind: Policy. Elas estão disponíveis em https://github.com/kyverno/policies.Uma que gosto bastante é a que limita a utilização de recursos e obriga todo pod a obedecer uma regra pré-definida de resources limits/requests:
Com isso, qualquer pod, em qualquer namespace, com exceção do Kube-system, terá que declarar a utilização de resources e, ainda, respeitar os limites para requests e limits. Como diria meu irmão: “existem mil maneiras de preparar Neston, invente a sua”.
Baseando-se nos modelos e exemplos do repositório e na documentação, fica fácil criarmos as políticas que precisamos aplicar, sem precisar aprender uma nova linguagem ou nos debruçar sobre vários recursos do K8s para troubleshooting ou evolução.
É isso aí, galera! Recomendo que corram pra se atualizar. Kyverno é uma maravilha e a curva de aprendizado é de algumas horas.
Qualquer dúvida, sugestão ou crítica, podem me chamar: adonai@getup.io.