Entrega contínua para gráficos do Helm no Kubernetes Engine usando o Concourse

Neste tutorial, mostramos como criar um processo de versão de software com o GKE, o Helm e o Concourse. O Helm é uma ferramenta para ajudar você a gerenciar os manifestos do Kubernetes. O Concourse, por sua vez, é possível aproveitar o Helm para implantar continuamente seus aplicativos.

Seguindo este tutorial, você terá o seguinte resultado:

  • Dois repositórios de código-fonte, um para o código-fonte do aplicativo e outro para o gráfico do Helm.
  • O aplicativo, empacotado como um contêiner do Docker, instalado e configurado como um gráfico do Helm no cluster.

Para dar início a uma versão, envie uma tag do Git para qualquer um desses repositórios.

Arquitetura

O diagrama a seguir descreve a arquitetura de alto nível do sistema.

Arquitetura geral

Com o Concourse, são montados canais de entrega contínua que podem ser usados para codificar as etapas dos processos de criação, teste e liberação. No Concourse, os estágios dos canais são chamados de jobs. Em cada job, é possível ter um recurso como entrada e criar um recurso como saída.

Neste tutorial, você usará os seguintes tipos de recurso do Concourse:

Use o Helm para transformar os manifestos do Kubernetes em modelos, para que possam ser configurados, instalados e atualizados como uma unidade. Configure o aplicativo como um gráfico para que o Helm o instale. Cada gráfico Helm tem um arquivo de valores que você usa para parametrizar os manifestos. Por exemplo, é possível que você tenha um valor que defina a imagem do Docker a ser usada para a implantação do aplicativo. Esse valor pode mudar quando você instala ou atualiza o gráfico. Cada instalação de um gráfico é chamada de versão. Você usa as versões para atualizar ou reverter uma instância do aplicativo.

É possível compartilhar os gráficos usando um repositório. Neste tutorial, você criará um repositório de gráfico particular usando o Cloud Storage.

No diagrama a seguir, explicamos a relação entre gráficos, repositórios e versões:

inter-relações de gráficos, repositórios e versões

Neste tutorial, você criará o canal de entrega contínua mostrado na captura de tela do Concourse a seguir. As entradas e saídas são mostradas em caixas escuras. Os jobs do canal são mostrados em caixas verdes.

Canal de entrega contínua

Como na captura de tela, no job build-image, o código-fonte do aplicativo, app-source, é usado como uma entrada. Quando uma nova tag é enviada ao código-fonte do aplicativo, o Concourse executa o job build-image. No processo de criação, o código é verificado, uma versão do Docker é criada e a imagem é enviada para o Container Registry, rotulada como uma saída no pipeline chamada app-image. A imagem Docker do aplicativo é uma entrada para o próximo job do canal, deploy-chart. No job deploy-chart, o código-fonte do aplicativo, chart-source, também é usado como uma entrada.

Quando a imagem do aplicativo e o código-fonte do gráfico estão disponíveis, o job deploy-chart é iniciado e segue as etapas a seguir:

  • Consegue informações sobre a imagem do aplicativo, como o repositório e a tag.
  • Verifica o código-fonte do gráfico no Cloud Source Repositories.
  • Empacota o gráfico usando o cliente do Helm.
  • Upload do gráfico empacotado ao repositório de gráficos particular no Cloud Storage usando o plug-in do Helm para Cloud Storage.
  • Instalação do gráfico no cluster do GKE usando o recurso Concourse Helm, chamado de dev-site na captura de tela anterior.

Objetivos

  • Abrir o Cloud Shell, criar um cluster do GKE e configurar seu esquema de gerenciamento de identidade e usuário.
  • Fazer o download de um aplicativo de amostra, criar um repositório Git e fazer o upload dele no Cloud Source Repositories.
  • Usar o Helm para implantar o Concourse no GKE.
  • Configurar um pipeline do Concourse para instalar e atualizar o aplicativo.
  • Implantar uma alteração de código no aplicativo para acionar o canal.
  • Implantar uma alteração no gráfico do Helm para implantá-la no cluster.

Custos

Neste tutorial, usamos componentes do GCP que podem ser cobrados, inclusive estes:

  • GKE
  • Cloud Storage

Use a calculadora de preços para gerar uma estimativa de custo com base no uso previsto.

Antes de começar

  1. Selecione ou crie um projeto do GCP.

    Acessar a página Gerenciar recursos

  2. Verifique se o faturamento foi ativado para o projeto.

    Saiba como ativar o faturamento

  3. {% dynamic if "no_credentials" in setvar.task_params %}{% dynamic setvar credential_type %}NO_AUTH{% dynamic endsetvar %}{% dynamic if not setvar.redirect_url %}{% dynamic setvar redirect_url %}https://console.cloud.google.com{% dynamic endsetvar %}{% dynamic endif %}{% dynamic endif %}{% dynamic if setvar.in_henhouse_no_auth_whitelist %}{% dynamic if not setvar.credential_type %}{% dynamic setvar credential_type %}NO_AUTH{% dynamic endsetvar %}{% dynamic endif %}{% dynamic elif setvar.in_henhouse_service_account_whitelist %}{% dynamic if not setvar.credential_type %}{% dynamic setvar credential_type %}SERVICE_ACCOUNT{% dynamic endsetvar %}{% dynamic endif %}{% dynamic endif %}{% dynamic if not setvar.service_account_roles and setvar.credential_type == "SERVICE_ACCOUNT" %}{% dynamic setvar service_account_roles %}{% dynamic endsetvar %}{% dynamic endif %}{% dynamic setvar console %}{% dynamic if "no_steps" not in setvar.task_params %}
  4. {% dynamic endif %}{% dynamic if setvar.api_list %}{% dynamic if setvar.in_henhouse_no_auth_whitelist or setvar.in_henhouse_service_account_whitelist %} Configure um projeto do Console do GCP.

    Configurar um projeto

    Clique para:

    • criar ou selecionar um projeto;
    • ativar {% dynamic if setvar.api_names %}{% dynamic print setvar.api_names %}{% dynamic else %}obrigatória{% dynamic endif %}{% dynamic if "," in setvar.api_list %} APIs{% dynamic elif "API" in setvar.api_names %}{% dynamic else %} API{% dynamic endif %} para o projeto;
    • {% dynamic if setvar.credential_type == 'SERVICE_ACCOUNT' %}
    • criar uma conta de serviço;
    • fazer o download de uma chave privada como JSON.
    • {% dynamic endif %}

    É possível ver e gerenciar esses recursos a qualquer momento no Console do GCP.

    {% dynamic else %}{% dynamic if "no_text" not in setvar.task_params %} Ativar {% dynamic if setvar.api_names %}{% dynamic print setvar.api_names %}{% dynamic else %}obrigatória{% dynamic endif %}{% dynamic if "," in setvar.api_list %} APIs{% dynamic elif "API" in setvar.api_names %}{% dynamic else %} API{% dynamic endif %}. {% dynamic endif %}

    Ativar {% dynamic if "," in setvar.api_list %} as APIs{% dynamic else %} a API{% dynamic endif %}

    {% dynamic endif %}{% dynamic endif %}{% dynamic if "no_steps" not in setvar.task_params %}
  5. {% dynamic endif %}{% dynamic endsetvar %}{% dynamic print setvar.console %}

Configurar o ambiente

Configure a infraestrutura e as identidades necessárias para concluir o tutorial.

Iniciar uma instância do Cloud Shell

Abra o Cloud Shell pelo Console do Google Cloud Platform. Você executará o restante do tutorial dentro do Cloud Shell.

Abrir o Cloud Shell

Criar um cluster do GKE

Você precisa de um cluster com os escopos cloud-source-repos-ro e storage-full para que seja possível fazer o download do código-fonte, enviar imagens e fazer o upload de gráficos para o repositório do Cloud Storage com os pods do Concourse.

Crie um cluster do GKE para implantar o Concourse e o gráfico de amostra do Helm com o seguinte comando:

gcloud container clusters create concourse --image-type ubuntu \
    --machine-type n1-standard-2 --zone us-central1-f \
    --scopes cloud-source-repos-ro,storage-full

Fazer o download do código de amostra

Neste tutorial, você usará um aplicativo existente, um gráfico do Helm e um canal. Faça o download do código de amostra de um intervalo do Cloud Storage criado para este tutorial e, em seguida, extraia-o para o Cloud Shell:

wget https://gke-concourse.storage.googleapis.com/sample-app-v4.zip
unzip sample-app-v4.zip
cd concourse-continuous-delivery-master

Como implantar o Concourse usando o Helm

Use o Helm para implantar o Concourse pelo repositório Gráficos.

Instalar Helm

  1. No Cloud Shell, faça o download do binário do Helm e instale-o:

    wget https://storage.googleapis.com/kubernetes-helm/helm-v2.6.2-linux-amd64.tar.gz

  2. Extraia o arquivo:

    tar zxfv helm-v2.6.2-linux-amd64.tar.gz
    cp linux-amd64/helm .

  3. Sua conta de usuário precisa ter a função cluster-admin em seu cluster.

    kubectl create clusterrolebinding user-admin-binding --clusterrole=cluster-admin --user=$(gcloud config get-value account)

  4. Crie uma conta de serviço que o Tiller, o lado do servidor do Helm, possa usar para implantar seus gráficos.

    kubectl create serviceaccount tiller --namespace kube-system

  5. Conceda à conta do serviço do Tiller a função de cluster-admin em seu cluster:

    kubectl create clusterrolebinding tiller-admin-binding --clusterrole=cluster-admin --serviceaccount=kube-system:tiller

  6. Conceda à conta de serviço do Concourse a função cluster-admin para que possa implantar recursos em todos os namespaces:

    kubectl create clusterrolebinding --clusterrole=cluster-admin --serviceaccount=default:default concourse-admin

  7. Inicialize o Helm para instalar o Tiller no seu cluster:

    ./helm init --service-account=tiller
    ./helm update

  8. Instale o plug-in do Helm e inicialize o repositório de gráfico particular em um intervalo do Cloud Storage. O primeiro comando é usado para armazenar o código do projeto atual em uma variável de ambiente. No segundo comando, o código do projeto é usado para criar um nome exclusivo para o intervalo. O nome é então armazenado em outra variável de ambiente para uso em comandos subsequentes:

    export PROJECT=$(gcloud info --format='value(config.project)')
    export BUCKET=$PROJECT-helm-repo
    ./helm plugin install https://github.com/viglesiasce/helm-gcs.git --version v0.1.1
    gsutil mb -l us-central1 gs://$BUCKET
    ./helm gcs init gs://$BUCKET

  9. Verifique se o Helm está instalado corretamente:

    ./helm version

    Você verá uma saída similar a esta. Se o Helm estiver instalado corretamente, v2.6.2 será exibido tanto para o cliente quanto para o servidor.

    Client: &version.Version{SemVer:"v2.6.2",
    GitCommit:"012cb0ac1a1b2f888144ef5a67b8dab6c2d45be6",
    GitTreeState:"clean"}Server: &version.Version{SemVer:"v2.6.2",
    GitCommit:"012cb0ac1a1b2f888144ef5a67b8dab6c2d45be6",
    GitTreeState:"clean"}

    Se você vir uma mensagem de que o Helm não conseguiu entrar em contato com o processo do Tiller, espere um pouco e tente novamente. Pode levar até dois minutos para que o Tiller seja inicializado.

Implantar o Concourse

  1. No Cloud Shell, crie um arquivo com os valores de configuração a serem transmitidos para a instalação do Concourse. No primeiro comando, o comando openssl é usado para gerar uma string aleatória que serve de senha para o usuário administrador do Concourse:

    export PASSWORD=$(openssl rand -base64 15)
    cat > concourse.yaml <<EOF
    concourse:
      password: $PASSWORD
      baggageclaimDriver: overlay
    web:
      service:
        type: LoadBalancer
    EOF

  2. Use o Helm para implantar o gráfico do Concourse:

    ./helm install stable/concourse --name concourse -f concourse.yaml --version 0.10.0

  3. Aguarde de três a quatro minutos e, em seguida, verifique se o pod concourse-web está em execução e pronto:

    kubectl get pods -l app=concourse-web

    Quando o pod estiver pronto, você verá uma saída similar a esta:

    NAME                             READY     STATUS    RESTARTS   AGE
    concourse-web-2711520304-483vw   1/1       Running   0          3m

  4. Faça o download do fly, a ferramenta de linha de comando do Concourse:

    export SERVICE_IP=$(kubectl get svc \
        --namespace default concourse-web \
        -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
    wget -O fly "http://$SERVICE_IP:8080/api/v1/cli?arch=amd64&platform=linux"
    chmod +x fly

  5. Autentique a CLI fly na instalação do Concourse:

    ./fly -t local login -u concourse -p $PASSWORD -c http://$SERVICE_IP:8080

  6. Pegue o URL da interface do usuário do Concourse:

    export SERVICE_IP=$(kubectl get svc \
        --namespace default concourse-web \
        -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
    printf "Concourse URL: [http://$SERVICE_IP:8080]\nUsername: concourse\nPassword: $PASSWORD\n"

    Esse comando exibe um URL, o nome de usuário e a senha.

  7. No navegador, vá para o URL do comando anterior. Isso levará você ao Concourse.

  8. No Concourse, clique no botão de login no canto superior direito e em main.
  9. Faça login com o nome de usuário e a senha do comando anterior.

Configurar o gerenciamento de identidade e acesso

Crie uma conta de serviço do Cloud Identity & Access Management (Cloud IAM) para que seja possível enviar imagens do Concourse para o Container Registry.

  1. No Cloud Shell, crie a conta de serviço:

    gcloud iam service-accounts create concourse --display-name concourse

  2. Armazene o endereço de e-mail da conta de serviço e o código do projeto atual nas variáveis de ambiente para uso em comandos posteriores:

    export SA_EMAIL=$(gcloud iam service-accounts list \
        --filter="displayName:concourse" --format='value(email)')
    export PROJECT=$(gcloud info --format='value(config.project)')

  3. Vincule a função storage.admin à sua conta de serviço:

    gcloud projects add-iam-policy-binding $PROJECT \
        --role roles/storage.admin --member serviceAccount:$SA_EMAIL

  4. Faça o download da chave da conta de serviço. Em um passo posterior, instale o Concourse e faça o upload dessa chave no GKE.

    gcloud iam service-accounts keys create concourse-sa.json \
        --iam-account $SA_EMAIL

Implantar o aplicativo

Nesta seção, explicamos a você como criar os repositórios de código-fonte, configurar e criar o canal, implantar o aplicativo, alterá-lo e implantá-lo novamente.

Criar repositórios de código-fonte

Neste tutorial, você usará dois repositórios, um para lidar com o código-fonte do aplicativo e outro para o código-fonte que define o gráfico do Helm. Alterações feitas em qualquer um desses repositórios atualizarão a implantação.

  1. Crie os repositórios:

    gcloud source repos create chart-source
    gcloud source repos create app-source

  2. Configure o nome do usuário e o endereço de e-mail dos commits de Git nesses repositórios. Substitua [EMAIL_ADDRESS] pelo endereço de e-mail do Git, e [USERNAME] pelo nome do usuário do Git.

    git config --global user.email "[EMAIL_ADDRESS]"
    git config --global user.name "[USERNAME]"

  3. Envie o gráfico e o código-fonte do aplicativo do repositório local para o Cloud Source Repositories:

    export PROJECT=$(gcloud info --format='value(config.project)')
    for repo in app-source chart-source; do
    cd $repo
    git init && git add . && git commit -m 'Initial commit'
    git config credential.helper gcloud.sh
    git remote add google \
        https://source.developers.google.com/p/$PROJECT/r/$repo
        git push --all google
    cd ..
    done

Configurar e criar o canal

O Concourse permite que você interpole parâmetros nos canais. Use essa funcionalidade para parametrizá-los, bem como para injetar chaves secretas que você não quer verificar no seu repositório de código-fonte.

  1. No Cloud Shell, crie seu arquivo de configuração:

    export PROJECT=$(gcloud info --format='value(config.project)')
    export BUCKET=$PROJECT-helm-repo
    export TOKEN_SECRET=$(kubectl get serviceaccount default -o jsonpath="{.secrets[0].name}")
    export CLUSTER_CA=$(kubectl get secret $TOKEN_SECRET -o jsonpath='{.data.ca\.crt}')
    export TOKEN=$(kubectl get secret $TOKEN_SECRET -o jsonpath='{.data.token}' | base64 --decode)

    cat > params.yaml <<EOF chart_name: nginx release_name: dev-site bucket: $BUCKET cluster_ca: $CLUSTER_CA token: $TOKEN project: $PROJECT service_account_json: '$(cat concourse-sa.json)' EOF

  2. Use a CLI fly no Cloud Shell para fazer o upload do arquivo do canal:

    ./fly -t local set-pipeline -p dev-site-deploy \
        -c pipeline.yaml -l params.yaml -n

  3. Retome o canal para ativá-lo:

    ./fly -t local unpause-pipeline -p dev-site-deploy

  4. Atualize o Concourse no navegador.

    Você verá o canal:

    Canal atualizado

Como implantar o aplicativo pela primeira vez

O canal está configurado para ser acionado quando uma tag do Git for enviada para o aplicativo ou para o repositório de código-fonte do gráfico. Envie as primeiras tags em cada repositório para implantar seu aplicativo pela primeira vez.

  1. No Cloud Shell, crie e envie as tags do Git:

    for repo in app-source chart-source; do
        cd $repo
        git tag v1.0.0
        git push google --tags
        cd ..
    done

  2. No navegador, vá para Concourse. Após um ou dois minutos, você verá que o canal foi iniciado, o que é indicado pelos círculos amarelos pulsantes em torno do job build-image:

    Execução do canal

Como implantar uma alteração no aplicativo

  1. Após a conclusão do canal, verifique a versão do servidor da Web que está implantada atualmente encaminhando uma porta local para um contêiner e conseguindo a versão:

    export POD_NAME=$(kubectl get pods --namespace default \
        -l "app=nginx,release=dev-site" \
        -o jsonpath="{.items[0].metadata.name}")
    kubectl port-forward $POD_NAME 8080:80 &
    curl -is localhost:8080 | grep 'Server\|color'

    Você vê que o servidor da Web está executando a versão estável do nginx e a cor está definida como azul:

    Server: nginx/1.14.0
    <h1 style="color:blue;">Welcome to the sample app!</h1>

  2. Pare o encaminhamento de portas:

    killall kubectl

  3. Altere para o subdiretório do aplicativo:

    cd app-source

  4. Altere a versão do servidor da Web usada no Dockerfile de stable para latest:

    sed -i s/stable/latest/ Dockerfile

  5. Faça commit e atribua uma tag à origem:

    git add Dockerfile
    git commit -m 'Use latest NGINX'
    git tag v2.0.0

  6. Envie o código para o Cloud Source Repositories:

    git push google --mirror

  7. Use a CLI fly no Cloud Shell para forçar o Concourse a verificar imediatamente o código-fonte das novas tags:

    ../fly -t local check-resource -r dev-site-deploy/app-source

    O canal recomeça.

  8. Quando o canal for concluído, execute novamente os comandos a seguir para verificar a versão do nginx:

    export POD_NAME=$(kubectl get pods --namespace default \
        -l "app=nginx,release=dev-site" \
        -o jsonpath="{.items[0].metadata.name}")
    kubectl port-forward $POD_NAME 8080:80 &
    curl -is localhost:8080 | grep 'Server\|color'

    A versão do nginx é atualizada para a versão mais recente:

    Server: nginx/1.15.0
    <h1 style="color:blue;">Welcome to the sample app!</h1>

  9. Pare o encaminhamento de portas:

    killall kubectl

Em seguida, faça uma alteração na configuração do gráfico para acionar uma atualização.

Como implantar uma alteração no gráfico

A definição do gráfico contém um Mapa de configuração do Kubernetes que define a página padrão do aplicativo. Atualize o mapa de configuração para fazer uma alteração na página de índice do aplicativo.

  1. No Cloud Shell, entre no subdiretório do gráfico:

    cd ../chart-source/

  2. Altere a cor do cabeçalho de azul para verde. Basta substituir a string de cores no Config Map:

    sed -i s/blue/green/ templates/config-map.yaml

  3. Use o Git para fazer commit e atribuir uma tag ao código-fonte:

    git add templates/config-map.yaml
    git commit -m 'Use green for page heading'

  4. Marque e envie o código para iniciar o canal:

    git tag v2.0.0
    git push google --mirror

  5. Use o comando fly para forçar o Concourse a verificar imediatamente o código-fonte em busca de novas tags:

    ../fly -t local check-resource -r dev-site-deploy/chart-source

    No Concourse, o canal começa a partir do job de implantação do gráfico.

  6. No Cloud Shell, verifique a saída do aplicativo:

    export POD_NAME=$(kubectl get pods \
        -n default -l "app=nginx,release=dev-site" \
        -o jsonpath="{.items[0].metadata.name}")
    kubectl port-forward $POD_NAME 8080:80 &
    curl -is localhost:8080 | grep 'Server\|color'

    Você verá a saída a seguir. Desta vez, a resposta do servidor contém uma marcação que usa verde em vez de azul:

    Server: nginx/1.15.0
    <h1 style="color:green;">Welcome to the sample app!</h1>

Limpeza

Nas etapas a seguir, todos os recursos criados por este tutorial são removidos para que você não tenha cobranças desnecessárias.

  1. Exclua a instalação do Concourse:

    ../helm delete --purge concourse

  2. Exclua a conta de serviço:

    export SA_EMAIL=$(gcloud iam service-accounts list \
        --filter="displayName:concourse" \
        --format='value(email)')
    gcloud iam service-accounts delete $SA_EMAIL

  3. Exclua o cluster do GKE:

    gcloud container clusters delete concourse --zone us-central1-f

  4. Exclua os repositórios de código-fonte:

    gcloud source repos delete app-source --quiet
    gcloud source repos delete chart-source --quiet

  5. Exclua o intervalo:

    export PROJECT=$(gcloud info --format='value(config.project)')
    export BUCKET=$PROJECT-helm-repo
    gsutil -m rm -r gs://$BUCKET

Próximas etapas

Esta página foi útil? Conte sua opinião sobre:

Enviar comentários sobre…