Continuous Deployment in GitHub Actions

Image by Chris Pagan

Assalamu’alaikum Warahmatullah Wabarakatuh,

Setelah kita membuat script CI, waktunya kita membuat script untuk CD nya, tapi sebelum itu kita harus men-setting secret, yang nantinya akan kita gunakan untuk upload artifact docker images ke GitHub Container Registry dan melakukan remote SSH ke kubernetes master-nodes.

Pertama kita masuk ke setting repository :

Kemudian kita masuk kepada menu secrets

Dan jika kita telah menambahkan secrets kita bisa lanjut menuliskan CD scriptnya

Okeh kita langsung saja masuk ke script CD nya.

name: CI Build and CD to Kubernetes Clusteron:push: {}jobs:# Build Docker ImagesBuild:name: Build Docker Imagesruns-on: ubuntu-latestenv:GO111MODULE: onsteps:- name: Checkout Repouses: actions/checkout@v2- name: Set up QEMUuses: docker/setup-qemu-action@v1- uses: satackey/action-docker-layer-caching@v0.0.11continue-on-error: true- name: Set up Docker Buildxuses: docker/setup-buildx-action@v1- name: Login to GitHub Container Registryuses: docker/login-action@v1with:registry: ghcr.iousername: ${{ github.repository_owner }}password: ${{ secrets.TOKEN }}- name: Build and pushuses: docker/build-push-action@v2with:context: .platforms: linux/amd64,linux/arm64push: truetags: ghcr.io/mrofisr/simple:latest# Scanning Docker ImagesDockerImagesScan:name: Scanning Docker Imagesneeds: [Build]runs-on: ubuntu-lateststeps:- uses: actions/checkout@v2- name: Build an image from Dockerfilerun: docker build -t ghcr.io/mrofisr/simple:latest .- name: Run Trivy vulnerability scanneruses: aquasecurity/trivy-action@masterwith:image-ref: "ghcr.io/mrofisr/simple:latest"format: "template"template: "@/contrib/sarif.tpl"output: "trivy-results.sarif"severity: 'CRITICAL,HIGH'- name: Upload Trivy scan results to GitHub Security tabuses: github/codeql-action/upload-sarif@v1with:sarif_file: "trivy-results.sarif"# Deploy to Kubernetes ClusterDeployToKubernetes:name: Deploy To Kubernetesneeds: [DockerImagesScan]runs-on: ubuntu-lateststeps:- uses: appleboy/ssh-action@masterwith:host: ${{ secrets.SSH_HOST }}username: ${{ secrets.SSH_USERNAME }}key: ${{ secrets.SSH_KEY }}port: ${{ secrets.SSH_PORT }}script: |cd simplegit pullcd kuberneteskubectl delete all --all -n backendkubectl delete namespace backendkubectl apply -f namespace.yamlkubectl apply -f deployment.yamlkubectl apply -f autoscale.yamlkubectl get all -n backend

Penjelasan :

Build Docker Images

Pada tahap ini kita akan membuat task / jobs yang akan melakukan build Dockerfile kita menjadi docker images, kemudian setelah itu hasil docker images yang sudah dibuild akan di upload ke GitHub Container Registry

Scanning Docker Images

Kemudian setelah berhasil membuat docker images, kita akan melakukan vulnerability scanning pada docker images tersebut, disini saya menggunakan trivy, trivy merupakan tools yang digunakan untuk scanning pada container images, file systems, dan Git repositories. Apabila ada celah keamanan pada docker images yang kita miliki, maka trivy akan menginfokan pada tab security

Deploy to Kubernetes Cluster

Dan pada tahap terakhir, kita akan melakukan deploy docker images kita ke Kubernetes Cluster yang sudah kita buat.

namespace.yaml

apiVersion: v1kind: Namespacemetadata:name: backend

deployment.yaml

apiVersion: apps/v1kind: Deploymentmetadata:name: simple-go-apinamespace: backendspec:selector:matchLabels:run: simple-go-apitemplate:metadata:labels:run: simple-go-apispec:securityContext:runAsUser: 10001containers:- name: simple-go-apiimage: ghcr.io/mrofisr/simple:latestports:- containerPort: 3000resources:limits:cpu: 500mrequests:cpu: 200m---apiVersion: v1kind: Servicemetadata:name: simple-go-apinamespace: backendlabels:run: simple-go-apispec:type: LoadBalancerports:- name: httpport: 3000targetPort: 3000nodePort: 31000protocol: TCPselector:run: simple-go-api

autoscalling.yaml

apiVersion: autoscaling/v2beta2kind: HorizontalPodAutoscalermetadata:name: simple-go-apinamespace: backendspec:scaleTargetRef:apiVersion: apps/v1kind: Deploymentname: simple-go-apiminReplicas: 1maxReplicas: 5metrics:- type: Resourceresource:name: cputarget:type: UtilizationaverageUtilization: 50

setelah semua proses berhasil maka output atau hasilnya akan seperti ini :

Testing Horizontal Pod AutoScalling

Dan yang tahap terakhir kita akan melakukan testing pada HPA yang sudah kita buat, disini saya menggunakan Apache Benchmark untuk melakukan testing.

Testing :

mrofisr@mrofisr ~ % ab -n 10000 -c 1000 http://34.124.208.75:31000/quotesThis is ApacheBench, Version 2.3 <$Revision: 1879490 $>Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/Licensed to The Apache Software Foundation, http://www.apache.org/Benchmarking 34.124.208.75 (be patient)Completed 1000 requestsCompleted 2000 requestsCompleted 3000 requestsCompleted 4000 requests^CServer Software:Server Hostname:        34.124.208.75Server Port:            31000Document Path:          /quotesDocument Length:        224 bytesConcurrency Level:      1000Time taken for tests:   60.828 secondsComplete requests:      4845Failed requests:        4795(Connect: 0, Receive: 0, Length: 4795, Exceptions: 0)Total transferred:      1819471 bytesHTML transferred:       1291366 bytesRequests per second:    79.65 [#/sec] (mean)Time per request:       12554.697 [ms] (mean)Time per request:       12.555 [ms] (mean, across all concurrent requests)Transfer rate:          29.21 [Kbytes/sec] receivedConnection Times (ms)min  mean[+/-sd] median   maxConnect:       28  404 468.1    288    3500Processing:   305 10650 2602.1  11615   14534Waiting:      305 10649 2601.9  11615   14534Total:        352 11054 2581.8  11930   14895Percentage of the requests served within a certain time (ms)50%  1192966%  1219975%  1245780%  1261090%  1281795%  1306998%  1332099%  14064100%  14895 (longest request)

Before :

After :

After CPU usages normal :

Penjelasan :

Pada kasus ini saya membuat sebuah kondisi apabila penggunaan CPU melebihi 50% maka Kubernetes akan menggandakan podnya menjadi 4 buah pod agar proses aplikasi tetap berjalan dengan lancar.

Sekian, Terimakasih~

About me

I’m Muhammad Abdur Rofi Maulidin, a DevOps Engineer passionate about optimizing software development processes by supporting cloud infrastructure management like kubernetes orchestration, and automations. Dedicated to support the reliability, availability, and performance of systems by implementing SLI/SLO based on performance monitoring for business requirement.

Feel free to keep in touch with me:

Let’s go to the cloud 🚀

Free Palestine 🇵🇸

--

--