1. Visão geral
O Jenkins é uma das soluções de integração contínua mais conhecidas. Ele é usado para automatizar as partes não humanas essenciais do processo de desenvolvimento de software. Ao implantar o Jenkins no Kubenetes no Google Cloud e usar o plug-in do GKE, podemos dimensionar de forma rápida e automática os executores de build conforme a necessidade. Em combinação 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 GKE do Jenkins para permitir que o Jenkins crie e destrua pods como nós de execução
- Criar e testar um aplicativo SpringBoot de exemplo
- Criar e publicar um contêiner no Google Container Registry
- Implantar o aplicativo de exemplo em um ambiente de testes e de produção do GKE
O que é necessário
- Um projeto do Google Cloud com 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 nenhuma instalação ou configuração local.
Cloud Shell
Neste codelab, vamos provisionar e gerenciar diferentes recursos e serviços de nuvem usando a linha de comando pelo Cloud Shell.
Ativar as APIs
Estas são as APIs que precisamos ativar no 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ínua do Google Cloud
- API Service Management: permite que os produtores de serviços publiquem serviços no Google Cloud Platform.
- API Cloud 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}
Crie um bucket do GCS
Vamos precisar de um bucket do GCS para fazer o 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. Criação de clusters do Kubernetes
Criar o cluster
Em seguida, vamos criar um cluster do GKE que 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 implantar dois clusters para hospedar os builds de preparação e produção do nosso 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, podemos confirmar que 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 cluster. Para começar, faça o download do projeto que inclui os manifestos do Kubernetes que serão usados 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 si 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 para receber as credenciais dele:
gcloud container clusters get-credentials jenkins-cd --zone us-east1-d --project ${GOOGLE_CLOUD_PROJECT}
E faça o download do binário do Helm no Cloud Console:
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 alterações:
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 cluster, podemos prosseguir com a instalação do 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 vai 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á em execução 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, onde podemos inserir o admin
para o nome de usuário e a senha retornada na etapa anterior:
Quando clicamos em Fazer login, somos direcionados à página principal do Jenkins.
5. Instalar e configurar o plug-in do GKE
O plug-in do Google Kubernetes Engine permite que publiquemos implantações criadas no Jenkins nos clusters do Kubernetes em execução 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, faça o download do projeto do plug-in do GKE:
git clone https://github.com/jenkinsci/google-kubernetes-engine-plugin.git ~/google-kubernetes-engine-plugin
Configuração automática de permissões do IAM
Mude o diretório de trabalho atual para o diretório rbac do projeto do GKE clonado anteriormente:
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 nome do projeto, da região e 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'
Também são necessárias 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 as permissões de cluster do plug-in do GKE usando o deployer do robô 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 segredo 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 na loja de segredos 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 no seu 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".
Na página do Jenkins, no painel à esquerda, clique em Credentials e depois em System.
Na seção da página intitulada Sistema,clique em Credenciais globais e em Adicionar credenciais à esquerda:
No menu suspenso "Kind", selecione Google Service Account from private key. Insira "kaniko-role" como o nome, faça o 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 "preparação", para fins de demonstração, é
staging
. - JENK_INT_IT_PROD: o nome do cluster "prod". Para fins de demonstração, é
prod
- JENK_INT_IT_BUCKET: o bucket do Google 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 demos a ele,
kaniko-role
Para adicionar esses itens, acesse Manage Jenkins:
Em seguida, Configure System:
Há uma seção chamada Propriedades globais. Quando marcamos a caixa de Variáveis de ambiente, um botão Adicionar aparece. 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 alterações.
7. Configurar um pipeline
No Jenkins, clique em "New Item":
Insira "jenkins-integration-sample" como o nome, selecione "Multibranch Pipeline" como o tipo de projeto e clique em OK:
Você vai ser redirecionado para a página de configuração do pipeline. Em Branch Sources, insira https://github.com/GoogleCloudPlatform/jenkins-integration-samples.git como o Project Repository. Em Configuração da compilação, digite "gke/Jenkinsfile" como o caminho do script.
Clique em Salvar para aplicar essas configurações. Após a gravação, o Jenkins inicia uma verificação do repositório e um build subsequente para cada ramificação. À medida que o processo avança, você vai notar que os pods são criados, executados e destruídos conforme os builds avançam na página Cargas de trabalho do Kubernetes.
Quando os builds forem concluídos, você vai encontrar dois itens na página "Kubernetes Workloads", chamados "jenkins-integration-samples-gke", cada um correspondendo ao cluster de produção ou de teste. O status será OK:
Usando o comando gcloud a seguir, vamos conferir que enviamos uma imagem do contêiner para o Google Container Registry correspondente ao nosso pipeline:
gcloud container images list
Para conferir a carga de trabalho no navegador, confira as credenciais do cluster de produção:
gcloud container clusters get-credentials prod --zone us-east1-d --project ${GOOGLE_CLOUD_PROJECT}
E execute o seguinte para configurar um encaminhamento de porta da porta 8081 do shell para a porta 8080 da 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
Explicamos como implantar um Jenkins e um pipeline de vários ramos no Kubernetes. Agora é hora de limpar o 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.
Também é possível excluir todo o projeto diretamente do Cloud Shell com gcloud:
gcloud projects delete $GOOGLE_CLOUD_PROJECT
Se preferir excluir os diferentes componentes faturáveis um por um, avance 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 o 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, extraia 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 enviar 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 configurar um pipeline com várias ramificações que envia trabalhos para clusters do GKE.