Partilhar via


Liga-te a um Config Server gerido para Spring no Azure Container Apps

O Config Server for Spring fornece um local centralizado para disponibilizar dados de configuração para vários aplicativos. Neste artigo, aprende a ligar uma aplicação alojada no Azure Container Apps a uma instância do Java Config Server for Spring.

O Servidor de Configuração para o componente Spring Java utiliza um repositório GitHub como fonte para as definições de configuração. Os valores de configuração são disponibilizados para seu aplicativo de contêiner por meio de uma associação entre o componente e seu aplicativo de contêiner. À medida que os valores mudam no servidor de configuração, eles fluem automaticamente para seu aplicativo, tudo sem exigir que você recompile ou reimplante seu aplicativo.

Neste tutorial, irá aprender a:

  • Crie um Servidor de Configuração para o componente Spring Java
  • Vincular o Config Server for Spring ao seu aplicativo de contêiner
  • Observe os valores de configuração antes e depois de conectar o servidor de configuração ao seu aplicativo
  • Encriptar e decifrar valores de configuração com uma chave simétrica

Importante

Este tutorial utiliza serviços que podem afetar a sua fatura Azure. Se você decidir acompanhar o passo a passo, certifique-se de excluir os recursos apresentados neste artigo para evitar cobranças inesperadas.

Pré-requisitos

Considerações

Ao correr no Config Server for Spring no Azure Container Apps, esteja atento aos seguintes detalhes:

Item Explicação
Scope O Config Server for Spring é executado no mesmo ambiente que o aplicativo de contêiner conectado.
Dimensionamento Para manter uma única fonte de verdade, o Config Server para Spring não escala. As propriedades minReplicas de dimensionamento e maxReplicas estão ambas definidas como 1.
Recursos A alocação de recursos de contêiner para o Config Server for Spring é fixa, o número de núcleos de CPU é 0,5 e o tamanho da memória é 1Gi.
Preços O faturamento do Config Server for Spring se enquadra nos preços baseados no consumo. Os recursos consumidos pelos componentes Java geridos são faturados de acordo com as taxas de atividade/inatividade. Você pode excluir componentes que não estão mais em uso para interromper a cobrança.
Vinculação O aplicativo de contêiner se conecta a um Config Server for Spring por meio de uma ligação. A associação injeta configurações em variáveis de ambiente do aplicativo de contêiner. Depois que uma associação é estabelecida, o aplicativo contêiner pode ler valores de configuração de variáveis de ambiente.

Configurar

Antes de começar a trabalhar com o Config Server for Spring, primeiro você precisa criar os recursos necessários.

Execute os comandos a seguir para criar seu grupo de recursos e o ambiente de Aplicativos de Contêiner.

  1. Crie variáveis para dar suporte à configuração do aplicativo. Esses valores são fornecidos para você para os fins desta lição.

    export LOCATION=eastus
    export RESOURCE_GROUP=my-services-resource-group
    export ENVIRONMENT=my-environment
    export JAVA_COMPONENT_NAME=configserver
    export APP_NAME=my-config-client
    export IMAGE="mcr.microsoft.com/javacomponents/samples/sample-service-config-client:latest"
    export URI="https://github.com/Azure-Samples/azure-spring-cloud-config-java-aca.git"
    
    Variável Descrição
    LOCATION O local da região Azure onde cria a sua aplicação de contentores e o componente Java.
    ENVIRONMENT O nome do ambiente Azure Container Apps para a sua aplicação de demonstração.
    RESOURCE_GROUP O nome do grupo de recursos do Azure para a sua aplicação de demonstração.
    JAVA_COMPONENT_NAME O nome do componente Java criado para a tua aplicação container. Neste caso, crias um Config Server para o componente Spring Java.
    IMAGE A imagem de contêiner usada em seu aplicativo de contêiner.
    URI Você pode substituir o URI pela URL do repositório Git, se for privado, adicione as configurações de autenticação relacionadas, como spring.cloud.config.server.git.username e spring.cloud.config.server.git.password.
  2. Inicie sessão no Azure com a CLI do Azure.

    az login
    
  3. Crie um grupo de recursos.

    az group create --name $RESOURCE_GROUP --location $LOCATION
    
  4. Crie seu ambiente de aplicativos de contêiner.

    az containerapp env create \
        --name $ENVIRONMENT \
        --resource-group $RESOURCE_GROUP \
        --location $LOCATION
    

Esse ambiente é usado para hospedar o componente java do Config Server for Spring e seu aplicativo de contêiner.

Crie o Servidor de Configuração para o componente Spring Java

Agora que você tem um ambiente de aplicativos de contêiner, você pode criar seu aplicativo de contêiner e vinculá-lo a um componente java do Config Server for Spring. Quando você vincula seu aplicativo de contêiner, os valores de configuração são sincronizados automaticamente do componente Config Server para seu aplicativo.

  1. Crie o Servidor de Configuração para o componente Spring Java.

    az containerapp env java-component config-server-for-spring create \
        --environment $ENVIRONMENT \
        --resource-group $RESOURCE_GROUP \
        --name $JAVA_COMPONENT_NAME \
        --min-replicas 1 \
        --max-replicas 1 \
        --configuration spring.cloud.config.server.git.uri=$URI
    
  2. Atualize o Servidor de Configuração para o componente Spring Java.

    az containerapp env java-component config-server-for-spring update \
        --environment $ENVIRONMENT \
        --resource-group $RESOURCE_GROUP \
        --name $JAVA_COMPONENT_NAME \
        --min-replicas 2 \
        --max-replicas 2 \
        --configuration spring.cloud.config.server.git.uri=$URI spring.cloud.config.server.git.refresh-rate=60
    

    Aqui, você está dizendo ao componente onde encontrar o repositório que contém suas informações de configuração por meio da uri propriedade. A refresh-rate propriedade informa ao Container Apps com que frequência verificar se há alterações no repositório Git.

Vincule a sua aplicação container ao Config Server para o componente Spring Java

  1. Crie o aplicativo de contêiner que consome dados de configuração.

    az containerapp create \
        --name $APP_NAME \
        --resource-group $RESOURCE_GROUP \
        --environment $ENVIRONMENT \
        --image $IMAGE \
        --min-replicas 1 \
        --max-replicas 1 \
        --ingress external \
        --target-port 8080 \
        --query properties.configuration.ingress.fqdn
    

    Este comando retorna a URL do seu aplicativo de contêiner que consome dados de configuração. Copie o URL para um editor de texto para que você possa usá-lo em uma próxima etapa.

    Se você visitar seu aplicativo em um navegador, o connectTimeout valor retornado será o valor padrão de 0.

  2. Associe-se ao Config Server for Spring.

    Agora que o aplicativo de contêiner e o Config Server foram criados, você os vincula com o update comando ao seu aplicativo de contêiner.

    az containerapp update \
        --name $APP_NAME \
        --resource-group $RESOURCE_GROUP \
        --bind $JAVA_COMPONENT_NAME
    

    O --bind $JAVA_COMPONENT_NAME parâmetro cria o link entre seu aplicativo de contêiner e o componente de configuração.

Depois que o aplicativo contêiner e o componente Config Server são vinculados, as alterações de configuração são sincronizadas automaticamente com o aplicativo contêiner.

Quando você visita o URL do aplicativo novamente, o valor de connectTimeout é agora 10000. Esse valor vem do repositório Git definido na $URI variável originalmente definida como a origem do componente de configuração. Especificamente, esse valor é extraído da propriedade connectionTimeout no arquivo application.yml do repo.

O pedido de ligação introduz configurações no aplicativo como variáveis de ambiente. Esses valores agora estão disponíveis para o código do aplicativo para usar ao buscar definições de configuração do servidor de configuração.

Nesse caso, as seguintes variáveis de ambiente estão disponíveis para o aplicativo:

SPRING_CLOUD_CONFIG_URI=http://[JAVA_COMPONENT_INTERNAL_FQDN]:80
SPRING_CLOUD_CONFIG_COMPONENT_URI=http://[JAVA_COMPONENT_INTERNAL_FQDN]:80
SPRING_CONFIG_IMPORT=optional:configserver:$SPRING_CLOUD_CONFIG_URI

Se quiser personalizar o seu próprio SPRING_CONFIG_IMPORT, pode referir-se à variável de ambiente SPRING_CLOUD_CONFIG_COMPONENT_URI – por exemplo, pode substituir por argumentos de linha de comando, como Java -Dspring.config.import=optional:configserver:${SPRING_CLOUD_CONFIG_COMPONENT_URI}?fail-fast=true.

Você também pode remover uma associação do seu aplicativo.

(Opcional) Desvincule a sua aplicação container do Servidor de Configuração para o componente Spring Java

Para remover uma associação de uma aplicação contentor, use a opção --unbind.

az containerapp update \
    --name $APP_NAME \
    --unbind $JAVA_COMPONENT_NAME \
    --resource-group $RESOURCE_GROUP

Quando você visita o URL do aplicativo novamente, o valor de connectTimeout volta para 0.

Limpar recursos

Os recursos criados neste tutorial têm um impacto na sua fatura do Azure. Se você não vai usar esses serviços a longo prazo, execute o seguinte comando para remover tudo o que foi criado neste tutorial.

az group delete --resource-group $RESOURCE_GROUP

Opções de configuração

O az containerapp update comando usa o --configuration parâmetro para controlar como o Config Server for Spring é configurado. Você pode usar vários parâmetros ao mesmo tempo, desde que estejam separados por um espaço. Para obter mais informações, consulte Spring Cloud Config Server.

A tabela a seguir descreve os diferentes valores de configuração de back-end do Git disponíveis:

Nome Descrição
spring.cloud.config.server.git.uri
spring.cloud.config.server.git.repos.{repoName}.uri
URI do repositório remoto.
spring.cloud.config.server.git.username
spring.cloud.config.server.git.repos.{repoName}.username
Nome de usuário para autenticação com repositório remoto.
spring.cloud.config.server.git.password
spring.cloud.config.server.git.repos.{repoName}.password
Senha para autenticação com repositório remoto.
spring.cloud.config.server.git.search-paths
spring.cloud.config.server.git.repos.{repoName}.search-paths
Percursos de pesquisa para usar na cópia de trabalho local. Por padrão, pesquisa apenas a raiz.
spring.cloud.config.server.git.force-pull
spring.cloud.config.server.git.repos.{repoName}.force-pull
Indicador para indicar que o repositório deve forçar o pull. Se true, descarte todas as alterações locais e obtenha do repositório remoto.
spring.cloud.config.server.git.default-label
spring.cloud.config.server.git.repos.{repoName}.default-label
O rótulo padrão usado para o Git é principal. Se não definires spring.cloud.config.server.git.default-label e não existir um branch chamado main, o servidor de configuração por padrão também tenta procurar um branch chamado master. Se quiser desativar o comportamento de ramificação de fallback, você pode definir spring.cloud.config.server.git.tryMasterBranch como false.
spring.cloud.config.server.git.try-master-branch
spring.cloud.config.server.git.repos.{repoName}.try-master-branch
O servidor de configuração, por defeito, tenta verificar um ramo chamado master.
spring.cloud.config.server.git.skip-ssl-validation
spring.cloud.config.server.git.repos.{repoName}.skip-ssl-validation
Você pode desabilitar a validação do certificado TLS/SSL do servidor Git pelo servidor de configuração definindo a git.skipSslValidation propriedade como true.
spring.cloud.config.server.git.clone-on-start
spring.cloud.config.server.git.repos.{repoName}.clone-on-start
Sinalizador para indicar que o repositório deve ser clonado na inicialização, não sob demanda. Geralmente leva a uma inicialização mais lenta, mas a primeira consulta é mais rápida.
spring.cloud.config.server.git.timeout
spring.cloud.config.server.git.repos.{repoName}.timeout
Tempo limite em segundos para obter conexão HTTP ou SSH, se aplicável. O valor padrão é 5 segundos.
spring.cloud.config.server.git.refresh-rate
spring.cloud.config.server.git.repos.{repoName}.refresh-rate
Com que frequência o servidor de configuração busca dados de configuração atualizados do seu back-end Git.
spring.cloud.config.server.git.private-key
spring.cloud.config.server.git.repos.{repoName}.private-key
Chave privada SSH válida. Deve ser definido se ignore-local-ssh-settings é true e o URI do Git está no formato SSH.
spring.cloud.config.server.git.host-key
spring.cloud.config.server.git.repos.{repoName}.host-key
Chave de host SSH válida. Deve ser definido se host-key-algorithm também estiver definido.
spring.cloud.config.server.git.host-key-algorithm
spring.cloud.config.server.git.repos.{repoName}.host-key-algorithm
Um dos ssh-dss, ssh-rsa, ssh-ed25519, , ecdsa-sha2-nistp256ecdsa-sha2-nistp384, ou ecdsa-sha2-nistp521. Deve ser definido se host-key também estiver definido.
spring.cloud.config.server.git.strict-host-key-checking
spring.cloud.config.server.git.repos.{repoName}.strict-host-key-checking
true ou false. Se false, ignore erros com chave de host.
spring.cloud.config.server.git.repos.{repoName} URI do repositório remoto.
spring.cloud.config.server.git.repos.{repoName}.pattern O formato padrão é uma lista separada por vírgulas de {application}/{profile} nomes com curingas. Se {application}/{profile} não corresponder a nenhum dos padrões, usa o URI padrão definido abaixo.

A lista a seguir descreve configurações comuns:

  • Configurações relacionadas ao registo:

    • logging.level.*
    • logging.group.*
    • Quaisquer outras configurações sob o logging.* namespace devem ser proibidas - por exemplo, escrever arquivos de log usando logging.file deve ser proibido.
  • spring.cloud.config.server.overrides

    • Mapa extra para uma fonte de propriedade a ser enviado a todos os clientes incondicionalmente.
  • spring.cloud.config.override-none

    • Você pode alterar a prioridade de todas as substituições no cliente para se assemelhar mais aos valores padrão, permitindo que os aplicativos forneçam os seus próprios valores em variáveis de ambiente ou propriedades do sistema, ao definir o sinalizador spring.cloud.config.override-none=true - o padrão é falso - no repositório remoto.
  • spring.cloud.config.allow-override

    • Se ativares o bootstrap do tipo "config first", podes permitir que as aplicações clientes sobreponham a configuração do servidor de configuração. A substituição é feita colocando duas propriedades na configuração da aplicação provenientes do servidor de configuração.
  • spring.cloud.config.server.health.*

    • Você pode configurar o Indicador de integridade para verificar mais aplicativos, juntamente com perfis personalizados e rótulos personalizados.
  • spring.cloud.config.server.accept-empty

    • Você pode definir spring.cloud.config.server.accept-empty como false para que o servidor retorne um status HTTP 404 se a aplicação não for encontrada. Por padrão, esse sinalizador é definido como true.
  • Encriptação e desencriptação (simétrica):

    • encrypt.key
      • Conveniente quando você usa uma chave simétrica porque é um único valor de propriedade para configurar.
    • spring.cloud.config.server.encrypt.enabled
      • Defina esta propriedade como false para desativar a desencriptação do lado do servidor.

Atualizar

Os serviços que consomem propriedades precisam saber sobre uma mudança antes que ela aconteça. O método de notificação padrão para o Config Server for Spring envolve acionar manualmente o evento de atualização, como uma atualização por chamada https://<YOUR_CONFIG_CLIENT_HOST_NAME>/actuator/refresh, que pode não ser viável se houver muitas instâncias de aplicativo.

Em vez disso, você pode atualizar automaticamente os valores do Config Server permitindo que o cliente de configuração pesquise alterações com base em uma atualização interna. Use as seguintes etapas para atualizar automaticamente os valores do Config Server:

  1. Registre uma tarefa agendada para atualizar o contexto em um determinado intervalo, conforme mostrado no exemplo a seguir:

    @Configuration
    @AutoConfigureAfter({RefreshAutoConfiguration.class, RefreshEndpointAutoConfiguration.class})
    @EnableScheduling
    public class ConfigClientAutoRefreshConfiguration implements SchedulingConfigurer {
        @Value("${spring.cloud.config.refresh-interval:60}")
        private long refreshInterval;
        @Value("${spring.cloud.config.auto-refresh:false}")
        private boolean autoRefresh;
        private final RefreshEndpoint refreshEndpoint;
        public ConfigClientAutoRefreshConfiguration(RefreshEndpoint refreshEndpoint) {
            this.refreshEndpoint = refreshEndpoint;
        }
        @Override
        public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
            if (autoRefresh) {
                // set minimal refresh interval to 5 seconds
                refreshInterval = Math.max(refreshInterval, 5);
                scheduledTaskRegistrar.addFixedRateTask(refreshEndpoint::refresh,  Duration.ofSeconds(refreshInterval));
            }
        }
    }
    
  2. Habilite autorefresh e defina o intervalo de atualização apropriado no arquivo application.yml . No exemplo a seguir, o cliente sonda uma alteração de configuração a cada 60 segundos, que é o valor mínimo que você pode definir para um intervalo de atualização.

    Por padrão, autorefresh é definido como false e refresh-interval é definido como 60 segundos.

    spring:
        cloud:
            config:
            auto-refresh: true
            refresh-interval: 60
    management:
        endpoints:
            web:
            exposure:
                include:
                - refresh
    
  3. Adicione @RefreshScope ao seu código. No exemplo a seguir, a variável connectTimeout é atualizada automaticamente a cada 60 segundos:

    @RestController
    @RefreshScope
    public class HelloController {
        @Value("${timeout:4000}")
        private String connectTimeout;
    }
    

Encriptação e desencriptação com uma chave simétrica

Desencriptação do lado do servidor

Por padrão, a criptografia do lado do servidor está habilitada. Use os seguintes passos para ativar a desencriptação na sua aplicação:

  1. Adicione a propriedade criptografada em seu arquivo .properties no repositório Git.

    O seu ficheiro deve assemelhar-se ao seguinte exemplo:

    message={cipher}f43e3df3862ab196a4b367624a7d9b581e1c543610da353fbdd2477d60fb282f
    
  2. Atualize o Servidor de Configuração para o componente Spring Java para usar o repositório Git que tem a propriedade encriptada e definir a chave de encriptação.

    Antes de executar o comando a seguir, substitua pelos seus valores os espaços reservados cercados por <>.

    az containerapp env java-component config-server-for-spring update \
        --environment <ENVIRONMENT_NAME> \
        --resource-group <RESOURCE_GROUP> \
        --name <JAVA_COMPONENT_NAME> \
        --configuration spring.cloud.config.server.git.uri=<URI> encrypt.key=randomKey
    

Desencriptação do lado do cliente

Pode usar a desencriptação de propriedades do lado do cliente seguindo os passos:

  1. Adicione a propriedade criptografada em seu arquivo .properties no repositório Git.

  2. Atualize o Servidor de Configuração para o componente Spring Java para usar o repositório Git que tem a propriedade encriptada e desative a desencriptação do lado do servidor.

    Antes de executar o comando a seguir, substitua os espaços reservados cercados por <> pelos seus valores.

    az containerapp env java-component config-server-for-spring update \
        --environment <ENVIRONMENT_NAME> \
        --resource-group <RESOURCE_GROUP> \
        --name <JAVA_COMPONENT_NAME> \
        --configuration spring.cloud.config.server.git.uri=<URI> spring.cloud.config.server.encrypt.enabled=false
    
  3. No seu aplicativo cliente, adicione a chave ENCRYPT_KEY=randomKey de desencriptação como uma variável de ambiente.

    Como alternativa, se você incluir spring-cloud-starter-bootstrap no classpath, ou definir spring.cloud.bootstrap.enabled=true como uma propriedade do sistema, defina encrypt.key em bootstrap.properties.

    Antes de executar o comando a seguir, substitua pelos seus valores os espaços reservados cercados por <>.

    az containerapp update \
        --name <APP_NAME> \
        --resource-group <RESOURCE_GROUP> \
        --set-env-vars "ENCRYPT_KEY=randomKey"
    
    encrypt:
      key: somerandomkey