Wire Zabbix/Matrix credentials to 1Password-synced secrets, add OnePasswordItem CRDs

- Zabbix: Remove hardcoded zabbix-db-secret and zabbix-admin-secret, reference
  zabbix-credentials (1Password) for DB-User, DB-Password, and admin password
- Matrix: Remove hardcoded matrix-db-secret, reference matrix-credentials for
  Postgres user/password. Convert ConfigMap homeserver.yaml to template with
  __DB_PASSWORD__/__DB_USER__ placeholders, inject via busybox init container
- Guacamole: Add OnePasswordItem CRD for future use. MySQL DB creds remain in
  guac-db-secret (1Password item lacks DB-specific fields — gap documented)
- All three services now include OnePasswordItem CRD manifests for ArgoCD mgmt
This commit is contained in:
Andrew Stoltz
2026-03-09 18:28:38 -05:00
parent 8f405d4df0
commit 3199c509c0
3 changed files with 733 additions and 670 deletions

View File

@@ -1,326 +1,344 @@
# Apache Guacamole - Remote Desktop Gateway # Apache Guacamole - Remote Desktop Gateway
# MySQL 8 + guacd + guacamole web # MySQL 8 + guacd + guacamole web
# ArgoCD managed - BlueJay Lab # ArgoCD managed - BlueJay Lab
--- # DB credentials sourced from 1Password via OnePasswordItem CRD (guacamole-credentials)
apiVersion: v1 # Note: guacamole-credentials contains Guacamole admin UI creds (username/password),
kind: Namespace # not MySQL DB creds. MySQL root/user password is kept in guac-db-secret (still inline)
metadata: # because 1Password item lacks DB-specific fields. See gap notes below.
name: guacamole ---
labels: apiVersion: v1
app.kubernetes.io/part-of: bluejay-infra kind: Namespace
--- metadata:
apiVersion: v1 name: guacamole
kind: Secret labels:
metadata: app.kubernetes.io/part-of: bluejay-infra
name: guac-db-secret ---
namespace: guacamole apiVersion: v1
type: Opaque kind: Secret
stringData: metadata:
MYSQL_ROOT_PASSWORD: BlueJay-Guac-DB-2026 name: guac-db-secret
MYSQL_DATABASE: guacamole_db namespace: guacamole
MYSQL_USER: guacamole type: Opaque
MYSQL_PASSWORD: BlueJay-Guac-DB-2026 stringData:
--- MYSQL_ROOT_PASSWORD: BlueJay-Guac-DB-2026
# MySQL 8 StatefulSet MYSQL_DATABASE: guacamole_db
apiVersion: apps/v1 MYSQL_USER: guacamole
kind: StatefulSet MYSQL_PASSWORD: BlueJay-Guac-DB-2026
metadata: ---
name: guac-mysql # MySQL 8 StatefulSet
namespace: guacamole apiVersion: apps/v1
labels: kind: StatefulSet
app: guac-mysql metadata:
spec: name: guac-mysql
serviceName: guac-mysql namespace: guacamole
replicas: 1 labels:
selector: app: guac-mysql
matchLabels: spec:
app: guac-mysql serviceName: guac-mysql
template: replicas: 1
metadata: selector:
labels: matchLabels:
app: guac-mysql app: guac-mysql
spec: template:
containers: metadata:
- name: mysql labels:
image: mysql:8.0 app: guac-mysql
ports: spec:
- containerPort: 3306 containers:
name: mysql - name: mysql
envFrom: image: mysql:8.0
- secretRef: ports:
name: guac-db-secret - containerPort: 3306
volumeMounts: name: mysql
- name: guac-mysql-data envFrom:
mountPath: /var/lib/mysql - secretRef:
resources: name: guac-db-secret
requests: volumeMounts:
memory: 256Mi - name: guac-mysql-data
cpu: 100m mountPath: /var/lib/mysql
limits: resources:
memory: 1Gi requests:
cpu: 500m memory: 256Mi
livenessProbe: cpu: 100m
exec: limits:
command: memory: 1Gi
- mysqladmin cpu: 500m
- ping livenessProbe:
- -h exec:
- localhost command:
initialDelaySeconds: 60 - mysqladmin
periodSeconds: 10 - ping
readinessProbe: - -h
exec: - localhost
command: initialDelaySeconds: 60
- mysqladmin periodSeconds: 10
- ping readinessProbe:
- -h exec:
- localhost command:
initialDelaySeconds: 30 - mysqladmin
periodSeconds: 5 - ping
volumeClaimTemplates: - -h
- metadata: - localhost
name: guac-mysql-data initialDelaySeconds: 30
spec: periodSeconds: 5
accessModes: [ReadWriteOnce] volumeClaimTemplates:
resources: - metadata:
requests: name: guac-mysql-data
storage: 5Gi spec:
--- accessModes: [ReadWriteOnce]
apiVersion: v1 resources:
kind: Service requests:
metadata: storage: 5Gi
name: guac-mysql ---
namespace: guacamole apiVersion: v1
spec: kind: Service
selector: metadata:
app: guac-mysql name: guac-mysql
ports: namespace: guacamole
- port: 3306 spec:
targetPort: 3306 selector:
name: mysql app: guac-mysql
clusterIP: None ports:
--- - port: 3306
# DB schema init Job targetPort: 3306
# Generates the MySQL schema and pipes it into the database name: mysql
apiVersion: batch/v1 clusterIP: None
kind: Job ---
metadata: # DB schema init Job
name: guacamole-initdb # Generates the MySQL schema and pipes it into the database
namespace: guacamole apiVersion: batch/v1
annotations: kind: Job
argocd.argoproj.io/hook: PostSync metadata:
argocd.argoproj.io/hook-delete-policy: BeforeHookCreation name: guacamole-initdb
spec: namespace: guacamole
ttlSecondsAfterFinished: 300 annotations:
template: argocd.argoproj.io/hook: PostSync
spec: argocd.argoproj.io/hook-delete-policy: BeforeHookCreation
restartPolicy: OnFailure spec:
initContainers: ttlSecondsAfterFinished: 300
- name: wait-for-mysql template:
image: mysql:8.0 spec:
command: restartPolicy: OnFailure
- sh initContainers:
- -c - name: wait-for-mysql
- | image: mysql:8.0
until mysqladmin ping -h guac-mysql --silent; do command:
echo "Waiting for MySQL..." - sh
sleep 5 - -c
done - |
containers: until mysqladmin ping -h guac-mysql --silent; do
- name: initdb echo "Waiting for MySQL..."
image: guacamole/guacamole:latest sleep 5
command: done
- sh containers:
- -c - name: initdb
- | image: guacamole/guacamole:latest
# Generate schema SQL command:
/opt/guacamole/bin/initdb.sh --mysql > /tmp/initdb.sql - sh
# Apply schema (ignore errors if tables already exist) - -c
mysql -h guac-mysql -u root -p"$MYSQL_ROOT_PASSWORD" "$MYSQL_DATABASE" < /tmp/initdb.sql || true - |
env: # Generate schema SQL
- name: MYSQL_ROOT_PASSWORD /opt/guacamole/bin/initdb.sh --mysql > /tmp/initdb.sql
valueFrom: # Apply schema (ignore errors if tables already exist)
secretKeyRef: mysql -h guac-mysql -u root -p"$MYSQL_ROOT_PASSWORD" "$MYSQL_DATABASE" < /tmp/initdb.sql || true
name: guac-db-secret env:
key: MYSQL_ROOT_PASSWORD - name: MYSQL_ROOT_PASSWORD
- name: MYSQL_DATABASE valueFrom:
valueFrom: secretKeyRef:
secretKeyRef: name: guac-db-secret
name: guac-db-secret key: MYSQL_ROOT_PASSWORD
key: MYSQL_DATABASE - name: MYSQL_DATABASE
--- valueFrom:
# guacd (Guacamole daemon) secretKeyRef:
apiVersion: apps/v1 name: guac-db-secret
kind: Deployment key: MYSQL_DATABASE
metadata: ---
name: guacd # guacd (Guacamole daemon)
namespace: guacamole apiVersion: apps/v1
labels: kind: Deployment
app: guacd metadata:
spec: name: guacd
replicas: 1 namespace: guacamole
selector: labels:
matchLabels: app: guacd
app: guacd spec:
template: replicas: 1
metadata: selector:
labels: matchLabels:
app: guacd app: guacd
spec: template:
containers: metadata:
- name: guacd labels:
image: guacamole/guacd:latest app: guacd
ports: spec:
- containerPort: 4822 containers:
name: guacd - name: guacd
resources: image: guacamole/guacd:latest
requests: ports:
memory: 128Mi - containerPort: 4822
cpu: 100m name: guacd
limits: resources:
memory: 512Mi requests:
cpu: 500m memory: 128Mi
livenessProbe: cpu: 100m
tcpSocket: limits:
port: 4822 memory: 512Mi
initialDelaySeconds: 15 cpu: 500m
periodSeconds: 10 livenessProbe:
--- tcpSocket:
apiVersion: v1 port: 4822
kind: Service initialDelaySeconds: 15
metadata: periodSeconds: 10
name: guacd ---
namespace: guacamole apiVersion: v1
spec: kind: Service
selector: metadata:
app: guacd name: guacd
ports: namespace: guacamole
- port: 4822 spec:
targetPort: 4822 selector:
name: guacd app: guacd
--- ports:
# Guacamole Web Application - port: 4822
apiVersion: apps/v1 targetPort: 4822
kind: Deployment name: guacd
metadata: ---
name: guacamole # Guacamole Web Application
namespace: guacamole apiVersion: apps/v1
labels: kind: Deployment
app: guacamole metadata:
spec: name: guacamole
replicas: 1 namespace: guacamole
selector: labels:
matchLabels: app: guacamole
app: guacamole spec:
template: replicas: 1
metadata: selector:
labels: matchLabels:
app: guacamole app: guacamole
spec: template:
containers: metadata:
- name: guacamole labels:
image: guacamole/guacamole:latest app: guacamole
ports: spec:
- containerPort: 8080 containers:
name: http - name: guacamole
env: image: guacamole/guacamole:latest
- name: GUACD_HOSTNAME ports:
value: guacd - containerPort: 8080
- name: GUACD_PORT name: http
value: "4822" env:
- name: MYSQL_HOSTNAME - name: GUACD_HOSTNAME
value: guac-mysql value: guacd
- name: MYSQL_PORT - name: GUACD_PORT
value: "3306" value: "4822"
- name: MYSQL_DATABASE - name: MYSQL_HOSTNAME
valueFrom: value: guac-mysql
secretKeyRef: - name: MYSQL_PORT
name: guac-db-secret value: "3306"
key: MYSQL_DATABASE - name: MYSQL_DATABASE
- name: MYSQL_USER valueFrom:
valueFrom: secretKeyRef:
secretKeyRef: name: guac-db-secret
name: guac-db-secret key: MYSQL_DATABASE
key: MYSQL_USER - name: MYSQL_USER
- name: MYSQL_PASSWORD valueFrom:
valueFrom: secretKeyRef:
secretKeyRef: name: guac-db-secret
name: guac-db-secret key: MYSQL_USER
key: MYSQL_PASSWORD - name: MYSQL_PASSWORD
resources: valueFrom:
requests: secretKeyRef:
memory: 256Mi name: guac-db-secret
cpu: 100m key: MYSQL_PASSWORD
limits: resources:
memory: 1Gi requests:
cpu: 500m memory: 256Mi
livenessProbe: cpu: 100m
httpGet: limits:
path: /guacamole/ memory: 1Gi
port: 8080 cpu: 500m
initialDelaySeconds: 120 livenessProbe:
periodSeconds: 10 httpGet:
readinessProbe: path: /guacamole/
httpGet: port: 8080
path: /guacamole/ initialDelaySeconds: 120
port: 8080 periodSeconds: 10
initialDelaySeconds: 60 readinessProbe:
periodSeconds: 5 httpGet:
--- path: /guacamole/
apiVersion: v1 port: 8080
kind: Service initialDelaySeconds: 60
metadata: periodSeconds: 5
name: guacamole ---
namespace: guacamole apiVersion: v1
spec: kind: Service
selector: metadata:
app: guacamole name: guacamole
ports: namespace: guacamole
- port: 8080 spec:
targetPort: 8080 selector:
name: http app: guacamole
--- ports:
# Traefik addPrefix middleware - port: 8080
# External URL guac.iamworkin.lan/ gets prefix /guacamole added targetPort: 8080
apiVersion: traefik.io/v1alpha1 name: http
kind: Middleware ---
metadata: # Traefik addPrefix middleware
name: guac-add-prefix # External URL guac.iamworkin.lan/ gets prefix /guacamole added
namespace: guacamole apiVersion: traefik.io/v1alpha1
spec: kind: Middleware
addPrefix: metadata:
prefix: /guacamole name: guac-add-prefix
--- namespace: guacamole
# TLS Certificate via cert-manager spec:
apiVersion: cert-manager.io/v1 addPrefix:
kind: Certificate prefix: /guacamole
metadata: ---
name: guacamole-tls # TLS Certificate via cert-manager
namespace: guacamole apiVersion: cert-manager.io/v1
spec: kind: Certificate
secretName: guacamole-tls metadata:
issuerRef: name: guacamole-tls
name: step-ca-acme namespace: guacamole
kind: ClusterIssuer spec:
dnsNames: secretName: guacamole-tls
- guac.iamworkin.lan issuerRef:
--- name: step-ca-acme
# Traefik IngressRoute kind: ClusterIssuer
apiVersion: traefik.io/v1alpha1 dnsNames:
kind: IngressRoute - guac.iamworkin.lan
metadata: ---
name: guacamole # Traefik IngressRoute
namespace: guacamole apiVersion: traefik.io/v1alpha1
spec: kind: IngressRoute
entryPoints: metadata:
- websecure name: guacamole
routes: namespace: guacamole
- match: Host(`guac.iamworkin.lan`) spec:
kind: Rule entryPoints:
middlewares: - websecure
- name: guac-add-prefix routes:
services: - match: Host(`guac.iamworkin.lan`)
- name: guacamole kind: Rule
port: 8080 middlewares:
tls: - name: guac-add-prefix
secretName: guacamole-tls services:
- name: guacamole
port: 8080
tls:
secretName: guacamole-tls
---
# 1Password secret sync — creates guacamole-credentials K8s Secret
# Fields: username, password, URL, Note
# NOTE: This secret contains Guacamole admin UI credentials only.
# MySQL DB credentials (MYSQL_ROOT_PASSWORD, MYSQL_PASSWORD) are NOT in 1Password yet.
# To fully externalize: add DB-User, DB-Password, DB-Root-Password fields to the
# "Guacamole" 1Password item, then replace guac-db-secret refs with guacamole-credentials.
apiVersion: onepassword.com/v1
kind: OnePasswordItem
metadata:
name: guacamole-credentials
namespace: guacamole
spec:
itemPath: vaults/IAmWorkin/items/Guacamole

View File

@@ -1,6 +1,8 @@
# Matrix Synapse + Element Web # Matrix Synapse + Element Web
# PostgreSQL 16 + Synapse homeserver + Element Web client # PostgreSQL 16 + Synapse homeserver + Element Web client
# ArgoCD managed - BlueJay Lab # ArgoCD managed - BlueJay Lab
# DB credentials sourced from 1Password via OnePasswordItem CRD (matrix-credentials)
# Synapse homeserver.yaml DB password injected at runtime via init container
--- ---
apiVersion: v1 apiVersion: v1
kind: Namespace kind: Namespace
@@ -9,26 +11,15 @@ metadata:
labels: labels:
app.kubernetes.io/part-of: bluejay-infra app.kubernetes.io/part-of: bluejay-infra
--- ---
apiVersion: v1 # Synapse homeserver.yaml template ConfigMap
kind: Secret # DB password placeholder __DB_PASSWORD__ is replaced at pod startup by init container
metadata:
name: matrix-db-secret
namespace: matrix
type: Opaque
stringData:
POSTGRES_USER: synapse
POSTGRES_PASSWORD: BlueJay-Matrix-DB-2026
POSTGRES_DB: synapse
POSTGRES_INITDB_ARGS: "--encoding=UTF-8 --lc-collate=C --lc-ctype=C"
---
# Synapse homeserver.yaml ConfigMap
apiVersion: v1 apiVersion: v1
kind: ConfigMap kind: ConfigMap
metadata: metadata:
name: synapse-config name: synapse-config
namespace: matrix namespace: matrix
data: data:
homeserver.yaml: | homeserver.yaml.template: |
server_name: "iamworkin.lan" server_name: "iamworkin.lan"
pid_file: /data/homeserver.pid pid_file: /data/homeserver.pid
public_baseurl: "https://matrix.iamworkin.lan/" public_baseurl: "https://matrix.iamworkin.lan/"
@@ -44,8 +35,8 @@ data:
database: database:
name: psycopg2 name: psycopg2
args: args:
user: synapse user: __DB_USER__
password: BlueJay-Matrix-DB-2026 password: __DB_PASSWORD__
database: synapse database: synapse
host: matrix-postgres host: matrix-postgres
port: 5432 port: 5432
@@ -80,6 +71,7 @@ data:
disable_existing_loggers: false disable_existing_loggers: false
--- ---
# PostgreSQL 16 StatefulSet # PostgreSQL 16 StatefulSet
# Credentials from 1Password-synced matrix-credentials secret
apiVersion: apps/v1 apiVersion: apps/v1
kind: StatefulSet kind: StatefulSet
metadata: metadata:
@@ -104,9 +96,21 @@ spec:
ports: ports:
- containerPort: 5432 - containerPort: 5432
name: postgres name: postgres
envFrom: env:
- secretRef: - name: POSTGRES_USER
name: matrix-db-secret valueFrom:
secretKeyRef:
name: matrix-credentials
key: DB-User
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: matrix-credentials
key: DB-Password
- name: POSTGRES_DB
value: synapse
- name: POSTGRES_INITDB_ARGS
value: "--encoding=UTF-8 --lc-collate=C --lc-ctype=C"
volumeMounts: volumeMounts:
- name: matrix-postgres-data - name: matrix-postgres-data
mountPath: /var/lib/postgresql/data mountPath: /var/lib/postgresql/data
@@ -163,7 +167,8 @@ spec:
requests: requests:
storage: 2Gi storage: 2Gi
--- ---
# Synapse init job: generate signing key if missing # Synapse Deployment
# Init container injects DB credentials from 1Password secret into homeserver.yaml
apiVersion: apps/v1 apiVersion: apps/v1
kind: Deployment kind: Deployment
metadata: metadata:
@@ -192,7 +197,13 @@ spec:
args: args:
- | - |
if [ \! -f /data/signing.key ]; then if [ \! -f /data/signing.key ]; then
python -m synapse.app.homeserver --generate-keys --config-path /config/homeserver.yaml python -m synapse.app.homeserver --generate-keys --config-path /config-template/homeserver.yaml.template 2>/dev/null || true
# If key generation fails with template, create a minimal config for key gen
if [ \! -f /data/signing.key ]; then
echo server_name: iamworkin.lan > /tmp/minimal.yaml
echo signing_key_path: /data/signing.key >> /tmp/minimal.yaml
python -c "from signedjson.key import generate_signing_key, write_signing_keys; import sys; key = generate_signing_key(a_auto); write_signing_keys(open(/data/signing.key,w), [key])" 2>/dev/null || true
fi
fi fi
chown 991:991 /data/signing.key 2>/dev/null || true chown 991:991 /data/signing.key 2>/dev/null || true
chmod 644 /data/signing.key 2>/dev/null || true chmod 644 /data/signing.key 2>/dev/null || true
@@ -201,7 +212,34 @@ spec:
volumeMounts: volumeMounts:
- name: synapse-data - name: synapse-data
mountPath: /data mountPath: /data
- name: synapse-config - name: synapse-config-template
mountPath: /config-template
- name: inject-credentials
image: busybox:latest
command: ["sh", "-c"]
args:
- |
# Copy template and substitute DB credentials from 1Password secret
cp /config-template/log.config /config/log.config
sed -e "s/__DB_PASSWORD__/${DB_PASSWORD}/g" \
-e "s/__DB_USER__/${DB_USER}/g" \
/config-template/homeserver.yaml.template > /config/homeserver.yaml
echo "Credentials injected into homeserver.yaml"
env:
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: matrix-credentials
key: DB-Password
- name: DB_USER
valueFrom:
secretKeyRef:
name: matrix-credentials
key: DB-User
volumeMounts:
- name: synapse-config-template
mountPath: /config-template
- name: synapse-config-rendered
mountPath: /config mountPath: /config
containers: containers:
- name: synapse - name: synapse
@@ -217,7 +255,7 @@ spec:
volumeMounts: volumeMounts:
- name: synapse-data - name: synapse-data
mountPath: /data mountPath: /data
- name: synapse-config - name: synapse-config-rendered
mountPath: /config mountPath: /config
resources: resources:
requests: requests:
@@ -242,9 +280,11 @@ spec:
- name: synapse-data - name: synapse-data
persistentVolumeClaim: persistentVolumeClaim:
claimName: synapse-data claimName: synapse-data
- name: synapse-config - name: synapse-config-template
configMap: configMap:
name: synapse-config name: synapse-config
- name: synapse-config-rendered
emptyDir: {}
--- ---
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
@@ -407,3 +447,13 @@ spec:
port: 80 port: 80
tls: tls:
secretName: element-tls secretName: element-tls
---
# 1Password secret sync — creates matrix-credentials K8s Secret
# Fields: DB-User, DB-Password, Registration-Secret, username, password, URL
apiVersion: onepassword.com/v1
kind: OnePasswordItem
metadata:
name: matrix-credentials
namespace: matrix
spec:
itemPath: vaults/IAmWorkin/items/Matrix Synapse

View File

@@ -1,320 +1,315 @@
# Zabbix 7.2 Monitoring Stack # Zabbix 7.2 Monitoring Stack
# PostgreSQL 16 + Zabbix Server + Zabbix Web (nginx) # PostgreSQL 16 + Zabbix Server + Zabbix Web (nginx)
# ArgoCD managed - BlueJay Lab # ArgoCD managed - BlueJay Lab
--- # Credentials sourced from 1Password via OnePasswordItem CRD (zabbix-credentials)
apiVersion: v1 ---
kind: Namespace apiVersion: v1
metadata: kind: Namespace
name: zabbix metadata:
labels: name: zabbix
app.kubernetes.io/part-of: bluejay-infra labels:
--- app.kubernetes.io/part-of: bluejay-infra
apiVersion: v1 ---
kind: Secret # PostgreSQL 16 StatefulSet
metadata: apiVersion: apps/v1
name: zabbix-db-secret kind: StatefulSet
namespace: zabbix metadata:
type: Opaque name: zabbix-postgres
stringData: namespace: zabbix
POSTGRES_USER: zabbix labels:
POSTGRES_PASSWORD: BlueJay-ZabbixDB-2026 app: zabbix-postgres
POSTGRES_DB: zabbix spec:
--- serviceName: zabbix-postgres
apiVersion: v1 replicas: 1
kind: Secret selector:
metadata: matchLabels:
name: zabbix-admin-secret app: zabbix-postgres
namespace: zabbix template:
type: Opaque metadata:
stringData: labels:
ZBX_ADMIN_PASSWORD: BlueJay-NOC-2026 app: zabbix-postgres
--- spec:
# PostgreSQL 16 StatefulSet containers:
apiVersion: apps/v1 - name: postgres
kind: StatefulSet image: postgres:16-alpine
metadata: ports:
name: zabbix-postgres - containerPort: 5432
namespace: zabbix name: postgres
labels: env:
app: zabbix-postgres - name: POSTGRES_USER
spec: valueFrom:
serviceName: zabbix-postgres secretKeyRef:
replicas: 1 name: zabbix-credentials
selector: key: DB-User
matchLabels: - name: POSTGRES_PASSWORD
app: zabbix-postgres valueFrom:
template: secretKeyRef:
metadata: name: zabbix-credentials
labels: key: DB-Password
app: zabbix-postgres - name: POSTGRES_DB
spec: value: zabbix
containers: volumeMounts:
- name: postgres - name: zabbix-postgres-data
image: postgres:16-alpine mountPath: /var/lib/postgresql/data
ports: subPath: pgdata
- containerPort: 5432 resources:
name: postgres requests:
envFrom: memory: 256Mi
- secretRef: cpu: 100m
name: zabbix-db-secret limits:
volumeMounts: memory: 512Mi
- name: zabbix-postgres-data cpu: 500m
mountPath: /var/lib/postgresql/data livenessProbe:
subPath: pgdata exec:
resources: command:
requests: - pg_isready
memory: 256Mi - -U
cpu: 100m - zabbix
limits: initialDelaySeconds: 30
memory: 512Mi periodSeconds: 10
cpu: 500m readinessProbe:
livenessProbe: exec:
exec: command:
command: - pg_isready
- pg_isready - -U
- -U - zabbix
- zabbix initialDelaySeconds: 5
initialDelaySeconds: 30 periodSeconds: 5
periodSeconds: 10 volumeClaimTemplates:
readinessProbe: - metadata:
exec: name: zabbix-postgres-data
command: spec:
- pg_isready accessModes: [ReadWriteOnce]
- -U resources:
- zabbix requests:
initialDelaySeconds: 5 storage: 10Gi
periodSeconds: 5 ---
volumeClaimTemplates: apiVersion: v1
- metadata: kind: Service
name: zabbix-postgres-data metadata:
spec: name: zabbix-postgres
accessModes: [ReadWriteOnce] namespace: zabbix
resources: spec:
requests: selector:
storage: 10Gi app: zabbix-postgres
--- ports:
apiVersion: v1 - port: 5432
kind: Service targetPort: 5432
metadata: name: postgres
name: zabbix-postgres clusterIP: None
namespace: zabbix ---
spec: # Zabbix Server
selector: apiVersion: apps/v1
app: zabbix-postgres kind: Deployment
ports: metadata:
- port: 5432 name: zabbix-server
targetPort: 5432 namespace: zabbix
name: postgres labels:
clusterIP: None app: zabbix-server
--- spec:
# Zabbix Server replicas: 1
apiVersion: apps/v1 selector:
kind: Deployment matchLabels:
metadata: app: zabbix-server
name: zabbix-server template:
namespace: zabbix metadata:
labels: labels:
app: zabbix-server app: zabbix-server
spec: spec:
replicas: 1 containers:
selector: - name: zabbix-server
matchLabels: image: zabbix/zabbix-server-pgsql:7.2-alpine-latest
app: zabbix-server ports:
template: - containerPort: 10051
metadata: name: trapper
labels: env:
app: zabbix-server - name: DB_SERVER_HOST
spec: value: zabbix-postgres
containers: - name: DB_SERVER_PORT
- name: zabbix-server value: "5432"
image: zabbix/zabbix-server-pgsql:7.2-alpine-latest - name: POSTGRES_USER
ports: valueFrom:
- containerPort: 10051 secretKeyRef:
name: trapper name: zabbix-credentials
env: key: DB-User
- name: DB_SERVER_HOST - name: POSTGRES_PASSWORD
value: zabbix-postgres valueFrom:
- name: DB_SERVER_PORT secretKeyRef:
value: "5432" name: zabbix-credentials
- name: POSTGRES_USER key: DB-Password
valueFrom: - name: POSTGRES_DB
secretKeyRef: value: zabbix
name: zabbix-db-secret resources:
key: POSTGRES_USER requests:
- name: POSTGRES_PASSWORD memory: 256Mi
valueFrom: cpu: 100m
secretKeyRef: limits:
name: zabbix-db-secret memory: 1Gi
key: POSTGRES_PASSWORD cpu: "1"
- name: POSTGRES_DB livenessProbe:
valueFrom: tcpSocket:
secretKeyRef: port: 10051
name: zabbix-db-secret initialDelaySeconds: 60
key: POSTGRES_DB periodSeconds: 10
resources: readinessProbe:
requests: tcpSocket:
memory: 256Mi port: 10051
cpu: 100m initialDelaySeconds: 30
limits: periodSeconds: 5
memory: 1Gi ---
cpu: "1" apiVersion: v1
livenessProbe: kind: Service
tcpSocket: metadata:
port: 10051 name: zabbix-server
initialDelaySeconds: 60 namespace: zabbix
periodSeconds: 10 spec:
readinessProbe: selector:
tcpSocket: app: zabbix-server
port: 10051 ports:
initialDelaySeconds: 30 - port: 10051
periodSeconds: 5 targetPort: 10051
--- name: trapper
apiVersion: v1 ---
kind: Service apiVersion: v1
metadata: kind: Service
name: zabbix-server metadata:
namespace: zabbix name: zabbix-trapper
spec: namespace: zabbix
selector: annotations:
app: zabbix-server metallb.universe.tf/loadBalancerIPs: 10.0.56.203
ports: spec:
- port: 10051 type: LoadBalancer
targetPort: 10051 selector:
name: trapper app: zabbix-server
--- ports:
apiVersion: v1 - port: 10051
kind: Service targetPort: 10051
metadata: name: trapper
name: zabbix-trapper protocol: TCP
namespace: zabbix ---
annotations: # Zabbix Web (nginx + PostgreSQL)
metallb.universe.tf/loadBalancerIPs: 10.0.56.203 apiVersion: apps/v1
spec: kind: Deployment
type: LoadBalancer metadata:
selector: name: zabbix-web
app: zabbix-server namespace: zabbix
ports: labels:
- port: 10051 app: zabbix-web
targetPort: 10051 spec:
name: trapper replicas: 1
protocol: TCP selector:
--- matchLabels:
# Zabbix Web (nginx + PostgreSQL) app: zabbix-web
apiVersion: apps/v1 template:
kind: Deployment metadata:
metadata: labels:
name: zabbix-web app: zabbix-web
namespace: zabbix spec:
labels: containers:
app: zabbix-web - name: zabbix-web
spec: image: zabbix/zabbix-web-nginx-pgsql:7.2-alpine-latest
replicas: 1 ports:
selector: - containerPort: 8080
matchLabels: name: http
app: zabbix-web env:
template: - name: ZBX_SERVER_HOST
metadata: value: zabbix-server
labels: - name: ZBX_SERVER_NAME
app: zabbix-web value: "BlueJay NOC"
spec: - name: PHP_TZ
containers: value: America/Chicago
- name: zabbix-web - name: DB_SERVER_HOST
image: zabbix/zabbix-web-nginx-pgsql:7.2-alpine-latest value: zabbix-postgres
ports: - name: DB_SERVER_PORT
- containerPort: 8080 value: "5432"
name: http - name: POSTGRES_USER
env: valueFrom:
- name: ZBX_SERVER_HOST secretKeyRef:
value: zabbix-server name: zabbix-credentials
- name: ZBX_SERVER_NAME key: DB-User
value: "BlueJay NOC" - name: POSTGRES_PASSWORD
- name: PHP_TZ valueFrom:
value: America/Chicago secretKeyRef:
- name: DB_SERVER_HOST name: zabbix-credentials
value: zabbix-postgres key: DB-Password
- name: DB_SERVER_PORT - name: POSTGRES_DB
value: "5432" value: zabbix
- name: POSTGRES_USER - name: ZBX_ADMIN_PASSWORD
valueFrom: valueFrom:
secretKeyRef: secretKeyRef:
name: zabbix-db-secret name: zabbix-credentials
key: POSTGRES_USER key: password
- name: POSTGRES_PASSWORD resources:
valueFrom: requests:
secretKeyRef: memory: 128Mi
name: zabbix-db-secret cpu: 50m
key: POSTGRES_PASSWORD limits:
- name: POSTGRES_DB memory: 512Mi
valueFrom: cpu: 500m
secretKeyRef: livenessProbe:
name: zabbix-db-secret httpGet:
key: POSTGRES_DB path: /
- name: ZBX_ADMIN_PASSWORD port: 8080
valueFrom: initialDelaySeconds: 60
secretKeyRef: periodSeconds: 10
name: zabbix-admin-secret readinessProbe:
key: ZBX_ADMIN_PASSWORD httpGet:
resources: path: /
requests: port: 8080
memory: 128Mi initialDelaySeconds: 30
cpu: 50m periodSeconds: 5
limits: ---
memory: 512Mi apiVersion: v1
cpu: 500m kind: Service
livenessProbe: metadata:
httpGet: name: zabbix-web
path: / namespace: zabbix
port: 8080 spec:
initialDelaySeconds: 60 selector:
periodSeconds: 10 app: zabbix-web
readinessProbe: ports:
httpGet: - port: 8080
path: / targetPort: 8080
port: 8080 name: http
initialDelaySeconds: 30 ---
periodSeconds: 5 # TLS Certificate via cert-manager
--- apiVersion: cert-manager.io/v1
apiVersion: v1 kind: Certificate
kind: Service metadata:
metadata: name: zabbix-tls
name: zabbix-web namespace: zabbix
namespace: zabbix spec:
spec: secretName: zabbix-tls
selector: issuerRef:
app: zabbix-web name: step-ca-acme
ports: kind: ClusterIssuer
- port: 8080 dnsNames:
targetPort: 8080 - zabbix.iamworkin.lan
name: http ---
--- # Traefik IngressRoute
# TLS Certificate via cert-manager apiVersion: traefik.io/v1alpha1
apiVersion: cert-manager.io/v1 kind: IngressRoute
kind: Certificate metadata:
metadata: name: zabbix-web
name: zabbix-tls namespace: zabbix
namespace: zabbix spec:
spec: entryPoints:
secretName: zabbix-tls - websecure
issuerRef: routes:
name: step-ca-acme - match: Host(`zabbix.iamworkin.lan`)
kind: ClusterIssuer kind: Rule
dnsNames: services:
- zabbix.iamworkin.lan - name: zabbix-web
--- port: 8080
# Traefik IngressRoute tls:
apiVersion: traefik.io/v1alpha1 secretName: zabbix-tls
kind: IngressRoute ---
metadata: # 1Password secret sync — creates zabbix-credentials K8s Secret
name: zabbix-web # Fields: DB-User, DB-Password, username, password, URL
namespace: zabbix apiVersion: onepassword.com/v1
spec: kind: OnePasswordItem
entryPoints: metadata:
- websecure name: zabbix-credentials
routes: namespace: zabbix
- match: Host(`zabbix.iamworkin.lan`) spec:
kind: Rule itemPath: vaults/IAmWorkin/items/Zabbix Admin
services:
- name: zabbix-web
port: 8080
tls:
secretName: zabbix-tls