building homelab cluster part 10
Table of Content
building homelab cluster part 10¶
I will setup bytebase in this part which enables the GitOps workflow for databases.
- [x] create a postgres database for bytebase using postgres operator
- [x] create a secret containing postgres dsn for bytebase to use
- [x] deploy bytebase on kubernetes cluster using helm
- [x] setup gateway and httproute for the bytebase GUI access
- [x] setup gitops integration on bytebase using self-managed gitlab
bytebase¶
https://github.com/bytebase/bytebase
Bytebase is a Database CI/CD solution for the Developers and DBAs
helm chart¶
https://github.com/bytebase/bytebase/tree/main/helm-charts/bytebase
As usual, I will get the chart, confirm version, and download the values file.
# add helm repo
helm repo add bytebase-repo https://bytebase.github.io/bytebase
# confirm the version, and it's 1.1.0 as of March 2024
helm search repo -l bytebase
helm show chart bytebase-repo/bytebase
# get the values file
helm show values bytebase-repo/bytebase --version=1.1.0 > bytebase-values.yaml
values file¶
https://www.bytebase.com/docs/administration/production-setup/
There are few things listed in the production setup guide, and I will ensure they are set in the values file.
- enable https and websocket
- configure external URL
- store metadata in external postgres database
The https access will be ready through the gateway using NGINX Gateway Fabric.
The external URL can be set at bytebase.option.external-url
in the values file.
As for the external postgres database, I can pass the URL or DSN using the secret. I of course need the database first, so here we go.
postgres database for bytebase¶
I will use the postgres operator setup in the previous part.
First of all, the namespace is going to be "bytebase" with gateway access.
---
apiVersion: v1
kind: Namespace
metadata:
name: bytebase
labels:
service: bytebase
type: infrastructure
gateway-available: yes
Next, I will create a postgres database for bytebase. I will copy-paste the keycloak database manifest and prepare something like this. And do not forget to add this to the infra-config ks.
---
apiVersion: "acid.zalan.do/v1"
kind: postgresql
metadata:
name: bytebase-db
namespace: bytebase
spec:
teamId: "acid"
volume:
size: 2Gi
storageClass: directpv-min-io
numberOfInstances: 2
users:
bb: # database owner
- superuser
- createdb
databases: # {database name}:{database owner}
bytebase: bb
postgresql:
version: "16"
resources:
requests:
cpu: 10m
memory: 100Mi
limits:
cpu: 500m
memory: 500Mi
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: app.kubernetes.io/part-of
operator: In
values:
- directpv
This will spin up the database and create secret storing credentials for the user "bb". This command will display the password string.
kubectl -n bytebase get secret bb.bytebase-db.credentials.postgresql.acid.zalan.do -o jsonpath='{.data.password}' | base64 -d
https://www.bytebase.com/docs/get-started/install/external-postgres/#pg-connection-string
Now prepare the DSN secret.
postgresql://<
>:< >@< >:< >/< >
# on sops repo
cd clusters/homelab
mkdir bytebase
cd bytebase
kubectl create secret generic bytebase-db \
--from-literal=dsn='postgresql://bb:{PASSWORD_HERE}@bytebase-db/bytebase' \
-n bytebase \
--dry-run=client \
-o yaml > bytebase-db.yaml
sops -i --encrypt bytebase-db.yaml
# git commit and push
deploying bytebase¶
I will prepare the same usual script to generate flux helmrepo and helmrelease manifest for bytebase.
# add flux helmrepo to the manifest
flux create source helm bytebase-repo \
--url=https://bytebase.github.io/bytebase \
--interval=1h0m0s \
--export >bytebase.yaml
# add flux helm release to the manifest including the customized values.yaml file
flux create helmrelease bytebase \
--interval=10m \
--target-namespace=bytebase \
--source=HelmRepository/bytebase-repo \
--chart=bytebase \
--chart-version=1.1.0 \
--values=./bytebase-values.yaml \
--export >>bytebase.yaml
enable https access through gateway¶
I will copy-paste the keycloak-routes.yaml created in the previous part, and modify a little bit and prepare something like this as the HTTPRoute for bytebase GUI access.
---
apiVersion: gateway.networking.k8s.io/v1beta1
kind: HTTPRoute
metadata:
name: bytebase
namespace: bytebase
spec:
parentRefs:
- name: gateway
sectionName: https-bytebase
namespace: gateway
hostnames:
- "bytebase.blink-1x52.net"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: bytebase-entrypoint
port: 80
And of course I am going to add the gateway listener named "https-bytebase". The gateway manifest file is fairly long now, so below is just the listener section added.
- name: https-bytebase
hostname: bytebase.blink-1x52.net
port: 443
protocol: HTTPS
allowedRoutes:
namespaces:
from: Selector
selector:
matchLabels:
gateway-available: yes
tls:
mode: Terminate
certificateRefs:
- name: tls-bytebase-20240324
namespace: gateway
kind: Secret
Add bytebase-routes.yaml
to the infra-config ks and all is set. I can access https://bytebase.blink-1x52.net, and it will ask to register the admin account.
database gitops, vcs integration¶
https://www.bytebase.com/docs/vcs-integration/overview/
I can use bytebase to change database using GitOps methodology, and to do that I need to setup a project and associated database on bytebase to manage through GitOps.
Here is what I am going to do to setup the GitOps on bytebase:
- create a new namespace "dns-report-cloudflare"
- create a new repository on my self-managed GitLab to be the VCS of this project
- create a new postgres database for this namespace for a cronjob to insert record of metric data obtained using Cloudflare API for DNS service
- register the database on bytebase
- create a new project for the database on bytebase
- setup GitOps integration with the GitLab repo for the bytebase project
- (GitOps DEMO) create a table using bytebase database GitOps
- prepare necessary credentials for a cloudflare-dns-report script to run as encrypted secret on sops repository
- prepare CronJob manifest to run the script periodically
create namespace "dns-report-cloudflare"¶
---
apiVersion: v1
kind: Namespace
metadata:
name: dns-report-cloudflare
labels:
service: dns-report-cloudflare
type: application
create a new repository "dns-report-cloudflare"¶
I will create a separate repository to store manifests, and create flux gitrepo and kustomization to watch and reconcile the cluster using the manifests on the repository.
- [x] create a new blank project on my self-managed GitLab
- [x] create a read-only deploy token
- [x] create a secret from the deploy token username and password and place it and encrypt it on SOPS repository
- [x] place flux gitrepo and kustomization manifest in
./apps/base/dns-report-cloudflare/repo.yaml
and include it in./apps/homelab/kustomization.yaml
deploy token secret¶
kubectl create secret generic deploy-token-dns-report-cloudflare \
--from-literal=username="DEPLOY_TOKEN_NAME" \
--from-literal=password="DEPLOY_TOKEN_PASSWORD" \
--dry-run=client \
--namespace=flux-system \
-o yaml > {./clusters/homelab/flux-system/deploy-token-dns-report-cloudflare.yaml on SOPS repo}
flux gitrepo and kustomization for the new repository¶
---
apiVersion: source.toolkit.fluxcd.io/v1
kind: GitRepository
metadata:
name: dns-report-cloudflare
namespace: flux-system
spec:
interval: 1m0s
ref:
branch: main
secretRef:
name: deploy-token-dns-report-cloudflare
url: https://cp.blink-1x52.net/network/dns-report-cloudflare.git
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: dns-report-cloudflare
namespace: flux-system
spec:
interval: 1m0s
path: ./deploy/homelab
prune: true
sourceRef:
kind: GitRepository
name: dns-report-cloudflare
targetNamespace: dns-report-cloudflare
create database¶
Add this manifest and include it on infra-config ks. Note that there is no hyphen used in the database name.
---
apiVersion: "acid.zalan.do/v1"
kind: postgresql
metadata:
name: db
namespace: dns-report-cloudflare
spec:
teamId: "acid"
volume:
size: 5Gi
storageClass: directpv-min-io
numberOfInstances: 2
users:
dns-report-cloudflare-user:
- superuser
- createdb
databases:
dnsreportcloudflare: dns-report-cloudflare-user
postgresql:
version: "16"
resources:
requests:
cpu: 10m
memory: 100Mi
limits:
cpu: 500m
memory: 500Mi
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: app.kubernetes.io/part-of
operator: In
values:
- directpv
register the database on bytebase¶
Navigate to instances and click "add instance" to add the database created.
- select PostgreSQL as the database type
- give it an instance name - "dns-report-cloudflare"
- select environment - "Prod"
- host or socket - db.dns-report-cloudflare:5432
- username: dns-report-cloudflare-user
- password:
kubectl -n dns-report-cloudflare get secret dns-report-cloudflare-user.db.credentials.postgresql.acid.zalan.do -o jsonpath='{.data.password}' | base64 -d
- database - dnsreportcloudflare, note that there is no hyphen when creating the db and the same name goes here
- ssl and ssh connections - select None
Test the connection and add the instance.
create a bytebase project¶
Navigate to projects and click "new project" to create a new bytebase project.
- give it a name - dns-report-cloudflare
- key - anything
- mode - standard
add database to the bytebase project¶
Navigate to Database > Databases menu on left pane and click "transfer in DB" to add the unassigned database just created.
setup gitops workflow¶
Navigate to Integration > GitOps to start GitOps workflow configuration.
- url - https://cp.blink-1x52.net
- display name - anything
- follow the guide to fill the rest ... https://www.bytebase.com/docs/vcs-integration/self-host-gitlab/
- create a new app on self-managed gitlab as admin
- set the app id and secret provided by gitlab on bytebase
- confirm and add
Once the GitOps integration is configured, go to the project > Integration > GitOps menu again to select the configured GitOps integration to choose the repository and branch to use to manage the bytebase project (and its database).
- select repository - the new gitlab repo created for this
- branch - main by default
- base directory - bytebase by default
- schema change type - imperative, DDL, by default
- file path template -
{{ENV_ID}}/{{DB_NAME}}##{{VERSION}}##{{TYPE}}##{{DESCRIPTION}}.sql
by default
add DDL SQL to create a table¶
Add this file on "dns-report-cloudflare" repository and bytebase will pick this up, create an issue, apply necessary changes to the database, and resolve/close the issue on the project.
CREATE TABLE dnsreport (
hashed_id TEXT PRIMARY KEY,
time TIMESTAMP WITH TIME ZONE, -- iso8601, 2000-01-23T01:23:45Z
dname TEXT,
metric INTEGER
);
deleting bytebase¶
The bytebase helm added using flux can be deleted by removing the corresponding files/ks from the gitops repository. One thing to watch out is that the postgres database separately created for bytebase to use must be deleted separately, otherwise the bytebase release will continue to remain and run.