Skip to content

Instantly share code, notes, and snippets.

@euclid1990
Last active June 21, 2024 08:46
Show Gist options
  • Save euclid1990/476ef4e1d44f39ff1d190281e1f7f698 to your computer and use it in GitHub Desktop.
Save euclid1990/476ef4e1d44f39ff1d190281e1f7f698 to your computer and use it in GitHub Desktop.
Horizontal Pod Autoscaler / Go / K8s
FROM --platform=linux/amd64 golang:1.22.4
WORKDIR /app
COPY main.go ./
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=off go build -o /go-hpa
EXPOSE 8080
CMD ["/go-hpa"]
package main
import (
"bufio"
"fmt"
"log"
"math"
"net/http"
"os"
"path"
"time"
)
const (
STORAGE_PATH = "./storage"
FILE_NAME = "number.txt"
)
func status(w http.ResponseWriter, r *http.Request) {
fmt.Fprint(w, "Ok")
}
func store(x float64) {
_ = os.Mkdir(STORAGE_PATH, 0700)
f, err := os.OpenFile(path.Join(STORAGE_PATH, FILE_NAME),
os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0700)
if err != nil {
log.Fatal(err)
}
defer f.Close()
data := fmt.Sprintln(x)
if _, err := f.WriteString(data); err != nil {
log.Fatal(err)
}
}
func countLine() int {
file, err := os.Open(path.Join(STORAGE_PATH, FILE_NAME))
if err != nil {
log.Println("Error:", err)
return 0
}
defer file.Close()
scanner := bufio.NewScanner(file)
total := 0
for scanner.Scan() {
total++
}
return total
}
func handler(w http.ResponseWriter, r *http.Request) {
log.Println("Remote Address:", r.RemoteAddr)
start := time.Now()
x := 0.0001
for i := 0; i <= 20000000; i++ {
x += math.Sqrt(x)
}
elapsed := time.Since(start)
// Output to response
fmt.Fprintf(w, "X = %f\n", x)
fmt.Fprintf(w, "Handler took %s\n", elapsed)
fmt.Fprintf(w, "Total %d entries\n", countLine())
// Store X into txt file
store(x)
}
func main() {
port := ":8080"
http.HandleFunc("/startz", status)
http.HandleFunc("/healthz", status)
http.HandleFunc("/readyz", status)
http.HandleFunc("/favicon.ico", func(w http.ResponseWriter, r *http.Request) {})
http.HandleFunc("/", handler)
log.Println("Server Listen On", port)
log.Fatal(http.ListenAndServe(port, nil))
}
---
# Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
imagePullSecrets:
- name: regcred
containers:
- name: my-app
image: <k8s-private-registry>/go-hpa
imagePullPolicy: Always
ports:
- containerPort: 8080
name: myport
livenessProbe:
httpGet:
path: /healthz
port: myport
initialDelaySeconds: 5
periodSeconds: 10
failureThreshold: 1
startupProbe:
httpGet:
path: /startz
port: myport
failureThreshold: 4
periodSeconds: 15
readinessProbe:
httpGet:
path: /readyz
port: myport
initialDelaySeconds: 5
periodSeconds: 10
failureThreshold: 1
successThreshold: 3
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
volumeMounts:
- name: data
mountPath: /app/storage
volumes:
- name: data
persistentVolumeClaim:
claimName: my-pvc
---
# Horizontal Pod Autoscaler (HPA)
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: my-app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: my-app
minReplicas: 1
maxReplicas: 5
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
---
# Service
apiVersion: v1
kind: Service
metadata:
name: my-app
spec:
selector:
app: my-app
ports:
- name: svc-http
protocol: TCP
port: 80
targetPort: myport
type: ClusterIP
---
# Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-app
namespace: cev-09
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
# ingressClassName: nginx # Nếu bạn không muốn dùng annotations
rules:
- host: k8s09.sun-asterisk.vn
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-app
port:
name: svc-http
---
# Persistent Volume
apiVersion: v1
kind: PersistentVolume
metadata:
name: my-pv
spec:
storageClassName: standard
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
---
# Persistent Volume Claim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: my-pvc
spec:
resources:
requests:
storage: 500Mi
accessModes:
- ReadWriteOnce
volumeName: my-pv
@euclid1990
Copy link
Author

euclid1990 commented Jun 21, 2024

Build & Push Docker Images

# Build image
docker build --tag go-hpa .

# Login to the sun private registry
docker login <k8s-private-registry> -u <username> -p <password>

# Tag the image
docker tag go-hpa <k8s-private-registry>/go-hpa

# Push the image to sun registry
docker push <k8s-private-registry>/go-hpa

Config kubectl on Local

# Config cluster server
kubectl config set-cluster <your-cluster> --server=<https://k8s-cluster.domain>/ --certificate-authority=ca-file

# Set credential token
kubectl config set-credentials <your-user> --token <token>

# Set context
kubectl config set-context <your-context> --user <your-user> --namespace <your-name-space> --cluster <your-cluster>

# Switch to your context
kubectl config use-context <your-context>

Create a K8s secret based on existing credentials

# Create secret
kubectl create secret docker-registry regcred --docker-server=<k8s-private-registry> \
        --docker-username=<username> --docker-password=<password> --output=yaml

Apply K8s manifest

kubectl apply -f ./manifest.yaml

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment