Entendendo roles no kubernetes
Tags: kubernetes, devops, eks, sysops
Published: 2024-03-10 19:03:36

Você sabe a diferença entre role, rolebinding, clusterrole e clusterrolebinding? todos esses objetos fazem parte do conceito de [RBAC](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) do kubernetes, vale a pena entende-los para cuidarmos da segurança de um cluster. No começo pode ser um pouco confuso pois temos vários conceitos e objetos novos, mas neste artigo vamos esclarecer o que é cada um.

---

## **TEORIA**


&nbsp;
**ROLE**
Um objeto do tipo role no kubernetes é a especificação de permissões para determinadas ações sobre determinados objetos, para um namespace específico.

**ROLEBINDING**
O objeto rolebinding é o responsável por vincular uma ou mais roles a uma serviceaccount em um determinado namespace, quem usar esta serviceaccount terá as permissões que a role informada permite.

**CLUSTERROLE**
Ja o objetivo clusterrole é semelhante a role, porém esse tipo de role abrange o cluster como um todo e não se limita a um namespace especifico.

**CLUSTERROLEBINDING**
Serve para fazer o vinculo entre o clusterrole e quem poderá utilizar as permissões descritas no mesmo, seja uma serviceaccount, grupo ou usuário.

---

## **PRÁTICA COM ROLE E ROLEBINDING**

> _Para a prática utilizei o [minikube](https://minikube.sigs.k8s.io/docs/)._

&nbsp;
**Cenário:** vamos supor que temos um processo que irá deletar deployments nginx em um determinado namespace, nesse namespace não queremos nada de nginx. Esse nosso processo deve ficar dentro do seu próprio namespace (jobs) e o deployment do nginx, se existir, em outro namespace (test).

Vamos criar os namespaces, para isso, execute os comandos:

```
kubectl create namespace jobs
kubectl create namespace test
```
Agora vamos criar nosso cronjob que ficara no namespace jobs e irá deletar deployments nginx do namespace test, esse cronjob ira executar de acordo com o schedule, para escolher um período ajuste o campo schedule, para mais info sobre cron expression [clique aqui](https://kubernetes.io/docs/concepts/workloads/controllers/cron-jobs/#writing-a-cronjob-spec). Abaixo segue o manifesto do cronjob:

```
apiVersion: batch/v1
kind: CronJob
metadata:
  name: audit
  namespace: jobs
spec:
  schedule: "* * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: audit
            image: bitnami/kubectl
            command:
            - "bin/bash"
            - "-c"
            - "kubectl delete deployment nginx -n test"
          restartPolicy: Never
```

> _Utilize o comando kubectl apply -f [nome do arquivo manifesto] para criar os objetos._

Com nosso cronjob criado, vamos criar um deployment nginx no namespace test para ver se o cronjob irá deleta-lo mesmo, utilize o comando abaixo para criar o deployment:

```
kubectl create deployment nginx --image nginx -n test
```
Vamos ver se nosso cronjob já conseguiu excluir o deployment que criamos? se executarmos um kubectl get pod -n test veremos que o pod do deployment nginx continua lá:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4085t1oq33d9e9x96svl.png)

consultando os pods do cronjob com um kubectl get pod -n jobs, os pods aparecem com erro:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hjcvze5nbishixorkxo3.png)

ao executar o comando logs em um dos pods, recebemos a seguinte mensagem:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ejdf5ophgel3em61ylkn.png)

Isso acontece justamente pela falta de permissão, nosso cronjob tentou utilizar a [serviceaccount](https://kubernetes.io/docs/concepts/security/service-accounts/) default e esta não tem permissão para deletar deployments no namespace test, vamos corrigir isso, para começar vamos criar uma [serviceaccount](https://kubernetes.io/docs/concepts/security/service-accounts/):
```
apiVersion: v1
kind: ServiceAccount
metadata:
  name: jobs-sa 
  namespace: jobs
```

Agora vamos criar a nossa role:
```
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: audit-job-role
  namespace: test
rules:
  - apiGroups: [""]
    resources: ["pods"]
    verbs: ["get", "list", "create"]
  - apiGroups: ["extensions"]
    resources: ["deployments"]
    verbs: ["get", "list", "create", "delete"]
  - apiGroups: ["apps"]
    resources: ["deployments"]
    verbs: ["get", "list", "create", "delete"]
```

Como falamos no começo do artigo, precisamos vincular esta role a serviceaccount e para isso usamos o objeto rolebinding:
```
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: audit-job-rolebinding
  namespace: test
subjects:
  - kind: ServiceAccount
    name: jobs-sa
    namespace: jobs
roleRef:
  kind: Role
  name: audit-job-role
  apiGroup: rbac.authorization.k8s.io
```
Depois de criarmos todos esses objetos, nosso cronjob precisa de uma atualização, precisamos informar a serviceaccount que ele deverá utilizar, para isso, atualize o manifesto conforme abaixo:
```
apiVersion: batch/v1
kind: CronJob
metadata:
  name: audit
  namespace: jobs
spec:
  schedule: "* * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          serviceAccountName: jobs-sa
          containers:
          - name: audit
            image: bitnami/kubectl
            command:
            - "bin/bash"
            - "-c"
            - "kubectl delete deployment nginx -n test"
          restartPolicy: Never
```

Agora, estamos informando qual serviceaccount deverá ser usada, e com isso nosso cronjob executa com sucesso:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uywyo4tmpgbxpj3ppv23.png)

Se buscarmos por deployments no nosso namespace test, não encontraremos mais o nginx:
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hjj8zq1tr9xxm4rrk4r3.png)

&nbsp;
E com isso terminamos nossa prática com role e rolebinding, vale lembrar que quando criamos a [role](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#role-example), [rolebinding](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#clusterrole-example) e [serviceaccount](https://kubernetes.io/docs/concepts/security/service-accounts/) nós informamos o namespace, ou seja, tudo limitado a escopo de namespace, para não termos essa limitação podemos utilizar os objetos [clusterrole](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#clusterrole-example) e [clusterrolebinding](https://kubernetes.io/docs/reference/access-authn-authz/rbac/#clusterrolebinding-example).

---

**CONCLUSÕES FINAIS**
o RBAC é um poderoso mecanismo para controlarmos o acesso em um cluster kubernetes, é possível de forma detalhada refinar os acessos que cada usuário ou aplicação tem dentro do cluster. Os exemplos dados aqui foram apenas para demonstrar conceitos básicos de permissão em um cluster kubernetes, vale consultar a [documentação oficial](https://kubernetes.io/docs/reference/access-authn-authz/rbac/) para se aprofundar no assunto.

**Espero que tenham gostado, até a próxima!!**