Todos los productos
Search
Centro de documentos

Tair (Redis® OSS-Compatible):Use KMS to manage instance credentials

Última actualización: Sep 03, 2026

Almacene las credenciales de la instancia de Tair (Redis OSS-compatible) en KMS para que su aplicación recupere las contraseñas dinámicamente mediante el SDK, en lugar de integrar credenciales estáticas. También puede habilitar la rotación de credenciales para reducir el riesgo de filtraciones.

Funcionamiento

Con las credenciales gestionadas por KMS para instancias de Tair (Redis OSS-compatible), su aplicación ya no necesita contraseñas estáticas. Un administrador crea una credencial de instancia en KMS y la aplicación invoca la operación GetSecretValue para recuperar la cuenta y la contraseña en tiempo de ejecución.

Por ejemplo, si el nombre de la credencial es username, KMS crea tanto la cuenta username como username_clone en la instancia. Este enfoque de doble cuenta ofrece mayor disponibilidad y seguridad. Puede establecer una directiva de rotación en la consola de KMS. De forma predeterminada, KMS rota las cuentas cada 24 horas y alterna cuál de ellas está activa. Redis/Tair credentials.

Importante

No modifique ni elimine las contraseñas de cuentas gestionadas por KMS en la consola de Tair (Redis OSS-compatible). Esto evita interrupciones en el servicio.

image

Limitaciones

  • No es posible cambiar la contraseña de una cuenta gestionada por KMS desde la consola de Tair. Rótela manualmente o configure la rotación automática en la consola de KMS. Rotate Redis/Tair credentials.

  • No es posible eliminar una cuenta gestionada por KMS desde la consola de Tair. En su lugar, elimínela desde la consola de KMS. Delete Redis credentials.

  • No es posible modificar la descripción de una cuenta gestionada por KMS desde la consola de Tair.

Requisitos previos

  • Una instancia ECS con conectividad a la instancia de Tair. Este tema utiliza Alibaba Cloud Linux 3.2104 LTS de 64 bits con Java 1.8.0.

  • Si utiliza un usuario RAM o un rol RAM para gestionar las credenciales de la instancia, asigne la directiva de sistema AliyunKMSSecretAdminAccess al usuario o rol correspondiente. Grant permissions.

Procedimiento

  1. Cree y habilite una instancia de KMS. Create and enable a KMS instance.

    Seleccione la misma VPC que la instancia ECS al crear la instancia de KMS.

    Si ya cuenta con una instancia de KMS, agregue la VPC de la instancia ECS a dicha instancia. Configure a VPC.

  2. Cree un punto de acceso de aplicación (AAP). Create an application access point.

    Tras la creación, el navegador descarga el application identity credential content (ClientKeyContent, a JSON file) y el credential security token (ClientKeyPassword). Guárdelos en un lugar seguro.

  3. Descargue el certificado CA de la instancia de KMS desde la página Instance Management. Obtain the CA certificate of a KMS instance.

  4. Cree una customer master key (CMK). Getting started with key management.

  5. Cree una credencial para la instancia de Tair (Redis OSS-compatible). Create a Redis/Tair credential.

  6. Escriba el código de prueba en Java.

    1. Agregue las siguientes dependencias de Maven. La sección <build> empaqueta todas las dependencias en un único JAR.

          <dependencies>
              <dependency>
                  <groupId>redis.clients</groupId>
                  <artifactId>jedis</artifactId>
                  <version>5.1.0</version>
              </dependency>
              <dependency>
                  <groupId>com.aliyun</groupId>
                  <artifactId>alibabacloud-dkms-gcs-sdk</artifactId>
                  <version>0.5.2</version>
              </dependency>
              <dependency>
                  <groupId>com.aliyun</groupId>
                  <artifactId>tea</artifactId>
                  <version>1.2.3</version>
              </dependency>
              <dependency>
                  <groupId>org.slf4j</groupId>
                  <artifactId>slf4j-api</artifactId>
                  <version>1.7.10</version>
              </dependency>
              <dependency>
                  <groupId>ch.qos.logback</groupId>
                  <artifactId>logback-classic</artifactId>
                  <version>1.2.9</version>
              </dependency>
          </dependencies>
      
          <build>
              <plugins>
                  <plugin>
                      <groupId>org.apache.maven.plugins</groupId>
                      <artifactId>maven-assembly-plugin</artifactId>
                      <version>3.3.0</version>
                      <configuration>
                          <archive>
                              <manifest>
                                  <mainClass>
                                      com.aliyun.KMSJedisTest
                                  </mainClass>
                              </manifest>
                          </archive>
                          <descriptorRefs>
                              <descriptorRef>jar-with-dependencies</descriptorRef>
                          </descriptorRefs>
                      </configuration>
                      <executions>
                          <execution>
                              <id>assemble-all</id>
                              <phase>package</phase>
                              <goals>
                                  <goal>single</goal>
                              </goals>
                          </execution>
                      </executions>
                  </plugin>
                  <plugin>
                      <groupId>org.apache.maven.plugins</groupId>
                      <artifactId>maven-compiler-plugin</artifactId>
                      <configuration>
                          <source>1.8</source>
                          <target>1.8</target>
                      </configuration>
                  </plugin>
              </plugins>
          </build>
    2. Escriba el código principal en KMSJedisTest.java.

      Nota

      Este ejemplo almacena en caché las credenciales durante 600 segundos (configurable mediante setCredentialCacheTime) para evitar llamadas a KMS en cada nueva conexión. Se recomienda una duración de caché de al menos 10 minutos.

      package com.aliyun;
      
      import java.time.Duration;
      
      import redis.clients.jedis.DefaultJedisClientConfig;
      import redis.clients.jedis.HostAndPort;
      import redis.clients.jedis.Jedis;
      import redis.clients.jedis.JedisPool;
      
      public class KMSJedisTest {
          public static void main(String[] args) throws Exception {
              if (args.length < 2) {
                  System.out.println(
                      "Please input kmsEndpoint, clientKeyFilePath, clientKeyPass, caCertPath, secretName, redisHost");
                  return;
              }
      
              String endpoint = args[0];
              String clientKeyFilePath = args[1];
              String clientKeyPass = args[2];
              String caCertPath = args[3];
              String secretName = args[4];
              KMSRedisCredentialsProvider kmsRedisCredentialsProvider = new KMSRedisCredentialsProvider(endpoint,
                  clientKeyFilePath, clientKeyPass, caCertPath, secretName);
              kmsRedisCredentialsProvider.setCredentialCacheTime(Duration.ofSeconds(10)); // Set the cache duration to prevent frequent requests to KMS.
      
              String redisHost = args[5];
              JedisPool jedisPool = new JedisPool(HostAndPort.from(redisHost),
                  DefaultJedisClientConfig.builder().credentialsProvider(kmsRedisCredentialsProvider).build());
      
              for (int i = 0; i < Integer.MAX_VALUE; i++) {
                  Thread.sleep(1000);
                  try (Jedis jedis = jedisPool.getResource()) {
                      System.out.println(jedis.set("" + i, "" + i));
                      System.out.println(jedis.get("" + i));
                  } catch (Exception e) {
                      System.out.println(e);
                  }
              }
          }
      }
      
    3. Escriba el código para KMSRedisCredentialsProvider.java.

      package com.aliyun;
      
      import java.time.Duration;
      import java.time.LocalDateTime;
      import java.time.format.DateTimeFormatter;
      
      import org.json.JSONObject;
      import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
      import redis.clients.jedis.DefaultRedisCredentials;
      import redis.clients.jedis.RedisCredentials;
      import redis.clients.jedis.RedisCredentialsProvider;
      
      import com.aliyun.dkms.gcs.openapi.models.Config;
      import com.aliyun.dkms.gcs.sdk.Client;
      import com.aliyun.dkms.gcs.sdk.models.*;
      
      public class KMSRedisCredentialsProvider implements RedisCredentialsProvider {
          private static final Logger logger = LoggerFactory.getLogger(KMSRedisCredentialsProvider.class);
      
          private final String endpoint;
          private final String clientKeyFilePath;
          private final String clientKeyPass;
          private final String caCertPath;
          private final String secretName;
          private static Client client = null;
      
          // credential cache time
          private Duration credentialCacheTime = Duration.ofSeconds(600);
          private DefaultRedisCredentials cachedCredentials = null;
          private LocalDateTime credentialsExpiration = null;
      
          public KMSRedisCredentialsProvider(String endpoint, String clientKeyFilePath, String clientKeyPass,
              String caCertPath, String secretName) {
              this.endpoint = endpoint;
              this.clientKeyFilePath = clientKeyFilePath;
              this.clientKeyPass = clientKeyPass;
              this.caCertPath = caCertPath;
              this.secretName = secretName;
              createClientInstance(endpoint, clientKeyFilePath, clientKeyPass, caCertPath);
          }
      
          public void setCredentialCacheTime(Duration credentialCacheTime) {
              this.credentialCacheTime = credentialCacheTime;
          }
      
          private static synchronized void createClientInstance(String endpoint, String clientKeyFilePath,
              String clientKeyPass, String caCertPath) {
              if (client == null) {
                  try {
                      client = new Client(new Config()
                          .setProtocol("https")
                          .setEndpoint(endpoint)
                          .setCaFilePath(caCertPath)
                          .setClientKeyFile(clientKeyFilePath)
                          .setPassword(clientKeyPass));
                  } catch (Exception e) {
                      logger.error("Init kms client failed", e);
                      throw new RuntimeException(e);
                  }
              }
          }
      
          @Override
          public RedisCredentials get() {
              try {
                  LocalDateTime now = LocalDateTime.now();
                  // Check cache
                  if (cachedCredentials != null && now.isBefore(credentialsExpiration)) {
                      return cachedCredentials;
                  }
      
                  GetSecretValueRequest request = new GetSecretValueRequest().setSecretName(secretName);
                  GetSecretValueResponse getSecretValueResponse = client.getSecretValue(request);
                  logger.debug("Now: " + now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) +
                      ", getSecretValueRequest: " + request);
                  String secretData = getSecretValueResponse.getSecretData();
                  JSONObject secretObject = new JSONObject(secretData);
                  if (secretObject.get("AccountName") == null || secretObject.get("AccountPassword") == null) {
                      throw new IllegalArgumentException("secretData must contain AccountName and AccountPassword");
                  }
                  cachedCredentials = new DefaultRedisCredentials(secretObject.get("AccountName").toString(),
                      secretObject.get("AccountPassword").toString());
                  credentialsExpiration = now.plusSeconds(credentialCacheTime.getSeconds());
                  return cachedCredentials;
              } catch (Exception e) {
                  logger.error("get secret failed", e);
                  throw new RuntimeException(e);
              }
          }
      
          @Override
          public void prepare() {
              // do nothing
          }
      
          @Override
          public void cleanUp() {
              // do nothing
          }
      }
      
    4. Empaquete todo el proyecto en un archivo JAR mediante la ejecución del siguiente comando: mvn package.

  7. Ejecute el JAR en la instancia ECS para conectarse a Tair.

    Sintaxis:

    java -jar <kms-redis-jar-with-dependencies.jar> <kmsEndpoint> <clientKeyFilePath> <clientKeyPass> <caCertPath> <secretName> <redisHost>

    Parámetros:

    • kms-redis-jar-with-dependencies.jar: El JAR empaquetado con todas las dependencias.

    • kmsEndpoint: El endpoint de VPC de la instancia de KMS, disponible en la página de detalles de la instancia.

    • clientKeyFilePath: El archivo JSON de credenciales de identidad del AAP descargado en el paso 2.

    • clientKeyPass: El token de seguridad de credenciales (archivo TXT) descargado en el paso 2.

    • caCertPath: El certificado CA de la instancia de KMS (archivo PEM) descargado en el paso 3.

    • secretName: El nombre de la credencial de instancia creada en el paso 5.

    • redisHost: La dirección de conexión de VPC y el puerto; por ejemplo, r-bp1g727yrai5yh.redis.rds.aliyuncs.com:6379.

    Ejemplo:

    java -jar kms-redis-samples-1.0-SNAPSHOT-jar-with-dependencies.jar kst-hzz6674e7fbw21x9x****.cryptoservice.kms.aliyuncs.com /root/clientKey_KAAP.6432ddc6-f23a-4d78-ac84-****4598206b.json 267d1****1cda4415058e1d72ec49e0a /root/PrivateKmsCA_kst-hzz6674e7fbw21x9x****.pem kms-redis r-bp1g727yrai5yh****.redis.rds.aliyuncs.com:6379

    Salida esperada tras una conexión exitosa:

    0
    OK
    1
    OK
    2
    OK
    3
    OK
    4
    OK
  8. Pruebe la rotación inmediata de credenciales en la consola de KMS. Rotate Redis/Tair credentials.

    La rotación alterna la cuenta activa entre username y username_clone.

    Si la conexión de ECS permanece estable, la rotación funciona correctamente.

    ...
    30
    OK
    31
    OK
    32
    OK
    33
    OK
  9. Realice una prueba de conmutación por error de alta disponibilidad (HA) maestro-réplica en la instancia y supervise el cliente.

    La siguiente salida muestra una desconexión transitoria durante la conmutación por error de HA, seguida de una reconexión exitosa después de que KMS actualizó la credencial.

    138
    OK
    139
    redis.clients.jedis.exceptions.JedisConnectionException: Unexpected end of stream.
    OK
    142
    OK
    143
    OK

Referencias