Lorsque vous exécutez des charges de travail conteneurisées sur Container Service for Kubernetes (ACK), l'incorporation directe d'AccessKeys dans le code applicatif présente des risques de sécurité et complique la rotation des identifiants. L'accès cloud natif à KMS élimine ce risque en injectant un Sidecar KMS Agent dans les pods, permettant aux applications de récupérer en toute sécurité les identifiants gérés par KMS via des requêtes HTTP locales.
Fonctionnement
La fonctionnalité d'accès cloud natif du Key Management Service (KMS) propose un flux guidé pour l'installation et la configuration des composants. Lorsqu'un pod de votre cluster Container Service for Kubernetes (ACK) envoie une requête HTTP, le KMS Agent — automatiquement injecté dans le pod via le composant Helm ack-kms-agent-webhook-injector — reçoit la requête et s'authentifie à l'aide d'un jeton JWT OpenID Connect (OIDC) ou d'un rôle Resource Access Management (RAM). Une fois que KMS a vérifié les autorisations, il renvoie les identifiants via l'Agent. Ce dernier met en cache les identifiants localement afin de réduire les requêtes répétées et la latence de récupération des identifiants.
Périmètre
-
Restrictions liées au type de cluster ACK : Les clusters ACK managés et dédiés, les clusters ACK Serverless et la création d'un cluster ACS sont pris en charge.
RemarquePour les clusters ACK dédiés et les clusters ACK enregistrés, consultez la rubrique Déployer KMS Agent dans ACK pour récupérer des secrets.
Restrictions régionales : Le cluster ACK et l'instance KMS doivent se trouver dans la même région.
Restrictions de performance : Chaque pod exécute indépendamment un conteneur Sidecar KMS Agent. Si votre activité déploie un grand nombre de pods et que les demandes de jetons STS dépassent 500 par minute lors de l'authentification, une limitation de débit est déclenchée, ce qui affecte le fonctionnement normal du KMS Agent.
Activer RRSA pour votre cluster ACK
Activer lors de la création du cluster
Lorsque vous créez un cluster ACK managé et un cluster ACK Edge, vous pouvez activer RRSA dans la section Advanced Options (Optional) de la configuration du cluster.
Activer sur la page d'informations du cluster
Connectez-vous à la console ACK. Dans le volet de navigation de gauche, cliquez sur Clusters.
Sur la page Clusters, cliquez sur le nom de votre cluster. Dans le volet de navigation de gauche, cliquez sur Cluster Information.
Dans l'onglet Basic Information, section Security and Auditing, cliquez sur Enable à côté de RRSA OIDC.
-
Dans la boîte de dialogue Enable RRSA, cliquez sur OK.
RemarqueSur la page Basic Information, lorsque l'état du cluster passe de Updating à Running, la fonctionnalité RRSA est activée pour le cluster.
Installer le KMS Agent
Étape 1 : Créer un namespace et un compte de service (facultatif)
Un namespace partitionne votre cluster ACK en espaces virtuels logiquement isolés pour différents environnements tels que le développement, les tests et la production. Par défaut, les applications situées dans différents namespaces ne peuvent pas accéder aux ressources des autres. Si vous disposez déjà d'un namespace et d'un compte de service pour votre application métier, ignorez cette étape.
-
Créez un namespace.
-
Créez un namespace à l'aide d'un fichier YAML. L'exemple suivant utilise
app1-namespace.yamlpour créer un namespace nomméapp1-dev:apiVersion: v1 kind: Namespace metadata: name: app1-dev -
Exécutez la commande suivante pour créer le namespace :
kubectl apply -f app1-namespace.yaml -
Vérifiez que le namespace a été créé. Si la sortie inclut
app1-dev, le namespace est créé.kubectl get namespaces
-
-
Créez un compte de service.
-
Créez un compte de service à l'aide d'un fichier YAML. L'exemple suivant utilise
app1-serviceaccount.yamlpour créer un compte de service nomméapp1-servicedans le namespaceapp1-devque vous avez créé à l'étape précédente :apiVersion: v1 kind: ServiceAccount metadata: name: app1-service namespace: app1-dev -
Exécutez la commande suivante pour créer le compte de service :
kubectl apply -f app1-serviceaccount.yaml -
Vérifiez que le compte de service a été créé. Si la sortie inclut
app1-service, le compte de service est créé.kubectl get serviceaccount -n app1-dev
-
Étape 2 : Configurer les autorisations
L'accès cloud natif à KMS prend en charge les deux méthodes d'authentification suivantes.
OpenID Connect (OIDC) est recommandé pour la plupart des scénarios en raison de sa configuration plus simple. Utilisez un rôle RAM lorsque vous devez réutiliser des politiques de rôle RAM existantes ou lorsque vous avez besoin d'un accès inter-comptes.
|
Méthode d'authentification |
Fonctionnalités |
|
OIDC (ACK) |
Le cluster ACK s'authentifie à l'aide du standard JWT OpenID Connect (OIDC). L'Agent obtient automatiquement le jeton du compte de service pour prouver l'identité du pod à KMS. Aucun rôle RAM n'est requis et la configuration est la plus simple. |
|
Rôle RAM |
Accède à KMS en utilisant les identifiants temporaires STS d'un rôle RAM. Cette méthode convient aux scénarios où vous souhaitez réutiliser une configuration de rôle RAM existante. |
OIDC (ACK)
Dans le panneau de configuration qui s'affiche, définissez Authentication Method sur OIDC (ACK).
-
Configurez les paramètres suivants :
Paramètre
Description
Namespace
Nom du namespace dans lequel réside le pod, par exemple
app1-dev.ServiceAccount
Compte de service utilisé par le pod, par exemple
app1-service.PodNamePrefix
Préfixe du nom du pod. Après avoir configuré ce paramètre, seuls les pods dont les noms correspondent au préfixe sont autorisés à passer la vérification. Si vous ne configurez pas ce paramètre, seul le namespace et le compte de service sont vérifiés.
Scope
Méthode d'accès à KMS. Valeurs valides :
Specified KMS Instance : Accède aux clés et aux identifiants d'une instance KMS spécifique en utilisant le endpoint de l'instance.
Shared KMS Gateway : Accède aux identifiants en utilisant le endpoint du service KMS.
Application Access Point Name
Nom personnalisé du point d'accès à l'application (identifiant d'accès) pour l'identification et la gestion.
Policy Name
Nom personnalisé de la politique RAM. Créez une politique directement dans cette étape sans la précréer dans la console RAM.
RBAC Permissions
Niveau d'autorisation RBAC (Role-Based Access Control), qui détermine les autorisations d'opération sur les identifiants pour l'application.
Si Specified KMS Instance est sélectionné pour le scope :
CryptoServiceKeyUser : Autorise l'utilisation des clés dans l'instance KMS pour le chiffrement des identifiants.
CryptoServiceSecretUser : Autorise l'utilisation des identifiants dans l'instance KMS et prend en charge les API d'identifiants pour l'instance.
Si Shared KMS Gateway est sélectionné pour le scope : Seul SecretUser est pris en charge, ce qui permet l'utilisation de tous les identifiants sous le compte actuel.
Accessible Resources
Sélectionnez les identifiants et les clés (utilisés pour le chiffrement et le déchiffrement des identifiants) auxquels l'application doit accéder.
ImportantSi vous sélectionnez plusieurs identifiants et que la longueur totale des noms d'identifiants dépasse la limite, une erreur « parameter invalid » est renvoyée. Dans ce cas, utilisez un caractère générique pour spécifier les identifiants autorisés, par exemple
secret/rds-ibm*, ce qui permet d'accéder aux identifiants avec le préfixerds-ibm.Description
Facultatif. Description détaillée du point d'accès à l'application. Longueur maximale : 8 192 caractères.
Cliquez sur OK pour continuer.
Rôle RAM
-
Confirmez que le cluster ACK peut accéder à STS
Ajoutez le endpoint du service STS sts-intl.aliyuncs.com à la liste blanche de sortie du cluster ACK pour éviter qu'il ne soit bloqué par le pare-feu ou d'autres règles de défense réseau.
RemarqueL'utilisation de RAM Role pour KMS Agent doit appeler l'API STS
AssumeRoleWithOIDCpour obtenir des identifiants temporaires. Si le endpoint est bloqué, l'Agent ne peut pas actualiser les identifiants temporaires. -
Obtenez les informations du fournisseur d'identité.
Cliquez sur le nom du cluster cible pour accéder à la page des détails.
Dans l'onglet Basic Information, placez le pointeur sur l'étiquette Activé à côté de RRSA (RAM Roles for Service Accounts) OIDC dans la section Security and Auditing pour afficher les informations URL et ARN du fournisseur. L'URL du fournisseur est au format
https://oidc-ack-<region>.oss-<region>.aliyuncs.com/<cluster_id>et l'ARN du fournisseur est au formatacs:ram::<account_id>:oidc-provider/ack-rrsa-<cluster_id>.
-
Créez un rôle RAM.
Sélectionnez IdP comme type d'entité de confiance, puis cliquez sur Switch to Editor.
-
Dans la section Visual Editor, configurez les éléments suivants :
-
Configuration de base
Paramètre
Description
Effect
Sélectionnez Allow.
Action
Conservez la valeur par défaut
sts:AssumeRole.Condition
Ajoutez une condition avec la clé
oidc:sub, l'opérateurStringEqualset la valeursystem:serviceaccount:<namespace>:<ServiceAccountName>, oùnamespaceetServiceAccountNamecorrespondent au namespace et au compte de service du pod exécutant la charge de travail. -
Configurez le principal comme suit :
Sélectionnez Identity Provider comme Principal, puis cliquez sur Edit ci-dessous.
-
Sur la page de configuration Identity Provider, configurez les paramètres suivants et cliquez sur OK.
Paramètre
Description
IdP Type
Sélectionnez OIDC.
Fournisseur d'identité
Sélectionnez le fournisseur d'identité créé automatiquement par le cluster ACK après l'activation de RRSA :
ack-rrsa-<cluster_id>.RemarqueNe confondez pas la valeur
audiencests.aliyuncs.comdans la politique de confiance du rôle RAM et le modèle de pod avec le endpoint du service STS utilisé par KMS Agent. La valeuraudienceest l'ID client du fournisseur d'identité OIDC créé après l'activation de RRSA. Elle ne détermine pas le endpoint que KMS Agent utilise pour appeler STS.
-
Une fois la configuration terminée, cliquez sur OK pour définir le nom du rôle (par exemple,
app1-rrsa), puis cliquez sur OK.
-
Créez une politique et attachez-la au rôle RAM. Pour plus d'informations, consultez les rubriques Créer une politique personnalisée et Attacher une politique à un rôle RAM.
-
Cliquez sur Create Policy, sélectionnez Script Editor, puis configurez la politique à l'aide de l'exemple suivant.
RemarqueDans cet exemple, la politique est nommée
dev-role-for-rrsa-kms-policyet autorise l'accès uniquement aux identifiants portant le tagenv:app1.{ "Version": "1", "Statement": [ { "Effect": "Allow", "Action": [ "kms:Decrypt", "kms:GetSecretValue" ], "Resource": "*", "Condition": { "StringEqualsIgnoreCase": { "kms:tag/secret": [ "app1" ] } } } ] } Revenez à la liste des politiques, recherchez la politique cible et cliquez sur Attach to Identity dans la colonne Actions.
Dans la section Principal, sélectionnez le rôle RAM que vous avez créé, puis cliquez sur Confirm.
-
Étape 3 : Installer ack-kms-agent-webhook-injector
-
Sur la page Helm, cliquez sur Deploy. Configurez la section Basic Information, puis cliquez sur Next.
Paramètre
Description
Application Name
Utilisez le nom d'application par défaut
ack-kms-agent-webhook-injector.Namespace
Utilisez le namespace de chart par défaut
kube-system. Installez-le dans un seul namespace par cluster ACK ; inutile de l'installer plusieurs fois.Source
Par défaut : Marketplace. Ce paramètre ne peut pas être modifié.
Chart
Recherchez et sélectionnez
ack-kms-agent-webhook-injector. Lorsque la boîte de dialogue de confirmation apparaît, vérifiez les informations et cliquez sur Yes.
-
Sur la page Parameters, configurez les paramètres en fonction de la méthode d'authentification que vous avez sélectionnée à l'étape 2.
OIDC (ACK) : Conservez la configuration par défaut.
-
Rôle RAM : Laissez
agent.auth.roleArnvide et définissezagent.auth.roleArnMappingsur<Namespace>:<ServiceAccountName>:<RAM Role ARN>. L'exemple suivant utilise les données créées à l'étape 2 :RemarqueLes valeurs
NamespaceetServiceAccountNamecorrespondent au namespace et au compte de service du pod exécutant la charge de travail. L'ARN du rôle RAMpeut être consulté sur la page des détails du rôle RAM.agent: auth: roleArn: roleArnMapping: app1-dev:app1-service: acs:ram::190325303126****:role/app1-rrsa
Une fois la configuration terminée, cliquez sur OK. Vous êtes redirigé vers la page des détails de l'application.
Étape 4 : Injecter le Sidecar Agent
-
Ajouter une annotation de pod : Définissez la clé d'annotation sur
kms-agent-webhook-injector/injectet la valeur surtrue.-
Basculez vers le namespace dans lequel votre charge de travail s'exécute et ajoutez l'annotation de pod au Deployment.
ImportantPour la méthode d'authentification par rôle RAM, modifiez la configuration YAML du Deployment et définissez le paramètre
ServiceAccountNamesur le nom du compte de service du pod exécutant la charge de travail (par exemple,app1-service). Pour la méthode d'authentification OIDC (ACK), aucune modification n'est requise.-
Créer un nouveau Deployment
Create from Image
Cliquez sur Create from Image au-dessus de la liste des Deployments et configurez les paramètres.
Lors de la configuration de Advanced, accédez à la section Labels and Annotations et ajoutez l'annotation de pod : saisissez
kms-agent-webhook-injector/injectdans la colonne Name ettruedans la colonne Value.Cliquez sur Create pour terminer.
Create from YAML
Cliquez sur Create from YAML au-dessus de la liste des Deployments.
Modifiez le fichier YAML et ajoutez
kms-agent-webhook-injector/inject: "true"sousspec.template.metadata.annotations(créez cette section si elle n'existe pas).Cliquez sur Create pour terminer.
-
Modifier un Deployment existant
Recherchez la charge de travail cible et cliquez sur Actions > Details.
Sur la page des détails, cliquez sur Edit YAML en haut à droite.
Ajoutez
kms-agent-webhook-injector/inject: "true"sousspec.template.metadata.annotations(créez cette section si elle n'existe pas).Cliquez sur Update et attendez que la charge de travail soit prête.
-
-
-
Vérifier l'injection
-
Dans l'onglet Pods, vérifiez la colonne Image. Le KMS Agent apparaît injecté dans le pod en tant que Sidecar.
RemarqueUn pod peut être injecté deux fois avec le KMS Agent. Cela se produit parce qu'un conteneur d'initialisation est utilisé pour l'initialisation. Le conteneur d'initialisation se termine (Terminated) une fois l'initialisation achevée et n'a pas d'impact négatif sur l'application ni ne consomme continuellement des ressources de calcul.
-
Intégration de l'application
Une fois votre Deployment injecté avec le KMS Agent, le conteneur d'application peut récupérer les identifiants depuis KMS via des requêtes HTTP adressées au KMS Agent. Aucune AccessKey ne doit être configurée dans votre code. Les exemples suivants montrent comment récupérer les identifiants. Remplacez <SecretId> par le nom réel de votre identifiant.
Le KMS Agent écoute uniquement sur 127.0.0.1, ce qui signifie que seules les applications ou les processus sur la même machine peuvent communiquer avec lui. Les périphériques réseau externes ne peuvent pas se connecter. L'adresse d'accès prend uniquement en charge localhost ou 127.0.0.1, et non l'IP locale de l'application. Les exemples suivants utilisent localhost.
Outre la méthode d'accès via KMS Agent, KMS prend également en charge l'accès via SDK. Pour les opérations spécifiques, consultez la rubrique Secrets Manager Client.
OIDC (ACK)
Utilisation de curl
-
Exécutez la commande suivante pour récupérer un identifiant :
# 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>' -
La syntaxe
$(<file)est prise en charge uniquement dans les shells tels que bash et zsh. Si l'image de base de votre Pod utilise Alpine (dont le shell par défaut est BusyBox ash) ou toute autre image dont le shell par défaut ne prend pas en charge cette syntaxe, veuillez utiliser la commande suivante à la place :# 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>'
Utilisation de wget
-
Exécutez la commande suivante pour récupérer un identifiant :
# 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>' -
La syntaxe
$(<file)est prise en charge uniquement dans les shells tels que bash et zsh. Si l'image de base de votre Pod utilise Alpine (dont le shell par défaut est ash) ou toute autre image dont le shell par défaut ne prend pas en charge cette syntaxe, utilisez la commande suivante à la place :# 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>'
Exemple de code Go
L'exemple suivant montre comment récupérer un identifiant en utilisant 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))
}
Rôle RAM
Utilisation de curl
-
Exécutez la commande suivante pour récupérer un identifiant :
# 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>' -
La syntaxe
$(<file)est prise en charge uniquement dans les shells tels que bash et zsh. Si l'image de base de votre Pod utilise Alpine (dont le shell par défaut est BusyBox ash) ou toute autre image dont le shell par défaut ne prend pas en charge cette syntaxe, veuillez utiliser la commande suivante à la place :# 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>'
Utilisation de wget
-
Exécutez la commande suivante pour récupérer un identifiant :
# 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>' -
La syntaxe
$(<file)est prise en charge uniquement dans les shells tels que bash et zsh. Si l'image de base de votre Pod utilise Alpine (dont le shell par défaut est ash) ou toute autre image dont le shell par défaut ne prend pas en charge cette syntaxe, utilisez la commande suivante à la place :# 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>'
Exemple de code Go
L'exemple suivant montre comment récupérer un identifiant en utilisant 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))
}
Facturation
-
Coûts côté KMS :
Abonnement : Achetez une instance KMS avant d'utiliser le KMS Agent. Le KMS Agent lui-même n'entraîne pas de frais supplémentaires. Pour plus d'informations, consultez la rubrique Abonnement.
Paiement à l'utilisation : En plus des frais déjà encourus, des frais QPS supplémentaires s'appliquent lorsque le KMS Agent récupère des identifiants via des appels API. Pour plus d'informations, consultez la rubrique Paiement à l'utilisation.
-
Coûts côté ACK :
Le composant ack-kms-agent-webhook-injector est gratuit. Des coûts supplémentaires peuvent être engagés pour les ressources de calcul consommées par les charges de travail Sidecar et Webhook injectées.
Après avoir installé le composant ack-kms-agent-webhook-injector, une charge de travail de service Webhook est générée, ce qui consomme des ressources de calcul et engendre des coûts. Limitez l'utilisation du CPU et de la mémoire de cette charge de travail dans le fichier de configuration.
Lorsque vous créez ou mettez à jour une charge de travail éligible, ack-kms-agent-webhook-injector injecte le KMS Agent en tant que Sidecar dans le conteneur. Le KMS Agent consomme des ressources de calcul et engendre des coûts.
Dépannage
Si vous rencontrez des problèmes lors de l'installation ou de l'utilisation du KMS Agent, reportez-vous aux problèmes courants suivants pour le dépannage.
Cause | Solution |
Échec de l'installation de l'Agent | Exécutez |
Réseau inaccessible ou délai d'attente dépassé | Assurez-vous que le cluster ACK peut atteindre le service KMS. Si vous accédez à KMS via un VPC, assurez-vous que le VPC où réside le cluster ACK est connecté au réseau de l'instance KMS. |
Le KMS Agent ne parvient pas à obtenir des identifiants temporaires auprès de STS via | Procédez au dépannage comme suit :
Remarque : Une lecture réussie d'une valeur de secret mise en cache ne prouve pas que la chaîne d'identifiants du rôle RAM est saine. Vérifiez les journaux pour confirmer que |
Autorisations insuffisantes | Vérifiez les configurations suivantes :
|
Échec de l'injection de l'Agent | Vérifiez si le composant ack-kms-agent-webhook-injector est correctement installé et fonctionne normalement. Vérifiez que l'annotation de pod |
RRSA n'est pas activé | La méthode d'authentification OIDC (ACK) dépend de la fonctionnalité RRSA (RAM Roles for Service Accounts). Dans la console ACK, accédez au module de sécurité et d'audit du cluster pour activer RRSA. Pour les étapes détaillées, consultez la configuration du fournisseur d'identité dans l'onglet Rôle RAM de l'étape 2. |