O add-on csi-secrets-store-provider-alibabacloud oferece uma maneira segura de consumir credenciais do Key Management Service (KMS) em cargas de trabalho do Kubernetes. Permite montar secrets diretamente como volumes inline do CSI ou sincronizá-los como Secrets nativos do Kubernetes. Além disso, suporta a rotação automática de secrets para minimizar a exposição de credenciais e simplifica a integração entre suas aplicações e o KMS Secrets Manager.
Considerações de segurança
Por padrão, cargas de trabalho que leem secrets diretamente do sistema de arquivos podem enfrentar problemas de compatibilidade ao interagir com o KMS Secrets Manager. O csi-secrets-store-provider-alibabacloud resolve esses problemas de compatibilidade e permite sincronizar secrets como objetos Secret do Kubernetes para injeção de variáveis de ambiente. Avalie os seguintes riscos de segurança antes de prosseguir:
Travessia do sistema de arquivos: Secrets montados por meio do sistema de arquivos podem ficar expostos se aplicações vulneráveis forem exploradas em ataques de travessia de diretórios.
Exposição em depuração e logs: Breakpoints de depuração mal configurados ou acesso a logs com permissões excessivas podem causar o vazamento de Secrets. Referenciar Secrets por meio de variáveis de ambiente é inseguro e não é recomendado.
Permissões excessivas: Aplique o princípio do menor privilégio ao conceder acesso ao KMS para o
ack-secret-manager.
Se sua aplicação não precisar persistir secrets localmente, conceda permissões mínimas aos pods usando RRSA e chame GetSecretValue diretamente da aplicação. Essa abordagem evita completamente a exposição de secrets no sistema de arquivos do pod ou em Secrets do Kubernetes.
Pré-requisitos
-
É necessário ter um cluster do Container Service for Kubernetes (ACK) que execute o Kubernetes 1.20 ou posterior. Os tipos de cluster compatíveis incluem:
ACK managed cluster
ACK dedicated cluster
ACK Edge cluster
registered cluster
crie um cluster. Consulte Create an ACK managed cluster ou Create an ACK One registered cluster.
Etapa 1: configure a autenticação do add-on
configure a autenticação para o csi-secrets-store-provider-alibabacloud e conceda permissão para recuperar secrets do KMS. Caso contrário, o add-on não poderá importar ou sincronizar credenciais para o cluster. escolha um dos seguintes métodos de autorização com base no tipo do seu cluster:
Authorize using RRSA: Aplica-se a ACK managed cluster s que executam o Kubernetes 1.22 ou posterior.
Grant permissions to the worker RAM role: Aplica-se a ACK managed cluster s, ACK dedicated cluster s e ACK One registered cluster s.
Configure AccessKey credentials to assume a RAM role: Aplica-se a todos os clusters ACK.
Autorizar usando RRSA
Em comparação com outros métodos, o RRSA fornece isolamento de permissões no nível do pod e evita o risco de vazamento de credenciais causado pelo hardcoding de AccessKey IDs e AccessKey secrets.
Enable the RRSA feature for your cluster no ACK console. O RRSA usa as informações do provedor de identidade especificadas durante a criação do cluster .
-
Create a RAM role with an OIDC identity provider as the trusted entity. configure os parâmetros com base na tabela a seguir:
Parâmetro
Descrição
IdP Type
selecione OIDC.
Identity Provider
selecione
ack-rrsa-<cluster_id>. Substitua<cluster_id>pelo ID do seu cluster.Condition
-
oidc:iss: Mantenha o valor padrão.
-
oidc:aud: Mantenha o valor padrão.
-
oidc:sub: Adicione esta condição manualmente.
-
Key: selecione oidc:sub.
-
Operator: selecione StringEquals.
-
Value: Insira
system:serviceaccount:<namespace>:<serviceAccountName>. Substitua<namespace>pelo namespace da aplicação e<serviceAccountName>pelo nome da conta de serviço. Para este tópico, usesystem:serviceaccount:kube-system:csi-secrets-store-provider-alibabacloud.NotaRecomendamos que você instale o add-on no namespace padrão
kube-system. Se a instalação ocorrer em um namespace diferente, substituakube-systempelo seu namespace de destino.
-
-
-
crie uma política personalizada e anexe-a à função RAM criada na etapa anterior.
-
Create a custom policy para que o csi-secrets-store-provider-alibabacloud importe credenciais do KMS. Conteúdo da política:
{ "Action": [ "kms:GetSecretValue", "kms:Decrypt" ], "Resource": [ "*" ], "Effect": "Allow" } Anexe a política à função RAM da etapa anterior. Consulte Manage permissions for a RAM role.
-
-
crie um Kubernetes Secret chamado
alibaba-credentialsno cluster.-
crie um arquivo chamado
secretstore-rrsa.yamlcom o seguinte conteúdo. Substitua os marcadores de posição pelos seus valores reais.{rolearn}: ARN codificado em Base64 da função RAM criada em step 2.{oidcproviderarn}: ARN codificado em Base64 do provedor OIDC gerado após a ativação do RRSA.
apiVersion: v1 data: rolearn: {rolearn} oidcproviderarn: {oidcproviderarn} kind: Secret metadata: name: alibaba-credentials namespace: kube-system type: Opaque -
Implante o Kubernetes Secret:
kubectl apply -f secretstore-rrsa.yaml
-
Conceder permissões à função RAM do worker
-
Create a custom policy. Conteúdo da política:
{ "Action": [ "kms:GetSecretValue", "kms:Decrypt" ], "Resource": [ "*" ], "Effect": "Allow" }
configure credenciais AccessKey
-
Create a RAM role with its trusted entity set as your current Alibaba Cloud account.
NotaPara a entidade de confiança, selecione Current Account.
-
crie uma política personalizada e conceda permissões à função RAM criada na etapa anterior.
-
Create a custom policy para acesso a credenciais do KMS. Conteúdo da política:
{ "Action": [ "kms:GetSecretValue", "kms:Decrypt" ], "Resource": [ "*" ], "Effect": "Allow" } Conceda permissões à função RAM da etapa anterior. Consulte Manage permissions for a RAM role.
-
-
crie uma política personalizada para assumir a função anterior e anexe-a a um usuário RAM.
-
Create a custom policy para assumir a função. Conteúdo da política:
{ "Statement": [ { "Action": "sts:AssumeRole", "Effect": "Allow", "Resource": "acs:ram:*:<account-id>:role/<role-name>" } ], "Version": "1" }Nesta política personalizada, o elemento Resource especifica o role ARN, onde <ACCOUNT_ID> é o ID da conta Alibaba Cloud e <ROLE_NAME> é o nome da função RAM.
Conceder a política personalizada a um usuário RAM permite que você especifique quais funções RAM ele pode assumir. Para mais informações, consulte Manage RAM user permissions.
-
-
crie um Kubernetes Secret chamado
alibaba-credentialsno cluster.-
crie um arquivo chamado
alibaba-credentials.yamlcom o seguinte conteúdo. Substitua os marcadores de posição pelos seus valores reais.{rolearn}: ARN codificado em Base64 da função RAM de step 1.{ak}: AccessKey ID codificado em Base64 do usuário RAM.-
{sk}: AccessKey secret codificado em Base64 do usuário RAM.apiVersion: v1 data: id: {ak} secret: {sk} rolearn: {rolearn} kind: Secret metadata: name: alibaba-credentials namespace: kube-system type: Opaque
-
Implante o Kubernetes Secret.
kubectl apply -f alibaba-credentials.yaml
-
Etapa 2: instale o csi-secrets-store-provider-alibabacloud
Acesse o ACK console. No painel de navegação à esquerda, clique em Clusters.
Na página Clusters, clique em nome do seu cluster. No painel de navegação à esquerda, clique em .
-
Na página Helm, clique em Deploy. Pesquise por csi-secrets-store-provider-alibabacloud e selecione-o. Mantenha as configurações padrão e clique em Next.
Na caixa de diálogo, confirme a instalação do chart, que será instalado no namespace
kube-systempor padrão. Clique em Yes para prosseguir. Para usar um namespace personalizado, configure Application Name e Namespace na etapa Basic Information. -
selecione a Chart Version mais recente. Na seção Parameters, configure os parâmetros com base no método de autenticação de step 1. Em seguida, clique em OK.
-
Se você seguiu o procedimento em Authorize using RRSA, defina
rrsa.enablecomo true.
Outros parâmetros:
envVarsFromSecret: # ACCESS_KEY_ID: # secretKeyRef: alibaba-credentials # key: id # SECRET_ACCESS_KEY: # secretKeyRef: alibaba-credentials # key: secret ALICLOUD_ROLE_ARN: secretKeyRef: alibaba-credentials key: rolearn # ALICLOUD_ROLE_SESSION_NAME: # secretKeyRef: alibaba-credentials # key: rolesessionname # ALICLOUD_ROLE_SESSION_EXPIRATION: # secretKeyRef: alibaba-credentials # key: rolesessionexpiration ALICLOUD_OIDC_PROVIDER_ARN: secretKeyRef: alibaba-credentials key: oidcproviderarn Se você seguiu o procedimento em Grant permissions to the worker RAM role, use as configurações padrão.
-
Se você seguiu o procedimento em Configure AccessKey credentials to assume a RAM role, configure os seguintes parâmetros:
envVarsFromSecret: ACCESS_KEY_ID: secretKeyRef: alibaba-credentials key: id SECRET_ACCESS_KEY: secretKeyRef: alibaba-credentials key: secret ALICLOUD_ROLE_ARN: secretKeyRef: alibaba-credentials key: rolearn # ALICLOUD_ROLE_SESSION_NAME: # secretKeyRef: alibaba-credentials # key: rolesessionname # ALICLOUD_ROLE_SESSION_EXPIRATION: # secretKeyRef: alibaba-credentials # key: rolesessionexpiration # ALICLOUD_OIDC_PROVIDER_ARN: # secretKeyRef: alibaba-credentials # key: oidcproviderarn -
ative a sincronização de Secrets para Secrets nativos do Kubernetes, defina
syncSecret.enabledcomotruepara implantar a Role e o RoleBinding do RBAC necessários.syncSecret: enabled: true -
ative a rotação automática de secrets, configure os seguintes parâmetros:

secrets-store-csi-driver.enableSecretRotation: ative a rotação automática de secrets. defina como true.secrets-store-csi-driver.rotationPollInterval: Intervalo de sincronização de secrets. Exemplo: 120s sincroniza a cada dois minutos. Ajuste conforme necessário.
Após a implantação, você será redirecionado para a página csi-secrets-store-provider-alibabacloud. verifique se todos os recursos foram criados. Na seção Resource, verifique se os seguintes recursos do Kubernetes foram criados:
ServiceAccount:
secrets-store-csi-driverecsi-secrets-store-provider-alibabacloudClusterRole:
secretproviderclasses-admin-role,secretproviderclasses-viewer-roleesecretproviderclasses-roleClusterRoleBinding:
secretproviderclasses-rolebindingDaemonSet:
secrets-store-csi-driverecsi-secrets-store-provider-alibabacloudCSIDriver:
secrets-store.csi.k8s.io
-
Etapa 3: configure a sincronização de secrets
Após configurar a autenticação, use uma SecretProviderClass para especificar as credenciais do KMS a serem importadas.
Modelo
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: <NAME>
spec:
provider: alibabacloud # This value is fixed to 'alibabacloud'.
parameters:
objects: |
- objectName: <KMS Encryption Parameter Name> # Name of the KMS credential.
objectType: kms # Fixed to kms when synchronizing KMS credentials.
O campo parameters aceita as seguintes configurações:
|
Parâmetro |
Obrigatório |
Descrição |
|
|
Sim |
Especifica os secrets a serem montados como um array YAML. Exemplo:
O parâmetro
|
|
|
Opcional |
A região do KMS Secrets Manager. O padrão é a região do nó, o que pode adicionar sobrecarga de desempenho em implantações em grande escala. Recomenda-se que você especifique uma região. |
|
|
Opcional |
|
Exemplo de uso
Use uma SecretProviderClass para importar uma credencial do KMS chamada test da mesma região de um ACK managed cluster para uma carga de trabalho.
-
crie um arquivo chamado
secretstore.yamlcom o seguinte conteúdo.apiVersion: secrets-store.csi.x-k8s.io/v1 kind: SecretProviderClass metadata: name: test-secrets spec: provider: alibabacloud # This value is fixed to alibabacloud. parameters: objects: | # objectType supports oos and kms. The default is kms. - objectName: "test-hangzhou" objectType: "kms" objectAlias: "hangzhou-public" kmsEndpoint: "kms.{region}.aliyuncs.com" -
Implante a
SecretProviderClass.kubectl apply -f secretstore.yaml -
crie um arquivo chamado
deploy.yamlcom o seguinte conteúdo.Este Deployment do NGINX monta credenciais da
SecretProviderClassanterior usando um volume inline CSI em/mnt/secrets-store(Exemplos de Deployment).apiVersion: apps/v1 # For versions earlier than 1.8.0, use apps/v1beta1. kind: Deployment metadata: name: nginx-deployment-basic labels: app: nginx spec: replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: volumes: - name: secrets-store-inline csi: driver: secrets-store.csi.k8s.io readOnly: true volumeAttributes: secretProviderClass: "test-secrets" containers: - name: nginx image: anolis-registry.cn-zhangjiakou.cr.aliyuncs.com/openanolis/nginx:1.14.1-8.6 # Replace with your actual image. ports: - containerPort: 80 resources: limits: cpu: "500m" volumeMounts: - name: secrets-store-inline mountPath: "/mnt/secrets-store" readOnly: true -
Implante a aplicação.
kubectl apply -f deploy.yaml -
verifique se o secret foi montado corretamente.
Acesse o pod e verifique se existe um arquivo correspondente ao nome do secret em
/mnt/secrets-storecujo conteúdo corresponda à credencial do KMS.
Sincronizar credenciais do KMS para Secrets do Kubernetes
O Secrets Store CSI Driver permite a sincronização automática de secrets recuperados de services externos onde você gerencie secrets (como KMS e OOS) e os cria como Secrets nativos do Kubernetes no cluster. As aplicações podem usar esses secrets externos da maneira padrão do Kubernetes sem que você modifique o código.
configure: SecretProviderClass
Adicione o campo opcional secretObjects ao spec de um recurso SecretProviderClass para ativar essa funcionalidade.
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: <NAME>
spec:
provider: alibabacloud # This value is fixed to alibabacloud. Do not modify.
parameters:
objects: |
- objectName: <KMS Encryption Parameter Name> # Name of the KMS credential.
objectType: kms # Fixed to kms when synchronizing KMS credentials.
secretObjects:
- secretName: <Kubernetes Secret Name> # Name of the Kubernetes Secret.
type: <Kubernetes Secret Type> # Type of the Kubernetes Secret.
data:
- objectName: <parameters.objects.objectName> # The name from parameters.objects.objectName. Use the alias if specified.
key: <Kubernetes Secret Data Key> # The key name in the Kubernetes Secret data.
O secretObjects geralmente inclui os três parâmetros a seguir:
Parâmetro | Tipo | Descrição |
secretName | Obrigatório | O nome do Kubernetes Secret a ser criado. |
type | Obrigatório | O tipo do Secret. Valores válidos: |
data | Obrigatório | Define como mapear um secret externo para o campo
|
Ciclo de vida da sincronização
A sincronização e a limpeza de um objeto Secret são acionadas dinamicamente por um Pod que monta a SecretProviderClass correspondente:
Criação: O Kubernetes Secret é criado apenas quando o primeiro Pod que usa a
SecretProviderClassé iniciado e monta o volume.atualize: Quando
secrets-store-csi-driver.enableSecretRotationétrue, o Kubernetes Secret é atualizado periodicamente no intervalosecrets-store-csi-driver.rotationPollInterval. Caso contrário, não o atualize.Exclusão: Quando o último Pod que usa a
SecretProviderClassé excluído, o Kubernetes Secret correspondente também é excluído.
Exemplo: Sincronizar e injetar credenciais
Sincronize uma credencial do KMS para um Kubernetes Secret e injete-a como uma variável de ambiente em um pod NGINX.
-
crie uma
SecretProviderClass.crie um arquivo chamado
syncSecret.yamlcom o seguinte conteúdo.apiVersion: secrets-store.csi.x-k8s.io/v1 kind: SecretProviderClass metadata: name: alibabacloud-sync-secret spec: provider: alibabacloud parameters: objects: | - objectName: test-kms objectAlias: secretalias objectType: kms secretObjects: - secretName: test-sync-secret # Name of the generated Kubernetes Secret. type: Opaque data: - objectName: secretalias # Corresponds to objectName or objectAlias. key: test # Populates the data key of the generated Kubernetes Secret. -
Implante a
SecretProviderClass.kubectl apply -f syncSecret.yaml -
crie um pod de aplicação para acionar a sincronização.
crie um arquivo
pod-sync-secret.yamlcom o seguinte conteúdo. Este pod monta aSecretProviderClassanterior e tenta usarsecretKeyRefpara referenciar oSecretchamadotest-sync-secreta ser gerado.kind: Pod apiVersion: v1 metadata: name: pod-sync-secret spec: containers: - name: nginx image: nginx:latest volumeMounts: - name: secrets-store-inline mountPath: "/mnt/secrets-store" readOnly: true env: - name: SECRET_TEST valueFrom: secretKeyRef: name: test-sync-secret key: test volumes: - name: secrets-store-inline csi: driver: secrets-store.csi.k8s.io readOnly: true volumeAttributes: secretProviderClass: "alibabacloud-sync-secret" -
Implante o pod para acionar a sincronização.
kubectl apply -f pod-sync-secret.yaml -
verifique o resultado.
-
verifique se o Kubernetes Secret foi criado.
kubectl get secret test-sync-secretA saída exibe o Kubernetes Secret
test-sync-secret. -
verifique se a variável de ambiente foi injetada no pod.
kubectl exec -it $(kubectl get pods | awk '/pod-sync-secret/{print $1}' | head -1) -- envA saída inclui
SECRET_TESTcom um valor correspondente ao secret do KMS.
-
configure o kmsEndpoint
configure o endpoint do KMS para um gateway dedicado ou compartilhado (consulte Differences between shared and dedicated gateways).
Endereços dos endpoints do KMS
|
Tipo de gateway |
Tipo de domínio |
Endereço do endpoint |
Descrição |
|
Gateway dedicado |
KMS privado |
{kms-instance-id}.cryptoservice.kms.aliyuncs.com |
|
|
Gateway compartilhado |
VPC |
kms-vpc.{region}.aliyuncs.com |
|
|
Gateway compartilhado |
Público |
kms.{region}.aliyuncs.com |
|
Exemplo de configuração do endpoint do KMS
apiVersion: secrets-store.csi.x-k8s.io/v1
kind: SecretProviderClass
metadata:
name: test
spec:
provider: alibabacloud # Fixed to 'alibabacloud'
parameters:
# Gateway usage examples:
# hangzhou-public uses the public endpoint of a shared gateway. Replace {region} with the region where the KMS credential is located. This method allows you to access KMS credentials from a different region than the cluster.
# hangzhou-vpc does not specify a kmsEndpoint field and uses the default VPC endpoint of a shared gateway.
# hangzhou-cryptoservice uses a dedicated gateway. Replace {kms-instance-id} with the ID of the KMS instance.
# london-public uses the public endpoint of a shared gateway. Replace {region} with the region where the KMS credential is located. This method allows you to access KMS credentials from a different region than the cluster.
objects: |
- objectName: "test-hangzhou"
objectType: "kms"
objectAlias: "hangzhou-public"
kmsEndpoint: "kms.{region}.aliyuncs.com"
- objectName: "test-hangzhou"
objectType: "kms"
objectAlias: "hangzhou-vpc"
- objectName: "test-hangzhou"
objectType: "kms"
objectAlias: "hangzhou-cryptoservice"
kmsEndpoint: "{kms-instance-id}.cryptoservice.kms.aliyuncs.com"
- objectName: "test-london"
objectAlias: "london-public"
kmsEndpoint: "kms.{region}.aliyuncs.com"
Referências
Para cargas de trabalho de ACK Serverless cluster, consulte Use ack-secret-manager to import Alibaba Cloud KMS service credentials.
Para proteger secrets do KMS em cache, encrypt them with Alibaba Cloud KMS.