Overview
This page helps you plan a Goiabada deployment on a Kubernetes cluster.
Deploy it
Section titled “Deploy it”-
Check you have what Goiabada needs, below: a cluster with
kubectlaccess, a database server, two host names on one domain, and the setup wizard. -
Set up a gateway and its certificates, then generate the files with the setup wizard and apply them, as Gateway and certificates walks through with Envoy Gateway and cert-manager. On a cluster that already has a Gateway, an Ingress controller or routing of its own, follow Routing instead.
-
Sign in at your admin console’s URL, as First sign-in describes, with the password you read back out of the cluster.
-
Get it ready for production: High availability to run more than one pod, Security to decide who can reach the pods, and Secrets to choose how the Secrets are created and who can read them. To have Argo CD or Flux apply the files, see GitOps.
What Goiabada needs
Section titled “What Goiabada needs”| Requirement | Why |
|---|---|
| HTTPS on both public URLs | Each server marks its cookies Secure only when its URL is https://. The gateway serves HTTPS and passes plain HTTP to the pods. |
| Two host names, on one registrable domain | The gateway routes by host name, so the auth server and the admin console each need one of their own, such as auth.example.com and admin.example.com. Both must be on the same site: admin.example.net beside auth.example.com fails, because the admin console’s sign-in ends with the auth server posting back to it, and the browser leaves the admin console’s sign-in cookie off a cross-site post. Every sign-in then stops at “This sign-in can’t be finished”. |
| A database every pod shares | MySQL, PostgreSQL or SQL Server, in the cluster or outside it. SQLite isn’t offered: it’s a file on one host, used through one connection. See Database. |
| An empty database on the first start | The auth server seeds it with the administrator and the admin console’s client, configured for the URLs you gave the wizard. A database seeded for other URLs refuses the admin console’s sign-in: see Invalid redirect_uri. |
| A registry the nodes can pull from | Both images are on Docker Hub and on GitHub’s registry. A cluster that reaches neither, or may pull only from a registry of its own, pulls them from a mirror there: see Images from your own registry. |
| A route in, with certificates | By default the manifest creates a Gateway of class eg with a cert-manager annotation, the recipe Gateway and certificates sets up. The wizard can instead write a Gateway of your cluster’s class, routes on a Gateway someone else runs, or Ingresses, with certificates from your issuer or Secrets, or nothing but the Services: see Routing. |
You also need kubectl configured for the cluster, and the setup wizard on the machine you run it from.
What runs where
Section titled “What runs where”Internet → Gateway (HTTPS) → auth.example.com → goiabada-authserver Service (9090) → auth server pods → admin.example.com → goiabada-adminconsole Service (9091) → admin console pods
admin console pods → goiabada-authserver Service (9090), plain HTTP inside the clusterauth server pods → your databaseThe admin console calls the auth server’s API at GOIABADA_AUTHSERVER_INTERNALBASEURL, which the wizard sets to http://goiabada-authserver:9090: straight to the Service, without passing the gateway. That hop is plain HTTP, and it carries the admin console’s client secret, its refresh token and administrators’ tokens. It’s sound on a pod network you trust; Encrypt the hop to the auth server has what to do when it isn’t.
What the wizard generates
Section titled “What the wizard generates”The wizard writes two files. goiabada-k8s.yaml holds no secret, so you can commit it:
- A Namespace, labelled to warn about any pod that breaks the restricted Pod Security Standard, unless you answer that it already exists. See Security.
- Two ConfigMaps,
goiabada-authserver-configandgoiabada-adminconsole-config, each holding only what its server reads. - A third ConfigMap,
goiabada-db-ca, if you gave the wizard a CA file for the database’s certificate. It’s mounted into the auth server’s pods. See Check the database’s certificate. - Two ServiceAccounts,
goiabada-authserverandgoiabada-adminconsole, one per server, bound to no role and mounting no token. See Pod security. - Two Deployments, one per server, the auth server’s at two replicas unless you answer otherwise and the admin console’s at one, with a rolling update that never runs fewer pods than replicas and a spread over nodes. See High availability.
- Probes, a stop pause and a grace period on every container. See Probes and shutdown.
- Two PodDisruptionBudgets, one per Deployment.
- Two ClusterIP Services,
goiabada-authserveron 9090 andgoiabada-adminconsoleon 9091. - Two NetworkPolicies, if you ask for them, admitting only your routing layer’s namespace and the admin console. See Who can reach Goiabada.
- A Gateway and three HTTPRoutes, by default: one route per host name, and one redirecting HTTP to HTTPS. Other routing modes write the two routes alone, an Ingress per host, or nothing.
- A PodMonitor, if you ask for one, or scrape annotations. See Scrape on Kubernetes.
- The standard labels on every object, and any labels and annotations you add. See Labels and annotations.
goiabada-secrets.yaml, beside it, holds the Secrets the Deployments read: goiabada-encryption-key, with the AES key alone, goiabada-secrets, with every other secret, and, if you gave the wizard a database client certificate, goiabada-db-client-tls, with the certificate and its key. Never commit the file. See Secrets.
Both servers trust one proxy hop, the gateway or whatever routes to them, to tell them each client’s IP address, and log one record per request. See Client IP and proxy trust and Logs.
A namespace that already exists
Section titled “A namespace that already exists”Both files declare the Namespace, so applying either creates it. When someone else provides the namespace, such as a platform team with its own labels, quotas and access, answer no when the wizard asks whether to create it, or pass --create-namespace=false. Neither file declares it then, so applying them needs rights inside the namespace alone, and the labels its owner set stay as they are.
Labels and annotations
Section titled “Labels and annotations”Every object in both files, and both pod templates, carries the recommended labels, so cost tools, dashboards and policies can find Goiabada by them:
| Label | Value |
|---|---|
app.kubernetes.io/name |
goiabada |
app.kubernetes.io/instance |
The namespace, which holds one installation |
app.kubernetes.io/component |
authserver or adminconsole, on what belongs to one server. The objects both share, such as the Namespace, the Gateway and goiabada-secrets, have none. |
app.kubernetes.io/part-of |
goiabada |
app.kubernetes.io/version |
The image tag, such as 1.8.0 |
app.kubernetes.io/managed-by |
goiabada-setup |
When your cluster’s admission policies require labels or annotations of their own, such as a team or a cost centre, answer them when the wizard asks, or pass --labels and --annotations, each key=value separated by commas:
./goiabada-setup-linux-amd64 --answers=goiabada-setup.yaml --keep-secrets \ --labels=team=identity,cost-center=1234 --annotations=example.com/owner=identity-teamEvery object and both pod templates carry them, so a policy on Pods, such as one Kyverno extends to Deployments, is met as well as one on any other kind.
A policy checks a Secret when it’s created, so the Secrets you create yourself, the TLS Secrets you supply and the image pull secret, need the labels from the start. The steps the wizard prints add them, the standard labels and yours: the Secret is written locally, labeled and annotated there, and only then created:
kubectl create secret docker-registry registry-credentials -n goiabada --docker-server=registry.example.com \ --docker-username=<user> --docker-password=<password> --dry-run=client -o yaml | kubectl label --local -f - app.kubernetes.io/name=goiabada app.kubernetes.io/instance=goiabada \ app.kubernetes.io/part-of=goiabada app.kubernetes.io/version=<version> \ app.kubernetes.io/managed-by=goiabada-setup team=identity cost-center=1234 -o yaml | kubectl create -f ---keep-secrets leaves the secrets file as it is, so labels you add later don’t reach the Secrets. Add them yourself:
kubectl label secret goiabada-secrets goiabada-encryption-key -n goiabada team=identityRecover a locked-out administrator
Section titled “Recover a locked-out administrator”When nobody who holds authserver:manage can sign in any more, the auth server’s recover subcommand restores sign-in for one named user. The pods read the database credentials from the Secrets the manifest gives them, so the command runs inside one:
printf 'New password: ' && IFS= read -rs RECOVERY_PASSWORD && echoprintf '%s\n' "$RECOVERY_PASSWORD" | kubectl exec -i -n goiabada deployment/goiabada-authserver -- /app/goiabada-authserver recover --email [email protected] --grant-manage --password-stdinunset RECOVERY_PASSWORDThe first line asks for the new password without showing it. Recover the user with the auth server has every flag and what the command changes.