Implement DevOps in Google Cloud: Challenge Lab

Implement DevOps in Google Cloud: Challenge Lab

Task 1. Create the Lab resources

Enable APIs untuk GKE (Google Kubernetes Engine), Cloud Build dan Cloud Source Repositories

$ gcloud services enable container.googleapis.com \
    cloudbuild.googleapis.com \
    sourcerepo.googleapis.com

Menambahkan role Kubernetes Developer ke service akun Cloud Build

$ export PROJECT_ID=$(gcloud config get-value project)
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member=serviceAccount:$(gcloud projects describe $PROJECT_ID \
--format="value(projectNumber)")@cloudbuild.gserviceaccount.com --role="roles/container.developer"

Konfigurasi Git di Cloud shell, ganti user.email menjadi username, dan user.name set menjadi student

$git config --global user.email student-04-fca41af536e9@qwiklabs.net
$git config --global user.name student

sebelum membuat repo di google artifacts, enak nya kita set beberapa variable yang dibutuhkan biar mempermudah untuk kedepannya.

export PROJECT_ID=qwiklabs-gcp-03-3a6e4046cacb
export CLUSTER_NAME=hello-cluster
export ZONE=us-central1-a
export REGION=us-central1
export REPO=my-repository

$gcloud artifacts repositories create $REPO \
    --repository-format=docker \
    --location=$REGION \
    --description="repo my-repository"

jika sudah membuat repository di gcloud artifacts selanjutnya buat cluster GKE dengan nama hello-cluster

gcloud beta container --project "$PROJECT_ID" \
clusters create "$CLUSTER_NAME" --zone "$ZONE" \
--no-enable-basic-auth --cluster-version latest \
--release-channel "regular" --machine-type "e2-medium" \
--image-type "COS_CONTAINERD" --disk-type "pd-balanced" \
--disk-size "100" --metadata disable-legacy-endpoints=true  \
--logging=SYSTEM,WORKLOAD --monitoring=SYSTEM --enable-ip-alias \
--network "projects/$PROJECT_ID/global/networks/default" \
--subnetwork "projects/$PROJECT_ID/regions/$REGION/subnetworks/default" \
--no-enable-intra-node-visibility --default-max-pods-per-node "110" \
--enable-autoscaling --min-nodes "2" --max-nodes "6" \
--location-policy "BALANCED" --no-enable-master-authorized-networks \
--addons HorizontalPodAutoscaling,HttpLoadBalancing,GcePersistentDiskCsiDriver \
--enable-autoupgrade --enable-autorepair --max-surge-upgrade 1 \
--max-unavailable-upgrade 0 --enable-shielded-nodes --node-locations "$ZONE"

Pembuatan cluster GKE cukup lumayan lama sekitar 10-15 menit, jika sudah maka langkah selanjutnya membuat namespace dengan nama prod dan dev

$kubectl create namespace prod    

$kubectl create namespace dev

Task 2. Create a repository in Cloud Source Repositories

buat repo dengan nama sample-app

$gcloud source repos create sample-app

clone sample-app

$git clone https://source.developers.google.com/p/$PROJECT_ID/r/sample-app

pada baris ini akan mengcopy sample code ke dalam repo sample-app

cd ~
gsutil cp -r gs://spls/gsp330/sample-app/* sample-app

jika sudah buat first commit dan push ke branch master.

cd sample-app/
git init
git add .
git commit -m "first commit"
git push -u origin master

buat branch baru lagi dengan nama dev, commit dan push ke branch dev.

git checkout -b dev
git add .
git commit -m "first commit to dev"
git push -u origin dev

Task 3. Create the Cloud Build Triggers

pada bagian ini tugas ada dua yaitu membuat cloud Build Triggers untuk development dan production. Masuk ke Cloud Build -> create triggers.

Namesample-app-dev-deploy
EventPush to branch
Source Repositorysample-app
Branch^dev$
Cloud Build Configuration Filecloudbuild-dev.yaml
Namesample-app-prod-deploy
EventPush to branch
Source Repositorysample-app
Branch^master$
Cloud Build Configuration Filecloudbuild.yaml

contoh jika sukses membuat job triggers.

Task 4. Deploy the first versions of the application

pada task ini tugas nya deploy image container dari Cloud Build ke GKE.

COMMIT_ID="$(git rev-parse --short=7 HEAD)"
gcloud builds submit --tag="${REGION}-docker.pkg.dev/${PROJECT_ID}/$REPO/hello-cloudbuild:${COMMIT_ID}" .

Development

cloudbuild-dev.yaml

steps:
  # Step 1: Compile the Go Application
  - name: 'gcr.io/cloud-builders/go'
    env: ['GOPATH=/gopath']
    args: ['build', '-o', 'main', 'main.go']

  # Step 2: Build the Docker image for the Go application
  - name: 'gcr.io/cloud-builders/docker'
    args: ['build', '-t', 'us-central1-docker.pkg.dev/$PROJECT_ID/my-repository/hello-cloudbuild-dev:v1.0', '.']

  # Step 3: Push the Docker image to Artifact Registry
  - name: 'gcr.io/cloud-builders/docker'
    args: ['push', 'us-central1-docker.pkg.dev/$PROJECT_ID/my-repository/hello-cloudbuild-dev:v1.0']

  # Step 4: Apply the production deployment YAML file to the production namespace
  - name: 'gcr.io/cloud-builders/kubectl'
    id: 'Deploy'
    args: ['-n', 'dev', 'apply', '-f', 'dev/deployment.yaml']
    env:
    - 'CLOUDSDK_COMPUTE_REGION=us-central1-a'
    - 'CLOUDSDK_CONTAINER_CLUSTER=hello-cluster'

dev/deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: development-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: dev-app
  template:
    metadata:
      labels:
        app: dev-app
    spec:
      containers:
      - name: dev-container
        image: us-central1-docker.pkg.dev/qwiklabs-gcp-03-3a6e4046cacb/my-repository/hello-cloudbuild:v1.0
        ports:
        - containerPort: 8080

push to branch dev untuk mentriggers perubahan.

git add .
git commit -m "change version image"
git push -u origin dev

Production

cloudbuild.yaml

steps:
  # Step 1: Compile the Go Application
  - name: 'gcr.io/cloud-builders/go'
    id: 'Compile application'
    env: ['GOPATH=/gopath']
    args: ['build', '-o', 'main', 'main.go']

  # Step 2: Build the Docker image for the Go application
  - name: 'gcr.io/cloud-builders/docker'
    id: 'Build Docker image'
    args: ['build', '-t', 'us-central1-docker.pkg.dev/$PROJECT_ID/my-repository/hello-cloudbuild:v1.0', '.']

  # Step 3: Push the Docker image to Artifact Registry
  - name: 'gcr.io/cloud-builders/docker'
    id: 'Push Docker image'
    args: ['push', 'us-central1-docker.pkg.dev/$PROJECT_ID/my-repository/hello-cloudbuild:v1.0']

  # Step 4: Apply the production deployment YAML file to the production namespace
  - name: 'gcr.io/cloud-builders/kubectl'
    id: 'Deploy'
    args: ['-n', 'prod', 'apply', '-f', 'prod/deployment.yaml']
    env:
    - 'CLOUDSDK_COMPUTE_REGION=us-central1-a'
    - 'CLOUDSDK_CONTAINER_CLUSTER=hello-cluster'

prod/deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: production-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: production-app
  template:
    metadata:
      labels:
        app: production-app
    spec:
      containers:
      - name: production-container
        image: us-central1-docker.pkg.dev/qwiklabs-gcp-03-3a6e4046cacb/my-repository/hello-cloudbuild:v1.0
        ports:
        - containerPort: 8080

push to branch master, untuk mentriggers perubahan

git add .
git commit -m "change version image production"
git push -u origin master

kurang lebih seperti ini history dari Cloud Build mentriggers perubahan dari git commit yang sudah di push.

dan check juga di GKE, ke bagian Workloads status sudah OK tandanya sudah terdeploy untuk deployment dan production.

Task 5. Deploy the second versions of the application

Development Revision

main.go

func main() {
    http.HandleFunc("/blue", blueHandler)
    http.HandleFunc("/red", redHandler)
    http.ListenAndServe(":8080", nil)
}
...
func redHandler(w http.ResponseWriter, r *http.Request) {
    img := image.NewRGBA(image.Rect(0, 0, 100, 100))
    draw.Draw(img, img.Bounds(), &image.Uniform{color.RGBA{255, 0, 0, 255}}, image.ZP, draw.Src)
    w.Header().Set("Content-Type", "image/png")
    png.Encode(w, img)
}

cloudbuild-dev.yaml

...
# Step 2: Build the Docker image for the Go application
  - name: 'gcr.io/cloud-builders/docker'
    args: ['build', '-t', 'us-central1-docker.pkg.dev/$PROJECT_ID/my-repository/hello-cloudbuild-dev:v2.0', '.']

  # Step 3: Push the Docker image to Artifact Registry
  - name: 'gcr.io/cloud-builders/docker'
    args: ['push', 'us-central1-docker.pkg.dev/$PROJECT_ID/my-repository/hello-cloudbuild-dev:v2.0']
.....

dev/deployment.yaml

...
    image: us-central1-docker.pkg.dev/qwiklabs-gcp-03-3a6e4046cacb/my-repository/hello-cloudbuild:v2.0
...

commit dan push ke branch dev.

git add .
git commit -m "change version image revison 2.0"
git push -u origin dev

Production Revision

main.go

func main() {
    http.HandleFunc("/blue", blueHandler)
    http.HandleFunc("/red", redHandler)
    http.ListenAndServe(":8080", nil)
}
...
func redHandler(w http.ResponseWriter, r *http.Request) {
    img := image.NewRGBA(image.Rect(0, 0, 100, 100))
    draw.Draw(img, img.Bounds(), &image.Uniform{color.RGBA{255, 0, 0, 255}}, image.ZP, draw.Src)
    w.Header().Set("Content-Type", "image/png")
    png.Encode(w, img)
}

cloudbuild.yaml

...
# Step 2: Build the Docker image for the Go application
  - name: 'gcr.io/cloud-builders/docker'
    id: 'Build Docker image'
    args: ['build', '-t', 'us-central1-docker.pkg.dev/$PROJECT_ID/my-repository/hello-cloudbuild:<version>', '.']

  # Step 3: Push the Docker image to Artifact Registry
  - name: 'gcr.io/cloud-builders/docker'
    id: 'Push Docker image'
    args: ['push', 'us-central1-docker.pkg.dev/$PROJECT_ID/my-repository/hello-cloudbuild:<version>']
...

prod/deployment.yaml

...
    image: us-central1-docker.pkg.dev/qwiklabs-gcp-03-3a6e4046cacb/my-repository/hello-cloudbuild:v2.0
...

commit dan push ke branch master.

git add .
git commit -m "change version image revision 2.0 production"
git push -u origin master

terlihat revisions deployment sudah menggunakan image container dengan tag v2.0

terlihat revisions production sudah menggunakan image container dengan tag v2.0

Task 6. Roll back the production deployment

Pada bagian ini di history cloud build, klik name container sebelum build terakhir. klik di atas rebuild.

bagian ini juga di bagian history cloud build, klik name container sebelum build terakhir. klik di atas rebuild.

sekian thank you.