Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ffcf646d87 | |||
| a29fa5b8cc |
@@ -1,29 +0,0 @@
|
||||
when:
|
||||
- event: pull_request
|
||||
|
||||
steps:
|
||||
- name: vector-test
|
||||
image: artifactapi.k8s.syd1.au.unkin.net/dockerhub/timberio/vector:0.57.0-debian
|
||||
commands:
|
||||
# Dummy creds + writable dirs so the full topologies build; the unit tests
|
||||
# only exercise the transforms (sources are not started).
|
||||
- export CLICKHOUSE_USER=ci CLICKHOUSE_PASSWORD=ci
|
||||
- export NATS_PRODUCER_PASSWORD=ci NATS_CONSUMER_PASSWORD=ci
|
||||
- mkdir -p /vector-data-dir /etc/vault-ca
|
||||
- cp /etc/ssl/certs/ca-certificates.crt /etc/vault-ca/ca.crt
|
||||
# Transform tier + VM ingest: unit-tested transforms.
|
||||
- vector test apps/base/logging/vector/aggregator.yaml apps/base/logging/vector/aggregator-tests.yaml
|
||||
- vector test apps/base/logging/vector/vm-ingest.yaml apps/base/logging/vector/vm-ingest-tests.yaml
|
||||
# Agent has no transforms to unit-test; validate it builds. (The archiver
|
||||
# leg is now the logarchiver service, not a Vector pipeline.)
|
||||
- vector validate --no-environment apps/base/logging/vector/agent.yaml
|
||||
backend_options:
|
||||
kubernetes:
|
||||
serviceAccountName: default
|
||||
resources:
|
||||
requests:
|
||||
memory: 256Mi
|
||||
cpu: 250m
|
||||
limits:
|
||||
memory: 1Gi
|
||||
cpu: 1
|
||||
@@ -12,13 +12,13 @@ spec:
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
configmap.reloader.stakater.com/auto: "true"
|
||||
reloader.stakater.com/auto: "true"
|
||||
labels:
|
||||
app: age-api
|
||||
spec:
|
||||
containers:
|
||||
- name: age-api
|
||||
image: artifactapi.k8s.syd1.au.unkin.net/docker-internal/age-api:v0.1.0
|
||||
image: git.unkin.net/unkin/age-api:v0.1.0
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
|
||||
@@ -8,7 +8,6 @@ resources:
|
||||
- httproute.yaml
|
||||
- namespace.yaml
|
||||
- service.yaml
|
||||
- vpa.yaml
|
||||
|
||||
configMapGenerator:
|
||||
- name: age-api-config
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
---
|
||||
apiVersion: autoscaling.k8s.io/v1
|
||||
kind: VerticalPodAutoscaler
|
||||
metadata:
|
||||
name: age-api-vpa
|
||||
namespace: age-api
|
||||
spec:
|
||||
targetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: age-api
|
||||
updatePolicy:
|
||||
updateMode: "Off"
|
||||
@@ -5,8 +5,7 @@ metadata:
|
||||
name: api
|
||||
namespace: artifactapi
|
||||
annotations:
|
||||
configmap.reloader.stakater.com/auto: "true"
|
||||
secret.reloader.stakater.com/reload: "vault-ca-cert"
|
||||
reloader.stakater.com/auto: "true"
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
@@ -36,7 +35,7 @@ spec:
|
||||
mountPath: /combined-certs
|
||||
containers:
|
||||
- name: api
|
||||
image: git.unkin.net/unkin/artifactapi:v3.7.7
|
||||
image: git.unkin.net/unkin/artifactapi:v3.7.6
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- containerPort: 8000
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
---
|
||||
# Ceph RGW (S3) backup target for the artifactapi CNPG cluster, provisioned by the
|
||||
# in-estate cephrgw-operator. One dedicated bucket + owner user per cluster:
|
||||
# cephrgw CRs are namespace-scoped and CNPG reads its S3 credential Secret from
|
||||
# its own namespace, so backups are per-database rather than one shared bucket.
|
||||
apiVersion: ceph.unkin.net/v1alpha1
|
||||
kind: ObjectStoreUser
|
||||
metadata:
|
||||
name: cnpg-artifactapi-backup
|
||||
namespace: artifactapi
|
||||
spec:
|
||||
displayName: "CNPG backup owner (artifactapi)"
|
||||
# RGW users are global; keep the uid namespace-qualified so it never collides.
|
||||
uid: cnpg-artifactapi-backup
|
||||
maxBuckets: 5
|
||||
# Operator writes AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY (+ RGW_UID,
|
||||
# S3_ENDPOINT) into this Secret; the Cluster's barmanObjectStore consumes it.
|
||||
secretName: cnpg-artifactapi-backup-s3
|
||||
# Keep the RGW user (and thus the keys) if this CR is ever deleted, so an
|
||||
# in-flight restore can still reach the archive.
|
||||
retainOnDelete: true
|
||||
---
|
||||
apiVersion: ceph.unkin.net/v1alpha1
|
||||
kind: Bucket
|
||||
metadata:
|
||||
name: cnpg-artifactapi
|
||||
namespace: artifactapi
|
||||
spec:
|
||||
placementTarget: ec
|
||||
bucketName: cnpg-artifactapi
|
||||
# The owner user has full control of its own bucket (read + write), which is
|
||||
# all the backup/restore identity needs — no extra BucketAccess grant.
|
||||
ownerRef: cnpg-artifactapi-backup
|
||||
versioning: false
|
||||
tags:
|
||||
app: artifactapi
|
||||
purpose: cnpg-backup
|
||||
# Never drop the backups if the CR is removed; retire buckets by hand.
|
||||
retainOnDelete: true
|
||||
---
|
||||
# Nightly base backup. Continuous WAL archiving is always-on via the Cluster's
|
||||
# spec.backup.barmanObjectStore; this schedules the periodic full backup that
|
||||
# WAL is layered on top of. Schedules are staggered across clusters so the 8
|
||||
# base backups do not hit RGW at once (CNPG cron is 6-field, seconds first).
|
||||
apiVersion: postgresql.cnpg.io/v1
|
||||
kind: ScheduledBackup
|
||||
metadata:
|
||||
name: cnpg-artifactapi-nightly
|
||||
namespace: artifactapi
|
||||
spec:
|
||||
schedule: "0 40 1 * * *"
|
||||
immediate: false
|
||||
backupOwnerReference: self
|
||||
method: barmanObjectStore
|
||||
cluster:
|
||||
name: postgres
|
||||
@@ -7,35 +7,6 @@ metadata:
|
||||
spec:
|
||||
affinity:
|
||||
podAntiAffinityType: preferred
|
||||
backup:
|
||||
# 30-day retention (DEFAULT — adjust per cluster if needed). Enforced by CNPG
|
||||
# against the object store on each successful base backup.
|
||||
retentionPolicy: 30d
|
||||
barmanObjectStore:
|
||||
# Dedicated per-cluster Ceph RGW bucket (cephrgw-operator provisions it).
|
||||
destinationPath: s3://cnpg-artifactapi
|
||||
endpointURL: https://s3.ceph.unkin.net
|
||||
# radosgw serves a Vault-PKI cert; trust the internal CA (reflected into
|
||||
# every namespace as the vault-ca-cert Secret).
|
||||
endpointCA:
|
||||
name: vault-ca-cert
|
||||
key: ca.crt
|
||||
# Keys minted by the ObjectStoreUser in cnpg_backup.yaml; never hardcoded.
|
||||
s3Credentials:
|
||||
accessKeyId:
|
||||
name: cnpg-artifactapi-backup-s3
|
||||
key: AWS_ACCESS_KEY_ID
|
||||
secretAccessKey:
|
||||
name: cnpg-artifactapi-backup-s3
|
||||
key: AWS_SECRET_ACCESS_KEY
|
||||
# Path prefix within the bucket; keep stable across restores (see docs).
|
||||
serverName: artifactapi
|
||||
data:
|
||||
compression: bzip2
|
||||
jobs: 2
|
||||
wal:
|
||||
compression: zstd
|
||||
maxParallel: 2
|
||||
bootstrap:
|
||||
initdb:
|
||||
database: artifacts
|
||||
@@ -108,7 +79,7 @@ spec:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
requests:
|
||||
cpu: 50m
|
||||
cpu: 250m
|
||||
memory: 256Mi
|
||||
smartShutdownTimeout: 180
|
||||
startDelay: 3600
|
||||
|
||||
@@ -1,6 +1,30 @@
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: http-redirect
|
||||
namespace: artifactapi
|
||||
spec:
|
||||
hostnames:
|
||||
- artifactapi.k8s.syd1.au.unkin.net
|
||||
parentRefs:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: Gateway
|
||||
name: artifactapi
|
||||
sectionName: http
|
||||
rules:
|
||||
- filters:
|
||||
- type: RequestRedirect
|
||||
requestRedirect:
|
||||
scheme: https
|
||||
statusCode: 301
|
||||
matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: api-route
|
||||
namespace: artifactapi
|
||||
@@ -8,12 +32,6 @@ spec:
|
||||
hostnames:
|
||||
- artifactapi.k8s.syd1.au.unkin.net
|
||||
parentRefs:
|
||||
# Early-boot clients (anaconda/kickstart, yum in %post, PXE) need plain HTTP
|
||||
# for the rpm repos; serve the app directly on port 80 instead of redirecting.
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: Gateway
|
||||
name: artifactapi
|
||||
sectionName: http
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: Gateway
|
||||
name: artifactapi
|
||||
|
||||
@@ -7,7 +7,6 @@ resources:
|
||||
- api-hpa.yaml
|
||||
- configmap.yaml
|
||||
- cnpg_cluster.yaml
|
||||
- cnpg_backup.yaml
|
||||
- cnpg_pooler.yaml
|
||||
- gateway.yaml
|
||||
- httproute.yaml
|
||||
@@ -18,4 +17,3 @@ resources:
|
||||
- ui-hpa.yaml
|
||||
- vaultauth.yaml
|
||||
- vaultstaticsecret.yaml
|
||||
- vpa.yaml
|
||||
|
||||
@@ -5,7 +5,7 @@ metadata:
|
||||
name: ui
|
||||
namespace: artifactapi
|
||||
annotations:
|
||||
configmap.reloader.stakater.com/auto: "true"
|
||||
reloader.stakater.com/auto: "true"
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
@@ -22,7 +22,7 @@ spec:
|
||||
automountServiceAccountToken: true
|
||||
containers:
|
||||
- name: ui
|
||||
image: git.unkin.net/unkin/artifactapi-ui:v3.7.7
|
||||
image: git.unkin.net/unkin/artifactapi-ui:v3.7.6
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- containerPort: 80
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
---
|
||||
apiVersion: autoscaling.k8s.io/v1
|
||||
kind: VerticalPodAutoscaler
|
||||
metadata:
|
||||
name: api-vpa
|
||||
namespace: artifactapi
|
||||
# NOTE: this workload also has an HPA. updateMode Off is recommendation-only
|
||||
# and does not act, so there is no HPA/VPA conflict today. Do not flip to Auto/
|
||||
# Initial without first moving the HPA off CPU/memory (VPA owns those under Auto).
|
||||
spec:
|
||||
targetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: api
|
||||
updatePolicy:
|
||||
updateMode: "Off"
|
||||
---
|
||||
apiVersion: autoscaling.k8s.io/v1
|
||||
kind: VerticalPodAutoscaler
|
||||
metadata:
|
||||
name: redis-vpa
|
||||
namespace: artifactapi
|
||||
spec:
|
||||
targetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: redis
|
||||
updatePolicy:
|
||||
updateMode: "Off"
|
||||
---
|
||||
apiVersion: autoscaling.k8s.io/v1
|
||||
kind: VerticalPodAutoscaler
|
||||
metadata:
|
||||
name: ui-vpa
|
||||
namespace: artifactapi
|
||||
# NOTE: this workload also has an HPA. updateMode Off is recommendation-only
|
||||
# and does not act, so there is no HPA/VPA conflict today. Do not flip to Auto/
|
||||
# Initial without first moving the HPA off CPU/memory (VPA owns those under Auto).
|
||||
spec:
|
||||
targetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: ui
|
||||
updatePolicy:
|
||||
updateMode: "Off"
|
||||
@@ -1,56 +0,0 @@
|
||||
---
|
||||
# Ceph RGW (S3) backup target for the authentik CNPG cluster, provisioned by the
|
||||
# in-estate cephrgw-operator. One dedicated bucket + owner user per cluster:
|
||||
# cephrgw CRs are namespace-scoped and CNPG reads its S3 credential Secret from
|
||||
# its own namespace, so backups are per-database rather than one shared bucket.
|
||||
apiVersion: ceph.unkin.net/v1alpha1
|
||||
kind: ObjectStoreUser
|
||||
metadata:
|
||||
name: cnpg-authentik-backup
|
||||
namespace: authentik
|
||||
spec:
|
||||
displayName: "CNPG backup owner (authentik)"
|
||||
# RGW users are global; keep the uid namespace-qualified so it never collides.
|
||||
uid: cnpg-authentik-backup
|
||||
maxBuckets: 5
|
||||
# Operator writes AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY (+ RGW_UID,
|
||||
# S3_ENDPOINT) into this Secret; the Cluster's barmanObjectStore consumes it.
|
||||
secretName: cnpg-authentik-backup-s3
|
||||
# Keep the RGW user (and thus the keys) if this CR is ever deleted, so an
|
||||
# in-flight restore can still reach the archive.
|
||||
retainOnDelete: true
|
||||
---
|
||||
apiVersion: ceph.unkin.net/v1alpha1
|
||||
kind: Bucket
|
||||
metadata:
|
||||
name: cnpg-authentik
|
||||
namespace: authentik
|
||||
spec:
|
||||
placementTarget: ec
|
||||
bucketName: cnpg-authentik
|
||||
# The owner user has full control of its own bucket (read + write), which is
|
||||
# all the backup/restore identity needs — no extra BucketAccess grant.
|
||||
ownerRef: cnpg-authentik-backup
|
||||
versioning: false
|
||||
tags:
|
||||
app: authentik
|
||||
purpose: cnpg-backup
|
||||
# Never drop the backups if the CR is removed; retire buckets by hand.
|
||||
retainOnDelete: true
|
||||
---
|
||||
# Nightly base backup. Continuous WAL archiving is always-on via the Cluster's
|
||||
# spec.backup.barmanObjectStore; this schedules the periodic full backup that
|
||||
# WAL is layered on top of. Schedules are staggered across clusters so the 8
|
||||
# base backups do not hit RGW at once (CNPG cron is 6-field, seconds first).
|
||||
apiVersion: postgresql.cnpg.io/v1
|
||||
kind: ScheduledBackup
|
||||
metadata:
|
||||
name: cnpg-authentik-nightly
|
||||
namespace: authentik
|
||||
spec:
|
||||
schedule: "0 0 1 * * *"
|
||||
immediate: false
|
||||
backupOwnerReference: self
|
||||
method: barmanObjectStore
|
||||
cluster:
|
||||
name: postgres
|
||||
@@ -7,35 +7,6 @@ metadata:
|
||||
spec:
|
||||
affinity:
|
||||
podAntiAffinityType: preferred
|
||||
backup:
|
||||
# 30-day retention (DEFAULT — adjust per cluster if needed). Enforced by CNPG
|
||||
# against the object store on each successful base backup.
|
||||
retentionPolicy: 30d
|
||||
barmanObjectStore:
|
||||
# Dedicated per-cluster Ceph RGW bucket (cephrgw-operator provisions it).
|
||||
destinationPath: s3://cnpg-authentik
|
||||
endpointURL: https://s3.ceph.unkin.net
|
||||
# radosgw serves a Vault-PKI cert; trust the internal CA (reflected into
|
||||
# every namespace as the vault-ca-cert Secret).
|
||||
endpointCA:
|
||||
name: vault-ca-cert
|
||||
key: ca.crt
|
||||
# Keys minted by the ObjectStoreUser in cnpg_backup.yaml; never hardcoded.
|
||||
s3Credentials:
|
||||
accessKeyId:
|
||||
name: cnpg-authentik-backup-s3
|
||||
key: AWS_ACCESS_KEY_ID
|
||||
secretAccessKey:
|
||||
name: cnpg-authentik-backup-s3
|
||||
key: AWS_SECRET_ACCESS_KEY
|
||||
# Path prefix within the bucket; keep stable across restores (see docs).
|
||||
serverName: authentik
|
||||
data:
|
||||
compression: bzip2
|
||||
jobs: 2
|
||||
wal:
|
||||
compression: zstd
|
||||
maxParallel: 2
|
||||
bootstrap:
|
||||
initdb:
|
||||
database: authentik
|
||||
@@ -106,12 +77,10 @@ spec:
|
||||
resources:
|
||||
limits:
|
||||
cpu: 500m
|
||||
# 512Mi OOMKilled replicas under load (shared_buffers 128MB +
|
||||
# max_connections 200 leave no headroom) — see incident 2026-07-28.
|
||||
memory: 1Gi
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 512Mi
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 256Mi
|
||||
smartShutdownTimeout: 180
|
||||
startDelay: 3600
|
||||
stopDelay: 1800
|
||||
|
||||
@@ -4,7 +4,6 @@ kind: Kustomization
|
||||
|
||||
resources:
|
||||
- cnpg_cluster.yaml
|
||||
- cnpg_backup.yaml
|
||||
- cnpg_pooler.yaml
|
||||
- gateway.yaml
|
||||
- httproute.yaml
|
||||
@@ -18,4 +17,3 @@ resources:
|
||||
- redis-service.yaml
|
||||
- vaultauth.yaml
|
||||
- vaultstaticsecret.yaml
|
||||
- vpa.yaml
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
---
|
||||
apiVersion: autoscaling.k8s.io/v1
|
||||
kind: VerticalPodAutoscaler
|
||||
metadata:
|
||||
name: redis-vpa
|
||||
namespace: authentik
|
||||
spec:
|
||||
targetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: redis
|
||||
updatePolicy:
|
||||
updateMode: "Off"
|
||||
@@ -1,16 +0,0 @@
|
||||
---
|
||||
# Confines the agent-dns service account (in bind-system) to the agent-dns
|
||||
# ClusterRole within this namespace.
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: agent-dns
|
||||
namespace: bind-external
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: agent-dns
|
||||
namespace: bind-system
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: agent-dns
|
||||
@@ -1,52 +0,0 @@
|
||||
---
|
||||
# Externally-reachable authoritative BIND for zones we delegate to ourselves.
|
||||
# First tenant: acme.unkin.net, the DNS-01 challenge zone Let's Encrypt validates
|
||||
# via a one-time _acme-challenge.unkin.net CNAME. Authoritative-only, recursion
|
||||
# off, no forwarding, no open transfers -- the primaryService is the single
|
||||
# dmz-pinned LoadBalancer that public NAT targets and that cert-manager writes to.
|
||||
apiVersion: bind.unkin.net/v1alpha1
|
||||
kind: BindCluster
|
||||
metadata:
|
||||
name: bind-external
|
||||
namespace: bind-external
|
||||
spec:
|
||||
mode: authoritative
|
||||
recursion: false
|
||||
replicas: 2
|
||||
storageClassName: cephrbd-fast-delete
|
||||
storageSize: 1Gi
|
||||
# Public server: answer queries from anywhere (Let's Encrypt validates over the
|
||||
# internet), deny recursion and open zone transfers. localhost + pod net are
|
||||
# implied by "any" and cover in-pod nsupdate and secondary SOA refresh; per-zone
|
||||
# allow-transfer (catalog + acme zone) still permits key-authenticated AXFR.
|
||||
extraOptions:
|
||||
- "allow-query { any; }"
|
||||
- "allow-transfer { none; }"
|
||||
service:
|
||||
type: ClusterIP
|
||||
primaryService:
|
||||
type: LoadBalancer
|
||||
externalTrafficPolicy: Local
|
||||
annotations:
|
||||
purelb.io/service-group: dmz
|
||||
purelb.io/addresses: 198.18.199.53
|
||||
external-dns.alpha.kubernetes.io/hostname: bind-external-primary.k8s.syd1.au.unkin.net
|
||||
resources:
|
||||
requests:
|
||||
cpu: 20m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: "1"
|
||||
memory: 512Mi
|
||||
---
|
||||
# Catalog zone so the acme zone replicates onto the secondary (AXFR/IXFR keyed
|
||||
# with the certmanager TSIG key, reused here as the transfer key).
|
||||
apiVersion: bind.unkin.net/v1alpha1
|
||||
kind: BindCatalogZone
|
||||
metadata:
|
||||
name: bind-external-catalog
|
||||
namespace: bind-external
|
||||
spec:
|
||||
clusterRef: bind-external
|
||||
zoneName: catalog.external
|
||||
transferKeyRef: certmanager
|
||||
@@ -1,10 +0,0 @@
|
||||
---
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
|
||||
resources:
|
||||
- namespace.yaml
|
||||
- cluster.yaml
|
||||
- tsigkey.yaml
|
||||
- zones.yaml
|
||||
- agent-dns-rolebinding.yaml
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: bind-external
|
||||
@@ -1,20 +0,0 @@
|
||||
---
|
||||
# TSIG key cert-manager uses to send RFC2136 dynamic updates (the DNS-01 TXT
|
||||
# records) to the primary, and that the secondary reuses for AXFR. The operator
|
||||
# generates the material into Secret certmanager-tsig in this namespace;
|
||||
# secretTemplate stamps emberstack reflector hints so the Secret is mirrored into
|
||||
# the cert-manager namespace, where the rfc2136 solver reads its "secret" key.
|
||||
apiVersion: bind.unkin.net/v1alpha1
|
||||
kind: BindTSIGKey
|
||||
metadata:
|
||||
name: certmanager
|
||||
namespace: bind-external
|
||||
spec:
|
||||
clusterRef: bind-external
|
||||
algorithm: hmac-sha256
|
||||
secretTemplate:
|
||||
annotations:
|
||||
reflector.v1.k8s.emberstack.com/reflection-allowed: "true"
|
||||
reflector.v1.k8s.emberstack.com/reflection-allowed-namespaces: "cert-manager"
|
||||
reflector.v1.k8s.emberstack.com/reflection-auto-enabled: "true"
|
||||
reflector.v1.k8s.emberstack.com/reflection-auto-namespaces: "cert-manager"
|
||||
@@ -1,19 +0,0 @@
|
||||
---
|
||||
# Self-delegated ACME challenge zone. Google Cloud DNS holds a one-time
|
||||
# _acme-challenge.unkin.net CNAME -> _acme-challenge.acme.unkin.net and an
|
||||
# acme.unkin.net NS delegation pointing here; cert-manager writes the challenge
|
||||
# TXT records via RFC2136 authenticated with the certmanager key.
|
||||
apiVersion: bind.unkin.net/v1alpha1
|
||||
kind: BindZone
|
||||
metadata:
|
||||
name: acme-unkin-net
|
||||
namespace: bind-external
|
||||
spec:
|
||||
clusterRef: bind-external
|
||||
zoneName: acme.unkin.net
|
||||
type: primary
|
||||
defaultTTL: 60
|
||||
dynamicUpdate: true
|
||||
updateKeyRef: certmanager
|
||||
allowTransfer:
|
||||
- key certmanager
|
||||
@@ -1,16 +0,0 @@
|
||||
---
|
||||
# Confines the agent-dns service account (in bind-system) to the agent-dns
|
||||
# ClusterRole within this namespace.
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: agent-dns
|
||||
namespace: bind-internal
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: agent-dns
|
||||
namespace: bind-system
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: agent-dns
|
||||
@@ -24,6 +24,3 @@ spec:
|
||||
- 198.18.27.0/24
|
||||
- 198.18.28.0/24
|
||||
- 198.18.29.0/24
|
||||
# Admin/management access (individual hosts, not whole subnets)
|
||||
- 10.10.12.200/32 # benvin workstation (wireguard)
|
||||
- 198.18.21.160/32 # benvin router
|
||||
|
||||
@@ -13,14 +13,9 @@ spec:
|
||||
storageSize: 2Gi
|
||||
# Restrict queries to internal networks (puppet acl-main.unkin.net).
|
||||
# 10.42.0.0/16 (pod net) is required so secondaries can SOA-refresh
|
||||
# from the primary during catalog replication. localhost is required so the
|
||||
# operator's in-pod `nsupdate` (sent to 127.0.0.1) passes query-authorization;
|
||||
# without it every dynamic update is "denied due to allow-query".
|
||||
# from the primary during catalog replication.
|
||||
extraOptions:
|
||||
- "allow-query { localhost; auth-acl-main; 10.42.0.0/16; }"
|
||||
# Enable query logging for the Tier-2 vector bind_query pipeline (see the
|
||||
# resolvers cluster for the routing rationale).
|
||||
- "querylog yes"
|
||||
- "allow-query { auth-acl-main; 10.42.0.0/16; }"
|
||||
service:
|
||||
type: LoadBalancer
|
||||
externalTrafficPolicy: Local
|
||||
@@ -36,7 +31,7 @@ spec:
|
||||
external-dns.alpha.kubernetes.io/hostname: bind-authoritative-primary.k8s.syd1.au.unkin.net
|
||||
resources:
|
||||
requests:
|
||||
cpu: 20m
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: "1"
|
||||
|
||||
@@ -6,5 +6,4 @@ resources:
|
||||
- cluster.yaml
|
||||
- tsigkey.yaml
|
||||
- zones.yaml
|
||||
- records.yaml
|
||||
- acls.yaml
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
# Individually-managed authoritative records for the unkin.net zone.
|
||||
# DNSRecords must live in the same namespace as their BindZone (the operator
|
||||
# resolves zoneRef/clusterRef/updateKeyRef within the record's namespace), so
|
||||
# these sit alongside the zone in bind-internal, not in the app namespace.
|
||||
---
|
||||
apiVersion: bind.unkin.net/v1alpha1
|
||||
kind: DNSRecord
|
||||
metadata:
|
||||
# "internal" in the name distinguishes this from the external DNS that
|
||||
# Authentik will manage its own records from later.
|
||||
name: identity-dns-internal
|
||||
namespace: bind-internal
|
||||
spec:
|
||||
zoneRef: unkin-net
|
||||
name: identity
|
||||
type: A
|
||||
ttl: 600
|
||||
values:
|
||||
# traefik-internal gateway VIP; the authentik Gateway serves the
|
||||
# identity.unkin.net hostname there.
|
||||
- 198.18.200.4
|
||||
---
|
||||
# PRODUCTION CUTOVER RECORD — intentionally commented out.
|
||||
# git.unkin.net currently resolves to the LIVE VM forge (HAProxy VRRP VIP
|
||||
# 198.18.19.17), which holds every repo the estate depends on. Uncommenting this
|
||||
# repoints the whole org's git.unkin.net at the new k8s Gitea gateway VIP, so it
|
||||
# is the FINAL step of the forge migration — gated on the data migration (gitea
|
||||
# dump/restore + SECRET_KEY copy) in argocd-apps docs/gitea-migration.md.
|
||||
# NOTE: the live git.unkin.net answer is served by the puppet DNS master today
|
||||
# (profiles::dns::master, records from PuppetDB); this k8s apex zone holds only
|
||||
# SOA+NS + a few DNSRecords so far. Confirm the k8s bind cluster is the live
|
||||
# authority for unkin.net (or update the puppet record instead) before relying
|
||||
# on this CR at cutover.
|
||||
# ---
|
||||
# apiVersion: bind.unkin.net/v1alpha1
|
||||
# kind: DNSRecord
|
||||
# metadata:
|
||||
# name: git-dns-internal
|
||||
# namespace: bind-internal
|
||||
# spec:
|
||||
# zoneRef: unkin-net
|
||||
# name: git
|
||||
# type: A
|
||||
# ttl: 600
|
||||
# values:
|
||||
# # traefik-internal gateway VIP; the gitea Gateway serves git.unkin.net there.
|
||||
# - 198.18.200.4
|
||||
---
|
||||
apiVersion: bind.unkin.net/v1alpha1
|
||||
kind: DNSRecord
|
||||
metadata:
|
||||
name: s3-ceph-cname
|
||||
namespace: bind-internal
|
||||
spec:
|
||||
zoneRef: ceph-unkin-net
|
||||
name: s3
|
||||
type: CNAME
|
||||
ttl: 600
|
||||
values:
|
||||
# radosgw S3 endpoint. Points at the Consul service for now; the real
|
||||
# target will be changed later.
|
||||
- radosgw.service.consul.
|
||||
---
|
||||
apiVersion: bind.unkin.net/v1alpha1
|
||||
kind: DNSRecord
|
||||
metadata:
|
||||
name: dashboard-ceph-cname
|
||||
namespace: bind-internal
|
||||
spec:
|
||||
zoneRef: ceph-unkin-net
|
||||
name: dashboard
|
||||
type: CNAME
|
||||
ttl: 600
|
||||
values:
|
||||
# Ceph mgr dashboard, reached via lb1. Lets in-cluster clients (the
|
||||
# cephrgw-operator) resolve dashboard.ceph.unkin.net.
|
||||
- lb1.unkin.net.
|
||||
---
|
||||
apiVersion: bind.unkin.net/v1alpha1
|
||||
kind: DNSRecord
|
||||
metadata:
|
||||
name: lb1-unkin-net
|
||||
namespace: bind-internal
|
||||
spec:
|
||||
zoneRef: unkin-net
|
||||
name: lb1
|
||||
type: A
|
||||
ttl: 600
|
||||
values:
|
||||
- 103.216.191.185
|
||||
@@ -9,16 +9,3 @@ metadata:
|
||||
spec:
|
||||
clusterRef: bind-authoritative
|
||||
algorithm: hmac-sha256
|
||||
---
|
||||
# Client-update key: puppet clients (profiles::dns::updater) nsupdate their own
|
||||
# records to the authoritative zones with this key. Operator generates the
|
||||
# material into Secret client-update-tsig; the same value must reach puppet
|
||||
# eyaml (or the planned Vault-sync bridge) for clients to authenticate.
|
||||
apiVersion: bind.unkin.net/v1alpha1
|
||||
kind: BindTSIGKey
|
||||
metadata:
|
||||
name: client-update
|
||||
namespace: bind-internal
|
||||
spec:
|
||||
clusterRef: bind-authoritative
|
||||
algorithm: hmac-sha256
|
||||
|
||||
@@ -15,8 +15,6 @@ spec:
|
||||
zoneName: unkin.net
|
||||
type: primary
|
||||
defaultTTL: 600
|
||||
dynamicUpdate: true
|
||||
updateKeyRef: client-update
|
||||
---
|
||||
apiVersion: bind.unkin.net/v1alpha1
|
||||
kind: BindZone
|
||||
@@ -28,24 +26,6 @@ spec:
|
||||
zoneName: main.unkin.net
|
||||
type: primary
|
||||
defaultTTL: 600
|
||||
dynamicUpdate: true
|
||||
updateKeyRef: client-update
|
||||
---
|
||||
# ceph.unkin.net: the ceph host (ausyd1nxvm2069/halb) publishes
|
||||
# dashboard.ceph.unkin.net via nsupdate; puppet targets a dedicated
|
||||
# `zone ceph.unkin.net.`, so it must exist here or the update gets NOTZONE.
|
||||
apiVersion: bind.unkin.net/v1alpha1
|
||||
kind: BindZone
|
||||
metadata:
|
||||
name: ceph-unkin-net
|
||||
namespace: bind-internal
|
||||
spec:
|
||||
clusterRef: bind-authoritative
|
||||
zoneName: ceph.unkin.net
|
||||
type: primary
|
||||
defaultTTL: 600
|
||||
dynamicUpdate: true
|
||||
updateKeyRef: client-update
|
||||
---
|
||||
apiVersion: bind.unkin.net/v1alpha1
|
||||
kind: BindZone
|
||||
@@ -57,8 +37,6 @@ spec:
|
||||
zoneName: 13.18.198.in-addr.arpa
|
||||
type: primary
|
||||
defaultTTL: 600
|
||||
dynamicUpdate: true
|
||||
updateKeyRef: client-update
|
||||
---
|
||||
apiVersion: bind.unkin.net/v1alpha1
|
||||
kind: BindZone
|
||||
@@ -70,8 +48,6 @@ spec:
|
||||
zoneName: 14.18.198.in-addr.arpa
|
||||
type: primary
|
||||
defaultTTL: 600
|
||||
dynamicUpdate: true
|
||||
updateKeyRef: client-update
|
||||
---
|
||||
apiVersion: bind.unkin.net/v1alpha1
|
||||
kind: BindZone
|
||||
@@ -83,8 +59,6 @@ spec:
|
||||
zoneName: 15.18.198.in-addr.arpa
|
||||
type: primary
|
||||
defaultTTL: 600
|
||||
dynamicUpdate: true
|
||||
updateKeyRef: client-update
|
||||
---
|
||||
apiVersion: bind.unkin.net/v1alpha1
|
||||
kind: BindZone
|
||||
@@ -96,8 +70,6 @@ spec:
|
||||
zoneName: 16.18.198.in-addr.arpa
|
||||
type: primary
|
||||
defaultTTL: 600
|
||||
dynamicUpdate: true
|
||||
updateKeyRef: client-update
|
||||
---
|
||||
apiVersion: bind.unkin.net/v1alpha1
|
||||
kind: BindZone
|
||||
@@ -109,8 +81,6 @@ spec:
|
||||
zoneName: 17.18.198.in-addr.arpa
|
||||
type: primary
|
||||
defaultTTL: 600
|
||||
dynamicUpdate: true
|
||||
updateKeyRef: client-update
|
||||
---
|
||||
apiVersion: bind.unkin.net/v1alpha1
|
||||
kind: BindZone
|
||||
@@ -122,8 +92,6 @@ spec:
|
||||
zoneName: 19.18.198.in-addr.arpa
|
||||
type: primary
|
||||
defaultTTL: 600
|
||||
dynamicUpdate: true
|
||||
updateKeyRef: client-update
|
||||
---
|
||||
apiVersion: bind.unkin.net/v1alpha1
|
||||
kind: BindZone
|
||||
@@ -135,8 +103,6 @@ spec:
|
||||
zoneName: 20.18.198.in-addr.arpa
|
||||
type: primary
|
||||
defaultTTL: 600
|
||||
dynamicUpdate: true
|
||||
updateKeyRef: client-update
|
||||
---
|
||||
apiVersion: bind.unkin.net/v1alpha1
|
||||
kind: BindZone
|
||||
@@ -148,8 +114,6 @@ spec:
|
||||
zoneName: 21.18.198.in-addr.arpa
|
||||
type: primary
|
||||
defaultTTL: 600
|
||||
dynamicUpdate: true
|
||||
updateKeyRef: client-update
|
||||
---
|
||||
apiVersion: bind.unkin.net/v1alpha1
|
||||
kind: BindZone
|
||||
@@ -161,8 +125,6 @@ spec:
|
||||
zoneName: 22.18.198.in-addr.arpa
|
||||
type: primary
|
||||
defaultTTL: 600
|
||||
dynamicUpdate: true
|
||||
updateKeyRef: client-update
|
||||
---
|
||||
apiVersion: bind.unkin.net/v1alpha1
|
||||
kind: BindZone
|
||||
@@ -174,8 +136,6 @@ spec:
|
||||
zoneName: 23.18.198.in-addr.arpa
|
||||
type: primary
|
||||
defaultTTL: 600
|
||||
dynamicUpdate: true
|
||||
updateKeyRef: client-update
|
||||
---
|
||||
apiVersion: bind.unkin.net/v1alpha1
|
||||
kind: BindZone
|
||||
@@ -187,8 +147,6 @@ spec:
|
||||
zoneName: 24.18.198.in-addr.arpa
|
||||
type: primary
|
||||
defaultTTL: 600
|
||||
dynamicUpdate: true
|
||||
updateKeyRef: client-update
|
||||
---
|
||||
apiVersion: bind.unkin.net/v1alpha1
|
||||
kind: BindZone
|
||||
@@ -200,8 +158,6 @@ spec:
|
||||
zoneName: 25.18.198.in-addr.arpa
|
||||
type: primary
|
||||
defaultTTL: 600
|
||||
dynamicUpdate: true
|
||||
updateKeyRef: client-update
|
||||
---
|
||||
apiVersion: bind.unkin.net/v1alpha1
|
||||
kind: BindZone
|
||||
@@ -213,8 +169,6 @@ spec:
|
||||
zoneName: 26.18.198.in-addr.arpa
|
||||
type: primary
|
||||
defaultTTL: 600
|
||||
dynamicUpdate: true
|
||||
updateKeyRef: client-update
|
||||
---
|
||||
apiVersion: bind.unkin.net/v1alpha1
|
||||
kind: BindZone
|
||||
@@ -226,8 +180,6 @@ spec:
|
||||
zoneName: 27.18.198.in-addr.arpa
|
||||
type: primary
|
||||
defaultTTL: 600
|
||||
dynamicUpdate: true
|
||||
updateKeyRef: client-update
|
||||
---
|
||||
apiVersion: bind.unkin.net/v1alpha1
|
||||
kind: BindZone
|
||||
@@ -239,8 +191,6 @@ spec:
|
||||
zoneName: 28.18.198.in-addr.arpa
|
||||
type: primary
|
||||
defaultTTL: 600
|
||||
dynamicUpdate: true
|
||||
updateKeyRef: client-update
|
||||
---
|
||||
apiVersion: bind.unkin.net/v1alpha1
|
||||
kind: BindZone
|
||||
@@ -252,5 +202,3 @@ spec:
|
||||
zoneName: 29.18.198.in-addr.arpa
|
||||
type: primary
|
||||
defaultTTL: 600
|
||||
dynamicUpdate: true
|
||||
updateKeyRef: client-update
|
||||
|
||||
@@ -23,7 +23,7 @@ spec:
|
||||
type: ClusterIP
|
||||
resources:
|
||||
requests:
|
||||
cpu: 20m
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: "1"
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
---
|
||||
# Key that external-dns (and DNSRecord objects) use to send RFC2136 dynamic
|
||||
# updates to the primary. The operator generates the material into a Secret
|
||||
# (externaldns-key-tsig) in this namespace. secretTemplate stamps emberstack
|
||||
# reflector hints onto that Secret so it is mirrored into the externaldns
|
||||
# namespace, where the external-dns controller reads it -- guaranteeing
|
||||
# external-dns presents exactly the key the primary's allow-update accepts.
|
||||
# updates to the primary. The operator generates the material into a Secret.
|
||||
apiVersion: bind.unkin.net/v1alpha1
|
||||
kind: BindTSIGKey
|
||||
metadata:
|
||||
@@ -13,9 +9,3 @@ metadata:
|
||||
spec:
|
||||
clusterRef: bind-externaldns
|
||||
algorithm: hmac-sha256
|
||||
secretTemplate:
|
||||
annotations:
|
||||
reflector.v1.k8s.emberstack.com/reflection-allowed: "true"
|
||||
reflector.v1.k8s.emberstack.com/reflection-allowed-namespaces: "externaldns"
|
||||
reflector.v1.k8s.emberstack.com/reflection-auto-enabled: "true"
|
||||
reflector.v1.k8s.emberstack.com/reflection-auto-namespaces: "externaldns"
|
||||
|
||||
@@ -7,5 +7,3 @@ resources:
|
||||
- authoritative
|
||||
- resolvers
|
||||
- externaldns
|
||||
- tsig-api
|
||||
- agent-dns-rolebinding.yaml
|
||||
|
||||
@@ -8,15 +8,11 @@ metadata:
|
||||
spec:
|
||||
clusterRef: bind-resolvers
|
||||
entries:
|
||||
- 10.42.0.0/16 # k8s pod network (kube-proxy masquerades node-originated LB queries)
|
||||
- 198.18.1.10/32
|
||||
- 198.18.2.160/27
|
||||
- 198.18.21.160/27
|
||||
- 198.18.2.192/27
|
||||
- 198.18.21.192/27
|
||||
# Admin/management access
|
||||
- 10.10.12.200/32 # benvin workstation (wireguard)
|
||||
- 198.18.21.160/32 # benvin router (also within 198.18.21.160/27 above)
|
||||
- 198.18.13.0/24
|
||||
- 198.18.14.0/24
|
||||
- 198.18.15.0/24
|
||||
|
||||
@@ -21,23 +21,9 @@ spec:
|
||||
forwarders:
|
||||
- 8.8.8.8
|
||||
- 1.1.1.1
|
||||
# The internal split-horizon zones are served UNSIGNED by the in-cluster
|
||||
# authoritative, but their public parents publish DS records (e.g. unkin.net
|
||||
# is DNSSEC-signed on the Internet). With dnssec-validation on, the validator
|
||||
# sees "parent indicates secure" but gets an insecure answer and returns
|
||||
# SERVFAIL (broken trust chain). Treat the forwarded internal domains as
|
||||
# insecure so they are not validated. unkin.net covers all *.unkin.net
|
||||
# (incl. k8s.syd1.au.unkin.net); 18.198.in-addr.arpa covers every reverse zone.
|
||||
extraOptions:
|
||||
- "validate-except { unkin.net; 18.198.in-addr.arpa; consul; }"
|
||||
# Enable query logging so the Tier-2 vector bind_query pipeline can parse
|
||||
# client/qname/qtype. Routes to the `queries` category which, with no explicit
|
||||
# logging{} clause, follows the default category to the named foreground
|
||||
# stderr channel -> pod stdout -> vector (subject logs.k8s.bind-internal.*).
|
||||
- "querylog yes"
|
||||
resources:
|
||||
requests:
|
||||
cpu: 20m
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: "1"
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
# Conditional forward zones, from the puppet openforwarder view.
|
||||
# Upstreams: unkin authoritative 198.18.200.6, consul 198.18.19.14,
|
||||
# k8s 198.18.200.8 (in-cluster bind-externaldns VIP).
|
||||
# k8s -> in-cluster bind-externaldns 198.18.200.8 for both the forward zone
|
||||
# k8s.syd1.au.unkin.net and the reverse zone 200.18.198.in-addr.arpa, which
|
||||
# external-dns now publishes to (see the external-dns migration PRs).
|
||||
# Upstreams: unkin authoritative 198.18.200.6, consul 198.18.19.14, k8s 198.18.200.8.
|
||||
# k8s -> in-cluster bind-externaldns 198.18.200.8.
|
||||
# (Zones that forwarded to 10.10.16.x were dropped; consul left as-is.)
|
||||
---
|
||||
apiVersion: bind.unkin.net/v1alpha1
|
||||
@@ -64,22 +61,6 @@ spec:
|
||||
---
|
||||
apiVersion: bind.unkin.net/v1alpha1
|
||||
kind: BindZone
|
||||
metadata:
|
||||
name: fwd-200-18-198-in-addr-arpa
|
||||
namespace: bind-internal
|
||||
spec:
|
||||
clusterRef: bind-resolvers
|
||||
viewRef: openforwarder
|
||||
zoneName: 200.18.198.in-addr.arpa
|
||||
type: forward
|
||||
catalog: false
|
||||
forwarders:
|
||||
# Reverse zone for the k8s LB range, published by external-dns to the
|
||||
# in-cluster bind-externaldns alongside k8s.syd1.au.unkin.net.
|
||||
- 198.18.200.8
|
||||
---
|
||||
apiVersion: bind.unkin.net/v1alpha1
|
||||
kind: BindZone
|
||||
metadata:
|
||||
name: fwd-13-18-198-in-addr-arpa
|
||||
namespace: bind-internal
|
||||
|
||||
@@ -1,27 +0,0 @@
|
||||
---
|
||||
# Companion TSIG API. The operator reconciles this into a Deployment, Service,
|
||||
# ConfigMap, master-token Secret and namespaced RBAC. vault-plugin-secrets-bind-tsig
|
||||
# calls it to create/rotate/delete TSIG keys, which it does by managing
|
||||
# BindTSIGKey resources in this namespace (the operator reconciles the material).
|
||||
#
|
||||
# The master access token Secret (bind-tsig-api-token) is generated by the
|
||||
# operator if absent; a VaultStaticSecret may later pre-seed/overwrite it so the
|
||||
# token is sourced from Vault rather than generated in-cluster.
|
||||
apiVersion: bind.unkin.net/v1alpha1
|
||||
kind: BindTSIGAPI
|
||||
metadata:
|
||||
name: bind-tsig-api
|
||||
namespace: bind-internal
|
||||
spec:
|
||||
image: artifactapi.k8s.syd1.au.unkin.net/docker-internal/bind-tsig-api:v0.2.3
|
||||
replicas: 1
|
||||
port: 8443
|
||||
# targetNamespace defaults to this resource's namespace (bind-internal), where
|
||||
# the authoritative cluster and its keys live.
|
||||
resources:
|
||||
requests:
|
||||
cpu: 25m
|
||||
memory: 64Mi
|
||||
limits:
|
||||
cpu: 250m
|
||||
memory: 128Mi
|
||||
@@ -1,38 +0,0 @@
|
||||
---
|
||||
# Static service account that Vault's kubernetes secret engine mints scoped
|
||||
# tokens for (agent-dns role). RBAC is confined to the bind namespaces via the
|
||||
# per-namespace RoleBindings below, not a ClusterRoleBinding.
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: agent-dns
|
||||
namespace: bind-system
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: agent-dns
|
||||
rules:
|
||||
- apiGroups: ["bind.unkin.net"]
|
||||
resources: ["*"]
|
||||
verbs: ["*"]
|
||||
- apiGroups: [""]
|
||||
resources: ["pods", "services", "configmaps", "events"]
|
||||
verbs: ["get", "list", "watch"]
|
||||
- apiGroups: [""]
|
||||
resources: ["pods/log"]
|
||||
verbs: ["get"]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: agent-dns
|
||||
namespace: bind-system
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: agent-dns
|
||||
namespace: bind-system
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: agent-dns
|
||||
@@ -21,7 +21,7 @@ spec:
|
||||
runAsNonRoot: true
|
||||
containers:
|
||||
- name: operator
|
||||
image: artifactapi.k8s.syd1.au.unkin.net/docker-internal/bind-operator:v0.2.6
|
||||
image: git.unkin.net/unkin/bind-operator:v0.1.5
|
||||
args:
|
||||
- --metrics-bind-address=:8080
|
||||
- --health-probe-bind-address=:8081
|
||||
|
||||
@@ -6,8 +6,6 @@ resources:
|
||||
- namespace.yaml
|
||||
# CRDs are pulled from the bind-operator repo at the matching tag rather than
|
||||
# vendored here, so they never drift from the operator.
|
||||
- https://git.unkin.net/unkin/bind-operator/raw/tag/v0.2.6/config/crd/install.yaml
|
||||
- https://git.unkin.net/unkin/bind-operator/raw/tag/v0.1.5/config/crd/install.yaml
|
||||
- rbac.yaml
|
||||
- agent-dns-rbac.yaml
|
||||
- deployment.yaml
|
||||
- vpa.yaml
|
||||
|
||||
@@ -23,15 +23,7 @@ rules:
|
||||
resources: ["pods/exec"]
|
||||
verbs: ["create", "get"]
|
||||
- apiGroups: ["apps"]
|
||||
resources: ["statefulsets", "deployments"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
|
||||
# The BindTSIGAPI reconciler deploys the companion API: a ServiceAccount plus
|
||||
# a namespaced Role/RoleBinding granting it access to BindTSIGKey + Secrets.
|
||||
- apiGroups: [""]
|
||||
resources: ["serviceaccounts"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
|
||||
- apiGroups: ["rbac.authorization.k8s.io"]
|
||||
resources: ["roles", "rolebindings"]
|
||||
resources: ["statefulsets"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
|
||||
- apiGroups: [""]
|
||||
resources: ["events"]
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
---
|
||||
apiVersion: autoscaling.k8s.io/v1
|
||||
kind: VerticalPodAutoscaler
|
||||
metadata:
|
||||
name: bind-operator-vpa
|
||||
namespace: bind-system
|
||||
spec:
|
||||
targetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: bind-operator
|
||||
updatePolicy:
|
||||
updateMode: "Off"
|
||||
@@ -1,84 +0,0 @@
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: cephrgw-operator
|
||||
namespace: cephrgw-system
|
||||
labels:
|
||||
app.kubernetes.io/name: cephrgw-operator
|
||||
annotations:
|
||||
# Restart on internal CA rotation only; cephrgw-credentials is Vault-rotated
|
||||
# (VSO) and deliberately excluded so routine key rotation causes no restart.
|
||||
configmap.reloader.stakater.com/auto: "true"
|
||||
secret.reloader.stakater.com/reload: "vault-ca-cert"
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: cephrgw-operator
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: cephrgw-operator
|
||||
spec:
|
||||
serviceAccountName: cephrgw-operator
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
containers:
|
||||
- name: operator
|
||||
image: artifactapi.k8s.syd1.au.unkin.net/docker-internal/cephrgw-operator:v0.4.0
|
||||
args:
|
||||
- --metrics-bind-address=:8080
|
||||
- --health-probe-bind-address=:8081
|
||||
- --leader-elect
|
||||
envFrom:
|
||||
# Provides CEPH_RGW_ACCESS_KEY/SECRET_KEY and the endpoints
|
||||
# (CEPH_RGW_ENDPOINT / CEPH_RGW_ADMIN_ENDPOINT), plus optional
|
||||
# CEPH_RGW_REGION / CEPH_RGW_CA / CEPH_RGW_INSECURE. Rendered from
|
||||
# Vault per docs/ceph-setup.md; not managed in GitOps.
|
||||
- secretRef:
|
||||
name: cephrgw-credentials
|
||||
env:
|
||||
# Trust the internal unkin.net (Vault PKI) CA so the operator can
|
||||
# verify radosgw's TLS cert. vault-ca-cert is reflected into every
|
||||
# namespace from the certificates namespace.
|
||||
- name: CEPH_RGW_CA_FILE
|
||||
value: /etc/vault-ca/ca.crt
|
||||
volumeMounts:
|
||||
- name: vault-ca-cert
|
||||
mountPath: /etc/vault-ca/ca.crt
|
||||
subPath: ca.crt
|
||||
readOnly: true
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
name: metrics
|
||||
- containerPort: 8081
|
||||
name: health
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /readyz
|
||||
port: 8081
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: 8081
|
||||
initialDelaySeconds: 15
|
||||
periodSeconds: 20
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
capabilities:
|
||||
drop: ["ALL"]
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 64Mi
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 256Mi
|
||||
volumes:
|
||||
- name: vault-ca-cert
|
||||
secret:
|
||||
secretName: vault-ca-cert
|
||||
@@ -1,14 +0,0 @@
|
||||
---
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
|
||||
resources:
|
||||
- namespace.yaml
|
||||
# CRDs are pulled from the cephrgw-operator repo at the matching tag rather
|
||||
# than vendored here, so they never drift from the operator.
|
||||
- https://git.unkin.net/unkin/cephrgw-operator/raw/tag/v0.4.0/config/crd/install.yaml
|
||||
- rbac.yaml
|
||||
- deployment.yaml
|
||||
- vaultauth.yaml
|
||||
- vaultstaticsecret.yaml
|
||||
- vpa.yaml
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: cephrgw-system
|
||||
@@ -1,42 +0,0 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: cephrgw-operator
|
||||
namespace: cephrgw-system
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: cephrgw-operator
|
||||
rules:
|
||||
- apiGroups: ["ceph.unkin.net"]
|
||||
resources: ["*"]
|
||||
verbs: ["*"]
|
||||
# The operator delivers RGW access/secret keys into Secrets.
|
||||
- apiGroups: [""]
|
||||
resources: ["secrets"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
|
||||
- apiGroups: [""]
|
||||
resources: ["events"]
|
||||
verbs: ["create", "patch"]
|
||||
- apiGroups: ["coordination.k8s.io"]
|
||||
resources: ["leases"]
|
||||
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
|
||||
# v0.3.1 startup check reads its own CRDs to warn if they are stale/missing.
|
||||
- apiGroups: ["apiextensions.k8s.io"]
|
||||
resources: ["customresourcedefinitions"]
|
||||
verbs: ["get", "list"]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: cephrgw-operator
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: cephrgw-operator
|
||||
namespace: cephrgw-system
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: cephrgw-operator
|
||||
@@ -1,21 +0,0 @@
|
||||
---
|
||||
apiVersion: secrets.hashicorp.com/v1beta1
|
||||
kind: VaultAuth
|
||||
metadata:
|
||||
name: default
|
||||
namespace: cephrgw-system
|
||||
spec:
|
||||
method: kubernetes
|
||||
mount: k8s/au/syd1
|
||||
vaultConnectionRef: vso-system/default
|
||||
allowedNamespaces:
|
||||
- cephrgw-system
|
||||
kubernetes:
|
||||
# Shared "default" role: binds the namespace's default ServiceAccount and
|
||||
# grants the templated kv/kubernetes/namespace/<ns>/<sa>/* read policy, so
|
||||
# no per-app terraform-vault change is needed.
|
||||
role: default
|
||||
serviceAccount: default
|
||||
audiences:
|
||||
- vault
|
||||
tokenExpirationSeconds: 600
|
||||
@@ -1,30 +0,0 @@
|
||||
---
|
||||
# Renders the radosgw credentials from Vault into the cephrgw-credentials
|
||||
# Secret the operator Deployment consumes via envFrom. The KV secret's keys
|
||||
# (CEPH_RGW_ACCESS_KEY/SECRET_KEY, CEPH_RGW_ENDPOINT, optional
|
||||
# CEPH_RGW_ADMIN_ENDPOINT/REGION/CA) are copied verbatim, so they land as the
|
||||
# matching env vars.
|
||||
#
|
||||
# The path sits under the templated default policy
|
||||
# (kv/data/kubernetes/namespace/<ns>/<sa>/*), so it needs no dedicated Vault
|
||||
# role or policy. Seed the values with:
|
||||
# vault kv put kv/kubernetes/namespace/cephrgw-system/default/cephrgw-credentials \
|
||||
# CEPH_RGW_ENDPOINT=https://s3.ceph.unkin.net \
|
||||
# CEPH_RGW_ADMIN_ENDPOINT=https://radosgw.service.consul:443 \
|
||||
# CEPH_RGW_ACCESS_KEY=... CEPH_RGW_SECRET_KEY=...
|
||||
apiVersion: secrets.hashicorp.com/v1beta1
|
||||
kind: VaultStaticSecret
|
||||
metadata:
|
||||
name: cephrgw-credentials
|
||||
namespace: cephrgw-system
|
||||
spec:
|
||||
vaultAuthRef: default
|
||||
mount: kv
|
||||
type: kv-v2
|
||||
path: kubernetes/namespace/cephrgw-system/default/cephrgw-credentials
|
||||
refreshAfter: 5m
|
||||
hmacSecretData: true
|
||||
destination:
|
||||
name: cephrgw-credentials
|
||||
create: true
|
||||
overwrite: true
|
||||
@@ -1,13 +0,0 @@
|
||||
---
|
||||
apiVersion: autoscaling.k8s.io/v1
|
||||
kind: VerticalPodAutoscaler
|
||||
metadata:
|
||||
name: cephrgw-operator-vpa
|
||||
namespace: cephrgw-system
|
||||
spec:
|
||||
targetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: cephrgw-operator
|
||||
updatePolicy:
|
||||
updateMode: "Off"
|
||||
@@ -1,21 +0,0 @@
|
||||
---
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: ClusterIssuer
|
||||
metadata:
|
||||
name: letsencrypt-staging
|
||||
spec:
|
||||
acme:
|
||||
server: https://acme-staging-v02.api.letsencrypt.org/directory
|
||||
email: admin@unkin.net
|
||||
privateKeySecretRef:
|
||||
name: letsencrypt-staging-account-key
|
||||
solvers:
|
||||
- dns01:
|
||||
cnameStrategy: Follow
|
||||
rfc2136:
|
||||
nameserver: "198.18.199.53:53"
|
||||
tsigKeyName: certmanager
|
||||
tsigAlgorithm: HMACSHA256
|
||||
tsigSecretSecretRef:
|
||||
name: certmanager-tsig
|
||||
key: secret
|
||||
@@ -1,21 +0,0 @@
|
||||
---
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: ClusterIssuer
|
||||
metadata:
|
||||
name: letsencrypt
|
||||
spec:
|
||||
acme:
|
||||
server: https://acme-v02.api.letsencrypt.org/directory
|
||||
email: admin@unkin.net
|
||||
privateKeySecretRef:
|
||||
name: letsencrypt-account-key
|
||||
solvers:
|
||||
- dns01:
|
||||
cnameStrategy: Follow
|
||||
rfc2136:
|
||||
nameserver: "198.18.199.53:53"
|
||||
tsigKeyName: certmanager
|
||||
tsigAlgorithm: HMACSHA256
|
||||
tsigSecretSecretRef:
|
||||
name: certmanager-tsig
|
||||
key: secret
|
||||
@@ -1,27 +0,0 @@
|
||||
---
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: ClusterIssuer
|
||||
metadata:
|
||||
name: vault-issuer
|
||||
labels:
|
||||
app.kubernetes.io/instance: cert-manager-config
|
||||
app.kubernetes.io/managed-by: Helm
|
||||
app.kubernetes.io/name: cert-manager-config
|
||||
annotations:
|
||||
meta.helm.sh/release-name: cert-manager-clusterissuer
|
||||
meta.helm.sh/release-namespace: cert-manager
|
||||
spec:
|
||||
vault:
|
||||
server: https://vault.service.consul:8200
|
||||
path: pki_int/sign/servers_default
|
||||
caBundleSecretRef:
|
||||
key: ca.crt
|
||||
name: vault-ca-cert
|
||||
auth:
|
||||
kubernetes:
|
||||
mountPath: /v1/auth/k8s/au/syd1
|
||||
role: cert_manager_issuer
|
||||
serviceAccountRef:
|
||||
name: cert-manager-vault-issuer
|
||||
audiences:
|
||||
- vault
|
||||
@@ -7,7 +7,3 @@ resources:
|
||||
- serviceaccount.yaml
|
||||
- clusterrole.yaml
|
||||
- clusterrolebinding.yaml
|
||||
- clusterissuer_vault-issuer.yaml
|
||||
- vmservicescrape.yaml
|
||||
- clusterissuer_letsencrypt.yaml
|
||||
- clusterissuer_letsencrypt-staging.yaml
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
---
|
||||
# Scrape cert-manager webhook + cainjector metrics endpoints.
|
||||
# Picked up by the observability VMAgent (selectAllByDefault).
|
||||
apiVersion: operator.victoriametrics.com/v1beta1
|
||||
kind: VMServiceScrape
|
||||
metadata:
|
||||
name: cert-manager
|
||||
namespace: cert-manager
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/instance: cert-manager
|
||||
endpoints:
|
||||
- port: metrics
|
||||
path: /metrics
|
||||
- port: http-metrics
|
||||
path: /metrics
|
||||
@@ -1,6 +1,4 @@
|
||||
---
|
||||
# pre-commit: allow-plain-secret -- public CA bundle; this secret bootstraps
|
||||
# trust in Vault itself and therefore cannot be Vault-sourced.
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
@@ -30,7 +28,7 @@ stringData:
|
||||
mitItX+RAgMBAAGjgewwgekwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMB
|
||||
Af8wHQYDVR0OBBYEFEp/+grAdVqRSeb9xJjSeZYNW32MMB8GA1UdIwQYMBaAFBqc
|
||||
v6Y+hfHt4EjgKa/uoQGEHTknMEcGCCsGAQUFBwEBBDswOTA3BggrBgEFBQcwAoYr
|
||||
aHR0cHM6Ly92YXVsdC5zZXJ2dWNlLmNvbnN1bC92MS9wa2lfcm9vdC9jYTA9BgNV
|
||||
aHR0cHM6Ly92YXVsdC5zZXJ2aWNlLmNvbnN1bC92MS9wa2lfcm9vdC9jYTA9BgNV
|
||||
HR8ENjA0MDKgMKAuhixodHRwczovL3ZhdWx0LnNlcnZpY2UuY29uc3VsL3YxL3Br
|
||||
aV9yb290L2NybDANBgkqhkiG9w0BAQsFAAOCAQEAM0FS8tscZe7yly/gM7jO6lx5
|
||||
muMFusifjUIrcQGnZBkoECeuUVPNTs3e/Th+XaxjCnmSpqSNT3z9Irr6Hhxf7n03
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: clickhouse-system
|
||||
name: clickhouse-system
|
||||
@@ -1,30 +0,0 @@
|
||||
# consul (k8s)
|
||||
|
||||
Consul server cluster (DC `au-syd1`), deployed via the HashiCorp helm chart with
|
||||
ACLs enabled (`default_policy: deny`, parity with the VM cluster).
|
||||
|
||||
## API access (ACL auth)
|
||||
|
||||
The HTTP API and UI are served on port 8500 behind the gateway at
|
||||
`https://consul.k8s.syd1.au.unkin.net` (and `https://consul.service.consul`).
|
||||
With ACLs enabled, requests beyond the anonymous policy require a token:
|
||||
|
||||
```bash
|
||||
# management (bootstrap) token — seeded from Vault, synced by VSO into the
|
||||
# consul-bootstrap-acl-token secret; same value as the VM cluster's
|
||||
# initial_management token:
|
||||
CONSUL_HTTP_TOKEN=$(vault kv get -field=token kv/kubernetes/namespace/consul/default/bootstrap-acl-token)
|
||||
|
||||
curl -H "X-Consul-Token: $CONSUL_HTTP_TOKEN" https://consul.k8s.syd1.au.unkin.net/v1/status/leader
|
||||
|
||||
# consul CLI:
|
||||
CONSUL_HTTP_ADDR=https://consul.k8s.syd1.au.unkin.net CONSUL_HTTP_TOKEN=$CONSUL_HTTP_TOKEN consul members
|
||||
```
|
||||
|
||||
The UI at the same hostname exposes an ACL login (top right) — paste a token.
|
||||
Anonymous requests get the anonymous-token policy only (reads for DNS/service
|
||||
discovery; no writes, no ACL/token APIs).
|
||||
|
||||
Prefer short-lived tokens minted by Vault's consul secrets engine over the
|
||||
management token for day-to-day use; the terraform-* CI roles already work this
|
||||
way.
|
||||
@@ -46,8 +46,8 @@ spec:
|
||||
- backendRefs:
|
||||
- group: ""
|
||||
kind: Service
|
||||
name: consul-http
|
||||
port: 8500
|
||||
name: consul-ui
|
||||
port: 80
|
||||
weight: 1
|
||||
matches:
|
||||
- path:
|
||||
@@ -74,8 +74,8 @@ spec:
|
||||
- backendRefs:
|
||||
- group: ""
|
||||
kind: Service
|
||||
name: consul-http
|
||||
port: 8500
|
||||
name: consul-ui
|
||||
port: 80
|
||||
weight: 1
|
||||
matches:
|
||||
- path:
|
||||
|
||||
@@ -6,6 +6,3 @@ resources:
|
||||
- namespace.yaml
|
||||
- gateway.yaml
|
||||
- httproute.yaml
|
||||
- service.yaml
|
||||
- vaultauth.yaml
|
||||
- vaultstaticsecret.yaml
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
---
|
||||
# ClusterIP service targeting the consul server pods' HTTP API (8500).
|
||||
# The HashiCorp chart only ships consul-ui (also 8500 via the server pods)
|
||||
# and the headless consul-server; this named service gives the Gateway a
|
||||
# stable API backend. Consul serves both the HTTP API and the UI (at /ui/)
|
||||
# on this same port, so routing the API hostname here preserves the UI too.
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: consul-http
|
||||
namespace: consul
|
||||
labels:
|
||||
app.kubernetes.io/name: consul
|
||||
app.kubernetes.io/instance: consul
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
app: consul
|
||||
component: server
|
||||
release: consul
|
||||
ports:
|
||||
- name: http
|
||||
port: 8500
|
||||
protocol: TCP
|
||||
targetPort: 8500
|
||||
@@ -1,18 +0,0 @@
|
||||
---
|
||||
apiVersion: secrets.hashicorp.com/v1beta1
|
||||
kind: VaultAuth
|
||||
metadata:
|
||||
name: default
|
||||
namespace: consul
|
||||
spec:
|
||||
allowedNamespaces:
|
||||
- consul
|
||||
kubernetes:
|
||||
audiences:
|
||||
- vault
|
||||
role: default
|
||||
serviceAccount: default
|
||||
tokenExpirationSeconds: 600
|
||||
method: kubernetes
|
||||
mount: k8s/au/syd1
|
||||
vaultConnectionRef: vso-system/default
|
||||
@@ -1,17 +0,0 @@
|
||||
---
|
||||
apiVersion: secrets.hashicorp.com/v1beta1
|
||||
kind: VaultStaticSecret
|
||||
metadata:
|
||||
name: bootstrap-acl-token
|
||||
namespace: consul
|
||||
spec:
|
||||
destination:
|
||||
create: true
|
||||
name: consul-bootstrap-acl-token
|
||||
overwrite: true
|
||||
hmacSecretData: true
|
||||
mount: kv
|
||||
path: kubernetes/namespace/consul/default/bootstrap-acl-token
|
||||
refreshAfter: 5m
|
||||
type: kv-v2
|
||||
vaultAuthRef: default
|
||||
@@ -7,4 +7,3 @@ resources:
|
||||
- vaultauth.yaml
|
||||
- vaultstaticsecret.yaml
|
||||
- storageclass.yaml
|
||||
- vmservicescrape.yaml
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
---
|
||||
# Scrape the ceph-csi-cephfs nodeplugin + provisioner http-metrics endpoints.
|
||||
# Picked up by the observability VMAgent (selectAllByDefault).
|
||||
apiVersion: operator.victoriametrics.com/v1beta1
|
||||
kind: VMServiceScrape
|
||||
metadata:
|
||||
name: ceph-csi-cephfs
|
||||
namespace: csi-cephfs
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: ceph-csi-cephfs
|
||||
endpoints:
|
||||
- port: http-metrics
|
||||
path: /metrics
|
||||
@@ -7,4 +7,3 @@ resources:
|
||||
- vaultauth.yaml
|
||||
- vaultstaticsecret.yaml
|
||||
- storageclass.yaml
|
||||
- vmservicescrape.yaml
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
---
|
||||
# Scrape the ceph-csi-rbd nodeplugin + provisioner http-metrics endpoints.
|
||||
# Picked up by the observability VMAgent (selectAllByDefault).
|
||||
apiVersion: operator.victoriametrics.com/v1beta1
|
||||
kind: VMServiceScrape
|
||||
metadata:
|
||||
name: ceph-csi-rbd
|
||||
namespace: csi-cephrbd
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: ceph-csi-rbd
|
||||
endpoints:
|
||||
- port: http-metrics
|
||||
path: /metrics
|
||||
@@ -1,25 +0,0 @@
|
||||
---
|
||||
# Terraform-friendly REST API for KeaSubnet/KeaClientClass CRUD. The bearer
|
||||
# token Secret is generated by the operator when absent (no plain Secret is
|
||||
# committed here); it can later be pre-seeded from Vault under the same name.
|
||||
apiVersion: kea.unkin.net/v1alpha1
|
||||
kind: KeaAPI
|
||||
metadata:
|
||||
name: kea-api
|
||||
namespace: dhcp-system
|
||||
annotations:
|
||||
argocd.argoproj.io/sync-wave: "1"
|
||||
spec:
|
||||
replicas: 1
|
||||
image: git.unkin.net/unkin/kea-api:v0.1.2
|
||||
tokenSecretName: kea-api-token
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 8080
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 64Mi
|
||||
limits:
|
||||
cpu: "1"
|
||||
memory: 256Mi
|
||||
@@ -1,27 +0,0 @@
|
||||
# PXE boot classes matching client architecture (option 93), replacing the
|
||||
# legacy dhcpd "Legacy" and "UEFI-64" classes. Object names are lowercased to
|
||||
# satisfy RFC1123 (the operator renders the kea class name from metadata.name).
|
||||
---
|
||||
apiVersion: kea.unkin.net/v1alpha1
|
||||
kind: KeaClientClass
|
||||
metadata:
|
||||
name: legacy
|
||||
namespace: dhcp-system
|
||||
annotations:
|
||||
argocd.argoproj.io/sync-wave: "1"
|
||||
spec:
|
||||
clusterRef: kea
|
||||
archHex: ["0x0000"]
|
||||
bootFileName: /undionly.kpxe
|
||||
---
|
||||
apiVersion: kea.unkin.net/v1alpha1
|
||||
kind: KeaClientClass
|
||||
metadata:
|
||||
name: uefi-64
|
||||
namespace: dhcp-system
|
||||
annotations:
|
||||
argocd.argoproj.io/sync-wave: "1"
|
||||
spec:
|
||||
clusterRef: kea
|
||||
archHex: ["0x0007", "0x0009"]
|
||||
bootFileName: /ipxe.efi
|
||||
@@ -1,35 +0,0 @@
|
||||
---
|
||||
# HA pair fronted by a PureLB anycast Service on a NEW, unused common-pool IP
|
||||
# (198.18.200.10). This is intentionally NOT the current isc-dhcpd anycast
|
||||
# address (198.18.19.18) -- the production cutover is a separate later task.
|
||||
apiVersion: kea.unkin.net/v1alpha1
|
||||
kind: KeaCluster
|
||||
metadata:
|
||||
name: kea
|
||||
namespace: dhcp-system
|
||||
annotations:
|
||||
argocd.argoproj.io/sync-wave: "1"
|
||||
spec:
|
||||
replicas: 2
|
||||
image: git.unkin.net/unkin/kea:v0.1.2
|
||||
domainName: main.unkin.net
|
||||
defaultLeaseTime: 1200
|
||||
maxLeaseTime: 86400
|
||||
# No ntpServers: DHCP option 42 (ntp-servers) carries IPv4 addresses only, so
|
||||
# the rotating AU pool.ntp.org hostnames cannot be delivered this way (kea
|
||||
# rejects them at config load). Add concrete NTP server IPs here if needed.
|
||||
ha:
|
||||
mode: hot-standby
|
||||
service:
|
||||
type: LoadBalancer
|
||||
ipAddressPool: common
|
||||
loadBalancerIP: 198.18.200.10
|
||||
annotations:
|
||||
purelb.io/addresses: 198.18.200.10
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: "1"
|
||||
memory: 512Mi
|
||||
@@ -1,90 +0,0 @@
|
||||
# Translation of the legacy ISC dhcpd pools (puppet
|
||||
# roles/infra/dhcp/server.yaml): 198.18.13-17.0/24, each a .200-.220 pool,
|
||||
# next-server 198.18.19.19. Gateways per the original config:
|
||||
# .13/.14/.15/.16 -> .254, .17 -> .1. DNS points at the in-cluster
|
||||
# bind-resolvers PureLB IP (198.18.200.7), not the legacy 198.18.19.15.
|
||||
---
|
||||
apiVersion: kea.unkin.net/v1alpha1
|
||||
kind: KeaSubnet
|
||||
metadata:
|
||||
name: net-198-18-13
|
||||
namespace: dhcp-system
|
||||
annotations:
|
||||
argocd.argoproj.io/sync-wave: "1"
|
||||
spec:
|
||||
clusterRef: kea
|
||||
subnet: 198.18.13.0/24
|
||||
pools:
|
||||
- 198.18.13.200 - 198.18.13.220
|
||||
routers: [198.18.13.254]
|
||||
dnsServers: [198.18.200.7]
|
||||
domainName: main.unkin.net
|
||||
nextServer: 198.18.19.19
|
||||
---
|
||||
apiVersion: kea.unkin.net/v1alpha1
|
||||
kind: KeaSubnet
|
||||
metadata:
|
||||
name: net-198-18-14
|
||||
namespace: dhcp-system
|
||||
annotations:
|
||||
argocd.argoproj.io/sync-wave: "1"
|
||||
spec:
|
||||
clusterRef: kea
|
||||
subnet: 198.18.14.0/24
|
||||
pools:
|
||||
- 198.18.14.200 - 198.18.14.220
|
||||
routers: [198.18.14.254]
|
||||
dnsServers: [198.18.200.7]
|
||||
domainName: main.unkin.net
|
||||
nextServer: 198.18.19.19
|
||||
---
|
||||
apiVersion: kea.unkin.net/v1alpha1
|
||||
kind: KeaSubnet
|
||||
metadata:
|
||||
name: net-198-18-15
|
||||
namespace: dhcp-system
|
||||
annotations:
|
||||
argocd.argoproj.io/sync-wave: "1"
|
||||
spec:
|
||||
clusterRef: kea
|
||||
subnet: 198.18.15.0/24
|
||||
pools:
|
||||
- 198.18.15.200 - 198.18.15.220
|
||||
routers: [198.18.15.254]
|
||||
dnsServers: [198.18.200.7]
|
||||
domainName: main.unkin.net
|
||||
nextServer: 198.18.19.19
|
||||
---
|
||||
apiVersion: kea.unkin.net/v1alpha1
|
||||
kind: KeaSubnet
|
||||
metadata:
|
||||
name: net-198-18-16
|
||||
namespace: dhcp-system
|
||||
annotations:
|
||||
argocd.argoproj.io/sync-wave: "1"
|
||||
spec:
|
||||
clusterRef: kea
|
||||
subnet: 198.18.16.0/24
|
||||
pools:
|
||||
- 198.18.16.200 - 198.18.16.220
|
||||
routers: [198.18.16.254]
|
||||
dnsServers: [198.18.200.7]
|
||||
domainName: main.unkin.net
|
||||
nextServer: 198.18.19.19
|
||||
---
|
||||
apiVersion: kea.unkin.net/v1alpha1
|
||||
kind: KeaSubnet
|
||||
metadata:
|
||||
name: net-198-18-17
|
||||
namespace: dhcp-system
|
||||
annotations:
|
||||
argocd.argoproj.io/sync-wave: "1"
|
||||
spec:
|
||||
clusterRef: kea
|
||||
subnet: 198.18.17.0/24
|
||||
pools:
|
||||
- 198.18.17.200 - 198.18.17.220
|
||||
routers: [198.18.17.1]
|
||||
dnsServers: [198.18.200.7]
|
||||
domainName: main.unkin.net
|
||||
nextServer: 198.18.19.19
|
||||
@@ -1,56 +0,0 @@
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: kea-operator
|
||||
namespace: dhcp-system
|
||||
labels:
|
||||
app.kubernetes.io/name: kea-operator
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: kea-operator
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: kea-operator
|
||||
spec:
|
||||
serviceAccountName: kea-operator
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
containers:
|
||||
- name: operator
|
||||
image: git.unkin.net/unkin/kea-operator:v0.1.2
|
||||
args:
|
||||
- --metrics-bind-address=:8080
|
||||
- --health-probe-bind-address=:8081
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
name: metrics
|
||||
- containerPort: 8081
|
||||
name: health
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /readyz
|
||||
port: 8081
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: 8081
|
||||
initialDelaySeconds: 15
|
||||
periodSeconds: 20
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
capabilities:
|
||||
drop: ["ALL"]
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 64Mi
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 256Mi
|
||||
@@ -1,17 +0,0 @@
|
||||
---
|
||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||
kind: Kustomization
|
||||
|
||||
resources:
|
||||
- namespace.yaml
|
||||
# CRDs are pulled from the kea-operator repo at the matching tag rather than
|
||||
# vendored here, so they never drift from the operator.
|
||||
- https://git.unkin.net/unkin/kea-operator/raw/tag/v0.1.0/config/crd/install.yaml
|
||||
- rbac.yaml
|
||||
- deployment.yaml
|
||||
- vpa.yaml
|
||||
# CRs (sync-wave 1) reconcile after the operator + CRDs are established.
|
||||
- cr/keacluster.yaml
|
||||
- cr/keasubnets.yaml
|
||||
- cr/keaclientclasses.yaml
|
||||
- cr/keaapi.yaml
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: dhcp-system
|
||||
@@ -1,46 +0,0 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: kea-operator
|
||||
namespace: dhcp-system
|
||||
---
|
||||
# Sourced from the kea-operator repo config/rbac/role.yaml (v0.1.0). Leader
|
||||
# election is disabled so no coordination.k8s.io/leases grant is needed.
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: kea-operator
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["configmaps", "secrets", "serviceaccounts", "services"]
|
||||
verbs: ["create", "delete", "get", "list", "patch", "update", "watch"]
|
||||
- apiGroups: [""]
|
||||
resources: ["pods"]
|
||||
verbs: ["get", "list", "watch"]
|
||||
- apiGroups: ["apps"]
|
||||
resources: ["deployments", "statefulsets"]
|
||||
verbs: ["create", "delete", "get", "list", "patch", "update", "watch"]
|
||||
- apiGroups: ["kea.unkin.net"]
|
||||
resources: ["keaapis", "keaclientclasses", "keaclusters", "keasubnets"]
|
||||
verbs: ["create", "delete", "get", "list", "patch", "update", "watch"]
|
||||
- apiGroups: ["kea.unkin.net"]
|
||||
resources:
|
||||
["keaapis/status", "keaclientclasses/status", "keaclusters/status", "keasubnets/status"]
|
||||
verbs: ["get", "patch", "update"]
|
||||
- apiGroups: ["rbac.authorization.k8s.io"]
|
||||
resources: ["rolebindings", "roles"]
|
||||
verbs: ["create", "delete", "get", "list", "patch", "update", "watch"]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: kea-operator
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: kea-operator
|
||||
namespace: dhcp-system
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: kea-operator
|
||||
@@ -1,13 +0,0 @@
|
||||
---
|
||||
apiVersion: autoscaling.k8s.io/v1
|
||||
kind: VerticalPodAutoscaler
|
||||
metadata:
|
||||
name: kea-operator-vpa
|
||||
namespace: dhcp-system
|
||||
spec:
|
||||
targetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: kea-operator
|
||||
updatePolicy:
|
||||
updateMode: "Off"
|
||||
@@ -1,56 +0,0 @@
|
||||
---
|
||||
# Ceph RGW (S3) backup target for the encapi CNPG cluster, provisioned by the
|
||||
# in-estate cephrgw-operator. One dedicated bucket + owner user per cluster:
|
||||
# cephrgw CRs are namespace-scoped and CNPG reads its S3 credential Secret from
|
||||
# its own namespace, so backups are per-database rather than one shared bucket.
|
||||
apiVersion: ceph.unkin.net/v1alpha1
|
||||
kind: ObjectStoreUser
|
||||
metadata:
|
||||
name: cnpg-encapi-backup
|
||||
namespace: encapi
|
||||
spec:
|
||||
displayName: "CNPG backup owner (encapi)"
|
||||
# RGW users are global; keep the uid namespace-qualified so it never collides.
|
||||
uid: cnpg-encapi-backup
|
||||
maxBuckets: 5
|
||||
# Operator writes AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY (+ RGW_UID,
|
||||
# S3_ENDPOINT) into this Secret; the Cluster's barmanObjectStore consumes it.
|
||||
secretName: cnpg-encapi-backup-s3
|
||||
# Keep the RGW user (and thus the keys) if this CR is ever deleted, so an
|
||||
# in-flight restore can still reach the archive.
|
||||
retainOnDelete: true
|
||||
---
|
||||
apiVersion: ceph.unkin.net/v1alpha1
|
||||
kind: Bucket
|
||||
metadata:
|
||||
name: cnpg-encapi
|
||||
namespace: encapi
|
||||
spec:
|
||||
placementTarget: ec
|
||||
bucketName: cnpg-encapi
|
||||
# The owner user has full control of its own bucket (read + write), which is
|
||||
# all the backup/restore identity needs — no extra BucketAccess grant.
|
||||
ownerRef: cnpg-encapi-backup
|
||||
versioning: false
|
||||
tags:
|
||||
app: encapi
|
||||
purpose: cnpg-backup
|
||||
# Never drop the backups if the CR is removed; retire buckets by hand.
|
||||
retainOnDelete: true
|
||||
---
|
||||
# Nightly base backup. Continuous WAL archiving is always-on via the Cluster's
|
||||
# spec.backup.barmanObjectStore; this schedules the periodic full backup that
|
||||
# WAL is layered on top of. Schedules are staggered across clusters so the 8
|
||||
# base backups do not hit RGW at once (CNPG cron is 6-field, seconds first).
|
||||
apiVersion: postgresql.cnpg.io/v1
|
||||
kind: ScheduledBackup
|
||||
metadata:
|
||||
name: cnpg-encapi-nightly
|
||||
namespace: encapi
|
||||
spec:
|
||||
schedule: "0 40 2 * * *"
|
||||
immediate: false
|
||||
backupOwnerReference: self
|
||||
method: barmanObjectStore
|
||||
cluster:
|
||||
name: postgres
|
||||
@@ -7,35 +7,6 @@ metadata:
|
||||
spec:
|
||||
affinity:
|
||||
podAntiAffinityType: preferred
|
||||
backup:
|
||||
# 30-day retention (DEFAULT — adjust per cluster if needed). Enforced by CNPG
|
||||
# against the object store on each successful base backup.
|
||||
retentionPolicy: 30d
|
||||
barmanObjectStore:
|
||||
# Dedicated per-cluster Ceph RGW bucket (cephrgw-operator provisions it).
|
||||
destinationPath: s3://cnpg-encapi
|
||||
endpointURL: https://s3.ceph.unkin.net
|
||||
# radosgw serves a Vault-PKI cert; trust the internal CA (reflected into
|
||||
# every namespace as the vault-ca-cert Secret).
|
||||
endpointCA:
|
||||
name: vault-ca-cert
|
||||
key: ca.crt
|
||||
# Keys minted by the ObjectStoreUser in cnpg_backup.yaml; never hardcoded.
|
||||
s3Credentials:
|
||||
accessKeyId:
|
||||
name: cnpg-encapi-backup-s3
|
||||
key: AWS_ACCESS_KEY_ID
|
||||
secretAccessKey:
|
||||
name: cnpg-encapi-backup-s3
|
||||
key: AWS_SECRET_ACCESS_KEY
|
||||
# Path prefix within the bucket; keep stable across restores (see docs).
|
||||
serverName: encapi
|
||||
data:
|
||||
compression: bzip2
|
||||
jobs: 2
|
||||
wal:
|
||||
compression: zstd
|
||||
maxParallel: 2
|
||||
bootstrap:
|
||||
initdb:
|
||||
database: encapi
|
||||
@@ -108,7 +79,7 @@ spec:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
requests:
|
||||
cpu: 50m
|
||||
cpu: 250m
|
||||
memory: 256Mi
|
||||
smartShutdownTimeout: 180
|
||||
startDelay: 3600
|
||||
|
||||
@@ -5,7 +5,7 @@ metadata:
|
||||
name: encapi
|
||||
namespace: encapi
|
||||
annotations:
|
||||
configmap.reloader.stakater.com/auto: "true"
|
||||
reloader.stakater.com/auto: "true"
|
||||
spec:
|
||||
replicas: 2
|
||||
selector:
|
||||
@@ -23,7 +23,7 @@ spec:
|
||||
automountServiceAccountToken: true
|
||||
containers:
|
||||
- name: encapi
|
||||
image: artifactapi.k8s.syd1.au.unkin.net/docker-internal/encapi:v0.1.1
|
||||
image: git.unkin.net/unkin/encapi:v0.1.1
|
||||
imagePullPolicy: IfNotPresent
|
||||
ports:
|
||||
- containerPort: 8000
|
||||
|
||||
@@ -10,8 +10,6 @@ resources:
|
||||
- gateway.yaml
|
||||
- httproute.yaml
|
||||
- cnpg_cluster.yaml
|
||||
- cnpg_backup.yaml
|
||||
- cnpg_pooler.yaml
|
||||
- vaultauth.yaml
|
||||
- vaultstaticsecret.yaml
|
||||
- vpa.yaml
|
||||
|
||||
@@ -1,13 +0,0 @@
|
||||
---
|
||||
apiVersion: autoscaling.k8s.io/v1
|
||||
kind: VerticalPodAutoscaler
|
||||
metadata:
|
||||
name: encapi-vpa
|
||||
namespace: encapi
|
||||
spec:
|
||||
targetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: encapi
|
||||
updatePolicy:
|
||||
updateMode: "Off"
|
||||
@@ -1,16 +0,0 @@
|
||||
---
|
||||
# Confines the agent-dns service account (in bind-system) to the agent-dns
|
||||
# ClusterRole within this namespace.
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: agent-dns
|
||||
namespace: externaldns
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: agent-dns
|
||||
namespace: bind-system
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: agent-dns
|
||||
@@ -6,4 +6,3 @@ resources:
|
||||
- namespace.yaml
|
||||
- vaultauth.yaml
|
||||
- vaultstaticsecret.yaml
|
||||
- agent-dns-rolebinding.yaml
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
---
|
||||
# Ceph RGW (S3) backup target for the gitea CNPG cluster, provisioned by the
|
||||
# in-estate cephrgw-operator. One dedicated bucket + owner user per cluster.
|
||||
apiVersion: ceph.unkin.net/v1alpha1
|
||||
kind: ObjectStoreUser
|
||||
metadata:
|
||||
name: cnpg-gitea-backup
|
||||
namespace: gitea
|
||||
spec:
|
||||
displayName: "CNPG backup owner (gitea)"
|
||||
# RGW users are global; keep the uid namespace-qualified so it never collides.
|
||||
uid: cnpg-gitea-backup
|
||||
maxBuckets: 5
|
||||
# Operator writes AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY (+ RGW_UID,
|
||||
# S3_ENDPOINT) into this Secret; the Cluster's barmanObjectStore consumes it.
|
||||
secretName: cnpg-gitea-backup-s3
|
||||
retainOnDelete: true
|
||||
---
|
||||
apiVersion: ceph.unkin.net/v1alpha1
|
||||
kind: Bucket
|
||||
metadata:
|
||||
name: cnpg-gitea
|
||||
namespace: gitea
|
||||
spec:
|
||||
bucketName: cnpg-gitea
|
||||
ownerRef: cnpg-gitea-backup
|
||||
versioning: false
|
||||
tags:
|
||||
app: gitea
|
||||
purpose: cnpg-backup
|
||||
retainOnDelete: true
|
||||
---
|
||||
apiVersion: postgresql.cnpg.io/v1
|
||||
kind: ScheduledBackup
|
||||
metadata:
|
||||
name: cnpg-gitea-nightly
|
||||
namespace: gitea
|
||||
spec:
|
||||
# 6-field CNPG cron (seconds first). 04:00 — next free slot after netbox
|
||||
# (03:40), keeping the estate's 20-minute stagger.
|
||||
schedule: "0 0 4 * * *"
|
||||
immediate: false
|
||||
backupOwnerReference: self
|
||||
method: barmanObjectStore
|
||||
cluster:
|
||||
name: gitea-postgres
|
||||
@@ -1,90 +0,0 @@
|
||||
---
|
||||
# Postgres for the k8s Gitea (replaces the Patroni-shared DB the VM uses). Gitea
|
||||
# already runs on Postgres, so cutover is a plain pg dump/restore (no engine
|
||||
# conversion). App-user creds come from the postgres-credentials Vault secret.
|
||||
apiVersion: postgresql.cnpg.io/v1
|
||||
kind: Cluster
|
||||
metadata:
|
||||
name: gitea-postgres
|
||||
namespace: gitea
|
||||
spec:
|
||||
affinity:
|
||||
podAntiAffinityType: preferred
|
||||
backup:
|
||||
# 30-day retention. Enforced by CNPG against the object store on each
|
||||
# successful base backup.
|
||||
retentionPolicy: 30d
|
||||
barmanObjectStore:
|
||||
# Dedicated per-cluster Ceph RGW bucket (cephrgw-operator provisions it).
|
||||
destinationPath: s3://cnpg-gitea
|
||||
endpointURL: https://s3.ceph.unkin.net
|
||||
# radosgw serves a Vault-PKI cert; trust the internal CA (reflected into
|
||||
# every namespace as the vault-ca-cert Secret).
|
||||
endpointCA:
|
||||
name: vault-ca-cert
|
||||
key: ca.crt
|
||||
# Keys minted by the ObjectStoreUser in cnpg_backup.yaml; never hardcoded.
|
||||
s3Credentials:
|
||||
accessKeyId:
|
||||
name: cnpg-gitea-backup-s3
|
||||
key: AWS_ACCESS_KEY_ID
|
||||
secretAccessKey:
|
||||
name: cnpg-gitea-backup-s3
|
||||
key: AWS_SECRET_ACCESS_KEY
|
||||
# Path prefix within the bucket; keep stable across restores (see docs).
|
||||
serverName: gitea
|
||||
data:
|
||||
compression: bzip2
|
||||
jobs: 2
|
||||
wal:
|
||||
compression: zstd
|
||||
maxParallel: 2
|
||||
bootstrap:
|
||||
initdb:
|
||||
database: gitea
|
||||
encoding: UTF8
|
||||
localeCType: C
|
||||
localeCollate: C
|
||||
owner: gitea
|
||||
secret:
|
||||
name: postgres-credentials
|
||||
enablePDB: true
|
||||
enableSuperuserAccess: false
|
||||
failoverDelay: 0
|
||||
imageName: ghcr.io/cloudnative-pg/postgresql:18.1-system-trixie
|
||||
instances: 2
|
||||
logLevel: info
|
||||
monitoring:
|
||||
customQueriesConfigMap:
|
||||
- key: queries
|
||||
name: cnpg-default-monitoring
|
||||
disableDefaultQueries: false
|
||||
enablePodMonitor: false
|
||||
postgresql:
|
||||
parameters:
|
||||
max_connections: "200"
|
||||
shared_buffers: 256MB
|
||||
primaryUpdateMethod: restart
|
||||
primaryUpdateStrategy: unsupervised
|
||||
replicationSlots:
|
||||
highAvailability:
|
||||
enabled: true
|
||||
slotPrefix: _cnpg_
|
||||
synchronizeReplicas:
|
||||
enabled: true
|
||||
updateInterval: 30
|
||||
resources:
|
||||
limits:
|
||||
cpu: "2"
|
||||
memory: 2Gi
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 512Mi
|
||||
smartShutdownTimeout: 180
|
||||
startDelay: 3600
|
||||
stopDelay: 1800
|
||||
storage:
|
||||
resizeInUseVolumes: true
|
||||
size: 20Gi
|
||||
storageClass: cephrbd-fast-delete
|
||||
switchoverDelay: 3600
|
||||
@@ -1,36 +0,0 @@
|
||||
---
|
||||
# pgbouncer in front of the primary. Gitea opens a connection per request and
|
||||
# benefits from pooling under multiple app replicas. Session mode keeps Gitea's
|
||||
# occasional session-scoped state (advisory locks, LISTEN/NOTIFY) working.
|
||||
apiVersion: postgresql.cnpg.io/v1
|
||||
kind: Pooler
|
||||
metadata:
|
||||
name: gitea-postgres-pooler-rw
|
||||
namespace: gitea
|
||||
spec:
|
||||
cluster:
|
||||
name: gitea-postgres
|
||||
instances: 2
|
||||
pgbouncer:
|
||||
parameters:
|
||||
default_pool_size: "50"
|
||||
max_client_conn: "200"
|
||||
paused: false
|
||||
poolMode: session
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: pooler-rw
|
||||
spec:
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
- labelSelector:
|
||||
matchExpressions:
|
||||
- key: app
|
||||
operator: In
|
||||
values:
|
||||
- pooler-rw
|
||||
topologyKey: kubernetes.io/hostname
|
||||
containers: []
|
||||
type: rw
|
||||
@@ -1,69 +0,0 @@
|
||||
---
|
||||
# HTTPS front for the k8s Gitea, served on two names:
|
||||
# git.unkin.net — canonical/production (apex, bind-operator zone;
|
||||
# DNS flip is the gated cutover step, see the doc)
|
||||
# git.k8s.syd1.au.unkin.net — admin/backup route (external-dns k8s.syd1 zone),
|
||||
# same dual-name pattern as identity.unkin.net.
|
||||
# The cert-manager Certificate (vault-issuer) takes CN git.unkin.net and gets a
|
||||
# DNS SAN for each TLS listener hostname automatically.
|
||||
apiVersion: gateway.networking.k8s.io/v1
|
||||
kind: Gateway
|
||||
metadata:
|
||||
name: gitea
|
||||
namespace: gitea
|
||||
labels:
|
||||
app.kubernetes.io/name: gitea
|
||||
app.kubernetes.io/instance: gitea
|
||||
traefik.io/instance: internal
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: vault-issuer
|
||||
cert-manager.io/common-name: git.unkin.net
|
||||
cert-manager.io/private-key-size: "4096"
|
||||
# Only the k8s admin route is published by external-dns (it owns just the
|
||||
# k8s.syd1.au.unkin.net zone). git.unkin.net lives in the apex zone and is
|
||||
# flipped at cutover — NOT managed here.
|
||||
external-dns.alpha.kubernetes.io/hostname: git.k8s.syd1.au.unkin.net
|
||||
external-dns.alpha.kubernetes.io/target: 198.18.200.4
|
||||
spec:
|
||||
gatewayClassName: traefik-internal
|
||||
listeners:
|
||||
- name: http-primary
|
||||
port: 80
|
||||
protocol: HTTP
|
||||
hostname: git.unkin.net
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: Same
|
||||
- name: https-primary
|
||||
port: 443
|
||||
protocol: HTTPS
|
||||
hostname: git.unkin.net
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: Same
|
||||
tls:
|
||||
mode: Terminate
|
||||
certificateRefs:
|
||||
- group: ""
|
||||
kind: Secret
|
||||
name: gitea-tls
|
||||
- name: http-admin
|
||||
port: 80
|
||||
protocol: HTTP
|
||||
hostname: git.k8s.syd1.au.unkin.net
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: Same
|
||||
- name: https-admin
|
||||
port: 443
|
||||
protocol: HTTPS
|
||||
hostname: git.k8s.syd1.au.unkin.net
|
||||
allowedRoutes:
|
||||
namespaces:
|
||||
from: Same
|
||||
tls:
|
||||
mode: Terminate
|
||||
certificateRefs:
|
||||
- group: ""
|
||||
kind: Secret
|
||||
name: gitea-tls
|
||||
@@ -1,65 +0,0 @@
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: gitea-http-redirect
|
||||
namespace: gitea
|
||||
labels:
|
||||
app.kubernetes.io/name: gitea
|
||||
app.kubernetes.io/instance: gitea
|
||||
spec:
|
||||
hostnames:
|
||||
- git.unkin.net
|
||||
- git.k8s.syd1.au.unkin.net
|
||||
parentRefs:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: Gateway
|
||||
name: gitea
|
||||
sectionName: http-primary
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: Gateway
|
||||
name: gitea
|
||||
sectionName: http-admin
|
||||
rules:
|
||||
- filters:
|
||||
- type: RequestRedirect
|
||||
requestRedirect:
|
||||
scheme: https
|
||||
statusCode: 301
|
||||
matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: gitea
|
||||
namespace: gitea
|
||||
labels:
|
||||
app.kubernetes.io/name: gitea
|
||||
app.kubernetes.io/instance: gitea
|
||||
spec:
|
||||
hostnames:
|
||||
- git.unkin.net
|
||||
- git.k8s.syd1.au.unkin.net
|
||||
parentRefs:
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: Gateway
|
||||
name: gitea
|
||||
sectionName: https-primary
|
||||
- group: gateway.networking.k8s.io
|
||||
kind: Gateway
|
||||
name: gitea
|
||||
sectionName: https-admin
|
||||
rules:
|
||||
- backendRefs:
|
||||
- group: ""
|
||||
kind: Service
|
||||
name: gitea-http
|
||||
port: 3000
|
||||
weight: 1
|
||||
matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /
|
||||
@@ -1,7 +0,0 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: gitea
|
||||
name: gitea
|
||||
@@ -1,89 +0,0 @@
|
||||
---
|
||||
# Standalone Valkey (Redis-compatible) for Gitea's session store, cache and
|
||||
# queue. The Gitea chart bundles a redis-cluster subchart, but we run our own
|
||||
# standalone Valkey here: it keeps image control in-estate (valkey/valkey,
|
||||
# already allowlisted through the artifactapi dockerhub mirror) and matches the
|
||||
# standalone-cache pattern used by litellm/netbox. One instance serves three
|
||||
# logical DBs: DB 0 = session, DB 1 = cache, DB 2 = queue. AOF persistence is
|
||||
# enabled so queued actions/webhook deliveries survive a restart.
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: gitea-valkey
|
||||
namespace: gitea
|
||||
labels:
|
||||
app.kubernetes.io/name: gitea
|
||||
app.kubernetes.io/component: valkey
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: gitea-valkey
|
||||
strategy:
|
||||
type: Recreate
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: gitea-valkey
|
||||
app.kubernetes.io/name: gitea
|
||||
app.kubernetes.io/component: valkey
|
||||
spec:
|
||||
securityContext:
|
||||
fsGroup: 999
|
||||
containers:
|
||||
- name: valkey
|
||||
image: valkey/valkey:8-alpine
|
||||
imagePullPolicy: IfNotPresent
|
||||
command:
|
||||
- valkey-server
|
||||
- --appendonly
|
||||
- "yes"
|
||||
- --save
|
||||
- "60"
|
||||
- "1"
|
||||
ports:
|
||||
- containerPort: 6379
|
||||
name: valkey
|
||||
protocol: TCP
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
runAsNonRoot: true
|
||||
runAsUser: 999
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
livenessProbe:
|
||||
exec:
|
||||
command:
|
||||
- valkey-cli
|
||||
- ping
|
||||
failureThreshold: 3
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 30
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 5
|
||||
readinessProbe:
|
||||
exec:
|
||||
command:
|
||||
- valkey-cli
|
||||
- ping
|
||||
failureThreshold: 3
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
successThreshold: 1
|
||||
timeoutSeconds: 5
|
||||
resources:
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 128Mi
|
||||
volumeMounts:
|
||||
- mountPath: /data
|
||||
name: data
|
||||
restartPolicy: Always
|
||||
volumes:
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: gitea-valkey-data
|
||||
@@ -1,20 +0,0 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: gitea-valkey
|
||||
namespace: gitea
|
||||
labels:
|
||||
app.kubernetes.io/name: gitea
|
||||
app.kubernetes.io/component: valkey
|
||||
spec:
|
||||
internalTrafficPolicy: Cluster
|
||||
ports:
|
||||
- name: valkey
|
||||
port: 6379
|
||||
protocol: TCP
|
||||
targetPort: valkey
|
||||
selector:
|
||||
app: gitea-valkey
|
||||
sessionAffinity: None
|
||||
type: ClusterIP
|
||||
@@ -1,18 +0,0 @@
|
||||
---
|
||||
apiVersion: secrets.hashicorp.com/v1beta1
|
||||
kind: VaultAuth
|
||||
metadata:
|
||||
name: default
|
||||
namespace: gitea
|
||||
spec:
|
||||
allowedNamespaces:
|
||||
- gitea
|
||||
kubernetes:
|
||||
audiences:
|
||||
- vault
|
||||
role: default
|
||||
serviceAccount: default
|
||||
tokenExpirationSeconds: 600
|
||||
method: kubernetes
|
||||
mount: k8s/au/syd1
|
||||
vaultConnectionRef: vso-system/default
|
||||
@@ -1,83 +0,0 @@
|
||||
---
|
||||
# CNPG app-user credentials (keys: username, password). Consumed by the Cluster
|
||||
# bootstrap (initdb.secret) AND by Gitea (gitea.config.database.PASSWD via the
|
||||
# chart's existingSecret wiring). One-time Vault seed — see the PR description.
|
||||
apiVersion: secrets.hashicorp.com/v1beta1
|
||||
kind: VaultStaticSecret
|
||||
metadata:
|
||||
name: postgres-credentials
|
||||
namespace: gitea
|
||||
spec:
|
||||
destination:
|
||||
create: true
|
||||
name: postgres-credentials
|
||||
overwrite: true
|
||||
hmacSecretData: true
|
||||
mount: kv
|
||||
path: kubernetes/namespace/gitea/default/postgres-credentials
|
||||
refreshAfter: 5m
|
||||
type: kv-v2
|
||||
vaultAuthRef: default
|
||||
---
|
||||
# Initial Gitea admin (keys: username, password, email). Applied by the chart's
|
||||
# init job on first boot (gitea.admin.existingSecret). Local fallback account
|
||||
# that survives the Authentik OIDC cutover. One-time Vault seed.
|
||||
apiVersion: secrets.hashicorp.com/v1beta1
|
||||
kind: VaultStaticSecret
|
||||
metadata:
|
||||
name: gitea-admin
|
||||
namespace: gitea
|
||||
spec:
|
||||
destination:
|
||||
create: true
|
||||
name: gitea-admin
|
||||
overwrite: true
|
||||
hmacSecretData: true
|
||||
mount: kv
|
||||
path: kubernetes/namespace/gitea/default/gitea-admin
|
||||
refreshAfter: 5m
|
||||
type: kv-v2
|
||||
vaultAuthRef: default
|
||||
---
|
||||
# Gitea internal secrets (keys: SECRET_KEY, INTERNAL_TOKEN). Pinned here rather
|
||||
# than chart-generated so all replicas share identical values AND so the data
|
||||
# cutover can replace them with the VM's app.ini values (SECRET_KEY encrypts
|
||||
# 2FA/mirror/oauth secrets in the DB — it MUST match the restored database).
|
||||
# One-time Vault seed.
|
||||
apiVersion: secrets.hashicorp.com/v1beta1
|
||||
kind: VaultStaticSecret
|
||||
metadata:
|
||||
name: gitea-inner
|
||||
namespace: gitea
|
||||
spec:
|
||||
destination:
|
||||
create: true
|
||||
name: gitea-inner
|
||||
overwrite: true
|
||||
hmacSecretData: true
|
||||
mount: kv
|
||||
path: kubernetes/namespace/gitea/default/gitea-inner
|
||||
refreshAfter: 5m
|
||||
type: kv-v2
|
||||
vaultAuthRef: default
|
||||
---
|
||||
# Authentik OIDC client secret (key: client_secret). Read by the
|
||||
# terraform-authentik provider runner (policy already grants
|
||||
# kv/.../namespace/+/default/oauth-credentials) AND mounted into Gitea to
|
||||
# register the OIDC login source. One-time Vault seed.
|
||||
apiVersion: secrets.hashicorp.com/v1beta1
|
||||
kind: VaultStaticSecret
|
||||
metadata:
|
||||
name: oauth-credentials
|
||||
namespace: gitea
|
||||
spec:
|
||||
destination:
|
||||
create: true
|
||||
name: oauth-credentials
|
||||
overwrite: true
|
||||
hmacSecretData: true
|
||||
mount: kv
|
||||
path: kubernetes/namespace/gitea/default/oauth-credentials
|
||||
refreshAfter: 5m
|
||||
type: kv-v2
|
||||
vaultAuthRef: default
|
||||
@@ -1,56 +0,0 @@
|
||||
---
|
||||
# Ceph RGW (S3) backup target for the grafana CNPG cluster, provisioned by the
|
||||
# in-estate cephrgw-operator. One dedicated bucket + owner user per cluster:
|
||||
# cephrgw CRs are namespace-scoped and CNPG reads its S3 credential Secret from
|
||||
# its own namespace, so backups are per-database rather than one shared bucket.
|
||||
apiVersion: ceph.unkin.net/v1alpha1
|
||||
kind: ObjectStoreUser
|
||||
metadata:
|
||||
name: cnpg-grafana-backup
|
||||
namespace: grafana
|
||||
spec:
|
||||
displayName: "CNPG backup owner (grafana)"
|
||||
# RGW users are global; keep the uid namespace-qualified so it never collides.
|
||||
uid: cnpg-grafana-backup
|
||||
maxBuckets: 5
|
||||
# Operator writes AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY (+ RGW_UID,
|
||||
# S3_ENDPOINT) into this Secret; the Cluster's barmanObjectStore consumes it.
|
||||
secretName: cnpg-grafana-backup-s3
|
||||
# Keep the RGW user (and thus the keys) if this CR is ever deleted, so an
|
||||
# in-flight restore can still reach the archive.
|
||||
retainOnDelete: true
|
||||
---
|
||||
apiVersion: ceph.unkin.net/v1alpha1
|
||||
kind: Bucket
|
||||
metadata:
|
||||
name: cnpg-grafana
|
||||
namespace: grafana
|
||||
spec:
|
||||
placementTarget: ec
|
||||
bucketName: cnpg-grafana
|
||||
# The owner user has full control of its own bucket (read + write), which is
|
||||
# all the backup/restore identity needs — no extra BucketAccess grant.
|
||||
ownerRef: cnpg-grafana-backup
|
||||
versioning: false
|
||||
tags:
|
||||
app: grafana
|
||||
purpose: cnpg-backup
|
||||
# Never drop the backups if the CR is removed; retire buckets by hand.
|
||||
retainOnDelete: true
|
||||
---
|
||||
# Nightly base backup. Continuous WAL archiving is always-on via the Cluster's
|
||||
# spec.backup.barmanObjectStore; this schedules the periodic full backup that
|
||||
# WAL is layered on top of. Schedules are staggered across clusters so the 8
|
||||
# base backups do not hit RGW at once (CNPG cron is 6-field, seconds first).
|
||||
apiVersion: postgresql.cnpg.io/v1
|
||||
kind: ScheduledBackup
|
||||
metadata:
|
||||
name: cnpg-grafana-nightly
|
||||
namespace: grafana
|
||||
spec:
|
||||
schedule: "0 20 3 * * *"
|
||||
immediate: false
|
||||
backupOwnerReference: self
|
||||
method: barmanObjectStore
|
||||
cluster:
|
||||
name: postgres
|
||||
@@ -1,87 +0,0 @@
|
||||
---
|
||||
apiVersion: postgresql.cnpg.io/v1
|
||||
kind: Cluster
|
||||
metadata:
|
||||
name: postgres
|
||||
namespace: grafana
|
||||
spec:
|
||||
affinity:
|
||||
podAntiAffinityType: preferred
|
||||
backup:
|
||||
# 30-day retention (DEFAULT — adjust per cluster if needed). Enforced by CNPG
|
||||
# against the object store on each successful base backup.
|
||||
retentionPolicy: 30d
|
||||
barmanObjectStore:
|
||||
# Dedicated per-cluster Ceph RGW bucket (cephrgw-operator provisions it).
|
||||
destinationPath: s3://cnpg-grafana
|
||||
endpointURL: https://s3.ceph.unkin.net
|
||||
# radosgw serves a Vault-PKI cert; trust the internal CA (reflected into
|
||||
# every namespace as the vault-ca-cert Secret).
|
||||
endpointCA:
|
||||
name: vault-ca-cert
|
||||
key: ca.crt
|
||||
# Keys minted by the ObjectStoreUser in cnpg_backup.yaml; never hardcoded.
|
||||
s3Credentials:
|
||||
accessKeyId:
|
||||
name: cnpg-grafana-backup-s3
|
||||
key: AWS_ACCESS_KEY_ID
|
||||
secretAccessKey:
|
||||
name: cnpg-grafana-backup-s3
|
||||
key: AWS_SECRET_ACCESS_KEY
|
||||
# Path prefix within the bucket; keep stable across restores (see docs).
|
||||
serverName: grafana
|
||||
data:
|
||||
compression: bzip2
|
||||
jobs: 2
|
||||
wal:
|
||||
compression: zstd
|
||||
maxParallel: 2
|
||||
bootstrap:
|
||||
initdb:
|
||||
database: grafana
|
||||
encoding: UTF8
|
||||
localeCType: C
|
||||
localeCollate: C
|
||||
owner: grafana
|
||||
secret:
|
||||
name: postgres-credentials
|
||||
enablePDB: true
|
||||
enableSuperuserAccess: false
|
||||
failoverDelay: 0
|
||||
imageName: ghcr.io/cloudnative-pg/postgresql:18.1-system-trixie
|
||||
instances: 2
|
||||
logLevel: info
|
||||
monitoring:
|
||||
customQueriesConfigMap:
|
||||
- key: queries
|
||||
name: cnpg-default-monitoring
|
||||
disableDefaultQueries: false
|
||||
enablePodMonitor: false
|
||||
postgresql:
|
||||
parameters:
|
||||
max_connections: "200"
|
||||
shared_buffers: 128MB
|
||||
primaryUpdateMethod: restart
|
||||
primaryUpdateStrategy: unsupervised
|
||||
replicationSlots:
|
||||
highAvailability:
|
||||
enabled: true
|
||||
slotPrefix: _cnpg_
|
||||
synchronizeReplicas:
|
||||
enabled: true
|
||||
updateInterval: 30
|
||||
resources:
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 256Mi
|
||||
smartShutdownTimeout: 180
|
||||
startDelay: 3600
|
||||
stopDelay: 1800
|
||||
storage:
|
||||
resizeInUseVolumes: true
|
||||
size: 10Gi
|
||||
storageClass: cephrbd-fast-delete
|
||||
switchoverDelay: 3600
|
||||
@@ -1,33 +0,0 @@
|
||||
---
|
||||
apiVersion: postgresql.cnpg.io/v1
|
||||
kind: Pooler
|
||||
metadata:
|
||||
name: postgres-pooler-rw
|
||||
namespace: grafana
|
||||
spec:
|
||||
cluster:
|
||||
name: postgres
|
||||
instances: 2
|
||||
pgbouncer:
|
||||
parameters:
|
||||
default_pool_size: "50"
|
||||
max_client_conn: "200"
|
||||
paused: false
|
||||
poolMode: session
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: pooler-rw
|
||||
spec:
|
||||
affinity:
|
||||
podAntiAffinity:
|
||||
requiredDuringSchedulingIgnoredDuringExecution:
|
||||
- labelSelector:
|
||||
matchExpressions:
|
||||
- key: app
|
||||
operator: In
|
||||
values:
|
||||
- pooler-rw
|
||||
topologyKey: kubernetes.io/hostname
|
||||
containers: []
|
||||
type: rw
|
||||
@@ -1,13 +0,0 @@
|
||||
---
|
||||
apiVersion: grafana.integreatly.org/v1beta1
|
||||
kind: GrafanaDashboard
|
||||
metadata:
|
||||
name: bind9-exporter-dns
|
||||
namespace: grafana
|
||||
spec:
|
||||
instanceSelector:
|
||||
matchLabels:
|
||||
dashboards: "grafana"
|
||||
resyncPeriod: 5m
|
||||
allowCrossNamespaceImport: false
|
||||
gzipJson: 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
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,13 +0,0 @@
|
||||
---
|
||||
apiVersion: grafana.integreatly.org/v1beta1
|
||||
kind: GrafanaDashboard
|
||||
metadata:
|
||||
name: frr-ospf-route-metrics
|
||||
namespace: grafana
|
||||
spec:
|
||||
instanceSelector:
|
||||
matchLabels:
|
||||
dashboards: "grafana"
|
||||
resyncPeriod: 5m
|
||||
allowCrossNamespaceImport: false
|
||||
gzipJson: H4sIAAycS2oC/+1ZbW/bNhD+KwJRFC0gF7brZkGAfXDcZgiQpkFcbNiawqCkk82FJjWScuIK/u+7o14sN0lXB0nRJfliS5TIe+655046sWBcKe24E1pZtlcwKaxje58KFuVCukPF9nohS7jjVucmBrrFLTP8Z1PDU644C1kuEjzvdILfyqGg02GrkIHikcQ7nckhZDORNMci1mqkpTY4zUwj/qIbBv1eD3/evAmD3ktcU/E5GRmu0QXPg6EE4yxerSAk3M4izU3CVp/JYCJc22QqbMzln8DN2HHj3mvlZmyvGxL0bPZRa+lE5gekUOfo/qfPIcu4Amk9BakAmYy0SsWU/E4g5bl0nqY5zzKhptUcNzNgZ1om5TVNnjIeWS1zBwjXOsjKJePK66kBUHhlwWWON3dX4fqagWR9ZbeLrqFvegHGIIXe4opcEMmJ9vbQp9chu2B7g5BdeneWfkVGYcHo6ayJrjfxvsRXGqjIqMaUVjT0d26dSJfVYAzKgcFhbQQe+miQf7nTOJiBoRtGM66mMGqtbx1XCcUmJI/yGD60cHAZkydMcpTb57CkGkdY7Tkep1xaQDeQ2YuTtpXqEvIOl66yVqHZPhLEdpv9ryLT88q6QOaP+FLnrtQWDmUynwr1Oxhb0tHrv+q96hIEbqbgSiPtxGHPWmco1suMzKXGTNC0hNhpM8mzojn59Yxpm6VnLBSKuIwBR57Vx2ds5YlNDyn3hpgAaFk4Ej/7MD45CEb1OgGK3+WtrMEFnHf5/6nvwYa+d7bSNzfAr+i7ks49qftYu+NcyrsU+f2q0eC6MHFYduUkFVHBU4HCE9ligFJcmJRUiH+30OXhyWIQnNLyNhAqODjcfzCi3N0Q5S9PovxRoty5A1HuPFBRlpXydSXKwZMo70+U91MlH1h5rJX45kmJP0KJd1kat1NipZpGdhmX4Bx0YiTXipiawxjDqed0D78Udl+bBMwY+WwopOGR7zwg+QuM3rzQiipxzcrhIx6BLGNFpyeSxzDHNdZhiLgZSjFV5WjXD/whEjc74PSujEOv8I0yMfxi7JaeBGwNiexUSPkh47FwKORe2UMmJL7Nzom63ANTOiZhCipZa6LuN6vzhfiylhKGA1tbEp1tbiDLh0RApmUtcRrj1IvRgQfO9vooJS2UG4sv4JOLul54i428EVFeTmy69mqBWr00j9StYOFbPIvt7yYKjHd8jmWF1piizjIvk7AOrfd71S43FXFN8HWaMqoWP1l52vXlqd9t9cw7VX3qb9SnOozrGoHwE2Ezyetq5D+aUEKv9RZpR/ouaT6qlqgSv1FC4fVC6l7zXVFhkSrpidDGNTzfbdWg9nKiQEzxI4qxxXfWipKPA23mnIAVhUjR7dV/tKPHtZkgWgZe1TRrXVacmAOmgMBoPaLikpX591V5+amqS+8OqkvFz6MuLr1BVV1eP6bqQi9vE2n5ROXzCEzx3WXlI73LBEfjYVAUtMjX9SW8JQxwF9qcbw3nuJx3E6D9WwPiNjJboxmO909vgjK6PTf2FnE6HiOMG6C83RYKocCCC0Zhmx/rnMrT90N5V80kOC0U764+jAjviJa3Tw+gpwfQQ3wA7Vx9APX71QNo95E8gGyMXxFgkuTGy2tiAbcdE1ts8WrbbMZ84/X24PS0vdnijQZvK6PX1xfaZjQgNV+nD65NkiGPu5SPNp7BnDc8DHrEgJcXGcQbqJDhH7XnpF8CBPOMMqlUc7ORG+fG+KAVPhFjmScwxI8bteVqp3WDxX9yMEsqD5jr4Gbgt48aiL3WBmwzyQu2MVXWLYwzEC9BTfNaxozS6htxvBloa60apqTKOCk/z7y42tmEjf2X17tRrnO9B1XlbyGvR27rADZY22DH278Nm7Kf1JWJ+BxMGWc6/0I5halq9IX1zX1bsf45+Lz8uhO8B6ylsW228hFGh2B0TP3xZ1ELsb/6F7MoRVUzIAAA
|
||||
@@ -1,13 +0,0 @@
|
||||
---
|
||||
apiVersion: grafana.integreatly.org/v1beta1
|
||||
kind: GrafanaDashboard
|
||||
metadata:
|
||||
name: gitea
|
||||
namespace: grafana
|
||||
spec:
|
||||
instanceSelector:
|
||||
matchLabels:
|
||||
dashboards: "grafana"
|
||||
resyncPeriod: 5m
|
||||
allowCrossNamespaceImport: false
|
||||
gzipJson: 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
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user