diff --git a/ansible/roles/kubernetes/tasks/main.yml b/ansible/roles/kubernetes/tasks/main.yml index 80d66ffa..8c5cf1e3 100644 --- a/ansible/roles/kubernetes/tasks/main.yml +++ b/ansible/roles/kubernetes/tasks/main.yml @@ -57,11 +57,11 @@ - name: Set up control plane include_tasks: cplane.yml - when: k8s.cplane | length > 0 + when: k8s.cplane - name: Join cluster include_tasks: join.yml - when: k8s.cplane | length == 0 + when: not k8s.cplane - name: Add RequiresMountsFor to kubelet.service copy: diff --git a/k8s/helm/nexus/Chart.yaml b/k8s/helm/nexus/Chart.yaml index 169c9a52..8e361b26 100644 --- a/k8s/helm/nexus/Chart.yaml +++ b/k8s/helm/nexus/Chart.yaml @@ -5,10 +5,13 @@ home: https://github.com/instantlinux/docker-tools sources: - https://github.com/instantlinux/docker-tools type: application -version: 0.1.11 -# TODO: see vendor instructions for 3.71+ database migration -appVersion: "3.70.3" +version: 0.1.12 +appVersion: "3.87.1" dependencies: - name: chartlib version: 0.1.8 repository: https://instantlinux.github.io/docker-tools +- name: postgres + version: 0.1.0 + repository: file://subcharts/postgres + condition: postgres.enabled diff --git a/k8s/helm/nexus/subcharts/postgres/.helmignore b/k8s/helm/nexus/subcharts/postgres/.helmignore new file mode 100644 index 00000000..839de881 --- /dev/null +++ b/k8s/helm/nexus/subcharts/postgres/.helmignore @@ -0,0 +1,2 @@ +*~ +.git diff --git a/k8s/helm/nexus/subcharts/postgres/Chart.yaml b/k8s/helm/nexus/subcharts/postgres/Chart.yaml new file mode 100644 index 00000000..5d84c96b --- /dev/null +++ b/k8s/helm/nexus/subcharts/postgres/Chart.yaml @@ -0,0 +1,15 @@ +apiVersion: v2 +name: postgres +description: PostgreSQL database +home: https://github.com/instantlinux/docker-tools +sources: +- https://github.com/instantlinux/docker-tools +- https://hub.docker.com/_/postgres +type: application +version: 0.1.0 +# specify version tag from hub.docker.com in top-level values.yaml +appVersion: "0.0.1" +dependencies: +- name: chartlib + version: 0.1.8 + repository: https://instantlinux.github.io/docker-tools diff --git a/k8s/helm/nexus/subcharts/postgres/templates/NOTES.txt b/k8s/helm/nexus/subcharts/postgres/templates/NOTES.txt new file mode 100644 index 00000000..62ea3f4b --- /dev/null +++ b/k8s/helm/nexus/subcharts/postgres/templates/NOTES.txt @@ -0,0 +1,28 @@ +{{- if hasKey .Values "service" }} +{{- if or .Values.service.enabled (not (hasKey .Values.service "enabled")) }} +1. Get the application URL by running these commands: +{{- if hasKey .Values "ingress" }} +{{- if .Values.ingress.enabled }} +{{- range $host := .Values.ingress.hosts }} + {{- range .paths }} + http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} + {{- end }} +{{- end }} +{{- else if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "local.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" .Values.service.type }} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "local.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "local.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") + echo http://$SERVICE_IP:{{ .Values.service.port }} +{{- else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "local.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT +{{- end }} +{{- end }} +{{- end }} +{{- end }} diff --git a/k8s/helm/nexus/subcharts/postgres/templates/app.yaml b/k8s/helm/nexus/subcharts/postgres/templates/app.yaml new file mode 100644 index 00000000..5a01911b --- /dev/null +++ b/k8s/helm/nexus/subcharts/postgres/templates/app.yaml @@ -0,0 +1,15 @@ +{{- include "chartlib.configmap" . }} +--- +{{- include "chartlib.deployment" . }} +--- +{{- include "chartlib.hpa" . }} +--- +{{- include "chartlib.ingress" . }} +--- +{{- include "chartlib.ingresstotp" . }} +--- +{{- include "chartlib.service" . }} +--- +{{- include "chartlib.serviceaccount" . }} +--- +{{- include "chartlib.statefulset" . }} diff --git a/k8s/helm/nexus/subcharts/postgres/templates/cronjob.yaml b/k8s/helm/nexus/subcharts/postgres/templates/cronjob.yaml new file mode 100644 index 00000000..f024ba14 --- /dev/null +++ b/k8s/helm/nexus/subcharts/postgres/templates/cronjob.yaml @@ -0,0 +1,46 @@ +{{- $fullName := include "local.fullname" . -}} +apiVersion: batch/v1 +kind: CronJob +metadata: + name: {{ include "local.fullname" . }} + labels: + {{- include "local.labels" . | nindent 4 }} +spec: + schedule: "{{ .Values.backup.schedule }}" + timeZone: {{ .Values.backup.timeZone }} + jobTemplate: + spec: + template: + spec: + containers: + - name: {{ $fullName }}-backup + image: alpine/psql:{{ (split "-" .Values.image.tag)._0 }} + env: + - name: PGPASSFILE + value: /.pgpass + command: + - /bin/sh + - -c + - "pg_dump + -U synapse + -h {{ $fullName }} + -p 5432 + -d homeserver | gzip > /mnt/postgres/homeserver-$(date '+%Y-%m-%d-%H-%M').sql.gz 2>> /mnt/postgres/backup_error.log" + resources: + requests: + cpu: 500m + memory: 256Mi + volumeMounts: + - name: backup + mountPath: /mnt + - name: pgpass-secret + mountPath: /.pgpass + subPath: .pgpass + volumes: + - name: backup + hostPath: { path: /var/lib/docker/k8s-volumes/backup } + - name: pgpass-secret + secret: + secretName: synapse + defaultMode: 0600 + restartPolicy: Never diff --git a/k8s/helm/nexus/subcharts/postgres/templates/tests/test-connection.yaml b/k8s/helm/nexus/subcharts/postgres/templates/tests/test-connection.yaml new file mode 100644 index 00000000..ae159a4f --- /dev/null +++ b/k8s/helm/nexus/subcharts/postgres/templates/tests/test-connection.yaml @@ -0,0 +1,17 @@ +{{- if hasKey .Values "service" }} +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "local.fullname" . }}-test-connection" + labels: + {{- include "local.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['{{ include "local.fullname" . }}:{{ .Values.service.port }}'] + restartPolicy: Never +{{- end }} diff --git a/k8s/helm/nexus/subcharts/postgres/values.yaml b/k8s/helm/nexus/subcharts/postgres/values.yaml new file mode 100644 index 00000000..a36189cd --- /dev/null +++ b/k8s/helm/nexus/subcharts/postgres/values.yaml @@ -0,0 +1,53 @@ +# Default values for postgres +backup: + # Min Hour Day Month Weekday + timeZone: America/Los_Angeles + schedule: "0 5 * * *" + +statefulset: + containerPorts: [ containerPort: 5432 ] + # environment variables defined in parent + env: + postgres_user: user + postgres_db: appdb + xenv: + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + key: database_password + name: postgres + replicas: 1 + resources: + limits: + memory: 2048Mi + requests: + cpu: 300m + memory: 256Mi +volumeMounts: +- mountPath: /var/lib/postgresql/data + name: pgdata +volumeClaimTemplates: +- metadata: + name: pgdata + spec: + accessModes: [ ReadWriteOnce ] + resources: + requests: + storage: 8Gi + +image: + repository: postgres + pullPolicy: IfNotPresent + # tag: default + +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + enabled: false +service: + clusterIP: None + ports: [ port: 5432 ] + type: ClusterIP +autoscaling: + enabled: false diff --git a/k8s/helm/nexus/templates/app.yaml b/k8s/helm/nexus/templates/app.yaml index 5b83e9c4..b925dd1f 100644 --- a/k8s/helm/nexus/templates/app.yaml +++ b/k8s/helm/nexus/templates/app.yaml @@ -1,3 +1,5 @@ +{{- include "chartlib.configmap" . }} +--- {{- include "chartlib.deployment" . }} --- {{- include "chartlib.hpa" . }} diff --git a/k8s/helm/nexus/values.yaml b/k8s/helm/nexus/values.yaml index 2b82e6e6..21cef42d 100644 --- a/k8s/helm/nexus/values.yaml +++ b/k8s/helm/nexus/values.yaml @@ -3,14 +3,30 @@ autheliaIP: 10.0.10.10 domain: example.com deployment: + # Notes: + # port 1234 provides an h2 console, if configured + # port 5000 provides docker registry, if http port connector is added + # for that port containerPorts: + - containerPort: 1234 - containerPort: 5000 - containerPort: 8081 env: install4j_add_vm_params: > -Xms2048m -Xmx4096m -XX:MaxDirectMemorySize=3g -Djava.util.prefs.userRoot=${NEXUS_DATA}/javaprefs + # Set database to postgres instead of H2 (yes, this works in + # Community Edition as of 2025 -- ignore online statements to + # the contrary) + nexus_datastore_nexus_jdbcurl: jdbc:postgresql://nexus-postgres:5432/nexus + nexus_datastore_nexus_username: nexus tz: UTC + xenv: + - name: NEXUS_DATASTORE_NEXUS_PASSWORD + valueFrom: + secretKeyRef: + key: database_password + name: nexus nodeSelector: service.nexus: allow resources: @@ -82,3 +98,37 @@ ingress: autoscaling: enabled: false + +configmap: + name: nexus + data: + trigram.sql: | + CREATE SCHEMA nexus; + GRANT ALL PRIVILEGES ON DATABASE nexus TO nexus; + GRANT ALL PRIVILEGES ON SCHEMA nexus TO nexus; + CREATE EXTENSION pg_trgm SCHEMA nexus; + +postgres: + enabled: true + statefulset: + env: + postgres_user: nexus + postgres_db: nexus + xenv: + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + key: database_password + name: nexus + volumeMounts: + - mountPath: /var/lib/postgresql/data + name: pgdata + - mountPath: /docker-entrypoint-initdb.d/trigram.sql + name: nexus-config + subPath: trigram.sql + volumes: + - name: nexus-config + configMap: + name: nexus + image: + tag: 17.7-alpine