website/content/pt-br/docs/concepts/configuration/secret.md

1421 lines
54 KiB
Markdown

---
title: Secrets
content_type: concept
feature:
title: Secrets e gerenciamento de configuração
description: >
Crie e atualize Secrets e configurações da aplicação sem reconstruir sua imagem
de contêiner e sem expor credenciais na configuração da sua aplicação.
weight: 30
---
<!-- overview -->
Um Secret é um objeto que contém uma pequena quantidade de informação sensível,
como senhas, tokens ou chaves. Este tipo de informação poderia, em outras
circunstâncias, ser colocada diretamente em uma configuração de
{{< glossary_tooltip term_id="pod" >}} ou em uma
{{< glossary_tooltip text="imagem de contêiner" term_id="image" >}}. O uso de
Secrets evita que você tenha de incluir dados confidenciais no seu código.
Secrets podem ser criados de forma independente dos Pods que os consomem. Isto
reduz o risco de que o Secret e seus dados sejam expostos durante o processo de
criação, visualização e edição ou atualização de Pods. O Kubernetes e as
aplicações que rodam no seu cluster podem também tomar outras precauções com
Secrets, como por exemplo evitar a escrita de dados confidenciais em local de
armazenamento persistente (não-volátil).
Secrets são semelhantes a
{{< glossary_tooltip text="ConfigMaps" term_id="configmap" >}}, mas foram
especificamente projetados para conter dados confidenciais.
{{< caution >}}
Os Secrets do Kubernetes são, por padrão, gravados não-encriptados no sistema
de armazenamento de dados utilizado pelo servidor da API (etcd). Qualquer pessoa
com acesso à API ou ao etcd consegue obter ou modificar um Secret.
Além disso, qualquer pessoa que possui autorização para criar Pods em um namespace
consegue utilizar este privilégio para ler qualquer Secret naquele namespace. Isso
inclui acesso indireto, como por exemplo a permissão para criar Deployments.
Para utilizar Secrets de forma segura, siga pelo menos as instruções abaixo:
1. [Habilite encriptação em disco](/docs/tasks/administer-cluster/encrypt-data/) para Secrets.
1. Habilite ou configure [regras de RBAC](/docs/reference/access-authn-authz/authorization/)
que restrinjam o acesso de leitura a Secrets (incluindo acesso indireto).
1. Quando apropriado, utilize mecanismos como RBAC para limitar quais perfis e
usuários possuem permissão para criar novos Secrets ou substituir Secrets
existentes.
{{< /caution >}}
Consulte [Segurança da informação para Secrets](#information-security-for-secrets)
para mais detalhes.
<!-- body -->
## Usos para Secrets
Existem três formas principais para um Pod utilizar um Secret:
- Como [arquivos](#using-secrets-as-files-from-a-pod) em um
{{< glossary_tooltip text="volume" term_id="volume" >}} montado em um ou mais de
seus contêineres.
- Como uma [variável de ambiente](#using-secrets-as-environment-variables) de um
contêiner.
- Pelo [kubelet ao baixar imagens de contêiner](#using-imagepullsecrets) para o
Pod.
A camada de gerenciamento do Kubernetes também utiliza Secrets. Por exemplo,
os [Secrets de tokens de autoinicialização](#bootstrap-token-secrets) são um
mecanismo que auxilia a automação do registro de nós.
### Alternativas a Secrets
Ao invés de utilizar um Secret para proteger dados confidenciais, você pode
escolher uma maneira alternativa. Algumas das opções são:
- se o seu componente cloud native precisa autenticar-se a outra aplicação que
está rodando no mesmo cluster Kubernetes, você pode utilizar uma
[ServiceAccount](/pt-br/docs/reference/access-authn-authz/authentication/#tokens-de-contas-de-serviço)
e seus tokens para identificar seu cliente.
- existem ferramentas fornecidas por terceiros que você pode rodar, no seu
cluster ou externamente, que providenciam gerenciamento de Secrets. Por exemplo,
um serviço que Pods accessam via HTTPS, que revelam um Secret se o cliente
autenticar-se corretamente (por exemplo, utilizando um token de ServiceAccount).
- para autenticação, você pode implementar um serviço de assinatura de
certificados X.509 personalizado, e utilizar
[CertificateSigningRequests](/docs/reference/access-authn-authz/certificate-signing-requests/)
para permitir ao serviço personalizado emitir certificados a pods que os
necessitam.
- você pode utilizar um [plugin de dispositivo](/docs/concepts/extend-kubernetes/compute-storage-net/device-plugins/)
para expor a um Pod específico um hardware de encriptação conectado a um nó. Por
exemplo, você pode agendar Pods confiáveis em nós que oferecem um _Trusted
Platform Module_, configurado em um fluxo de dados independente.
Você pode também combinar duas ou mais destas opções, incluindo a opção de
utilizar objetos do tipo Secret.
Por exemplo: implemente (ou instale) um
{{< glossary_tooltip text="operador" term_id="operator-pattern" >}}
que solicite tokens de sessão de curta duração a um serviço externo, e crie
Secrets baseado nestes tokens. Pods rodando no seu cluster podem fazer uso de
tokens de sessão, e o operador garante que estes permanecem válidos. Esta
separação significa que você pode rodar Pods que não precisam ter conhecimento
do mecanismo exato para geração e atualização de tais tokens de sessão.
## Trabalhando com Secrets
### Criando um Secret
Existem diversas formas de criar um Secret:
- [crie um Secret utilizando o comando `kubectl`](/pt-br/docs/tasks/configmap-secret/managing-secret-using-kubectl/)
- [crie um Secret a partir de um arquivo de configuração](/pt-br/docs/tasks/configmap-secret/managing-secret-using-config-file/)
- [crie um Secret utilizando a ferramenta kustomize](/pt-br/docs/tasks/configmap-secret/managing-secret-using-kustomize/)
#### Restrições de nomes de Secret e dados {#restriction-names-data}
O nome de um Secret deve ser um [subdomínio DNS válido](/pt-br/docs/concepts/overview/working-with-objects/names#dns-subdomain-names).
Você pode especificar o campo `data` e/ou o campo `stringData` na criação de um
arquivo de configuração de um Secret. Ambos os campos `data` e `stringData` são
opcionais. Os valores das chaves no campo `data` devem ser strings codificadas
no formato base64. Se a conversão para base64 não for desejável, você pode
optar por informar os dados no campo `stringData`, que aceita strings arbitrárias
como valores.
As chaves dos campos `data` e `stringData` devem consistir de caracteres
alfanuméricos, `-`, `_`, ou `.`. Todos os pares chave-valor no campo `stringData`
são internamente combinados com os dados do campo `data`. Se uma chave aparece
em ambos os campos, o valor informado no campo `stringData` tem a precedência.
#### Limite de tamanho {#restriction-data-size}
Secrets individuais são limitados a 1MiB em tamanho. Esta limitação tem por
objetivo desencorajar a criação de Secrets muito grandes que possam exaurir a
memória do servidor da API e do kubelet. No entanto, a criação de vários Secrets
pequenos também pode exaurir a memória. Você pode utilizar uma
[cota de recurso](/pt-br/docs/concepts/policy/resource-quotas/) a fim de limitar
o número de Secrets (ou outros recursos) em um namespace.
### Editando um Secret
Você pode editar um Secret existente utilizando kubectl:
```shell
kubectl edit secrets mysecret
```
Este comando abre o seu editor padrão configurado e permite a modificação dos
valores do Secret codificados em base64 no campo `data`. Por exemplo:
```yaml
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file, it will be
# reopened with the relevant failures.
#
apiVersion: v1
data:
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm
kind: Secret
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: { ... }
creationTimestamp: 2016-01-22T18:41:56Z
name: mysecret
namespace: default
resourceVersion: "164619"
uid: cfee02d6-c137-11e5-8d73-42010af00002
type: Opaque
```
Este manifesto de exemplo define um Secret com duas chaves no campo `data`:
`username` and `password`.
Os valores são strings codificadas em formato base64. No entanto, quando um
Secret é utilizado em um Pod, o kubelet fornece os dados _decodificados_ ao Pod
e seus contêineres.
Você pode especificar muitas chaves e valores em um Secret só, ou utilizar
muitos Secrets. Escolha a opção que for mais conveniente para o caso de uso.
### Utilizando Secrets
Secrets podem ser montados como volumes de dados ou expostos como
{{< glossary_tooltip text="variáveis de ambiente" term_id="container-env-variables" >}}
para serem utilizados num container de um Pod. Secrets também podem ser
utilizados por outras partes do sistema, sem serem diretamente expostos ao Pod.
Por exemplo, Secrets podem conter credenciais que outras partes do sistema devem
utilizar para interagir com sistemas externos no lugar do usuário.
Secrets montados como volumes são verificados para garantir que o nome
referenciado realmente é um objeto do tipo Secret. Portanto, um Secret deve ser
criado antes de quaisquer Pods que dependem deste Secret.
Se um Secret não puder ser encontrado (porque não existe, ou devido a um problema
de conectividade com o servidor da API) o kubelet tenta periodicamente reiniciar
aquele Pod. O kubelet também relata um evento para aquele Pod, incluindo detalhes
do problema ao buscar o Secret.
#### Secrets Opcionais {#restriction-secret-must-exist}
Quando você define uma variável de ambiente em um contêiner baseada em um Secret,
você pode especificar que o Secret em questão será _opcional_. O padrão é o
Secret ser requerido.
Nenhum dos contêineres de um Pod irão inicializar até que todos os Secrets
requeridos estejam disponíveis.
Se um Pod referencia uma chave específica em um Secret e o Secret existe, mas
não possui a chave com o nome referenciado, o Pod falha durante a inicialização.
### Utilizando Secrets como arquivos em um Pod {#using-secrets-as-files-from-a-pod}
Se você deseja acessar dados de um Secret em um Pod, uma das formas de consumir
esta informação é fazer com que o Kubernetes deixe o valor daquele Secret
disponível como um arquivo dentro do sistema de arquivos de um ou mais dos
contêineres daquele Pod.
Para configurar isso:
1. Crie um Secret ou utilize um previamente existente. Múltiplos Pods podem
referenciar o mesmo secret.
1. Modifique sua definição de Pod para adicionar um volume na lista
`.spec.volumes[]`. Escolha um nome qualquer para o seu volume e adicione um
campo `.spec.volumes[].secret.secretName` com o mesmo valor do seu objeto
Secret.
1. Adicione um ponto de montagem de volume à lista
`.spec.containers[].volumeMounts[]` de cada contêiner que requer o Secret.
Especifique `.spec.containers[].volumeMounts[].readOnly = true` e especifique o
valor do campo `.spec.containers[].volumeMounts[].mountPath` com o nome de um
diretório não utilizado onde você deseja que os Secrets apareçam.
1. Modifique sua imagem ou linha de comando de modo que o programa procure por
arquivos naquele diretório. Cada chave no campo `data` se torna um nome de
arquivo no diretório especificado em `mountPath`.
Este é um exemplo de Pod que monta um Secret de nome `mysecret` em um volume:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret # configuração padrão; "mysecret" precisa existir
```
Cada Secret que você deseja utilizar deve ser referenciado na lista
`.spec.volumes`.
Se existirem múltiplos contêineres em um Pod, cada um dos contêineres
necessitará seu próprio bloco `volumeMounts`, mas somente um volume na lista
`.spec.volumes` é necessário por Secret.
{{< note >}}
Versões do Kubernetes anteriores a v1.22 criavam automaticamente credenciais
para acesso à API do Kubernetes. Este mecanismo antigo era baseado na criação de
Secrets com tokens que podiam então ser montados em Pods em execução.
Em versões mais recentes, incluindo o Kubernetes v{{< skew currentVersion >}},
credenciais para acesso à API são obtidas diretamente através da API
[TokenRequest](/docs/reference/kubernetes-api/authentication-resources/token-request-v1/)
e são montadas em Pods utilizando um
[volume projetado](/docs/reference/access-authn-authz/service-accounts-admin/#bound-service-account-token-volume).
Os tokens obtidos através deste método possuem tempo de vida limitado e são
automaticamente invalidados quando o Pod em que estão montados é removido.
Você ainda pode
[criar manualmente](/docs/tasks/configure-pod-container/configure-service-account/#manually-create-a-service-account-api-token)
um Secret de token de service account se você precisa de um token que não expire,
por exemplo. No entanto, o uso do subrecurso
[TokenRequest](/docs/reference/kubernetes-api/authentication-resources/token-request-v1/)
é recomendado para obtenção de um token para acesso à API ao invés do uso de
Secrets de token de service account.
{{< /note >}}
#### Projeção de chaves de Secrets em caminhos específicos
Você pode também controlar os caminhos dentro do volume onde as chaves do Secret
são projetadas. Você pode utilizar o campo `.spec.volumes[].secret.items` para
mudar o caminho de destino de cada chave:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
readOnly: true
volumes:
- name: foo
secret:
secretName: mysecret
items:
- key: username
path: my-group/my-username
```
Neste caso:
* O valor da chave `username` é armazenado no arquivo
`/etc/foo/my-group/my-username` ao invés de `/etc/foo/username`.
* O valor da chave `password` não é projetado no sistema de arquivos.
Se `.spec.volumes[].secret.items` for utilizado, somente chaves especificadas
na lista `items` são projetadas. Para consumir todas as chaves do Secret, deve
haver um item para cada chave no campo `items`.
Se você listar as chaves explicitamente, então todas as chaves listadas precisam
existir no Secret correspondente. Caso contrário, o volume não é criado.
#### Permissões de arquivos de Secret
Você pode trocar os bits de permissão POSIX de uma chave avulsa de Secret.
Se nenhuma permissão for especificada, `0644` é utilizado por padrão.
Você pode também especificar uma permissão padrão para o volume inteiro de
Secret e sobrescrever esta permissão por chave, se necessário.
Por exemplo, você pode especificar uma permissão padrão da seguinte maneira:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: redis
volumeMounts:
- name: foo
mountPath: "/etc/foo"
volumes:
- name: foo
secret:
secretName: mysecret
defaultMode: 0400
```
Dessa forma, o Secret será montado em `/etc/foo` e todos os arquivos criados
no volume terão a permissão `0400`.
{{< note >}}
Se você estiver definindo um Pod ou um template de Pod utilizando JSON, observe
que a especificação JSON não suporta a notação octal. Você pode utilizar o valor
decimal para o campo `defaultMode` (por exemplo, 0400 em base octal equivale a
256 na base decimal).
Se você estiver escrevendo YAML, você pode escrever o valor para `defaultMode`
em octal.
{{< /note >}}
#### Consumindo valores de Secrets em volumes
Dentro do contêiner que monta um volume de Secret, as chaves deste Secret
aparecem como arquivos e os valores dos Secrets são decodificados do formato
base64 e armazenados dentro destes arquivos.
Ao executar comandos dentro do contêiner do exemplo anterior, obteremos os
seguintes resultados:
```shell
ls /etc/foo
```
O resultado é semelhante a:
```
username
password
```
```shell
cat /etc/foo/username
```
O resultado é semelhante a:
```
admin
```
```shell
cat /etc/foo/password
```
O resultado é semelhante a:
```
1f2d1e2e67df
```
A aplicação rodando dentro do contêiner é responsável pela leitura dos Secrets
dentro dos arquivos.
#### Secrets montados são atualizados automaticamente
Quando um volume contém dados de um Secret, e o Secret referenciado é atualizado,
o Kubernetes rastreia a atualização e atualiza os dados no volume, utilizando
uma abordagem de consistência eventual.
{{< note >}}
Um contêiner que utiliza Secrets através de um volume montado com a propriedade
[`subPath`](/docs/concepts/storage/volumes#using-subpath) não recebe
atualizações automatizadas para este Secret.
{{< /note >}}
O kubelet mantém um cache das chaves e valores atuais dos Secrets que são
utilizados em volumes de Pods daquele nó. Você pode configurar a forma que o
kubelet detecta diferenças dos valores armazenados em cache. O campo
`configMapAndSecretDetectionStrategy` na
[configuração do kubelet](/docs/reference/config-api/kubelet-config.v1beta1/)
controla qual estratégia o kubelet usa. A estratégia padrão é `Watch`.
Atualizações em Secrets podem ser propagadas por um mecanismo de observação da
API (estratégia padrão), baseado em cache com um tempo de expiração definido
(_time-to-live_), ou solicitado diretamente ao servidor da API do cluster a cada
iteração do ciclo de sincronização do kubelet.
Como resultado, o atraso total entre o momento em que o Secret foi atualizado
até o momento em que as novas chaves são projetadas no Pod pode ser tão longo
quanto a soma do tempo de sincronização do kubelet somado ao tempo de atraso de
propagação do cache, onde o atraso de propagação do cache depende do tipo de
cache escolhido. Seguindo a mesma ordem listada no parágrafo anterior, estes
valores são: atraso de propagação via _watch_, tempo de expiração configurado no
cache (_time-to-live_, ou TTL), ou zero para solicitação direta ao servidor da
API.
### Utilizando Secrets como variáveis de ambiente {#using-secrets-as-environment-variables}
Para utilizar um secret em uma {{< glossary_tooltip text="variável de ambiente" term_id="container-env-variables" >}}
em um Pod:
1. Crie um Secret ou utilize um já existente. Múltiplos Pods podem referenciar o
mesmo Secret.
1. Modifique a definição de cada contêiner do Pod em que desejar consumir o
Secret, adicionando uma variável de ambiente para cada uma das chaves que
deseja consumir.
A variável de ambiente que consumir o valor da chave em questão deverá
popular o nome do Secret e a sua chave correspondente no campo
`env[].valueFrom.secretKeyRef`.
1. Modifique sua imagem de contêiner ou linha de comando de forma que o programa
busque os valores nas variáveis de ambiente especificadas.
Este é um exemplo de um Pod que utiliza Secrets em variáveis de ambiente:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: secret-env-pod
spec:
containers:
- name: mycontainer
image: redis
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: mysecret
key: username
optional: false # valor padrão; "mysecret" deve existir
# e incluir uma chave com o nome "username"
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: password
optional: false # valor padrão; "mysecret" deve existir
# e incluir uma chave com o nome "password"
restartPolicy: Never
```
#### Variáveis de ambiente inválidas {#restriction-env-from-invalid}
Secrets utilizados para popular variáveis de ambiente através do campo `envFrom`
que possuem chaves consideradas inválidas para nomes de variáveis de ambiente
têm tais chaves ignoradas. O Pod irá iniciar normalmente.
Se você definir um Pod contendo um nome de variável de ambiente inválido, os
eventos de inicialização do Pod incluirão um evento com a razão
`InvalidVariableNames` e uma mensagem que lista as chaves inválidas ignoradas.
O exemplo abaixo demonstra um Pod que referencia um Secret chamado `mysecret`,
onde `mysecret` contém duas chaves inválidas: `1badkey` and `2alsobad`.
```shell
kubectl get events
```
O resultado é semelhante a:
```
LASTSEEN FIRSTSEEN COUNT NAME KIND SUBOBJECT TYPE REASON
0s 0s 1 dapi-test-pod Pod Warning InvalidEnvironmentVariableNames kubelet, 127.0.0.1 Keys [1badkey, 2alsobad] from the EnvFrom secret default/mysecret were skipped since they are considered invalid environment variable names.
```
#### Consumindo valores de Secret em variáveis de ambiente
Dentro de um contêiner que consome um Secret em variáveis de ambiente, as chaves
do Secret aparecem como variáveis de ambiente comuns, contendo os dados do
Secret decodificados do formato base64. Ao executar comandos no contêiner do
exemplo anterior, obteremos os resultados abaixo:
```shell
echo $SECRET_USERNAME
```
O resultado é semelhante a:
```
admin
```
```shell
echo $SECRET_PASSWORD
```
O resultado é semelhante a:
```
1f2d1e2e67df
```
{{< note >}}
Se um contêiner já consome um Secret em uma variável de ambiente, uma
atualização do Secret não será detectada pelo contêiner a menos que este seja
reiniciado. Há soluções de terceiros que fornecem a funcionalidade de
reinicialização automática de Pods quando o valor dos Secrets mudam.
{{< /note >}}
### Secrets para obtenção de imagens de contêiner {#using-imagepullsecrets}
Se você deseja obter imagens de contêiner de um repositório privado, você
precisa fornecer ao kubelet uma maneira de se autenticar a este repositório.
Você pode configurar o campo `imagePullSecrets` para esta finalidade. Estes
Secrets são configurados a nível de Pod.
O campo `imagePullSecrets` de um Pod é uma lista de referências a Secrets
no mesmo namespace que o Pod.
Você pode utilizar `imagePullSecrets` para enviar credenciais para acesso a um
registro de contêineres ao kubelet. O kubelet utiliza essa informação para
baixar uma imagem privada no lugar do seu Pod.
Veja o campo `PodSpec` na
[referência da API de Pods](/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodSpec)
para maiores detalhes sobre o campo `imagePullSecrets`.
#### Usando `imagePullSecrets`
O campo `imagePullSecrets` é uma lista de referências a Secrets no mesmo
namespace.
Você pode utilizar o campo `imagePullSecrets` para enviar um Secret que contém
uma senha para um registro de imagens de contêiner do Docker (ou outro registro
de imagens de contêiner). O kubelet utiliza essa informação para baixar uma
imagem privada no lugar do seu Pod.
Veja a [API `PodSpec`](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#podspec-v1-core)
para mais informações sobre o campo `imagePullSecrets`.
##### Especificando `imagePullSecrets` manualmente
Você pode ler sobre como especificar `imagePullSecrets` em um Pod na
[documentação de imagens de contêiner](/pt-br/docs/concepts/containers/images/#especificando-imagepullsecrets-em-um-pod).
##### Configurando `imagePullSecrets` para serem adicionados automaticamente
Você pode criar manualmente `imagePullSecrets` e referenciá-los em uma
ServiceAccount. Quaisquer Pods criados com esta ServiceAccount, especificada
explicitamente ou por padrão, têm o campo `imagePullSecrets` populado com os
mesmos valores existentes na service account.
Veja [adicionando `imagePullSecrets` a uma service account](/docs/tasks/configure-pod-container/configure-service-account/#add-imagepullsecrets-to-a-service-account)
para uma explicação detalhada do processo.
### Utilizando Secrets com pods estáticos {#restriction-static-pod}
Você não pode utilizar ConfigMaps ou Secrets em
{{< glossary_tooltip text="Pods estáticos" term_id="static-pod" >}}.
## Casos de uso
### Caso de uso: Como variáveis de ambiente em um contêiner
Crie um manifesto de Secret
```yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
USER_NAME: YWRtaW4=
PASSWORD: MWYyZDFlMmU2N2Rm
```
Crie o Secret no seu cluster:
```shell
kubectl apply -f mysecret.yaml
```
Utilize `envFrom` para definir todos os dados do Secret como variáveis de
ambiente do contêiner. Cada chave do Secret se torna o nome de uma variável de
ambiente no Pod.
```yaml
apiVersion: v1
kind: Pod
metadata:
name: secret-test-pod
spec:
containers:
- name: test-container
image: registry.k8s.io/busybox
command: [ "/bin/sh", "-c", "env" ]
envFrom:
- secretRef:
name: mysecret
restartPolicy: Never
```
### Caso de uso: Pod com chaves SSH
Crie um Secret contendo chaves SSH:
```shell
kubectl create secret generic ssh-key-secret --from-file=ssh-privatekey=/path/to/.ssh/id_rsa --from-file=ssh-publickey=/path/to/.ssh/id_rsa.pub
```
O resultado é semelhante a:
```
secret "ssh-key-secret" created
```
Você também pode criar um manifesto `kustomization.yaml` com um campo
`secretGenerator` contendo chaves SSH.
{{< caution >}}
Analise cuidadosamente antes de enviar suas próprias chaves SSH: outros usuários
do cluster podem ter acesso a este Secret.
Como alternativa, você pode criar uma chave SSH privada representando a
identidade de um serviço que você deseja que seja acessível a todos os usuários
com os quais você compartilha o cluster do Kubernetes em questão. Desse modo,
você pode revogar esta credencial em caso de comprometimento.
{{< /caution >}}
Agora você pode criar um Pod que referencia o Secret com a chave SSH e consome-o
em um volume:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: secret-test-pod
labels:
name: secret-test
spec:
volumes:
- name: secret-volume
secret:
secretName: ssh-key-secret
containers:
- name: ssh-test-container
image: mySshImage
volumeMounts:
- name: secret-volume
readOnly: true
mountPath: "/etc/secret-volume"
```
Ao rodar o comando do contêiner, as partes da chave estarão disponíveis em:
```
/etc/secret-volume/ssh-publickey
/etc/secret-volume/ssh-privatekey
```
O contêiner então pode utilizar os dados do secret para estabelecer uma conexão
SSH.
### Caso de uso: Pods com credenciais de ambientes de produção ou testes
Este exemplo ilustra um Pod que consome um Secret contendo credenciais de um
ambiente de produção e outro Pod que consome um Secret contendo credenciais de
um ambiente de testes.
Você pode criar um manifesto `kustomization.yaml` com um `secretGenerator` ou
rodar `kubectl create secret`.
```shell
kubectl create secret generic prod-db-secret --from-literal=username=produser --from-literal=password=Y4nys7f11
```
O resultado é semelhante a:
```
secret "prod-db-secret" created
```
Você pode também criar um Secret com credenciais para o ambiente de testes.
```shell
kubectl create secret generic test-db-secret --from-literal=username=testuser --from-literal=password=iluvtests
```
O resultado é semelhante a:
```
secret "test-db-secret" created
```
{{< note >}}
Caracteres especiais como `$`, `\`, `*`, `+` e `!` serão interpretados pelo seu
[shell](https://pt.wikipedia.org/wiki/Shell_(computa%C3%A7%C3%A3o)) e precisam
de sequências de escape.
Na maioria dos shells, a forma mais fácil de gerar sequências de escape para
suas senhas é escrevê-las entre aspas simples (`'`). Por exemplo, se a sua senha
for `S!B\*d$zDsb=`, você deve executar o comando da seguinte forma:
```shell
kubectl create secret generic dev-db-secret --from-literal=username=devuser --from-literal=password='S!B\*d$zDsb='
```
Não é necessário gerar sequências de escape para caracteres especiais em arquivos
(utilizados com a opção `--from-file`).
{{< /note >}}
Agora, crie os Pods:
```shell
cat <<EOF > pod.yaml
apiVersion: v1
kind: List
items:
- kind: Pod
apiVersion: v1
metadata:
name: prod-db-client-pod
labels:
name: prod-db-client
spec:
volumes:
- name: secret-volume
secret:
secretName: prod-db-secret
containers:
- name: db-client-container
image: myClientImage
volumeMounts:
- name: secret-volume
readOnly: true
mountPath: "/etc/secret-volume"
- kind: Pod
apiVersion: v1
metadata:
name: test-db-client-pod
labels:
name: test-db-client
spec:
volumes:
- name: secret-volume
secret:
secretName: test-db-secret
containers:
- name: db-client-container
image: myClientImage
volumeMounts:
- name: secret-volume
readOnly: true
mountPath: "/etc/secret-volume"
EOF
```
Adicione os Pods a um manifesto `kustomization.yaml`:
```shell
cat <<EOF >> kustomization.yaml
resources:
- pod.yaml
EOF
```
Crie todos estes objetos no servidor da API rodando o comando:
```shell
kubectl apply -k .
```
Ambos os contêineres terão os seguintes arquivos presentes nos seus sistemas de
arquivos, com valores para cada um dos ambientes dos contêineres:
```
/etc/secret-volume/username
/etc/secret-volume/password
```
Observe como as `spec`s para cada um dos Pods diverge somente em um campo. Isso
facilita a criação de Pods com capacidades diferentes a partir de um template
mais genérico.
Você pode simplificar ainda mais a definição básica do Pod através da utilização
de duas service accounts diferentes:
1. `prod-user` com o Secret `prod-db-secret`
1. `test-user` com o Secret `test-db-secret`
A especificação do Pod é reduzida para:
```yaml
apiVersion: v1
kind: Pod
metadata:
name: prod-db-client-pod
labels:
name: prod-db-client
spec:
serviceAccount: prod-db-client
containers:
- name: db-client-container
image: myClientImage
```
### Caso de uso: _dotfiles_ em um volume de Secret
Você pode fazer com que seus dados fiquem "ocultos" definindo uma chave que se
inicia com um ponto (`.`). Este tipo de chave representa um _dotfile_, ou
arquivo "oculto". Por exemplo, quando o Secret abaixo é montado em um volume,
`secret-volume`:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: dotfile-secret
data:
.secret-file: dmFsdWUtMg0KDQo=
---
apiVersion: v1
kind: Pod
metadata:
name: secret-dotfiles-pod
spec:
volumes:
- name: secret-volume
secret:
secretName: dotfile-secret
containers:
- name: dotfile-test-container
image: registry.k8s.io/busybox
command:
- ls
- "-l"
- "/etc/secret-volume"
volumeMounts:
- name: secret-volume
readOnly: true
mountPath: "/etc/secret-volume"
```
Este volume irá conter um único arquivo, chamado `.secret-file`, e o contêiner
`dotfile-test-container` terá este arquivo presente no caminho
`/etc/secret-volume/.secret-file`.
{{< note >}}
Arquivos com nomes iniciados por um caractere de ponto são ocultados do
resultado do comando `ls -l`. Você precisa utilizar `ls -la` para vê-los ao
listar o conteúdo de um diretório.
{{< /note >}}
### Caso de uso: Secret visível somente em um dos contêineres de um pod {#use-case-secret-visible-to-one-container-in-a-pod}
Suponha que um programa necessita manipular requisições HTTP, executar regras
de negócio complexas e então assinar mensagens com HMAC. Devido à natureza
complexa da aplicação, pode haver um _exploit_ despercebido que lê arquivos
remotos no servidor e que poderia expor a chave privada para um invasor.
Esta aplicação poderia ser dividida em dois processos, separados em dois
contêineres distintos: um contêiner de _front-end_, que manipula as interações
com o usuário e a lógica de negócio, mas não consegue ver a chave privada; e
um contêiner assinador, que vê a chave privada e responde a requisições simples
de assinatura do _front-end_ (por exemplo, através de rede local).
Com essa abordagem particionada, um invasor agora precisa forçar o servidor de
aplicação a rodar comandos arbitrários, o que é mais difícil de ser feito do que
apenas ler um arquivo presente no disco.
## Tipos de Secrets {#secret-types}
Ao criar um Secret, você pode especificar o seu tipo utilizando o campo `type`
do objeto Secret, ou algumas opções de linha de comando equivalentes no comando
`kubectl`, quando disponíveis. O campo `type` de um Secret é utilizado para
facilitar a manipulação programática de diferentes tipos de dados confidenciais.
O Kubernetes oferece vários tipos embutidos de Secret para casos de uso comuns.
Estes tipos variam em termos de validações efetuadas e limitações que o
Kubernetes impõe neles.
| Tipo embutido | Caso de uso |
|----------------------------------------|----------------------------------------------------|
| `Opaque` | dados arbitrários definidos pelo usuário |
| `kubernetes.io/service-account-token` | token de service account (conta de serviço) |
| `kubernetes.io/dockercfg` | arquivo `~/.dockercfg` serializado |
| `kubernetes.io/dockerconfigjson` | arquivo `~/.docker/config.json` serializado |
| `kubernetes.io/basic-auth` | credenciais para autenticação básica (basic auth) |
| `kubernetes.io/ssh-auth` | credenciais para autenticação SSH |
| `kubernetes.io/tls` | dados para um cliente ou servidor TLS |
| `bootstrap.kubernetes.io/token` | dados de token de autoinicialização |
Você pode definir e utilizar seu próprio tipo de Secret definindo o valor do
campo `type` como uma string não-nula em um objeto Secret (uma string em branco
é tratada como o tipo `Opaque`).
O Kubernetes não restringe nomes de tipos. No entanto, quando tipos embutidos
são utilizados, você precisa atender a todos os requisitos daquele tipo.
Se você estiver definindo um tipo de Secret que seja para uso público, siga a
convenção e estruture o tipo de Secret para conter o seu domínio antes do nome,
separado por uma barra (`/`).
Por exemplo: `cloud-hosting.example.net/cloud-api-credentials`.
Para melhor desempenho em uma requisição `get` repetitiva, clientes podem criar
objetos que referenciam o Secret e então utilizar a requisição `watch` neste
novo objeto, requisitando o Secret novamente quando a referência mudar.
Além disso, uma [API de "observação em lotes"](https://git.k8s.io/design-proposals-archive/api-machinery/bulk_watch.md)
para permitir a clientes observar recursos individuais também foi proposta e
provavelmente estará disponível em versões futuras do Kubernetes.
`Opaque` é o tipo predefinido de Secret quando o campo `type` é omitido em um
arquivo de configuração de Secret. Quando um Secret é criado usando o comando
`kubectl`, você deve usar o subcomando `generic` para indicar que um Secret é
do tipo `Opaque`. Por exemplo, o comando a seguir cria um Secret vazio do tipo
`Opaque`:
```shell
kubectl create secret generic empty-secret
kubectl get secret empty-secret
```
O resultado será semelhante ao abaixo:
```
NAME TYPE DATA AGE
empty-secret Opaque 0 2m6s
```
A coluna `DATA` demonstra a quantidade de dados armazenados no Secret. Neste
caso, `0` significa que este objeto Secret está vazio.
### Secrets de token de service account (conta de serviço)
Secrets do tipo `kubernetes.io/service-account-token` são utilizados para
armazenar um token que identifica uma service account (conta de serviço). Ao
utilizar este tipo de Secret, você deve garantir que a anotação
`kubernetes.io/service-account.name` contém um nome de uma service account
existente. Um controlador do Kubernetes preenche outros campos, como por exemplo
a anotação `kubernetes.io/service-account.uid` e a chave `token` no campo `data`
com o conteúdo do token.
O exemplo de configuração abaixo declara um Secret de token de service account:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: secret-sa-sample
annotations:
kubernetes.io/service-account-name: "sa-name"
type: kubernetes.io/service-account-token
data:
# Você pode incluir pares chave-valor adicionais, da mesma forma que faria com
# Secrets do tipo Opaque
extra: YmFyCg==
```
Ao criar um {{< glossary_tooltip text="Pod" term_id="pod" >}}, o Kubernetes
automaticamente cria um Secret de service account e automaticamente atualiza o
seu Pod para utilizar este Secret. O Secret de token de service account contém
credenciais para acessar a API.
A criação automática e o uso de credenciais de API podem ser desativados ou
substituídos se desejado. Porém, se tudo que você necessita é poder acessar o
servidor da API de forma segura, este é o processo recomendado.
Veja a documentação de
[ServiceAccount](/docs/tasks/configure-pod-container/configure-service-account/)
para mais informações sobre o funcionamento de service accounts. Você pode
verificar também os campos `automountServiceAccountToken` e `serviceAccountName`
do [`Pod`](/docs/reference/generated/kubernetes-api/{{< param "version" >}}/#pod-v1-core)
para mais informações sobre como referenciar service accounts em Pods.
### Secrets de configuração do Docker
Você pode utilizar um dos tipos abaixo para criar um Secret que armazena
credenciais para accesso a um registro de contêineres para busca de imagens:
- `kubernetes.io/dockercfg`
- `kubernetes.io/dockerconfigjson`
O tipo `kubernetes.io/dockercfg` é reservado para armazenamento de um arquivo
`~/.dockercfg` serializado. Este arquivo é o formato legado para configuração
do utilitário de linha de comando do Docker. Ao utilizar este tipo de Secret,
é preciso garantir que o campo `data` contém uma chave `.dockercfg` cujo valor
é o conteúdo do arquivo `~/.dockercfg` codificado no formato base64.
O tipo `kubernetes.io/dockerconfigjson` foi projetado para armazenamento de um
conteúdo JSON serializado que obedece às mesmas regras de formato que o arquivo
`~/.docker/config.json`. Este arquivo é um formato mais moderno para o conteúdo
do arquivo `~/.dockercfg`. Ao utilizar este tipo de Secret, o conteúdo do campo
`data` deve conter uma chave `.dockerconfigjson` em que o conteúdo do arquivo
`~/.docker/config.json` é fornecido codificado no formato base64.
Um exemplo de um Secret do tipo `kubernetes.io/dockercfg`:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: secret-dockercfg
type: kubernetes.io/dockercfg
data:
.dockercfg: |
"<base64 encoded ~/.dockercfg file>"
```
{{< note >}}
Se você não desejar fazer a codificação em formato base64, você pode utilizar o
campo `stringData` como alternativa.
{{< /note >}}
Ao criar estes tipos de Secret utilizando um manifesto (arquivo YAML), o
servidor da API verifica se a chave esperada existe no campo `data` e se o valor
fornecido pode ser interpretado como um conteúdo JSON válido. O servidor da API
não verifica se o conteúdo informado é realmente um arquivo de configuração do
Docker.
Quando você não tem um arquivo de configuração do Docker, ou quer utilizar o
comando `kubectl` para criar um Secret de registro de contêineres, você pode
rodar o comando:
```shell
kubectl create secret docker-registry secret-tiger-docker \
--docker-email=tiger@acme.example \
--docker-username=tiger \
--docker-password=pass1234 \
--docker-server=my-registry.example:5000
```
Esse comando cria um secret do tipo `kubernetes.io/dockerconfigjson`. Se você
obtiver o conteúdo do campo `.data.dockerconfigjson` deste novo Secret e
decodificá-lo do formato base64:
```shell
kubectl get secret secret-tiger-docker -o jsonpath='{.data.*}' | base64 -d
```
o resultado será equivalente a este documento JSON (que também é um arquivo de
configuração válido do Docker):
```json
{
"auths": {
"my-registry.example:5000": {
"username": "tiger",
"password": "pass1234",
"email": "tiger@acme.example",
"auth": "dGlnZXI6cGFzczEyMzQ="
}
}
}
```
{{< note >}}
O valor do campo `auth` no exemplo acima é codificado em base64; ele está
ofuscado mas não criptografado. Qualquer pessoa com acesso a este Secret pode
ler o conteúdo do token _bearer_.
{{< /note >}}
### Secret de autenticação básica
O tipo `kubernetes.io/basic-auth` é fornecido para armazenar credenciais
necessárias para autenticação básica. Ao utilizar este tipo de Secret, o campo
`data` do Secret deve conter as duas chaves abaixo:
- `username`: o usuário utilizado para autenticação;
- `password`: a senha ou token para autenticação.
Ambos os valores para estas duas chaves são textos codificados em formato base64.
Você pode fornecer os valores como texto simples utilizando o campo `stringData`
na criação do Secret.
O arquivo YAML abaixo é um exemplo de configuração para um Secret de autenticação
básica:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: secret-basic-auth
type: kubernetes.io/basic-auth
stringData:
username: admin # required field for kubernetes.io/basic-auth
password: t0p-Secret # required field for kubernetes.io/basic-auth
```
O tipo de autenticação básica é fornecido unicamente por conveniência. Você pode
criar um Secret do tipo `Opaque` utilizado para autenticação básica. No entanto,
utilizar o tipo embutido e público de Secret (`kubernetes.io/basic-auth`)
auxilia outras pessoas a compreenderem o propósito do seu Secret, e define uma
convenção de expectativa de nomes de chaves
O tipo embutido também fornece verificação dos campos requeridos pelo servidor
da API.
### Secret de autenticação SSH
O tipo embutido `kubernetes.io/ssh-auth` é fornecido para armazenamento de dados
utilizados em autenticação SSH. Ao utilizar este tipo de Secret, você deve
especificar um par de chave-valor `ssh-privatekey` no campo `data` (ou no campo
`stringData`) com a credencial SSH a ser utilizada.
O manifesto abaixo é um exemplo de configuração para um Secret de autenticação
SSH com um par de chaves pública/privada:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: secret-ssh-auth
type: kubernetes.io/ssh-auth
data:
# os dados estão abreviados neste exemplo
ssh-privatekey: |
MIIEpQIBAAKCAQEAulqb/Y ...
```
O Secret de autenticação SSH é fornecido apenas para a conveniência do usuário.
Você pode criar um Secret do tipo `Opaque` para credentials utilizadas para
autenticação SSH. No entanto, a utilização do tipo embutido e público de Secret
(`kubernetes.io/tls`) auxilia outras pessoas a compreenderem o propósito do
seu Secret, e define uma convenção de quais chaves podem ser esperadas.
O tipo embutido também fornece verificação dos campos requeridos em uma
configuração de Secret.
{{< caution >}}
Chaves privadas SSH não estabelecem, por si só, uma comunicação confiável
entre um cliente SSH e um servidor. Uma forma secundária de estabelecer
confiança é necessária para mitigar ataques _man-in-the-middle_ (MITM), como por
exemplo um arquivo `known_hosts` adicionado a um ConfigMap.
{{< /caution >}}
### Secrets TLS
O Kubernetes fornece o tipo embutido de Secret `kubernetes.io/tls` para
armazenamento de um certificado e sua chave associada que são tipicamente
utilizados para TLS.
Uma utilização comum de Secrets TLS é a configuração de encriptação em trânsito
para um recurso [Ingress](/docs/concepts/services-networking/ingress/), mas
este tipo de secret pode também ser utilizado com outros recursos ou diretamente
por uma carga de trabalho.
Ao utilizar este tipo de Secret, as chaves `tls.key` e `tls.crt` devem ser
informadas no campo `data` (ou `stringData`) da configuração do Secret, embora o
servidor da API não valide o conteúdo de cada uma destas chaves.
O YAML a seguir tem um exemplo de configuração para um Secret TLS:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: secret-tls
type: kubernetes.io/tls
data:
# os dados estão abreviados neste exemplo
tls.crt: |
MIIC2DCCAcCgAwIBAgIBATANBgkqh ...
tls.key: |
MIIEpgIBAAKCAQEA7yn3bRHQ5FHMQ ...
```
O tipo TLS é fornecido para a conveniência do usuário. Você pode criar um
Secret do tipo `Opaque` para credenciais utilizadas para o servidor e/ou
cliente TLS. No entanto, a utilização do tipo embutido auxilia a manter a
consistência dos formatos de Secret no seu projeto; o servidor da API
valida se os campos requeridos estão presentes na configuração do Secret.
Ao criar um Secret TLS utilizando a ferramenta de linha de comando `kubectl`,
você pode utilizar o subcomando `tls` conforme demonstrado no exemplo abaixo:
```shell
kubectl create secret tls my-tls-secret \
--cert=path/to/cert/file \
--key=path/to/key/file
```
O par de chaves pública/privada deve ser criado previamente. O certificado
de chave pública a ser utilizado no argumento `--cert` deve ser codificado em
formato DER conforme especificado na
[seção 5.1 da RFC 7468](https://datatracker.ietf.org/doc/html/rfc7468#section-5.1)
e deve corresponder à chave privada fornecida no argumento `--key`
(PKCS #8 no formato DER;
[seção 11 da RFC 7468](https://datatracker.ietf.org/doc/html/rfc7468#section-11)).
{{< note >}}
Um Secret kubernetes.io/tls armazena o conteúdo de chaves e certificados em
formato DER codificado em base64. Se você tem familiaridade com o formato PEM
para chaves privadas e certificados, o conteúdo é o mesmo do formato PEM,
excluindo-se a primeira e a última linhas.
Por exemplo, para um certificado, você **não** inclui as linhas
`--------BEGIN CERTIFICATE-----` e `-------END CERTIFICATE----`.
{{< /note >}}
### Secret de token de autoinicialização {#bootstrap-token-secrets}
Um Secret de token de autoinicialização pode ser criado especificando o tipo de
um Secret explicitamente com o valor `bootstrap.kubernetes.io/token`. Este tipo
de Secret é projetado para tokens utilizados durante o processo de inicialização
de nós. Este tipo de Secret armazena tokens utilizados para assinar ConfigMaps
conhecidos.
Um Secret de token de autoinicialização é normalmente criado no namespace
`kube-system` e nomeado na forma `bootstrap-token-<id-do-token>`, onde
`<id-do-token>` é um texto com 6 caracteres contendo a identificação do token.
No formato de manifesto do Kubernetes, um Secret de token de autoinicialização
se assemelha ao exemplo abaixo:
```yaml
apiVersion: v1
kind: Secret
metadata:
name: bootstrap-token-5emitj
namespace: kube-system
type: bootstrap.kubernetes.io/token
data:
auth-extra-groups: c3lzdGVtOmJvb3RzdHJhcHBlcnM6a3ViZWFkbTpkZWZhdWx0LW5vZGUtdG9rZW4=
expiration: MjAyMC0wOS0xM1QwNDozOToxMFo=
token-id: NWVtaXRq
token-secret: a3E0Z2lodnN6emduMXAwcg==
usage-bootstrap-authentication: dHJ1ZQ==
usage-bootstrap-signing: dHJ1ZQ==
```
Um Secret do tipo token de autoinicialização possui as seguintes chaves no campo
`data`:
- `token-id`: Uma string com 6 caracteres aleatórios como identificador do
token. Requerido.
- `token-secret`: Uma string de 16 caracteres aleatórios como o conteúdo secreto
do token. Requerido.
- `description`: Uma string contendo uma descrição do propósito para o qual este
token é utilizado. Opcional.
- `expiration`: Um horário absoluto UTC no formato [RFC3339](https://datatracker.ietf.org/doc/html/rfc3339) especificando quando
o token deve expirar. Opcional.
- `usage-bootstrap-<usage>`: Um conjunto de flags booleanas indicando outros
usos para este token de autoinicialização.
- `auth-extra-groups`: Uma lista separada por vírgulas de nomes de grupos que
serão autenticados adicionalmente, além do grupo `system:bootstrappers`.
O YAML acima pode parecer confuso, já que os valores estão todos codificados em
formato base64. Você pode criar o mesmo Secret utilizando este YAML:
```yaml
apiVersion: v1
kind: Secret
metadata:
# Observe como o Secret é nomeado
name: bootstrap-token-5emitj
# Um Secret de token de inicialização geralmente fica armazenado no namespace
# kube-system
namespace: kube-system
type: bootstrap.kubernetes.io/token
stringData:
auth-extra-groups: "system:bootstrappers:kubeadm:default-node-token"
expiration: "2020-09-13T04:39:10Z"
# Esta identificação de token é utilizada no nome
token-id: "5emitj"
token-secret: "kq4gihvszzgn1p0r"
# Este token pode ser utilizado para autenticação
usage-bootstrap-authentication: "true"
# e pode ser utilizado para assinaturas
usage-bootstrap-signing: "true"
```
## Secrets imutáveis {#secret-immutable}
{{< feature-state for_k8s_version="v1.21" state="stable" >}}
O Kubernetes permite que você marque Secrets (e ConfigMaps) específicos como
_imutáveis_. Prevenir mudanças nos dados de um Secret existente tem os seguintes
benefícios:
- protege você de alterações acidentais (ou indesejadas) que poderiam provocar
disrupções em aplicações.
- em clusters com uso extensivo de Secrets (pelo menos dezenas de milhares de
montagens únicas de Secrets a Pods), utilizar Secrets imutáveis melhora o
desempenho do seu cluster através da redução significativa de carga no
kube-apiserver. O kubelet não precisa manter um _watch_ em Secrets que são
marcados como imutáveis.
### Marcando um Secret como imutável {#secret-immutable-create}
Você pode criar um Secret imutável adicionando o campo `immutable` com o valor
`true` ao manifesto do Secret. Por exemplo:
```yaml
apiVersion: v1
kind: Secret
metadata:
...
data:
...
immutable: true
```
Você pode também atualizar qualquer Secret mutável existente para torná-lo
imutável.
{{< note >}}
Uma vez que um Secret ou ConfigMap seja marcado como imutável, _não_ é mais
possível reverter esta mudança, nem alterar os conteúdos do campo `data`. Você
pode somente apagar e recriar o Secret. Pods existentes mantém um ponto de
montagem referenciando o Secret removido - é recomendado recriar tais Pods.
{{< /note >}}
## Informações de segurança sobre Secrets {#information-security-for-secrets}
Embora ConfigMaps e Secrets funcionem de formas similares, o Kubernetes aplica
proteções extras aos objetos Secret.
Secrets frequentemente contém valores dentro de um espectro de importância,
muitos dos quais podem provocar escalações de privilégios dentro do Kubernetes
(por exemplo, um token de service account) e em sistemas externos. Mesmo que uma
aplicação individual possa avaliar o poder dos Secrets com os quais espera
interagir, outras aplicações dentro do mesmo namespace podem tornar tais
suposições inválidas.
Um Secret só é enviado a um nó se um Pod naquele nó precisa do Secret em questão.
Para montar Secrets em Pods, o kubelet armazena uma cópia dos dados dentro de um
sistema de arquivos `tmpfs`, de modo que os dados confidenciais não sejam
escritos em armazenamento durável. Uma vez que o Pod que dependia do Secret seja
removido, o kubelet apaga sua cópia local dos dados confidenciais do Secret.
Um Pod pode possuir vários contêineres. Por padrão, contêineres que você define
têm acesso somente à ServiceAccount padrão e seu Secret relacionado. Você deve
explicitamente definir variáveis de ambiente ou mapear um volume dentro de um
contêiner para ter acesso a qualquer outro Secret.
Podem haver Secrets para vários Pods no mesmo nó. No entanto, somente os Secrets
que um Pod requisitou estão potencialmente visíveis dentro de seus contêineres.
Portanto, um Pod não tem acesso aos Secrets de outro Pod.
{{< warning >}}
Quaisquer contêineres privilegiados em um nó são passíveis de acesso a todos os
Secrets naquele nó.
{{< /warning >}}
### Recomendações de segurança para desenvolvedores
- Aplicações ainda devem proteger o valor da informação confidencial após lê-la
de uma variável de ambiente ou volume. Por exemplo, sua aplicação deve evitar
imprimir os dados do Secret sem encriptação ou transmitir esta informação para
aplicações terceiras de confiabilidade não-estabelecida.
- Se você estiver definindo múltiplos contêineres em um Pod, e somente um destes
contêineres necessita acesso a um Secret, defina o volume ou variável de
ambiente de maneira que os demais contêineres não tenham acesso àquele Secret.
- Se você configurar um Secret através de um {{< glossary_tooltip text="manifesto" term_id="manifest" >}},
com os dados codificados em formato base64, compartilhar este arquivo ou
salvá-lo em um sistema de controle de versão de código-fonte significa que o
Secret está disponível para qualquer pessoa que pode ler o manifesto. O formato
base64 _não é_ um método de encriptação e não fornece nenhuma confidencialidade
adicional em comparação com texto puro.
- Ao instalar aplicações que interagem com a API de Secrets, você deve limitar
o acesso utilizando
[políticas de autorização](/docs/reference/access-authn-authz/authorization/),
como por exemplo [RBAC](/docs/reference/access-authn-authz/rbac/).
- Na API do Kubernetes, requisições `watch` e `list` em Secrets dentro de um
namespace são extremamente poderosas. Evite fornecer este acesso quando
possível, já que listar Secrets permite aos clientes inspecionar os valores de
todos os Secrets naquele namespace.
### Recomendações de segurança para administradores de cluster
{{< caution >}}
Um usuário que pode criar um Pod que utiliza um Secret pode também ver o valor
daquele Secret. Mesmo que as permissões do cluster não permitam ao usuário ler
o Secret diretamente, o mesmo usuário poderia ter acesso a criar um Pod que
então expõe o Secret.
{{< /caution >}}
- Restrinja a habilidade de usar as requisições `watch` e `list` para listar todos
os Secrets em um cluster (utilizando a API do Kubernetes) de modo que somente
os componentes mais privilegiados e de nível de sistema possam realizar esta
ação.
- Ao instalar aplicações que interajam com a API de Secrets, você deve limitar o
acesso utilizando
[políticas de autorização](/docs/reference/access-authn-authz/authorization/),
como por exemplo [RBAC](/docs/reference/access-authn-authz/rbac/).
- No servidor da API, objetos (incluindo Secrets) são persistidos no
{{< glossary_tooltip term_id="etcd" >}}; portanto:
- somente permita a administradores do sistema o acesso ao etcd (incluindo
acesso somente-leitura);
- habilite [encriptação em disco](/docs/tasks/administer-cluster/encrypt-data/)
para objetos Secret, de modo que os dados de tais Secrets não sejam
armazenados em texto plano no {{< glossary_tooltip term_id="etcd" >}};
- considere a destruição do armazenamento durável previamente utilizado pelo
etcd quando não estiver mais em uso;
- se houverem múltiplas instâncias do etcd em uso, garanta que o etcd esteja
configurado para utilizar SSL/TLS para comunicação entre instâncias.
## {{% heading "whatsnext" %}}
- Aprenda a [gerenciar Secrets utilizando `kubectl`](/pt-br/docs/tasks/configmap-secret/managing-secret-using-kubectl/)
- Aprenda a [gerenciar Secrets utilizando arquivos de configuração](/pt-br/docs/tasks/configmap-secret/managing-secret-using-config-file/)
- Aprenda a [gerenciar Secrets utilizando kustomize](/pt-br/docs/tasks/configmap-secret/managing-secret-using-kustomize/)
- Leia a [documentação de referência da API](/docs/reference/kubernetes-api/config-and-storage-resources/secret-v1/) de Secrets