Kubernetes Role Base Access Control
Raramente você tem a oportunidade de projetar um cluster produtivo e entre as muitas tarefas que devem ser realizadas está a correta configuração da autenticação e autorização dos diferentes usuários do cluster.
Neste artigo veremos o fluxo pelo qual passa uma solicitação do usuário ao invocar um comando usando a CLI do kubectl
e como ele consegue passar pelos principais mecanismos de segurança da AWS e do Kubernetes para, finalmente, executar corretamente.
Antes de começar, vamos definir de forma breve e informal alguns termos que usaremos.
Autenticação: É o processo de saber que o usuário é quem afirma ser.
Autorização: É o processo para saber se uma ação é permitida.
Em um artigo futuro falaremos mais sobre esses dois conceitos, mas por enquanto com essas definições já temos o suficiente para poder acompanhar o processo entre AWS e Kubernetes.
Kubernetes
O Kubernetes é uma plataforma que gerencia ou orquestra de forma semiautomática contêineres do tipo Docker para que um serviço esteja sempre disponível. Os usuários interagem com esta plataforma principalmente por 2 formas:
- A API do Kubernetes.
- A CLI
kubectl
.
Como qualquer plataforma de gerenciamento de recursos, é importante ter um mecanismo de segurança que nos diga quem pode executar determinadas ações e quem não pode.
O Kubernetes foi projetado para rodar na nuvem, ou seja, dentro de plataformas que fornecem infraestrutura e ferramentas para configurá-lo. Por esta razão, o Kubernetes não possui um sistema de autenticação, mas delega o processo de autenticação de um usuário à plataforma onde reside um cluster. Por outro lado, possui uma longa lista de ações que você pode executar nos recursos internos de um cluster. Como essas ações e recursos são internos a um cluster, cabe ao Kubernetes ter um modelo de quem pode executar uma determinada ação em um recurso. O modelo que o Kubernetes usa por padrão é o RBAC (Role Based Access Control), que usa funções que, por sua vez, são atribuídas aos usuários para determinar o conjunto de ações permitidas para esse usuário.
Amazon Web Services
Existem vários provedores de serviços em nuvem, embora hoje os mais famosos sejam AWS, GCP e Azure. Geralmente usamos um deles para criar nosso cluster, mas a ideia básica será a mesma, independentemente do provedor de nuvem que escolhermos.
Neste artigo vamos focar na AWS cujo serviço Kubernetes é chamado de EKS.
Autenticação de um usuário
Para entender como o processo de autenticação e autorização interagem, vamos percorrer o fluxo com um exemplo simples. No diagrama a seguir observamos o que acontece internamente quando queremos executar uma ação usando a CLI de kubectl
(espanhol):
Para que este fluxo seja executado corretamente, alguns requisitos devem existir:
1) Primeiro você deve configurar corretamente o usuário da AWS. Para isso devem ter as seguintes políticas:
"Action": [
"eks:AccessKubernetesAPI",
"eks:DescribeCluster",
"eks:ListCluster",
],
"Effect": "Allow",
"Resource": [
"arn:aws:..."
]
Com essas permissões, informamos à AWS que qualquer pessoa que assumir a função poderá realizar as ações listadas nessas regras.
Resource
devemos inserir o ARN do nosso cluster.2) Agora temos que configurar nossa CLI kubectl
para que você possa se comunicar com nosso cluster. Nesse caso, como a AWS é quem faz a autenticação do usuário, precisamos fazer o kubectl
primeiro obtenha as informações necessárias para acessar o cluster. Felizmente, a AWS CLI facilita muito para nós.
Primeiro, precisamos ter certeza de que a CLI está configurada para assumir a função que estamos usando. Isso vai depender do tipo de login que fazemos. Normalmente, o seguinte comando deve ser suficiente:
aws configure
Então você tem que executar o seguinte comando:
aws eks list-cluster
Isso listará os clusters aos quais temos acesso. É por isso que precisamos da permissão ListClusters em nossa função da AWS. Assim que tivermos o nome do cluster ao qual queremos nos conectar, devemos configurar kubectl
com o seguinte comando:
aws eks update-kubeconfig --name <nombre_del_cluster>
Este comando cria uma entrada no arquivo ~/.kube/config
que indica que para acessar o cluster, um token deve ser obtido usando a AWS CLI. Tudo isso acontece automaticamente, então não devemos nos preocupar.
Com essas etapas anteriores, kubectl
você estará pronto para poder se comunicar com nosso cluster no EKS.
Fluxo de autorização
Com o processo anterior resolvido, podemos garantir que nosso comando chegue ao plano de controle do nosso cluster Kubernetes, mas ainda precisamos que o cluster autorize a ação, que neste exemplo é get pods
.
Nossa requisição já passou para o domínio Kubernetes, que no caso da AWS é chamado de EKS.
O EKS por meio do plano de controle primeiro precisa saber quais permissões o usuário possui e, para obter isso, o EKS usa um ConfigMap específico chamado aws-auth, que contém uma lista de associações entre funções da AWS e usuários ou grupos.
apiVersion: v1
kind: ConfigMap
metadata:
name: aws-auth
namespace: kube-system
data:
mapRoles: |
- rolearn: <ARN del role>
username: <usuario_del_cluster>
groups:
- <lista_de_grupos>
Os detalhes que devemos levar em conta ao editar este config map são:
- O ARN da função deve ter um formato específico:
arn:aws:iam::<cuenta>:role/mi role
- Em
username
normalmente indicamos um nome de usuário para que nos logs ou registros identifiquemos as ações realizadas por esse usuário. - Em
groups
, criamos uma lista de nomes de grupos. Usaremos esses nomes de grupos posteriormente para poder associar uma função ao usuário.
Resumindo, o que este ConfigMap faz é associar um usuário interno e/ou um ou mais grupos ao usuário cuja função AWS é aquela especificada no campo rolearn
.
O cluster então verifica os RoleBindings registrados para descobrir se algum deles está vinculando um usuário ou um grupo a uma função.
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: mi-rolebinding
namespace: default
subjects:
- kind: Group
name: monitoreo
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: role-solo-lectura
apiGroup: rbac.authorization.k8s.io
Deve-se levar em conta que dentro do campo subjets
podemos especificar um ou mais grupos e/ou usuários e no campo name
devemos colocar o nome do grupo que utilizamos no aws-auth ConfigMap.
Finalmente, o EKS procura o papel referido no RoleBinding, pois dentro dele estão definidas as permissões que esse papel terá.
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: role-solo-lectura
rules:
- apiGroups: [""]
resources: ["*"]
verbs: ["get", "watch", "list"]
- apiGroups: ["apps"]
resources: ["*"]
verbs: ["get", "watch", "list"]
Esta função de exemplo define duas regras em que, na primeira, são concedidas permissões para executar as ações get
, watch
e list
para todos os recursos do apiGroup
padrão (principalmente pods). No segundo, a mesma permissão é dada, mas para os apiGroup apps
onde normalmente encontramos os Deployments
.
Quando o EKS encontra a função associada correta, ele já pode decidir se deve executar a ação solicitada pelo usuário, neste caso get pods .
Vamos recapitular
kubectl
usa a AWS CLI para poder assumir uma função da AWS. Este é o processo de autenticação.- A função da AWS deve ter permissões para poder usar o EKS.
- Dentro do cluster deve haver 3 elementos que são usados para o processo de autorização:
- A associação da função AWS com um grupo no ConfigMap
aws-auth
. - Um RoleBinding que associa um grupo ou usuário a um Role.
- Uma Função que contém as permissões que queremos que um grupo ou usuário tenha.
Deve-se lembrar que no Kubernetes, Roles e RoleBindings se aplicam a um namespace específico. No entanto, também existem ClusterRoles e ClusterRoleBindings que, ao contrário dos anteriores, aplicam regras de autorização no nível do cluster.
Até a próxima!
A Revelo Content Network acolhe todas as raças, etnias, nacionalidades, credos, gêneros, orientações, pontos de vista e ideologias, desde que promovam diversidade, equidade, inclusão e crescimento na carreira dos profissionais de tecnologia.