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.