Podinfo is a tiny web application made with Go that showcases best practices of running microservices in Kubernetes. Podinfo is used by CNCF projects like Flux and Flagger for end-to-end testing and workshops.
Specifications:
- Health checks (readiness and liveness)
- Graceful shutdown on interrupt signals
- File watcher for secrets and configmaps
- Instrumented with Prometheus and Open Telemetry
- Structured logging with zap
- 12-factor app with viper
- Fault injection (random errors and latency)
- Swagger docs
- Timoni, Helm and Kustomize installers
- End-to-End testing with Kubernetes Kind and Helm
- Multi-arch container image with Docker buildx and GitHub Actions
- Container image signing with Sigstore cosign
- SBOMs and SLSA Provenance embedded in the container image
- CVE scanning with govulncheck
Web API:
GET /
prints runtime informationGET /version
prints podinfo version and git commit hashGET /metrics
return HTTP requests duration and Go runtime metricsGET /healthz
used by Kubernetes liveness probeGET /readyz
used by Kubernetes readiness probePOST /readyz/enable
signals the Kubernetes LB that this instance is ready to receive trafficPOST /readyz/disable
signals the Kubernetes LB to stop sending requests to this instanceGET /status/{code}
returns the status codeGET /panic
crashes the process with exit code 255POST /echo
forwards the call to the backend service and echos the posted contentGET /env
returns the environment variables as a JSON arrayGET /headers
returns a JSON with the request HTTP headersGET /delay/{seconds}
waits for the specified periodPOST /token
issues a JWT token valid for one minuteJWT=$(curl -sd 'anon' podinfo:9898/token | jq -r .token)
GET /token/validate
validates the JWT tokencurl -H "Authorization: Bearer $JWT" podinfo:9898/token/validate
GET /configs
returns a JSON with configmaps and/or secrets mounted in theconfig
volumePOST/PUT /cache/{key}
saves the posted content to RedisGET /cache/{key}
returns the content from Redis if the key existsDELETE /cache/{key}
deletes the key from Redis if existsPOST /store
writes the posted content to disk at /data/hash and returns the SHA1 hash of the contentGET /store/{hash}
returns the content of the file /data/hash if existsGET /ws/echo
echos content via websocketspodcli ws ws://localhost:9898/ws/echo
GET /chunked/{seconds}
usestransfer-encoding
typechunked
to give a partial response and then waits for the specified periodGET /swagger.json
returns the API Swagger docs, used for Linkerd service profiling and Gloo routes discovery
gRPC API:
/grpc.health.v1.Health/Check
health checking/grpc.EchoService/Echo
echos the received content/grpc.VersionService/Version
returns podinfo version and Git commit hash/grpc.DelayService/Delay
returns a successful response after the given seconds in the body of gRPC request/grpc.EnvService/Env
returns environment variables as a JSON array/grpc.HeaderService/Header
returns the headers present in the gRPC request. Any custom header can also be given as a part of request and that can be returned using this API/grpc.InfoService/Info
returns the runtime information/grpc.PanicService/Panic
crashes the process with gRPC status code as '1 CANCELLED'/grpc.StatusService/Status
returns the gRPC Status code given in the request body/grpc.TokenService/TokenGenerate
issues a JWT token valid for one minute/grpc.TokenService/TokenValidate
validates the JWT token
Web UI:
To access the Swagger UI open <podinfo-host>/swagger/index.html
in a browser.
- Getting started with Timoni
- Getting started with Flux
- Progressive Deliver with Flagger and Linkerd
- Automated canary deployments with Kubernetes Gateway API
To install Podinfo on Kubernetes the minimum required version is Kubernetes v1.23.
Install with Timoni:
timoni -n default apply podinfo oci://ghcr.io/stefanprodan/modules/podinfo
Install from github.io:
helm repo add podinfo https://stefanprodan.github.io/podinfo
helm upgrade --install --wait frontend \
--namespace test \
--set replicaCount=2 \
--set backend=http://backend-podinfo:9898/echo \
podinfo/podinfo
helm test frontend --namespace test
helm upgrade --install --wait backend \
--namespace test \
--set redis.enabled=true \
podinfo/podinfo
Install from ghcr.io:
helm upgrade --install --wait podinfo --namespace default \
oci://ghcr.io/stefanprodan/charts/podinfo
kubectl apply -k github.com/stefanprodan/podinfo//kustomize
docker run -dp 9898:9898 stefanprodan/podinfo
In order to install podinfo on a Kubernetes cluster and keep it up to date with the latest release in an automated manner, you can use Flux.
Install the Flux CLI on MacOS and Linux 6E28 using Homebrew:
brew install fluxcd/tap/flux
Install the Flux controllers needed for Helm operations:
flux install \
--namespace=flux-system \
--network-policy=false \
--components=source-controller,helm-controller
Add podinfo's Helm repository to your cluster and configure Flux to check for new chart releases every ten minutes:
flux create source helm podinfo \
--namespace=default \
--url=https://stefanprodan.github.io/podinfo \
--interval=10m
Create a podinfo-values.yaml
file locally:
cat > podinfo-values.yaml <<EOL
replicaCount: 2
resources:
limits:
memory: 256Mi
requests:
cpu: 100m
memory: 64Mi
EOL
Create a Helm release for deploying podinfo in the default namespace:
flux create helmrelease podinfo \
--namespace=default \
--source=HelmRepository/podinfo \
--release-name=podinfo \
--chart=podinfo \
--chart-version=">5.0.0" \
--values=podinfo-values.yaml
Based on the above definition, Flux will upgrade the release automatically when a new version of podinfo is released. If the upgrade fails, Flux can rollback to the previous working version.
You can check what version is currently deployed with:
flux get helmreleases -n default
To delete podinfo's Helm repository and release from your cluster run:
flux -n default delete source helm podinfo
flux -n default delete helmrelease podinfo
If you wish to manage the lifecycle of your applications in a GitOps manner, check out this workflow example for multi-env deployments with Flux, Kustomize and Helm.