Implantação contínua no Google Kubernetes Engine (GKE) com o Cloud Build

1. Visão geral

Neste laboratório, você vai aprender a configurar um pipeline de entrega contínua para GKE com o Cloud Build. Este laboratório mostra como acionar jobs do Cloud Build para diferentes eventos do Git, além de um padrão simples para lançamentos canários automatizados no GKE.

Você vai concluir as seguintes etapas:

  • Criar o aplicativo do GKE
  • Automatizar implantações para ramificações do Git
  • Automatizar implantações para a ramificação principal do Git
  • Automatizar implantações para tags do Git

2. Antes de começar

Para este guia de referência, você precisa de um projeto do Google Cloud. É possível criar um novo projeto ou selecionar um que já foi criado:

  1. Selecione ou crie um projeto do Google Cloud.

ACESSAR A PÁGINA DO SELETOR DE PROJETOS

  1. Ative o faturamento no projeto.

ATIVAR FATURAMENTO

3. Como preparar o ambiente

  1. Crie variáveis de ambiente para usar neste tutorial:
    export PROJECT_ID=$(gcloud config get-value project)
    export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format='value(projectNumber)')
    
    export ZONE=us-central1-b
    export CLUSTER=gke-progression-cluster
    export APP_NAME=myapp
    
  2. Ative as seguintes APIs:
    • Resource Manager
    • GKE
    • Cloud Source Repositories
    • Cloud Build
    • Container Registry
    gcloud services enable \
        cloudresourcemanager.googleapis.com \
        container.googleapis.com \
        sourcerepo.googleapis.com \
        cloudbuild.googleapis.com \
        containerregistry.googleapis.com \
        --async
    
  3. Clone a origem de amostra e mude para o diretório do laboratório:
    git clone https://github.com/GoogleCloudPlatform/software-delivery-workshop.git gke-progression
    
    cd gke-progression/labs/gke-progression
    rm -rf ../../.git
    
  4. Substitua os valores de marcador no repositório de amostra pelo seu PROJECT_ID:nesta etapa, você cria instâncias dos vários arquivos de configuração exclusivos do seu ambiente atual.Para conferir um exemplo dos modelos sendo atualizados, execute o seguinte comando.
    cat k8s/deployments/dev/frontend-dev.yaml.tmpl
    
    Execute o comando a seguir para fazer a substituição de variáveis.
    for template in $(find . -name '*.tmpl'); do envsubst '${PROJECT_ID} ${ZONE} ${CLUSTER} ${APP_NAME}' < ${template} > ${template%.*}; done
    
    Para revisar um exemplo do arquivo após a substituição, execute o seguinte comando.
    cat k8s/deployments/dev/frontend-dev.yaml
    
  5. Se você nunca usou o Git no Cloud Shell, defina os valores user.name e user.email que quer usar:
    git config --global user.email "YOUR_EMAIL_ADDRESS"
    git config --global user.name "YOUR_USERNAME"
    
  6. Armazene o código do repositório de amostra no Cloud Source Repositories:
    gcloud source repos create gke-progression
    git init
    git config credential.helper gcloud.sh
    git remote add gcp https://source.developers.google.com/p/$PROJECT_ID/r/gke-progression
    git branch -m main
    git add . && git commit -m "initial commit"
    git push gcp main
    
  7. Crie seu cluster do GKE.
    gcloud container clusters create ${CLUSTER} \
        --project=${PROJECT_ID} \
        --zone=${ZONE}
    
  8. Conceda direitos do Cloud Build ao seu cluster.O Cloud Build vai implantar o aplicativo no cluster do GKE e precisa de direitos para isso.
    gcloud projects add-iam-policy-binding ${PROJECT_ID} \
        --member=serviceAccount:${PROJECT_NUMBER}@cloudbuild.gserviceaccount.com \
        --role=roles/container.developer
    

Seu ambiente está pronto!

4. Como criar seu aplicativo do GKE

Nesta seção, você criará e implantará o aplicativo de produção inicial usado ao longo deste tutorial.

  1. Crie o aplicativo com o Cloud Build:
    gcloud builds submit --tag gcr.io/$PROJECT_ID/$APP_NAME:1.0.0 src/
    
  2. Implante manualmente nos ambientes canário e de produção:crie as implantações e serviços de produção e canário usando os comandos kubectl apply.
    kubectl create ns production
    kubectl apply -f k8s/deployments/prod -n production
    kubectl apply -f k8s/deployments/canary -n production
    kubectl apply -f k8s/services -n production
    
    O serviço implantado aqui vai rotear o tráfego para as implantações canário e de produção.
  3. Revise o número de pods em execução. Confirme que você tem quatro pods em execução para o front-end, incluindo três para o tráfego de produção e um para as versões canário. Isso significa que as mudanças na versão canário vão afetar apenas um a cada quatro usuários (25%).
    kubectl get pods -n production -l app=$APP_NAME -l role=frontend
    
  4. Consulte o endereço IP externo dos serviços de produção.
    kubectl get service $APP_NAME -n production
    
    Depois que o balanceador de carga retornar o endereço IP, continue para a próxima etapa.
  5. Armazene o IP externo para uso posterior.
    export PRODUCTION_IP=$(kubectl get -o jsonpath="{.status.loadBalancer.ingress[0].ip}"  --namespace=production services $APP_NAME)
    
  6. Revise o aplicativo e verifique a saída da versão do serviço. Ele deve ler "Hello World v1.0".
    curl http://$PRODUCTION_IP
    

Parabéns! Você implantou o app de exemplo. Em seguida, você vai configurar acionadores para implantar as mudanças de maneira contínua.

5. Automatizar implantações para ramificações do Git

Nesta seção, você vai configurar um gatilho que executa um job do Cloud Build no commit de qualquer ramificação que não seja main. O arquivo do Cloud Build usado aqui cria automaticamente um namespace e uma implantação para qualquer ramificação nova ou atual, permitindo que os desenvolvedores visualizem o código antes da integração com a ramificação principal.

  1. Configure o acionador:o componente principal desse acionador é o uso do parâmetro branchName para corresponder a main e o parâmetro invertRegex, que é definido como "true" e altera o padrão branchName para corresponder a qualquer coisa que não seja main. Para sua referência, você pode encontrar as seguintes linhas em build/branch-trigger.json.
      "branchName": "main",
      "invertRegex": true
    
    Além disso, as últimas linhas do arquivo do Cloud Build usado com esse gatilho criam um namespace com o nome da ramificação que acionou o job e implantam o aplicativo e o serviço no novo namespace. Para sua referência, você pode encontrar as seguintes linhas em build/branch-cloudbuild.yaml
      kubectl get ns ${BRANCH_NAME} || kubectl create ns ${BRANCH_NAME}
      kubectl apply --namespace ${BRANCH_NAME} --recursive -f k8s/deployments/dev
      kubectl apply --namespace ${BRANCH_NAME} --recursive -f k8s/services
    
    Agora que você entende os mecanismos em uso, crie o gatilho com o comando gcloud abaixo.
    gcloud beta builds triggers create cloud-source-repositories \
      --trigger-config build/branch-trigger.json
    
  2. Para analisar o gatilho, acesse a página Gatilhos do Cloud Build no console.Acessar gatilhos
  3. Crie uma ramificação:
    git checkout -b new-feature-1
    
  4. Modifique o código para indicar v1.1Edite src/app.py e mude a resposta de 1.0 para 1.1
    @app.route('/')
    def hello_world():
        return 'Hello World v1.1'
    
  5. Confirme a mudança e envie para o repositório remoto:
    git add . && git commit -m "updated" && git push gcp new-feature-1
    
  6. Para revisar a versão em andamento, acesse a página de histórico do Cloud Build no console. Acesse "Builds". Depois que a versão for concluída, continue para a próxima etapa.
  7. Recupere o endereço IP externo do serviço de ramificação recém-implantado.
    kubectl get service $APP_NAME -n new-feature-1
    
    Depois que o balanceador de carga retornar o endereço IP, continue para a próxima etapa.
  8. Armazene o IP externo para uso posterior.
    export BRANCH_IP=$(kubectl get -o jsonpath="{.status.loadBalancer.ingress[0].ip}"  --namespace=new-feature-1 services $APP_NAME)
    
  9. Revise o aplicativo e verifique a resposta retornada para a versão do serviço. Ele deve ler "Hello World v1.0".
    curl http://$BRANCH_IP
    

6. Como automatizar implantações para a ramificação principal do git

Antes de liberar o código para produção, é comum liberar o código para um pequeno subconjunto de tráfego em tempo real antes de migrar todo o tráfego para a nova base de código.

Nesta seção, você implementará um acionador que será ativado quando o código for confirmado na ramificação principal. O gatilho implanta a implantação canário, que recebe 25% de todo o trânsito em tempo real para a nova revisão.

  1. Configure o acionador para a ramificação principal:
    gcloud beta builds triggers create cloud-source-repositories \
      --trigger-config build/main-trigger.json
    
  2. Para analisar o novo gatilho, acesse a página "Gatilhos do Cloud Build" no console.Acessar gatilhos
  3. Mescle a ramificação à linha principal e envie ao repositório remoto:
    git checkout main
    git merge new-feature-1
    git push gcp main
    
  4. Para revisar a versão em andamento, acesse a página de histórico do Cloud Build no console. Acesse "Compilações". Depois que a compilação for concluída, continue para a próxima etapa.
  5. Analise várias respostas do servidor. Execute o comando a seguir e observe que aproximadamente 25% das respostas mostram a nova resposta do Hello World v1.1.
    while true; do curl -w "\n" http://$PRODUCTION_IP; sleep 1;  done
    
    Quando estiver tudo pronto para continuar, pressione Ctrl+c para sair do loop.

7. Como automatizar implantações para tags do Git

Depois que a implantação canário é validada com um pequeno subconjunto de tráfego, você libera a implantação para o restante do tráfego ativo.

Nesta seção, você configurará um gatilho que é ativado quando você cria uma tag no repositório. O gatilho rotula a imagem com a tag apropriada e implanta as atualizações na produção, garantindo que 100% do tráfego esteja acessando a imagem marcada.

  1. Configure o acionador de tag:
    gcloud beta builds triggers create cloud-source-repositories \
      --trigger-config build/tag-trigger.json
    
  2. Para analisar o novo gatilho, acesse a página "Gatilhos do Cloud Build" no console.Acessar gatilhos
  3. Crie uma tag e envie-a para o repositório remoto:
    git tag 1.1
    git push gcp 1.1
    
  4. Para revisar a versão em andamento, acesse a página de histórico do Cloud Build no console.Acessar "Builds"
  5. Analise várias respostas do servidor. Execute o comando a seguir e observe que 100% das respostas mostram a nova resposta do Hello World v1.1. Isso pode levar um momento, já que os novos pods são implantados e verificados no GKE.
    while true; do curl -w "\n" http://$PRODUCTION_IP; sleep 1;  done
    
    Quando estiver tudo pronto para continuar, pressione Ctrl+c para sair do loop.Parabéns! Você criou acionadores de CI/CD no Cloud Build para ramificações e tags implantarem seus apps no GKE.

8. Limpeza

Excluir o projeto

  1. No console do Cloud, acesse a página Gerenciar recursos.
  2. Na lista de projetos, selecione o projeto que você quer excluir e clique em Excluir.
  3. Na caixa de diálogo, digite o ID do projeto e clique em Encerrar para excluí-lo.