1. Omówienie
Jenkins to jedno z najpopularniejszych dostępnych rozwiązań ciągłej integracji. Służy on do automatyzacji kluczowych elementów procesu tworzenia oprogramowania, które nie wymagają udziału człowieka. Dzięki wdrożeniu Jenkinsa w Kubenetes w Google Cloud i użyciu wtyczki GKE możemy szybko i automatycznie skalować wykonawców kompilacji w razie potrzeby. W połączeniu z Cloud Storage możemy tworzyć i testować aplikacje z minimalnym wysiłkiem.
Co musisz zrobić
- Wdrażanie usługi Jenkins w klastrze Kubernetes
- Wdróż i skonfiguruj wtyczkę Jenkins GKE, aby umożliwić Jenkinsowi tworzenie i usuwanie podów jako węzłów wykonawczych.
- Kompilowanie i testowanie przykładowej aplikacji SpringBoot
- Tworzenie i publikowanie kontenera w Google Container Registry
- Wdrażanie przykładowej aplikacji w środowisku testowym i produkcyjnym GKE
Czego potrzebujesz
- projekt Google Cloud z skonfigurowanymi rozliczeniami, Jeśli go nie masz, musisz je utworzyć.
2. Konfiguracja
To Codelab może działać całkowicie w Google Cloud Platform bez instalacji ani konfiguracji na komputerze lokalnym.
Cloud Shell
W tym samouczku będziemy tworzyć i zarządzać różnymi zasobami i usługami w chmurze za pomocą wiersza poleceń w Cloud Shell.
Włącz interfejsy API
Oto interfejsy API, które musimy włączyć w projekcie:
- Compute Engine API – tworzy i uruchamia maszyny wirtualne.
- Interfejs API Kubernetes Engine – tworzy aplikacje oparte na kontenerach i nimi zarządza.
- Cloud Build API – platforma Google Cloud do ciągłej integracji i ciągłego dostarczania.
- Service Management API – umożliwia producentom usług publikowanie usług w Google Cloud Platform.
- Cloud Resource Manager API – tworzy, odczytuje i aktualizuje metadane kontenerów zasobów Google Cloud.
Włącz wymagane interfejsy API za pomocą tego polecenia gcloud:
gcloud services enable compute.googleapis.com \ container.googleapis.com \ cloudbuild.googleapis.com \ servicemanagement.googleapis.com \ cloudresourcemanager.googleapis.com \ --project ${GOOGLE_CLOUD_PROJECT}
Tworzenie zasobnika GCS
Do przesłania testowych danych potrzebujemy zasobnika GCS. Aby zapewnić unikalność, utwórz zasobnik, używając w nazwie identyfikatora projektu:
gsutil mb gs://${GOOGLE_CLOUD_PROJECT}-jenkins-test-bucket/
3. Tworzenie klastrów Kubernetes
Tworzenie klastra
Następnie utworzymy klaster GKE, który będzie hostować nasz system Jenkins, w tym pody, które będą wysyłane jako węzły robocze. Dodatkowy zakres wskazany przez flagę --scopes
pozwoli Jenkinsowi uzyskać dostęp do repozytoriów Cloud Source Repositories i rejestru kontenerów. W Cloud Console wykonaj te czynności:
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
Utworzymy też 2 klastry, które będą hostować wersje testowe i produkcyjne przykładowej aplikacji:
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
Zweryfikuj
Po utworzeniu klastrów możemy potwierdzić, że działają one z użyciem gcloud container clusters list
Dane wyjściowe w kolumnie STATUS
powinny zawierać RUNNING
:
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. Wdrażanie Jenkinsa za pomocą Helm
Instalowanie Helm
Do zainstalowania Jenkinsa w naszym klastrze użyjemy Helma, menedżera pakietów aplikacji dla Kubernetes. Aby rozpocząć, pobierz projekt zawierający pliki manifestu Kubernetes, których użyjemy do wdrożenia Jenkinsa:
git clone https://github.com/GoogleCloudPlatform/continuous-deployment-on-kubernetes.git ~/continuous-deployment-on-kubernetes
Zmień bieżący katalog roboczy na katalog projektu:
cd ~/continuous-deployment-on-kubernetes/
Aby uzyskać uprawnienia roli administratora klastra, utwórz powiązanie roli klastra:
kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin --user=$(gcloud config get-value account)
Połącz się z klastrem Jenkinsa, uzyskując jego dane logowania:
gcloud container clusters get-credentials jenkins-cd --zone us-east1-d --project ${GOOGLE_CLOUD_PROJECT}
Pobierz plik binarny Helm do konsoli Cloud:
wget https://storage.googleapis.com/kubernetes-helm/helm-v2.14.1-linux-amd64.tar.gz
Rozpakuj plik i skopiuj dołączony plik helm do bieżącego katalogu roboczego:
tar zxfv helm-v2.14.1-linux-amd64.tar.gz && \ cp linux-amd64/helm .
Tiller to serwerowa część Helma, która działa w klastrze Kubernetes. Utwórz konto usługi o nazwie tiller
:
kubectl create serviceaccount tiller \ --namespace kube-system
Połącz go z rolą klastra cluster-admin
, aby mógł wprowadzać zmiany:
kubectl create clusterrolebinding tiller-admin-binding \ --clusterrole=cluster-admin \ --serviceaccount=kube-system:tiller
Teraz możemy zainicjować Helm i zaktualizować repozytorium:
./helm init --service-account=tiller && \ ./helm repo update
Weryfikuj
Sprawdź, czy Helm jest gotowy do użycia, za pomocą polecenia ./helm version
. Powinien on zwrócić numery wersji klienta i serwera:
Client: &version.Version{SemVer:"v2.14.1", GitCommit:"5270352a09c7e8b6e8c9593002a73535276507c0", GitTreeState:"clean"} Server: &version.Version{SemVer:"v2.14.1", GitCommit:"5270352a09c7e8b6e8c9593002a73535276507c0", GitTreeState:"clean"}
Instalowanie Jenkinsa
Teraz, gdy Helm jest zainstalowany na naszym klastrze, możemy zainstalować Jenkinsa:
./helm install stable/jenkins -n cd \ -f jenkins/values.yaml \ --version 1.2.2 --wait
Zweryfikuj
Sprawdźmy pody:
kubectl get pods
Wyjście powinno zawierać informację o naszym kontenerze Jenkinsa ze stanem RUNNING (działający):
NAME READY STATUS RESTARTS AGE cd-jenkins-7c786475dd-vbhg4 1/1 Running 0 1m
Sprawdź, czy usługa Jenkins została utworzona prawidłowo:
kubectl get svc
Dane wyjściowe powinny wyglądać mniej więcej tak:
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
Instalacja Jenkinsa będzie używać wtyczki Kubernetes do tworzenia agentów kompilacji. W razie potrzeby będą one automatycznie uruchamiane przez głównego Jenkinsa. Po zakończeniu pracy są automatycznie zamykane, a ich zasoby są ponownie dodawane do puli zasobów klastra.
Łączenie z Jenkinsem
Jenkins działa w naszym klastrze, ale aby uzyskać dostęp do interfejsu użytkownika, skonfigurujmy przekierowanie portów w 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 &
Podczas instalacji zostało wygenerowane hasło administratora. Aby go pobrać:
printf $(kubectl get secret cd-jenkins -o jsonpath="{.data.jenkins-admin-password}" | base64 --decode);echo
W górnej części Cloud Shell kliknij ikonę podglądu w przeglądarce i wybierz „Podejrzyj na porcie 8080”.
Powinien pojawić się ekran logowania do Jenkinsa, na którym możemy wpisać admin
jako nazwę użytkownika i hasło zwrócone w poprzednim kroku:
Po kliknięciu Zaloguj się powinniśmy trafić na stronę główną Jenkinsa.
5. Instalowanie i konfigurowanie wtyczki GKE
Wtyczka Google Kubernetes Engine umożliwia publikowanie wdrożeń utworzonych w Jenkinsie w klastrach Kubernetesa działających w GKE. W projekcie trzeba skonfigurować uprawnienia IAM. Skonfigurujemy ją za pomocą Terraform.
Najpierw pobierz projekt wtyczki GKE:
git clone https://github.com/jenkinsci/google-kubernetes-engine-plugin.git ~/google-kubernetes-engine-plugin
Automatyczna konfiguracja uprawnień IAM
Zmień bieżący katalog roboczy na katalog rbac projektu GKE, który wcześniej sklonowaliśmy:
cd ~/google-kubernetes-engine-plugin/docs/rbac/
gcp-sa-setup.tf
to plik konfiguracji Terraform, który utworzy niestandardową rolę uprawnień GCP z ograniczonymi uprawnieniami oraz konto usługi GCP, któremu zostanie przypisana ta rola. Plik wymaga wartości zmiennych nazwy projektu, regionu i konta usługi. Te wartości podajemy, deklarując najpierw te zmienne środowiskowe:
export TF_VAR_project=${GOOGLE_CLOUD_PROJECT} export TF_VAR_region=us-east1-d export TF_VAR_sa_name=kaniko-role
Zainicjuj Terraform, wygeneruj plan i zastosuj go:
terraform init terraform plan -out /tmp/tf.plan terraform apply /tmp/tf.plan && rm /tmp/tf.plan
Aby zapisać pliki w zasobniku Cloud Storage, konto usługi musi mieć uprawnienia administratora pamięci masowej:
gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} \ --member serviceAccount:kaniko-role@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com \ --role 'roles/storage.admin'
Potrzebuje też uprawnień do kontenera na potrzeby etapów wdrażania w naszym potoku:
gcloud projects add-iam-policy-binding ${GOOGLE_CLOUD_PROJECT} --member \ serviceAccount:kaniko-role@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com --role 'roles/container.developer'
Teraz możemy używać Helm do konfigurowania uprawnień klastra dla wtyczki GKE za pomocą narzędzia gke robot deployer. Zmień katalog roboczy na katalog helm projektu GKE:
cd ~/google-kubernetes-engine-plugin/docs/helm/
Zainstaluj za pomocą podanej karty Helm:
export TARGET_NAMESPACE=kube-system && \ envsubst < gke-robot-deployer/values.yaml | helm install ./gke-robot-deployer --name gke-robot-deployer -f -
6. Konfigurowanie Jenkinsa
Klucze kont usługi
Aby konto usługi działało prawidłowo, musimy wygenerować plik klucza prywatnego i dodać go jako obiekt tajny Kubernetes. Najpierw wygeneruj plik za pomocą tego polecenia gcloud:
gcloud iam service-accounts keys create /tmp/kaniko-secret.json --iam-account kaniko-role@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com
Utworzymy klucz obiektu tajnego w magazynie obiektów tajnych Kubernetes za pomocą tego pliku:
kubectl create secret generic jenkins-int-samples-kaniko-secret --from-file=/tmp/kaniko-secret.json
Pobierz plik JSON na dysk lokalny, klikając opcję Pobierz plik w menu z 3 kropkami w Cloud Shell:
Wpisz ścieżkę do pliku /tmp/kaniko-secret.json
i kliknij Pobierz.
W panelu po lewej stronie na stronie Jenkinsa kliknij kolejno Dane logowania i System.
W sekcji strony zatytułowanej System kliknij Uprawnienia globalne,a następnie po lewej stronie kliknij Dodaj uprawnienia:
W menu Typ wybierz Konto usługi Google z kluczem prywatnym. Wpisz „kaniko-role” jako nazwę, a następnie prześlij klucz JSON utworzony w poprzednich krokach i kliknij OK.
Zmienne środowiskowe
Zanim utworzymy potok wielogałęziowy, musimy zdefiniować w Jenkinsie kilka zmiennych środowiskowych. Są to:
- JENK_INT_IT_ZONE – strefa klastra Kubernetes. W naszym przypadku
us-east1-d
- JENK_INT_IT_PROJECT_ID – odnosi się do identyfikatora projektu GCP hostującego tę instancję Jenkinsa.
- JENK_INT_IT_STAGING – nazwa klastra „statycznego” (na potrzeby demonstracji jest to
staging
). - JENK_INT_IT_PROD – nazwa klastra produkcyjnego. Na potrzeby demonstracji:
prod
- JENK_INT_IT_BUCKET – zasobnik Google Cloud Storage utworzony w poprzednim kroku
- JENK_INT_IT_CRED_ID – odnosi się do danych logowania utworzonych za pomocą pliku JSON w poprzednim kroku. Wartość powinna być zgodna z nazwą, którą jej nadaliśmy,
kaniko-role
Aby je dodać, wybierz Zarządzaj Jenkinsem:
Następnie Skonfiguruj system:
Pojawi się sekcja o nazwie Właściwości globalne. Gdy zaznaczysz pole Zmienne środowiska, pojawi się przycisk Dodaj, który pozwoli Ci dodać zmienne powyżej jako pary klucz-wartość:
Aby zastosować zmiany, kliknij przycisk Zapisz u dołu strony.
7. Konfigurowanie potoku
W Jenkinsie kliknij „Nowy element”:
Wpisz „jenkins-integration-sample” jako nazwę, jako typ projektu wybierz „Multibranch Pipeline” i kliknij OK:
Przekierujemy Cię na stronę konfiguracji potoku. W sekcji Źródła gałęzi wpisz https://github.com/GoogleCloudPlatform/jenkins-integration-samples.git jako Repozytorium projektu. W sekcji Konfiguracja kompilacji wpisz „gke/Jenkinsfile” jako ścieżkę skryptu.
Aby zastosować te ustawienia, kliknij Zapisz. Po zapisaniu Jenkins rozpocznie skanowanie repozytorium i subsequentną kompilację każdej gałęzi. W miarę postępu tworzenia, uruchamiania i usuwania podów na stronie Zadania Kubernetes będą pojawiać się informacje o tych działaniach.
Po zakończeniu kompilacji na stronie Zadania Kubernetes znajdziesz 2 elementy o nazwie jenkins-integration-samples-gke, z których każdy odpowiada klastrowi produkcyjnemu lub testowemu. Stan: OK:
Po wykonaniu tego polecenia gcloud zobaczysz, że obraz kontenera został przesłany do Google Container Registry zgodnie z naszym potokiem:
gcloud container images list
Aby wyświetlić zadanie w przeglądarce, uzyskaj poświadczenia do klastra produkcyjnego:
gcloud container clusters get-credentials prod --zone us-east1-d --project ${GOOGLE_CLOUD_PROJECT}
Aby skonfigurować przekierowanie portu z portu 8081 powłoki na port 8080 obciążenia, uruchom następujące polecenie:
export POD_NAME=$(kubectl get pods -o jsonpath="{.items[0].metadata.name}") && kubectl port-forward $POD_NAME 8081:8080 >> /dev/null &
U góry Cloud Shell kliknij ikonę podglądu w przeglądarce i wybierz „Podgląd na porcie 8081”.
8. Czyszczenie
Poznaliśmy sposób wdrażania Jenkinsa i przykładowego potoku wielogałęziowego w Kubernetes. Teraz czas wyczyścić projekt ze wszystkich utworzonych zasobów.
Usuwanie projektu
Jeśli wolisz, możesz usunąć cały projekt. W konsoli GCP otwórz stronę Menedżer zasobów w chmurze:
Na liście projektów wybierz projekt, nad którym pracujesz, i kliknij Usuń. Pojawi się prośba o wpisanie identyfikatora projektu. Wpisz hasło i kliknij Wyłącz.
Możesz też usunąć cały projekt bezpośrednio z Cloud Shell za pomocą gcloud:
gcloud projects delete $GOOGLE_CLOUD_PROJECT
Jeśli wolisz usuwać poszczególne elementy podlegające rozliczeniu pojedynczo, przejdź do następnej sekcji.
Klaster Kubernetes
Aby usunąć cały klaster Kubernetes za pomocą gcloud:
gcloud container clusters delete jenkins-cd --zone=us-east1-d
Zasobniki na dane
Usuń wszystkie przesłane pliki i usuń nasz bucket za pomocą gsutil:
gsutil rm -r gs://${GOOGLE_CLOUD_PROJECT}-jenkins-test-bucket
Obrazy w Google Container Registry
Usuniemy obrazy z Google Container Registry, korzystając z digestów obrazów. Najpierw pobierz zbiorcze podsumowania za pomocą tego polecenia:
gcloud container images list-tags gcr.io/${GOOGLE_CLOUD_PROJECT}/jenkins-integration-samples-gke --format="value(digest)"
Następnie dla każdego zwróconego podsumowania:
gcloud container images delete gcr.io/${GOOGLE_CLOUD_PROJECT}/jenkins-integration-samples-gke@sha256:<DIGEST>
9. Gratulacje!
Super! Udało się. Znasz już metody wdrażania Jenkinsa w GKE i przydzielania zadań do klastrów Kubernetes.
Omówione zagadnienia
- Wdrożyliśmy klaster Kubernetes i za pomocą Helma zainstalowaliśmy Jenkinsa.
- Zainstalowaliśmy i skonfigurowaliśmy wtyczkę GKE, aby umożliwić Jenkinsowi wdrażanie artefaktów kompilacji w klastrach Kubernetes
- Skonfigurowaliśmy Jenkinsa, aby ustawić potok wielogałęziowy, który wysyła pracę do klastrów GKE.