Criando e debugando secrets no Kubernetes

Criar e debugar Secrets no Kubernetes pode ser um tarefa sensível mas às vezes essencial para o dia a dia ao manter uma aplicação, pois é crucial garantir que as informações que devem ser mantidas em segredo estão corretas e de fato chegando os pods, para que sua aplicação funcione da maneira correta.

A seguir vamos explicar como criar, manter e debugar secrets no Kubernetes, mas um ponto de dúvida é o que são Secrets, e o que diferenciam elas de de um ConfigMap.

O que é Secret

Uma Secret na verdade tem uma funcionalidade bem parecida com os ConfigMap, elas armazenam valores que podem ser utilizados por outros recursos dentro do cluster, a diferença é que no ConfigMap os valores ficam expostos, qualquer usuário do cluster que simplesmente usa um describe no ConfigMap consegue ver os valores armazenados, já em uma Secret não, os valores ficam codificados, por uma questão de segurança é uma boa prática armazenar informações como credenciais ou qualquer tipo de informação sensível utilizando-se desse recurso.

Como criar uma Secret

Temos algumas opções quando precisamos criar uma Secret, abaixo demonstro algumas dessas formas:

Criar a partir de valores específicos

kubectl create secret generic nome-da-secret \
--from-literal=chave1="valor1" \
--from-literal=chave2="valor2"
Terminal

Lembre-se que na criação você deve substituir “nome-da-secret”, “chave1”, “valor1”, “chave2”, “valor2” pelos nomes e valores que você deseja, e esse número não se limita a duas informações você pode utilizar quantas forem necessárias.

Criar a partir de um arquivo

kubectl create secret generic credenciais --from-file=/caminho-do-arquivo.txt
Terminal

Criar a partir de um arquivo manifesto YAML

Exemplo de arquivo:

apiVersion: v1
kind: Secret
metadata:
  name: credenciais
data:
  username: QXJ0ZWZhdG8gWA== # Valor codificado em base64
  password: MTIzNDU2 # Valor codificado em base64
secret.yml

Comando para aplicar o arquivo manifesto:

kubectl apply -f secret.yml
Terminal

Nesse caso nomeamos o nosso arquivo manifesto como “secret.yml”, mas isso não é necessário, o nome do arquivo pode ser de sua preferência, desde que você faça a referencia certa quando for fazer o comando para aplicar.

Note que para criar a partir de um arquivo manifesto, você precisa previamente codificar seus valores para Base64, é possível fazer essa conversão usando o próprio terminal, abaixo mostramos como fazer isso em terminais de diferentes sistemas operacionais:

Codificando texto em Base64 pelo terminal

Ambientes baseados em Unix (Linux, MacOs, etc)

echo -n "valor a ser codificado" | base64
Terminal

Ambiente Windows PowerShell

[Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("valor a ser codificado"))
Terminal

Ambiente Windows CMD

echo “valor a ser codificado” | certutil -encodebase64 -
Terminal

Listando e exibindo suas Secrets

Você pode verificar se a Secret foi criada corretamente listando todas as Secrets criadas com o comando abaixo:

kubectl get secrets
Terminal

E pode ver detalhes de uma Secret específica através do comando describe, segue o exemplo:

kubectl describe secret "nome-da-secret"
Terminal

Excluindo uma Secret

Caso haja a necessidade de excluir uma Secret podemos facilmente fazer utilizando o comando abaixo, mas lembre-se, a exclusão é irreversível, cuidado ao executar esse comando em ambientes produtivos, pois pode prejudicar o ambiente caso algum outro recurso utilize-se desse para o funcionamento.

kubectl delete secret "nome-da-secret"
Terminal

Utilizando Secrets nos Pods

Para utilizar Secrets nos Pods é bem simples, podemos utilizar a abordagem de transformar cada par chave/valor em uma variável de ambiente, seguindo a seguinte abordagem:

apiVersion: v1
kind: Pod
metadata:
  name: nome-do-pod
spec:
  containers:
  - name: nome-do-container
    image: minha-imagem
    envFrom:
    - secretRef:
          name: nome-da-secret
pod.yml

Dessa forma cada aplicação presente nos contêineres dentro do Pod pode ter acesso capturando o valor como variável de ambiente pelo nome da chave.

Debugando Secrets

Agora que aprendemos a criar, listar e exibir, note que mesmo quando exibimos a nossa Secret, as informações de valor de cada chave não são exibidas também, pois as mesma encontram-se codificadas, essa é a grande diferença em utilizar-se de Secret ao invés de ConfigMap.

Para exibir as informações de cada chave precisamos utilizar de outros comandos, a seguir vamos mostrar os comandos e para exemplificar criamos uma Secret com o nome “credenciais” que contém duas chaves “usuario” e “senha” e seus respectivos valores.

Listando chaves e valores

Para exibir todas as chaves e valores que contém a nossa Secret vamos utilizar o comando abaixo que vai exibir ela no formato json.

kubectl get secret "nome-da-secret" -o json
Terminal

Exemplo de saída, para o comando com a nossa Secret criada anteriormente.

{
    "apiVersion": "v1",
    "data": {
        "senha": "MTIzNDU2",
        "usuario": "QXJ0ZWZhdG8gWA=="
    },
    "kind": "Secret",
    "metadata": {
        "creationTimestamp": "2023-11-28T14:41:27Z",
        "name": "credenciais",
        "namespace": "default",
        "resourceVersion": "3091",
        "uid": "bae0cd6f-626e-4d44-b83f-c00a508b3555"
    },
    "type": "Opaque"
}
JSON

Note que mesmo exibindo dessa forma os valores das chaves estão codificados em base64 ainda, podemos copiar cada um desses valores e utilizar os comandos de terminal que já aprendemos na sessão anterior para decodificar, ou podemos utilizar um comando que já fará isso para uma chave específica, como vamos demonstrar a seguir:

Exibindo o valor de uma chave específica

Comando para exibir o valor de uma chave, já decodificando em base64:

kubectl get secret credenciais -o jsonpath=’{data.nome-da-chave}’ | base64 –decode
Terminal

Para o nosso exemplo o comando ficaria assim:

kubectl get secret credenciais -o jsonpath=’{data.usuario}’ | base64 –decode
Terminal

Veja que dessa forma podemos recuperar todos os valores, presentes na nossa Secret.

Criando um pod para debug

Uma opção interessante para fazer o debug dos valores, é criar um pod com um container de teste, assim é possível verificar os valores que estão chegando ao pod, e ao container respectivamente, para fazer esse tipo de debug vamos criar um arquivo manifesto YAML, que utiliza a nossa Secret, veja o exemplo:

apiVersion: v1
kind: Pod
metadata:
  name: test-secret-pod
spec:
  containers:
  - name: test-container
    image: busybox
    command: ["/bin/sh", "-c", "env"]
    envFrom:
      - secretRef:
          name: credenciais
test-secret-pod.yml

Após a criação do arquivo precisamos aplicá-lo, vamos fazer isso através do comando apply:

kubectl apply -f test-secret-pod.yml
Terminal

Após a criação do nosso pod de teste, vamos utilizar o comando para verificar os logs, pois o que o container dentro do pod faz é executar o comando para listar as variáveis de ambiente, se estiver criado corretamente, veremos as nossas secrets chegando como variáveis dentro do container:

Comando para verificar os logs do pod:

kubectl logs test-secret-pod
Terminal

Exemplo de saída do comando:

KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.96.0.1:443
HOSTNAME=test-secret-pod
SHLVL=1
HOME=/root
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
senha=123456
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_SERVICE_HOST=10.96.0.1
PWD=/
usuario=Artefato X
Terminal

Note que nas linhas 10 e 15 estão listados a chave e o valor que nós inserimos na criação da nossa Secret.

Lembre-se de substituir os valores, pelos nomes corretos utilizados no seu ambiente, no nosso exemplo criamos o pod com o nome de “test-secret-pod”, mas essa escolha é livre você pode criar com o nome que for mais conveniente no seu ambiente.

Como vimos a criação e o debug de Secrets no Kubernetes não é tão complicado, lembre-se sempre de tomar cuidado com as informações sensíveis principalmente em ambientes produtivos, certifique-se de sempre seguir as melhores práticas para gerenciamento de recursos dentro do Kubernetes.

Links uteis

Mauricio Lima
Mauricio Lima

Bacharel em Ciência da Computação, profissional dedicado ao desenvolvimento de software e entusiasta da tecnologia.

Artigos: 65