cncamp_homework
cncamp_homework copied to clipboard
homework for cncamp ☁️
cncamp_homework
httpserver
A simple HTTP server that you may:
- Access
/headerto find your Request Headers in the Response Headers - Access
/versionto get the VERSION environment variable - Access
/logto write logs in the server - Access
/healthzfor a health check
Sample usage
Start a server on 0.0.0.0:8080:
$ ./httpserver :8080
Note for Dockerfile
- When using Apple M1 to play with docker, it pulls and builds images for linux/arm/v8 platform by default.
- In order to build images for other platform, you may find buildx helpful.
- OR, you may also make use of GitHub Actions to avoid the issue.
- When using
alpineas the base image to run a go binary,CGO_ENABLED=0must be set when building due to a different libc implementation onalpine. Replacing the dynamic link library also helps.
Note for Google Cloud Platform
- Running
gcloud --quiet auth configure-dockerrequires the service account to have the permission to create bucket. For instance,Storage Adminrole works, but it's clearly not the least privilege you can grant. - You'll need
Kubernetes Engine Developer/Kubernetes Engine Adminrole for your service account. secrets.GKE_PROJECT: GKE's Project IDsecrets.GKE_SA_KEY: Base64 encoded JSON key of your service account
Things to modify for a different golang app
- Target binary name in
Dockerfile - Entrypoint command in
Dockerfile - Kubernetes and kustomize yaml files in
gkedirectory - Deploy to GKE workflow in
.github/workflows/gke.ymlenvsecrets.GKE_PROJECTsecrets.GKE_SA_KEY
Docker
Build a multi-stage docker image for httpserver.
See Dockerfile.
Kubernetes
Deploy httpserver on Kubernetes. Based on the first homework, I would like to deploy it on Google Kubernetes Engine.
Changes in httpserver
- Deprecate
valyala/fasthttp, usenet/httpandgorilla/mux - Add unit tests, coverage 100%
- Add graceful termination when receiving SIGTERM
- Add support for structured & leveled logging
- Deprecate
log, useuber-go/zap - Add a logging middleware
- Support structured & leveled logging
- Deprecate
Features
- [x] CI / CD with GitHub Actions
- [x] CI: Codecov
- [x] CD: Deploy to GKE
- [x] Resource limit and request
- [x] Health check
- [x] Readiness probe
- [x] Liveness probe
- [x] Graceful initialization with postStart
- [x] Graceful termination in httpserver source code
- [x] Configurations with ConfigMap
- [x] Structured & leveled logging
- [x] Logs stored in a mounted volume
- [x] Ingress with HTTPS
Notes
The gke directory is designed for deploying httpserver on GKE. To deploy on a local Kubernetes cluster, you should check out the base directory.
Prometheus
Monitor httpserver with Loki, Prometheus and Grafana.
Changes in httpserver
- Add random delay and Prometheus metrics in
metricsMiddleware - Logs will also be written to stdout now to be collected by Loki
Features
- Collect metrics with Prometheus
- Collect logs with Loki
- View various metrics in both Prometheus and Grafana
- View logs with Loki in Grafana
Notes
To install loki-stack on Kubernetes v1.22+, we need to change rbac.authorization.k8s.io/v1beta1 to rbac.authorization.k8s.io/v1. Therefore, manual installation is required:
$ helm repo add grafana https://grafana.github.io/helm-charts
$ helm pull grafana/loki-stack
$ tar -xvf loki-stack-2.5.0.tgz
$ cd loki-stack
$ sed s#rbac.authorization.k8s.io/v1beta1#rbac.authorization.k8s.io/v1#g *.yaml
$ cd ..
$ helm upgrade --install loki ./loki-stack --set grafana.enabled=true,prometheus.enabled=true,prometheus.alertmanager.persistentVolume.enabled=false,prometheus.server.persistentVolume.enabled=false
Demos
View Cluster Dashboard in Grafana

View Pod Dashboard in Grafana

View Server Latency Sum in Prometheus

View Server Latency with Prometheus in Grafana

View Server Events Count with Prometheus in Grafana

View Server Logs with Loki in Grafana

Istio
Deploy httpserver with Istio Service Mesh.
Changes in httpserver
- Move version info to Config Map to automate version updating
Features
- [x] Expose httpserver service with Istio Ingress Gateway
- [x] HTTPS support
- [x] L7 routing support
- [x] Distributed Tracing
Notes
Test with cURL
To test the HTTPS-ready httpserver exposed with Istio Ingress Gateway, run:
$ curl --resolve "sigmerc.top:$INGRESS_SECURE_PORT:$INGRESS_HOST" https://sigmerc.top -k
On my own machine, it's like:
$ curl --resolve sigmerc.top:443:127.0.0.1 https://sigmerc.top -k
L7 routing
In base/virtualservice.yaml:
http:
- match:
- port: 443
# uri:
# prefix: /version
You can uncomment uri and prefix lines, so that only access to /version is allowed. You can also use multiple match to make use of L7 routing.
Distributed Tracing
See documentation and follow the steps.