Ao executar cargas de trabalho em contêineres no Container Service for Kubernetes (ACK), inserir AccessKeys diretamente no código da aplicação representa riscos de segurança e dificulta a rotação de credenciais. O acesso cloud-native do KMS elimina esse risco injetando um Sidecar do KMS Agent nos pods, o que permite que as aplicações recuperem com segurança as credenciais gerenciadas no KMS por meio de requisições HTTP locais.
Como funciona
O recurso de acesso cloud-native do Key Management Service (KMS) oferece um fluxo de trabalho guiado para instalar e configurar componentes. Quando um pod no seu cluster do Container Service for Kubernetes (ACK) envia uma requisição HTTP, o KMS Agent — injetado automaticamente no pod pelo componente Helm ack-kms-agent-webhook-injector — recebe a requisição e autentica usando um JWT do OpenID Connect (OIDC) ou uma função do Resource Access Management (RAM). Depois que o KMS verifica as permissões, ele retorna as credenciais por meio do Agent. O Agent armazena credenciais em cache localmente para reduzir requisições repetidas e diminuir a latência na recuperação de credenciais.
Escopo
-
Restrições de tipo de cluster ACK: Há suporte para ACK managed and dedicated clusters, ACK Serverless clusters e Create an ACS cluster.
NotaPara clusters dedicados do ACK e clusters registrados do ACK, consulte Deploy KMS Agent in ACK to retrieve secrets.
Restrições de região: O cluster do ACK e a instância do KMS devem estar na mesma região.
Restrições de desempenho: Cada pod executa de forma independente um contêiner Sidecar do KMS Agent. Se você implantar um grande número de pods e as requisições de STS Token ultrapassarem 500 por minuto durante a autenticação, o sistema aplica limitação de taxa, afetando a operação normal do KMS Agent.
Ative o RRSA para o seu cluster do ACK
Ativar durante a criação do cluster
Ao criar um ACK managed cluster e um ACK Edge cluster, ative o RRSA na seção Advanced Options (Optional) da configuração do cluster.
Ativar na página de informações do cluster
Acesse o ACK console. No painel de navegação à esquerda, clique em Clusters.
Na página Clusters, clique no nome do seu cluster. No painel de navegação à esquerda, clique em Cluster Information.
Na aba Basic Information, na seção Security and Auditing, clique em Enable ao lado de RRSA OIDC.
-
Na caixa de diálogo Enable RRSA, clique em OK.
NotaNa página Basic Information, quando o status do cluster mudar de Updating para Running, o recurso RRSA estará ativado para o cluster.
Instale o KMS Agent
Etapa 1: Crie um namespace e uma conta de serviço (opcional)
Um namespace particiona o seu cluster do ACK em espaços virtuais logicamente isolados para diferentes ambientes, como desenvolvimento, testes e produção. Por padrão, as aplicações em namespaces diferentes não acessam os recursos umas das outras. Se você já tiver um namespace e uma conta de serviço para a sua aplicação, pule esta etapa.
-
Crie um namespace.
-
Crie um namespace usando um arquivo YAML. O exemplo a seguir usa
app1-namespace.yamlpara criar um namespace chamadoapp1-dev:apiVersion: v1 kind: Namespace metadata: name: app1-dev -
Execute o seguinte comando para criar o namespace:
kubectl apply -f app1-namespace.yaml -
Verifique se o namespace foi criado. Se a saída incluir
app1-dev, a criação do namespace foi bem-sucedida.kubectl get namespaces
-
-
Crie uma conta de serviço.
-
Crie uma conta de serviço usando um arquivo YAML. O exemplo a seguir usa
app1-serviceaccount.yamlpara criar uma conta de serviço chamadaapp1-serviceno namespaceapp1-devque você criou na etapa anterior:apiVersion: v1 kind: ServiceAccount metadata: name: app1-service namespace: app1-dev -
Execute o seguinte comando para criar a conta de serviço:
kubectl apply -f app1-serviceaccount.yaml -
Verifique se a conta de serviço foi criada. Se a saída incluir
app1-service, a criação da conta de serviço foi bem-sucedida.kubectl get serviceaccount -n app1-dev
-
Etapa 2: Configure as permissões
O acesso cloud-native do KMS suporta os dois métodos de autenticação a seguir.
Recomendamos o OpenID Connect (OIDC) para a maioria dos cenários devido à sua configuração mais simples. Use a função do RAM quando precisar reutilizar políticas de função do RAM existentes ou exigir acesso entre contas.
|
Método de autenticação |
Características |
|
OIDC (ACK) |
O cluster do ACK autentica usando o JWT padrão do OpenID Connect (OIDC). O Agent obtém automaticamente o token da conta de serviço para provar a identidade do pod ao KMS. Não é necessária nenhuma função do RAM, e apresenta a configuração mais simples. |
|
Função do RAM |
Acessa o KMS usando credenciais temporárias do STS de uma função do RAM. Este método é adequado para cenários nos quais você deseja reutilizar uma configuração de função do RAM existente. |
OIDC (ACK)
No painel de configuração exibido, defina o Authentication Method como OIDC (ACK).
-
Configure os seguintes parâmetros:
Parâmetro
Descrição
Namespace
O nome do namespace onde o pod reside, como
app1-dev.ServiceAccount
A conta de serviço usada pelo pod, como
app1-service.PodNamePrefix
O prefixo do nome do pod. Após configurar este parâmetro, apenas os pods cujos nomes correspondem ao prefixo podem passar na verificação. Se você não configurar este parâmetro, o sistema verifica apenas o namespace e a conta de serviço.
Scope
O método para acessar o KMS. Valores válidos:
Specified KMS Instance: Acessa chaves e credenciais em uma instância específica do KMS usando o endpoint da instância.
Shared KMS Gateway: Acessa credenciais usando o endpoint do serviço KMS.
Application Access Point Name
O nome personalizado do ponto de acesso da aplicação (credencial de acesso) para identificação e gerenciamento.
Policy Name
O nome personalizado da política do RAM. Crie uma política diretamente nesta etapa sem precisar criá-la previamente no console do RAM.
RBAC Permissions
O nível de permissão RBAC (Role-Based Access Control), que determina as permissões de operação de credenciais para a aplicação.
Se Specified KMS Instance for selecionado para o escopo:
CryptoServiceKeyUser: Permite o uso de chaves na instância do KMS para criptografia de credenciais.
CryptoServiceSecretUser: Permite o uso de credenciais na instância do KMS e oferece suporte a APIs de credenciais para a instância.
Se Shared KMS Gateway for selecionado para o escopo: Há suporte apenas para SecretUser, o que permite o uso de todas as credenciais na conta atual.
Accessible Resources
Selecione as credenciais e chaves (usadas para criptografia e descriptografia de credenciais) que a aplicação precisa acessar.
ImportanteSe você selecionar várias credenciais e o comprimento total dos nomes das credenciais exceder o limite, o sistema retorna um erro de "parameter invalid". Nesse caso, use um curinga para especificar as credenciais permitidas, como
secret/rds-ibm*, permitindo o acesso a credenciais com o prefixords-ibm.Description
Opcional. Uma descrição detalhada do ponto de acesso da aplicação. Comprimento máximo: 8.192 caracteres.
Clique em OK para prosseguir.
Função do RAM
-
Confirme se o cluster do ACK pode acessar o STS
Adicione o endpoint do serviço STS sts-intl.aliyuncs.com à lista de permissões de saída do cluster do ACK para evitar bloqueios por firewall ou outras regras de defesa de rede.
NotaAo usar a RAM Role, o KMS Agent deve chamar a API
AssumeRoleWithOIDCdo STS para obter credenciais temporárias. Se o endpoint estiver bloqueado, o Agent não poderá atualizar as credenciais temporárias. -
Obtenha as informações do provedor de identidade.
Clique no nome do cluster de destino para acessar a página de detalhes.
Na aba Basic Information, passe o ponteiro sobre o rótulo Enabled ao lado de RRSA (RAM Roles for Service Accounts) OIDC na seção Security and Auditing e visualize a URL do provedor e as informações do ARN. A URL do provedor está no formato
https://oidc-ack-<region>.oss-<region>.aliyuncs.com/<cluster_id>, e o ARN do provedor está no formatoacs:ram::<account_id>:oidc-provider/ack-rrsa-<cluster_id>.
-
Crie uma função do RAM.
Selecione IdP como o tipo de entidade confiável e, em seguida, clique em Switch to Editor.
-
Na seção Visual Editor, configure os seguintes itens:
-
Configuração básica
Parâmetro
Descrição
Effect
Selecione Allow.
Action
Mantenha o valor padrão
sts:AssumeRole.Condition
Adicione uma condição com a chave
oidc:sub, o operadorStringEqualse o valorsystem:serviceaccount:<namespace>:<ServiceAccountName>, ondenamespaceeServiceAccountNamecorrespondem ao namespace and service account do pod que executa a carga de trabalho. -
Configure o principal da seguinte forma:
Selecione Identity Provider como o Principal e, em seguida, clique em Edit abaixo.
-
Na página de configuração do Identity Provider, configure os seguintes parâmetros e clique em OK.
Parâmetro
Descrição
IdP Type
Selecione OIDC.
Identity Provider
Selecione o provedor de identidade criado automaticamente pelo cluster do ACK após a ativação do RRSA:
ack-rrsa-<cluster_id>.NotaNão confunda o valor
audiencests.aliyuncs.comna política de confiança da função do RAM e no modelo de pod com o endpoint do serviço STS que o KMS Agent utiliza. O valoraudienceé o ID do cliente do provedor de identidade OIDC criado após a ativação do RRSA. Ele não determina o endpoint que o KMS Agent usa para chamar o STS.
-
Após concluir a configuração, clique em OK para definir o nome da função (por exemplo,
app1-rrsa) e, em seguida, clique em OK.
-
Crie uma política e anexe-a à função do RAM. Para mais informações, consulte Create a custom policy e Attach a policy to a RAM role.
-
Clique em Create Policy, selecione Script Editor e, em seguida, configure a política usando o exemplo a seguir.
NotaNeste exemplo, a política recebe o nome
dev-role-for-rrsa-kms-policye permite acesso apenas a credenciais com a tagenv:app1.{ "Version": "1", "Statement": [ { "Effect": "Allow", "Action": [ "kms:Decrypt", "kms:GetSecretValue" ], "Resource": "*", "Condition": { "StringEqualsIgnoreCase": { "kms:tag/secret": [ "app1" ] } } } ] } Volte para a lista de políticas, encontre a política de destino e clique em Attach to Identity na coluna Actions.
Na seção Principal, selecione a função do RAM que você criou e, em seguida, clique em Confirm.
-
Etapa 3: Instale o ack-kms-agent-webhook-injector
-
Na página Helm, clique em Deploy. Configure a seção Basic Information e, em seguida, clique em Next.
Parâmetro
Descrição
Application Name
Use o nome padrão da aplicação
ack-kms-agent-webhook-injector.Namespace
Use o namespace padrão do chart
kube-system. Instale em apenas um namespace por cluster do ACK; evite instalar várias vezes.Source
Padrão: Marketplace. Este parâmetro não pode ser modificado.
Chart
Pesquise e selecione
ack-kms-agent-webhook-injector. Quando a caixa de diálogo de confirmação for exibida, verifique as informações e clique em Yes.
-
Na página Parameters, configure os parâmetros com base no método de autenticação selecionado na Etapa 2.
OIDC (ACK): Mantenha a configuração padrão.
-
Função do RAM: Deixe
agent.auth.roleArnvazio e definaagent.auth.roleArnMappingcomo<Namespace>:<ServiceAccountName>:<RAM Role ARN>. O exemplo a seguir usa os dados criados na Etapa 2:NotaO
Namespacee oServiceAccountNamecorrespondem ao namespace and service account do pod que executa a carga de trabalho. ORAM Role ARNestá disponível na página de detalhes da função do RAM.agent: auth: roleArn: roleArnMapping: app1-dev:app1-service: acs:ram::190325303126****:role/app1-rrsa
Após concluir a configuração, clique em OK. O sistema redireciona você para a página de detalhes da aplicação.
Etapa 4: Injete o Sidecar do Agent
-
Adicione uma anotação de pod: Defina a chave da anotação como
kms-agent-webhook-injector/injecte o valor comotrue.-
Alterne para o namespace onde a sua carga de trabalho é executada e adicione a anotação de pod ao Deployment.
ImportantePara o método de autenticação de função do RAM, modifique a configuração YAML do Deployment e defina o parâmetro
ServiceAccountNamecomo o service account name do pod que executa a carga de trabalho (por exemplo,app1-service). Para o método de autenticação OIDC (ACK), não é necessária nenhuma modificação.-
Crie um novo Deployment
Create from Image
Clique em Create from Image acima da lista de Deployments e configure os parâmetros.
Ao configurar Advanced, vá para a seção Labels and Annotations e adicione a anotação de pod: insira
kms-agent-webhook-injector/injectna coluna Name etruena coluna Value.Clique em Create para concluir.
Create from YAML
Clique em Create from YAML acima da lista de Deployments.
Edite o arquivo YAML e adicione
kms-agent-webhook-injector/inject: "true"emspec.template.metadata.annotations(crie esta seção se ela não existir).Clique em Create para concluir.
-
Modifique um Deployment existente
Encontre a carga de trabalho de destino e clique em Actions > Details.
Na página de detalhes, clique em Edit YAML no canto superior direito.
Adicione
kms-agent-webhook-injector/inject: "true"emspec.template.metadata.annotations(crie esta seção se ela não existir).Clique em Update e aguarde até que a carga de trabalho esteja pronta.
-
-
-
Verifique a injeção
-
Na aba Pods, verifique a coluna Image. O KMS Agent aparece injetado no pod como um Sidecar.
NotaUm pod pode receber a injeção do KMS Agent duas vezes. Isso acontece porque o sistema usa um contêiner de inicialização (init container). O contêiner de inicialização é finalizado (Terminated) após a conclusão do processo e não impacta negativamente a aplicação nem consome recursos de computação continuamente.
-
O KMS Agent escuta apenas em 127.0.0.1, ou seja, apenas aplicações ou processos na mesma máquina podem se comunicar com ele. Dispositivos de rede externos não conseguem se conectar. O endereço de acesso suporta apenas localhost ou 127.0.0.1, e não o IP local da aplicação. Os exemplos a seguir usam localhost.
Além do método de acesso do KMS Agent, o KMS também suporta acesso via SDK. Para operações específicas, consulte Secrets Manager Client.
-
Execute o seguinte comando para recuperar uma credencial:
# Read token from file, specify AapArn curl -v -H "X-KMS-Token:$(</var/run/kmstoken/token)" -H "AapArn:<AapArn>" 'http://localhost:2025/secretsmanager/get?secretId=<SecretId>' -
A sintaxe
$(<file)tem suporte apenas em shells como bash e zsh. Se a imagem base do seu Pod usar Alpine (cujo shell padrão é o BusyBox ash) ou qualquer outra imagem cujo shell padrão não ofereça suporte a esta sintaxe, use o seguinte comando:# Read token from file, specify AapArn (Alpine/BusyBox compatible) curl -v -H "X-KMS-Token:$(cat /var/run/kmstoken/token)" -H "AapArn:<AapArn>" 'http://localhost:2025/secretsmanager/get?secretId=<SecretId>' -
Execute o seguinte comando para recuperar uma credencial:
# Read token from file, specify AapArn wget -q -O - --header "X-KMS-Token:$(</var/run/kmstoken/token)" --header "AapArn:<AapArn>" 'http://localhost:2025/secretsmanager/get?secretId=<SecretId>' -
A sintaxe
$(<file)tem suporte apenas em shells como bash e zsh. Se a imagem base do seu Pod usar Alpine (cujo shell padrão é o ash) ou qualquer outra imagem cujo shell padrão não ofereça suporte a esta sintaxe, use o seguinte comando:# Read token from file, specify AapArn (Alpine compatible) wget -q -O - --header "X-KMS-Token:$(cat /var/run/kmstoken/token)" --header "AapArn:<AapArn>" 'http://localhost:2025/secretsmanager/get?secretId=<SecretId>' -
Execute o seguinte comando para recuperar uma credencial:
# Read token from file curl -v -H "X-KMS-Token:$(</var/run/kmstoken/token)" 'http://localhost:2025/secretsmanager/get?secretId=<SecretId>' # Or write the token directly curl -v -H "X-KMS-Token:<token>" 'http://localhost:2025/secretsmanager/get?secretId=<SecretId>' -
A sintaxe
$(<file)tem suporte apenas em shells como bash e zsh. Se a imagem base do seu Pod usar Alpine (cujo shell padrão é o BusyBox ash) ou qualquer outra imagem cujo shell padrão não ofereça suporte a esta sintaxe, use o seguinte comando:# Read token from file (Alpine/BusyBox compatible) curl -v -H "X-KMS-Token:$(cat /var/run/kmstoken/token)" 'http://localhost:2025/secretsmanager/get?secretId=<SecretId>' -
Execute o seguinte comando para recuperar uma credencial:
# Read token from file wget -q -O - --header "X-KMS-Token:$(</var/run/kmstoken/token)" 'http://localhost:2025/secretsmanager/get?secretId=<SecretId>' # Or write the token directly wget -q -O - --header "X-KMS-Token:<token>" 'http://localhost:2025/secretsmanager/get?secretId=<SecretId>' -
A sintaxe
$(<file)tem suporte apenas em shells como bash e zsh. Se a imagem base do seu Pod usar Alpine (cujo shell padrão é o ash) ou qualquer outra imagem cujo shell padrão não ofereça suporte a esta sintaxe, use o seguinte comando:# Read token from file (Alpine compatible) wget -q -O - --header "X-KMS-Token:$(cat /var/run/kmstoken/token)" 'http://localhost:2025/secretsmanager/get?secretId=<SecretId>' -
Custos do lado do KMS:
Assinatura: Adquira uma instância do KMS antes de usar o KMS Agent. O próprio KMS Agent não incorre em cobranças adicionais. Para mais informações, consulte Subscription.
Pagamento conforme o uso: Além das cobranças já incorridas, há cobrança adicional de QPS quando o KMS Agent recupera credenciais por meio de chamadas de API. Para mais informações, consulte Pay-as-you-go.
-
Custos do lado do ACK:
O componente ack-kms-agent-webhook-injector é gratuito. Podem ocorrer custos adicionais com recursos de computação consumidos pelas cargas de trabalho de Sidecar e Webhook injetadas.
Após instalar o componente ack-kms-agent-webhook-injector, o sistema gera uma carga de trabalho de serviço Webhook, que consome recursos de computação e gera custos. Limite o uso de CPU e memória dessa carga de trabalho no arquivo de configuração.
Quando você cria ou atualiza uma carga de trabalho qualificada, o ack-kms-agent-webhook-injector injeta o KMS Agent como um Sidecar no contêiner. O KMS Agent consome recursos de computação e gera custos.
Verifique se as políticas de saída do cluster do ACK permitem o acesso ao endpoint real do serviço STS ( sts-intl.aliyuncs.com).
Teste a acessibilidade ao endpoint de dentro do pod da aplicação.
Verifique os logs do contêiner do KMS Agent em busca de falhas ou tempos limite relacionados a
AssumeRoleWithOIDC.OIDC (ACK): Verifique o namespace e a conta de serviço, e confirme se um filtro PodNamePrefix está configurado.
Função do RAM: Verifique se a função do RAM está corretamente anexada ao provedor de identidade e se a política inclui as permissões
kms:GetSecretValueekms:Decrypt.
Integração da aplicação
Depois que o seu Deployment recebe a injeção do KMS Agent, o contêiner da aplicação pode recuperar credenciais do KMS por meio de requisições HTTP para o KMS Agent. Não é necessário configurar nenhuma AccessKey no seu código. Os exemplos a seguir demonstram como recuperar credenciais. Substitua <SecretId> pelo nome real da sua credencial.
OIDC (ACK)
Usando curl
Usando wget
Exemplo de código Go
O exemplo a seguir demonstra como recuperar uma credencial usando Go:
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func main() {
// You can specify versionStage or versionId to retrieve a specific credential version.
// The following example retrieves a credential by versionId:
// url := fmt.Sprintf("http://localhost:2025/secretsmanager/get?secretId=%s&versionId=%s", "agent-test", "version-id")
aapArn := "acs:kms:cn-hangzhou:19*********224:applicationaccesspoint/****"
url := fmt.Sprintf("http://localhost:2025/secretsmanager/get?secretId=%s", "agent-test")
token, err := ioutil.ReadFile("/var/run/kmstoken/token")
if err != nil {
fmt.Printf("error reading token file: %v\n", err)
}
req, err := http.NewRequest("GET", url, nil)
if err != nil {
fmt.Printf("error creating request: %v\n", err)
}
req.Header.Add("X-KMS-Token", string(token))
req.Header.Add("AapArn", aapArn)
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
fmt.Printf("error sending request: %v \n", err)
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Printf("status code %d - %s \n", resp.StatusCode, string(body))
}
Função do RAM
Usando curl
Usando wget
Exemplo de código Go
O exemplo a seguir demonstra como recuperar uma credencial usando Go:
package main
import (
"fmt"
"io/ioutil"
"net/http"
)
func main() {
// You can specify versionStage or versionId to retrieve a specific credential version.
// The following example retrieves a credential by versionId:
// url := fmt.Sprintf("http://localhost:2025/secretsmanager/get?secretId=%s&versionId=%s", "agent-test", "version-id")
url := fmt.Sprintf("http://localhost:2025/secretsmanager/get?secretId=%s", "agent-test")
token, err := ioutil.ReadFile("/var/run/kmstoken/token")
if err != nil {
fmt.Printf("error reading token file: %v\n", err)
}
req, err := http.NewRequest("GET", url, nil)
if err != nil {
fmt.Printf("error creating request: %v\n", err)
}
req.Header.Add("X-KMS-Token", string(token))
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
fmt.Printf("error sending request: %v \n", err)
}
defer resp.Body.Close()
body, _ := ioutil.ReadAll(resp.Body)
fmt.Printf("status code %d - %s \n", resp.StatusCode, string(body))
}
Faturamento
Solução de problemas
Se você encontrar problemas ao instalar ou usar o KMS Agent, consulte os problemas comuns a seguir para solucioná-los.
Causa | Solução |
Falha ao instalar o Agent | Execute |
Rede inacessível ou tempo limite esgotado | Certifique-se de que o cluster do ACK alcança o serviço KMS. Se você acessar o KMS por meio de uma VPC, certifique-se de que a VPC onde reside o cluster do ACK está conectada à rede da instância do KMS. |
O KMS Agent falha ao obter credenciais temporárias do STS por meio de | Solucione o problema da seguinte forma: Nota: Uma leitura bem-sucedida de um valor de segredo em cache não garante que a cadeia de credenciais da função do RAM está íntegra. Verifique os logs para confirmar que |
Permissões insuficientes | Verifique as seguintes configurações: |
Falha ao injetar o Agent | Verifique se o componente ack-kms-agent-webhook-injector está instalado corretamente e em execução normal. Confirme se a anotação de pod |
O RRSA não está ativado | O método de autenticação OIDC (ACK) requer o recurso RRSA (RAM Roles for Service Accounts). No console do ACK, acesse o módulo de segurança e auditoria do cluster para ativar o RRSA. Para etapas detalhadas, consulte a configuração do provedor de identidade na aba de função do RAM da Etapa 2. |