1. Visão geral
O Jenkins é uma das soluções de integração contínua mais usadas. Ele é usado para automatizar as partes não humanas essenciais do processo de desenvolvimento de software. Ao implantar o Jenkins no Kubernetes no Google Cloud e usar o plug-in do GKE, podemos escalonar rapidamente e de forma automática os executores de build conforme a necessidade. Combinado com o Cloud Storage, podemos criar e testar um aplicativo com o mínimo de esforço.
O que você aprenderá
- Implantar o Jenkins em um cluster do Kubernetes
- Implante e configure o plug-in do Jenkins GKE para permitir que o Jenkins crie e destrua pods como nós executores.
- Criar e testar um aplicativo de exemplo do SpringBoot
- Criar e publicar um contêiner no Google Container Registry
- Implantar o aplicativo de exemplo em um ambiente de preparo e produção do GKE
O que é necessário
- Um projeto na nuvem do Google Cloud com o faturamento configurado. Se você não tiver uma, crie uma.
2. Etapas da configuração
Este codelab pode ser executado completamente no Google Cloud Platform sem instalação ou configuração local.
Cloud Shell
Ao longo deste codelab, vamos provisionar e gerenciar diferentes recursos e serviços de nuvem usando a linha de comando pelo Cloud Shell.
Ativar APIs
Estas são as APIs que precisamos ativar no nosso projeto:
- API Compute Engine: cria e executa máquinas virtuais.
- API Kubernetes Engine: cria e gerencia aplicativos baseados em contêineres.
- API Cloud Build: plataforma de integração e entrega contínuas do Google Cloud.
- API Service Management: permite que produtores de serviços publiquem serviços no Google Cloud Platform.
- API Resource Manager: cria, lê e atualiza metadados para contêineres de recursos do Google Cloud.
Ative as APIs necessárias com o seguinte comando gcloud:
gcloud services enable compute.googleapis.com \
container.googleapis.com \
cloudbuild.googleapis.com \
servicemanagement.googleapis.com \
cloudresourcemanager.googleapis.com \
--project ${GOOGLE_CLOUD_PROJECT}
Criar um bucket do GCS
Vamos precisar de um bucket do GCS para fazer upload do nosso trabalho de teste. Vamos criar um bucket usando o ID do projeto no nome para garantir a exclusividade:
gsutil mb gs://${GOOGLE_CLOUD_PROJECT}-jenkins-test-bucket/
3. Criar clusters do Kubernetes
Criar o cluster
Em seguida, vamos criar um cluster do GKE que vai hospedar nosso sistema Jenkins, incluindo os pods que serão enviados como nós de trabalho. O escopo adicional indicado pela flag --scopes permite que o Jenkins acesse o Cloud Source Repositories e o Container Registry. No console do Cloud, execute o seguinte:
gcloud container clusters create jenkins-cd \ --machine-type n1-standard-2 --num-nodes 1 \ --zone us-east1-d \ --scopes "https://www.googleapis.com/auth/source.read_write,cloud-platform" \ --cluster-version latest
Vamos também implantar dois clusters para hospedar nossos builds de preparo e produção do aplicativo de exemplo:
gcloud container clusters create staging \ --machine-type n1-standard-2 --num-nodes 1 \ --zone us-east1-d \ --cluster-version latest
gcloud container clusters create prod \ --machine-type n1-standard-2 --num-nodes 2 \ --zone us-east1-d \ --cluster-version latest
Verificar
Depois que os clusters forem criados, confirme se eles estão em execução com gcloud container clusters list
A saída precisa ter RUNNING na coluna STATUS:
NAME LOCATION MASTER_VERSION MASTER_IP MACHINE_TYPE NODE_VERSION NUM_NODES STATUS jenkins-cd us-east1-d 1.15.9-gke.9 34.74.77.124 n1-standard-2 1.15.9-gke.9 2 RUNNING prod us-east1-d 1.15.9-gke.9 35.229.98.12 n1-standard-2 1.15.9-gke.9 2 RUNNING staging us-east1-d 1.15.9-gke.9 34.73.92.228 n1-standard-2 1.15.9-gke.9 2 RUNNING
4. Implantar o Jenkins com o Helm
Instalar o Helm
Vamos usar o Helm, um gerenciador de pacotes de aplicativos para Kubernetes, para instalar o Jenkins no nosso cluster. Para começar, faça o download do projeto que inclui os manifestos do Kubernetes que vamos usar para implantar o Jenkins:
git clone https://github.com/GoogleCloudPlatform/continuous-deployment-on-kubernetes.git ~/continuous-deployment-on-kubernetes
Mude o diretório de trabalho atual para o diretório do projeto:
cd ~/continuous-deployment-on-kubernetes/
Crie uma vinculação de papel do cluster para conceder a você mesmo permissões de administrador do cluster:
kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin --user=$(gcloud config get-value account)
Conecte-se ao cluster do Jenkins recebendo as credenciais dele:
gcloud container clusters get-credentials jenkins-cd --zone us-east1-d --project ${GOOGLE_CLOUD_PROJECT}
Faça o download do binário do Helm no console do Cloud:
wget https://storage.googleapis.com/kubernetes-helm/helm-v2.14.1-linux-amd64.tar.gz
Descompacte o arquivo e copie o arquivo helm incluído para o diretório de trabalho atual:
tar zxfv helm-v2.14.1-linux-amd64.tar.gz && \ cp linux-amd64/helm .
O Tiller é o lado do servidor do Helm que é executado no cluster do Kubernetes. Vamos criar uma conta de serviço chamada tiller:
kubectl create serviceaccount tiller \ --namespace kube-system
e vincule-o à função de cluster cluster-admin para que ele possa fazer mudanças:
kubectl create clusterrolebinding tiller-admin-binding \ --clusterrole=cluster-admin \ --serviceaccount=kube-system:tiller
Agora podemos inicializar o Helm e atualizar o repositório:
./helm init --service-account=tiller && \ ./helm repo update
Verificar
Confirme se o Helm está pronto para uso com ./helm version. Isso vai retornar os números de versão do cliente e do servidor:
Client: &version.Version{SemVer:"v2.14.1", GitCommit:"5270352a09c7e8b6e8c9593002a73535276507c0", GitTreeState:"clean"}
Server: &version.Version{SemVer:"v2.14.1", GitCommit:"5270352a09c7e8b6e8c9593002a73535276507c0", GitTreeState:"clean"}
Instalar o Jenkins
Agora que o Helm está instalado no nosso cluster, podemos instalar o Jenkins:
./helm install stable/jenkins -n cd \ -f jenkins/values.yaml \ --version 1.2.2 --wait
Verificar
Vamos verificar os pods:
kubectl get pods
A saída precisa mostrar o pod do Jenkins com o status "RUNNING":
NAME READY STATUS RESTARTS AGE cd-jenkins-7c786475dd-vbhg4 1/1 Running 0 1m
Confirme se o serviço do Jenkins foi criado corretamente:
kubectl get svc
A resposta será semelhante a esta:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE cd-jenkins ClusterIP 10.35.241.170 <none> 8080/TCP 2m27s cd-jenkins-agent ClusterIP 10.35.250.57 <none> 50000/TCP 2m27s kubernetes ClusterIP 10.35.240.1 <none> 443/TCP 75m
A instalação do Jenkins vai usar o plug-in do Kubernetes para criar agentes de criador. Eles serão iniciados automaticamente pelo mestre do Jenkins conforme necessário. Quando o trabalho for concluído, eles serão finalizados de maneira automática, e os respectivos recursos serão adicionados novamente ao pool de recursos do cluster.
Conectar ao Jenkins
O Jenkins está sendo executado no cluster, mas para acessar a interface, vamos configurar o encaminhamento de portas no Cloud Shell:
export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/component=jenkins-master" -l "app.kubernetes.io/instance=cd" -o jsonpath="{.items[0].metadata.name}") &&
kubectl port-forward $POD_NAME 8080:8080 >> /dev/null &
Uma senha de administrador foi gerada durante a instalação. Vamos recuperá-lo:
printf $(kubectl get secret cd-jenkins -o jsonpath="{.data.jenkins-admin-password}" | base64 --decode);echo
Na parte de cima do Cloud Shell, clique no ícone de visualização da Web
e selecione "Visualizar na porta 8080".

Uma tela de login do Jenkins vai aparecer. Nela, insira o admin para nome de usuário e a senha retornada na etapa anterior:

Ao clicar em Fazer login, você será direcionado à página principal do Jenkins.

5. Instalar e configurar o plug-in do GKE
O plug-in do Google Kubernetes Engine permite publicar implantações criadas no Jenkins em nossos clusters do Kubernetes executados no GKE. É necessário fazer algumas configurações com as permissões do IAM no seu projeto. Vamos implantar essa configuração usando o Terraform.
Primeiro, baixe o projeto de plug-in do GKE:
git clone https://github.com/jenkinsci/google-kubernetes-engine-plugin.git ~/google-kubernetes-engine-plugin
Configuração automatizada de permissões do IAM
Mude o diretório de trabalho atual para o diretório rbac do projeto do GKE que clonamos antes:
cd ~/google-kubernetes-engine-plugin/docs/rbac/
gcp-sa-setup.tf é um arquivo de configuração do Terraform que cria um papel personalizado do IAM do GCP com permissões restritas e uma conta de serviço do GCP para conceder esse papel. O arquivo exige valores para as variáveis de projeto, região e nome da conta de serviço. Fornecemos esses valores declarando primeiro as seguintes variáveis de ambiente:
export TF_VAR_project=${GOOGLE_CLOUD_PROJECT}
export TF_VAR_region=us-east1-d
export TF_VAR_sa_name=kaniko-role
Inicialize o Terraform, gere um plano e aplique-o:
terraform init terraform plan -out /tmp/tf.plan terraform apply /tmp/tf.plan && rm /tmp/tf.plan
A conta de serviço precisa de permissões de administrador de armazenamento para salvar no bucket do Cloud Storage:
gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \
--member serviceAccount:kaniko-role@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com \
--role 'roles/storage.admin'
Ele também vai precisar de permissões de contêiner para os estágios de implantação do pipeline:
gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} --member \
serviceAccount:kaniko-role@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com --role 'roles/container.developer'
Agora podemos usar o Helm para configurar permissões de cluster para o plug-in do GKE usando o implantador de robôs do gke. Mude o diretório de trabalho para o diretório do Helm do projeto do GKE:
cd ~/google-kubernetes-engine-plugin/docs/helm/
e instale usando o gráfico do Helm fornecido:
export TARGET_NAMESPACE=kube-system && \ envsubst < gke-robot-deployer/values.yaml | helm install ./gke-robot-deployer --name gke-robot-deployer -f -
6. Configurar o Jenkins
Chaves da conta de serviço
Para que a conta de serviço funcione corretamente, precisamos gerar um arquivo de chave privada e adicioná-lo como um secret do Kubernetes. Primeiro, gere o arquivo com o seguinte comando gcloud:
gcloud iam service-accounts keys create /tmp/kaniko-secret.json --iam-account kaniko-role@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com
Vamos criar uma chave secreta no armazenamento de Secrets do Kubernetes com esse arquivo:
kubectl create secret generic jenkins-int-samples-kaniko-secret --from-file=/tmp/kaniko-secret.json
Faça o download do arquivo JSON para o disco local acessando o item "Fazer o download do arquivo" no menu de três pontos do Cloud Shell:

Insira o caminho do arquivo /tmp/kaniko-secret.json e clique em "Fazer o download".
De volta à página do Jenkins, no painel à esquerda, clique em Credenciais e depois em Sistema.


Na seção da página chamada Sistema,clique em "Credenciais globais" e em "Adicionar credenciais" à esquerda:


No menu suspenso "Tipo", selecione Conta de serviço do Google da chave privada. Insira "kaniko-role" como o nome, faça upload da chave JSON criada nas etapas anteriores e clique em "OK".

Variáveis de ambiente
Há algumas variáveis de ambiente que precisamos definir no Jenkins antes de criar o pipeline de várias ramificações. São eles:
- JENK_INT_IT_ZONE: a zona do cluster do Kubernetes. No nosso caso,
us-east1-d - JENK_INT_IT_PROJECT_ID: refere-se ao ID do projeto do GCP que hospeda esta instância do Jenkins.
- JENK_INT_IT_STAGING: o nome do cluster de teste. Para fins de demonstração, é
staging. - JENK_INT_IT_PROD: nome do nosso cluster "prod". Para fins de demonstração, é
prod - JENK_INT_IT_BUCKET: o bucket do Cloud Storage criado na etapa anterior
- JENK_INT_IT_CRED_ID: refere-se às credenciais criadas usando o JSON na etapa anterior. O valor precisa corresponder ao nome que atribuímos a ele,
kaniko-role.
Para adicionar esses itens, acesse Manage Jenkins:

Em seguida, Configure System:

Vai aparecer uma seção chamada Propriedades globais. Ao marcar a caixa Variáveis de ambiente, um botão Adicionar vai aparecer. Clique nele para adicionar as variáveis acima como pares de chave-valor:

Clique no botão Salvar na parte de baixo da página para aplicar as mudanças.
7. Configurar um pipeline
No Jenkins, clique em "Novo item":

Insira "jenkins-integration-sample" como nome, selecione "Multibranch Pipeline" como tipo de projeto e clique em OK:

Vamos redirecionar você para a página de configuração do pipeline. Em Origens de ramificação, insira https://github.com/GoogleCloudPlatform/jenkins-integration-samples.git como o Repositório do projeto. Em Configuração da compilação, insira "gke/Jenkinsfile" como o Caminho do script.

Clique em Salvar para aplicar essas configurações. Ao salvar, o Jenkins vai iniciar uma verificação do repositório e um build subsequente para cada ramificação. À medida que o processo avança, você vê os pods sendo criados, executados e destruídos na página "Cargas de trabalho do Kubernetes".
Quando os builds forem concluídos, você vai encontrar dois itens na página "Cargas de trabalho do Kubernetes" chamados "jenkins-integration-samples-gke", cada um correspondendo ao cluster de produção ou de teste. O status vai mostrar OK:

Usando o seguinte comando gcloud, vamos ver que enviamos uma imagem de contêiner para o Google Container Registry correspondente ao nosso pipeline:
gcloud container images list
Para ver a carga de trabalho no navegador, receba as credenciais do cluster de produção:
gcloud container clusters get-credentials prod --zone us-east1-d --project ${GOOGLE_CLOUD_PROJECT}
Execute o seguinte para configurar um encaminhamento de portas da porta 8081 do shell para a porta 8080 da sua carga de trabalho:
export POD_NAME=$(kubectl get pods -o jsonpath="{.items[0].metadata.name}") &&
kubectl port-forward $POD_NAME 8081:8080 >> /dev/null &
Na parte de cima do Cloud Shell, clique no ícone "Visualização da Web" e selecione "Visualizar na porta 8081".


8. Limpeza
Você aprendeu a implantar um Jenkins e um pipeline multibranch de amostra no Kubernetes. Agora é hora de liberar espaço do nosso projeto de todos os recursos que criamos.
Excluir o projeto
Se preferir, exclua todo o projeto. No Console do GCP, acesse a página Cloud Resource Manager:
Na lista de projetos, selecione o projeto em que estamos trabalhando e clique em Excluir. Você precisará digitar o ID do projeto. Depois de fazer isso, clique em Desligar.
Outra opção é excluir todo o projeto diretamente no Cloud Shell com gcloud:
gcloud projects delete $GOOGLE_CLOUD_PROJECT
Se você preferir excluir os diferentes componentes faturáveis um por um, siga para a próxima seção.
Cluster do Kubernetes
Exclua todo o cluster do Kubernetes com o gcloud:
gcloud container clusters delete jenkins-cd --zone=us-east1-d
Buckets de armazenamento
Remova todos os arquivos enviados e exclua nosso bucket com o gsutil:
gsutil rm -r gs://${GOOGLE_CLOUD_PROJECT}-jenkins-test-bucket
Imagens do Google Container Registry
Vamos excluir as imagens do Google Container Registry usando os resumos de imagem. Primeiro, recupere os resumos com o seguinte comando:
gcloud container images list-tags gcr.io/${GOOGLE_CLOUD_PROJECT}/jenkins-integration-samples-gke --format="value(digest)"
Em seguida, para cada resumo retornado:
gcloud container images delete gcr.io/${GOOGLE_CLOUD_PROJECT}/jenkins-integration-samples-gke@sha256:<DIGEST>
9. Parabéns!
Uhu! Você conseguiu! Você aprendeu a implantar o Jenkins no GKE e a despachar jobs para clusters do Kubernetes.
O que aprendemos
- Implantamos um cluster do Kubernetes e usamos o Helm para instalar o Jenkins.
- Instalamos e configuramos o plug-in do GKE para permitir que o Jenkins implante artefatos de build em clusters do Kubernetes.
- Configuramos o Jenkins para criar um pipeline de várias ramificações que envia trabalho para clusters do GKE.