Skip to content

Commit ffca1c3

Browse files
authored
Init
1 parent aa18887 commit ffca1c3

21 files changed

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