Skip to content

Commit a2f39a4

Browse files
authored
Merge pull request #4 from DevSecOpsSamples/develop
Develop
2 parents aa18887 + b7bc04c commit a2f39a4

21 files changed

+1038
-13
lines changed

.github/workflows/build.yml

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
name: Build
2+
on:
3+
push:
4+
branches:
5+
- master
6+
- develop
7+
pull_request:
8+
types: [opened, synchronize, reopened]
9+
jobs:
10+
docker-build:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v3
14+
- name: Build the Docker image
15+
run: cd app && docker build . -t ${{ secrets.IMAGE_NAME }}:$(date +%s)
16+
sonarqube:
17+
name: Sonarqube
18+
runs-on: ubuntu-latest
19+
steps:
20+
- uses: actions/checkout@v3
21+
- name: Set up JDK 11
22+
uses: actions/setup-java@v3
23+
with:
24+
distribution: 'temurin'
25+
java-version: 11
26+
- name: Cache SonarCloud packages
27+
uses: actions/cache@v3
28+
with:
29+
path: ~/.sonar/cache
30+
key: ${{ runner.os }}-sonar
31+
restore-keys: ${{ runner.os }}-sonar
32+
- name: Cache Gradle packages
33+
uses: actions/cache@v3
34+
with:
35+
path: ~/.gradle/caches
36+
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }}
37+
restore-keys: ${{ runner.os }}-gradle
38+
- name: Build and analyze
39+
env:
40+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any
41+
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
42+
run: ./gradlew build sonarqube --info

.gitignore

Lines changed: 52 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,55 @@
1-
# Binaries for programs and plugins
2-
*.exe
3-
*.exe~
4-
*.dll
5-
*.so
6-
*.dylib
1+
build
2+
.gradle
3+
.vscode
4+
.idea
75

8-
# Test binary, built with `go test -c`
9-
*.test
6+
*.log
7+
*.jar
8+
*.war
9+
*.nar
10+
*.ear
11+
*.zip
12+
*.tar.gz
13+
*.rar
1014

11-
# Output of the go coverage tool, specifically when used with LiteIDE
12-
*.out
15+
# go
16+
vendor
17+
echo
18+
main
1319

14-
# Dependency directories (remove the comment below to include it)
15-
# vendor/
20+
# MAC
21+
.DS_Store
22+
23+
# internal
24+
*internal*
25+
26+
# k8s template output
27+
# go-echo-api-onepod-template.yaml
28+
# go-echo-api-template.yaml
29+
**/go-echo-api-onepod.yaml
30+
**/go-echo-api.yaml
31+
32+
# test
33+
2023*
34+
35+
# GCP
36+
## .sa .readonly-sa
37+
.*sa
38+
## google-github-actions/auth@v1
39+
gha-creds-*.json
40+
41+
# terraform
42+
.terraform
43+
*.tfstate
44+
*.tfstate.*
45+
crash.log
46+
crash.*.log
47+
*.tfvars
48+
*.tfvars.json
49+
override.tf
50+
override.tf.json
51+
*_override.tf
52+
*_override.tf.json
53+
.terraformrc
54+
terraform.rc
55+
*.hcl

README.md

Lines changed: 197 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,197 @@
1-
# gcp-golang-performance-test
1+
# Performance testing on GKE using labstack eacho application
2+
3+
[![Build](https://github.com/DevSecOpsSamples/gcp-golang-performance-test/actions/workflows/build.yml/badge.svg?branch=master)](https://github.com/DevSecOpsSamples/gcp-golang-performance-test/actions/workflows/build.yml)
4+
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=DevSecOpsSamples_gcp-golang-performance-test&metric=alert_status)](https://sonarcloud.io/summary/new_code?id=DevSecOpsSamples_gcp-golang-performance-test) [![Lines of Code](https://sonarcloud.io/api/project_badges/measure?project=DevSecOpsSamples_gcp-golang-performance-test&metric=ncloc)](https://sonarcloud.io/summary/new_code?id=DevSecOpsSamples_gcp-golang-performance-test)
5+
6+
Performance testing on GKE using the https://echo.labstack.com application.
7+
8+
9+
## Table of Contents
10+
11+
- [1. Create a GKE cluster](#1-create-a-gke-cluster)
12+
- [2. Deploy two applications for checking the performance per Pod and scaling](#2-deploy-two-applications-for-checking-the-performance-per-pod-and-scaling)
13+
- [2.1. Deploy for performance of one Pod](#21-deploy-for-performance-of-one-pod)
14+
- [2.2. Deploy for Scaling Test](#22-deploy-for-scaling-test)
15+
- [3. Performance Testing](#3-performance-testing)
16+
- [3.1. Install the Taurus](#31-install-the-taurus)
17+
- [3.2. Test for performance of one Pod](#32-test-for-performance-of-one-pod)
18+
- [3.3. Test with auto scaling](#33-test-with-auto-scaling)
19+
- [Cleanup](#6-cleanup)
20+
21+
---
22+
23+
## Prerequisites
24+
25+
### Installation
26+
27+
- [Install the gcloud CLI](https://cloud.google.com/sdk/docs/install)
28+
- [Install kubectl and configure cluster access](https://cloud.google.com/kubernetes-engine/docs/how-to/cluster-access-for-kubectl)
29+
- [Installing and Upgrading for the Taurus ](https://gettaurus.org/install/Installation/)
30+
31+
### Set environment variables
32+
33+
```bash
34+
COMPUTE_ZONE="us-central1"
35+
# replace with your project
36+
PROJECT_ID="sample-project"
37+
```
38+
39+
### Set GCP project
40+
41+
```bash
42+
gcloud config set project ${PROJECT_ID}
43+
gcloud config set compute/zone ${COMPUTE_ZONE}
44+
```
45+
46+
---
47+
48+
## 1. Create a GKE cluster
49+
50+
Create an Autopilot GKE cluster. It may take around 9 minutes.
51+
52+
```bash
53+
gcloud container clusters create-auto sample-cluster --region=${COMPUTE_ZONE}
54+
gcloud container clusters get-credentials sample-cluster
55+
```
56+
57+
## 2. Deploy two applications for checking the performance per Pod and scaling
58+
59+
Build and push to GCR:
60+
61+
```bash
62+
cd app
63+
docker build -t go-echo-api . --platform linux/amd64
64+
docker tag go-echo-api:latest gcr.io/${PROJECT_ID}/go-echo-api:latest
65+
66+
gcloud auth configure-docker
67+
docker push gcr.io/${PROJECT_ID}/go-echo-api:latest
68+
```
69+
70+
```bash
71+
kubectl get namespaces
72+
73+
kubectl create namespace echo-test
74+
```
75+
76+
Two deployments may take around 5 minutes to create a load balancer, including health checking.
77+
78+
## 2.1. Deploy for performance of one Pod
79+
80+
To check request per seconds(RPS) WITHOUT scaling, create and deploy K8s Deployment, Service, HorizontalPodAutoscaler, Ingress, and GKE BackendConfig using the [go-echo-api-onepod-template.yaml](app/go-echo-api-onepod-template.yaml) template file:
81+
82+
```bash
83+
sed -e "s|<project-id>|${PROJECT_ID}|g" go-echo-api-onepod-template.yaml > go-echo-api-onepod.yaml
84+
cat go-echo-api-onepod.yaml
85+
86+
kubectl get namespaces
87+
kubectl apply -f go-echo-api-onepod.yaml -n echo-test --dry-run=client
88+
```
89+
90+
Confirm Pod logs and configuration after deployment:
91+
92+
```bash
93+
kubectl logs -l app=go-echo-api-onepod -n echo-test
94+
95+
kubectl describe pods -n echo-test
96+
97+
kubectl get ingress go-echo-api-onepod-ingress -n echo-test
98+
```
99+
100+
## 2.2. Deploy for Scaling Test
101+
102+
To check request per seconds(RPS) with scaling, create and deploy K8s Deployment, Service, HorizontalPodAutoscaler, Ingress, and GKE BackendConfig using the [go-echo-api-template.yaml](app/go-echo-api-template.yaml) template file:
103+
104+
```bash
105+
sed -e "s|<project-id>|${PROJECT_ID}|g" go-echo-api-template.yaml > go-echo-api.yaml
106+
cat go-echo-api.yaml
107+
108+
kubectl apply -f go-echo-api.yaml -n echo-test --dry-run=client
109+
```
110+
111+
```bash
112+
kubectl apply -f go-echo-api.yaml -n echo-test
113+
```
114+
115+
Confirm Pod logs and configuration after deployment:
116+
117+
```bash
118+
kubectl logs -l app=go-echo-api -n echo-test
119+
120+
kubectl describe pods -n echo-test
121+
122+
kubectl get ingress go-echo-api-ingress -n echo-test
123+
```
124+
125+
Confirm that response of `/` API.
126+
127+
```bash
128+
LB_IP_ADDRESS=$(gcloud compute forwarding-rules list | grep go-echo-api | awk '{ print $2 }')
129+
echo ${LB_IP_ADDRESS}
130+
```
131+
132+
```bash
133+
curl http://${LB_IP_ADDRESS}/
134+
```
135+
136+
## 3. Performance Testing
137+
138+
### 3.1. Install the Taurus
139+
140+
https://gettaurus.org/install/Installation/
141+
142+
```bash
143+
sudo apt-get update -y
144+
sudo apt-get install python3 default-jre-headless python3-tk python3-pip python3-dev libxml2-dev libxslt-dev zlib1g-dev net-tools -y
145+
sudo python3 -m pip install bzt
146+
sudo apt-get install htop -y
147+
```
148+
149+
### 3.2. Test for performance of one Pod
150+
151+
```bash
152+
cd test
153+
# test with 300 threads and connection:close option
154+
bzt echo-bzt-onepod.yaml
155+
```
156+
157+
[test/echo-bzt-onepod.yaml](./test/echo-bzt-onepod.yaml)
158+
159+
```bash
160+
kubectl describe hpa go-echo-api-onepod-hpa -n echo-test
161+
162+
kubectl get hpa go-echo-api-onepod-hpa -n echo-test -w
163+
```
164+
165+
### 3.3. Test with auto scaling
166+
167+
```bash
168+
cd test
169+
# test with 2000 threads and connection:close option
170+
bzt echo-bzt.yaml
171+
```
172+
173+
[test/echo-bzt.yaml](./test/echo-bzt.yaml)
174+
175+
```bash
176+
kubectl describe hpa go-echo-api-hpa -n echo-test
177+
178+
kubectl get hpa go-echo-api-hpa -n echo-test -w
179+
```
180+
181+
## Cleanup
182+
183+
```bash
184+
kubectl scale deployment go-echo-api-onepod -n echo-test --replicas=0
185+
kubectl scale deployment go-echo-api -n echo-test --replicas=0
186+
187+
kubectl delete -f app/go-echo-api-onepod.yaml -n echo-test
188+
kubectl delete -f app/go-echo-api.yaml -n echo-test
189+
```
190+
191+
## References
192+
193+
- https://echo.labstack.com
194+
195+
- [Cloud SDK > Documentation > Reference > gcloud container clusters](https://cloud.google.com/sdk/gcloud/reference/container/clusters)
196+
197+
- [Google Kubernetes Engine (GKE) > Documentation > Guides > GKE Ingress for HTTP(S) Load Balancing](https://cloud.google.com/kubernetes-engine/docs/concepts/ingress)

app/.dockerignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
vendor
2+
echo
3+
main

app/Dockerfile

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
FROM golang:1.18 AS builder
2+
3+
RUN mkdir /app
4+
5+
COPY ./go.mod /app/
6+
COPY ./go.sum /app/
7+
COPY ./main.go /app/
8+
WORKDIR /app
9+
10+
RUN go install
11+
RUN go build main.go
12+
13+
RUN adduser go
14+
RUN chown go ./main
15+
16+
USER go
17+
18+
EXPOSE 8000
19+
20+
CMD ["./main"]

app/Makefile

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
build:
2+
go build ./...
3+
4+
install:
5+
go install -mod=vendor -v ./...
6+
7+
test:
8+
go test ./...
9+
10+
clean:
11+
go clean ./...

app/build-multi-arch.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#!/bin/bash
2+
set -e
3+
4+
echo "PROJECT_ID: ${PROJECT_ID}"
5+
6+
docker buildx ls
7+
docker buildx create --name builder --use builder
8+
time docker buildx build -t gcr.io/${PROJECT_ID}/go-echo-api:latest . --platform linux/amd64,linux/arm/v7 --push

app/build.sh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#!/bin/bash
2+
set -e
3+
4+
echo "PROJECT_ID: ${PROJECT_ID}"
5+
6+
docker build -t go-echo-api . --platform linux/amd64
7+
docker tag go-echo-api:latest gcr.io/${PROJECT_ID}/go-echo-api:latest
8+
docker push gcr.io/${PROJECT_ID}/go-echo-api:latest
9+
10+
# docker run -it -p 8000:8000 go-echo-api:latest
11+
12+
# docker run -it -p 8000:8000 gcr.io/${PROJECT_ID}/go-echo-api:latest

0 commit comments

Comments
 (0)