initial: yandex-prod gitops infrastructure

Gitea + ArgoCD + cert-manager + Traefik + CNPG + monitoring + loki + alloy
Matrix homeservers for mrt0rtikize.ru, t0rt1k.tech, roglog.space
This commit is contained in:
Alexander Rogov
2026-06-26 19:05:55 +03:00
commit 85c9bafbc2
38 changed files with 2241 additions and 0 deletions

22
argocd/app-of-apps.yaml Normal file
View File

@@ -0,0 +1,22 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: root-app
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
repoURL: http://gitea.gitea.svc.cluster.local:3000/admin/main.git
targetRevision: master
path: argocd/apps
directory:
recurse: true
include: "*.yaml"
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
syncOptions:
- CreateNamespace=true

103
argocd/apps/alloy.yaml Normal file
View File

@@ -0,0 +1,103 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: alloy
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "0"
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
repoURL: https://grafana.github.io/helm-charts
chart: alloy
targetRevision: ">=1.5.0"
helm:
values: |
alloy:
configMap:
content: |-
// Discover Kubernetes pods
discovery.kubernetes "pods" {
role = "pod"
}
// Relabel pods to intelligently map existing Kubernetes labels to service/component
discovery.relabel "pods" {
targets = discovery.kubernetes.pods.targets
// Create service label - try multiple sources in priority order
rule {
source_labels = ["__meta_kubernetes_pod_label_app_kubernetes_io_name"]
regex = "(.+)"
replacement = "${1}"
target_label = "service"
}
// 2. Second priority: app label
rule {
source_labels = ["__meta_kubernetes_pod_label_app", "service"]
regex = "^(.+);$"
replacement = "${1}"
target_label = "service"
}
// 3. Third priority: extract from pod name (remove hash suffix)
rule {
source_labels = ["__meta_kubernetes_pod_name", "service"]
regex = "^([a-z0-9-]+?)(?:-[a-f0-9]{5,10})?;$"
replacement = "${1}"
target_label = "service"
}
// Create component label from app.kubernetes.io/component or component label
rule {
source_labels = ["__meta_kubernetes_pod_label_app_kubernetes_io_component"]
regex = ".+"
target_label = "component"
}
rule {
source_labels = ["__meta_kubernetes_pod_label_component"]
regex = ".+"
target_label = "component"
}
// Drop pods that we still can't identify
rule {
source_labels = ["service"]
regex = "^$"
action = "drop"
}
// Map standard Kubernetes metadata to Loki labels
rule {
source_labels = ["__meta_kubernetes_namespace"]
target_label = "namespace"
}
rule {
source_labels = ["__meta_kubernetes_pod_name"]
target_label = "pod"
}
rule {
source_labels = ["__meta_kubernetes_pod_container_name"]
target_label = "container"
}
}
// Collect logs from Kubernetes pods using the Kubernetes API
loki.source.kubernetes "pods" {
targets = discovery.relabel.pods.output
forward_to = [loki.write.loki.receiver]
}
// Write logs to Loki
loki.write "loki" {
endpoint {
url = "http://loki.metrics.svc.cluster.local:3100/loki/api/v1/push"
}
}
destination:
server: https://kubernetes.default.svc
namespace: metrics
syncPolicy:
syncOptions:
- CreateNamespace=true

View File

@@ -0,0 +1,22 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: cert-manager-issuers
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "0"
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
repoURL: http://gitea.gitea.svc.cluster.local:3000/admin/main.git
targetRevision: master
path: manifests/cert-manager
directory:
recurse: true
include: "*.yaml"
destination:
server: https://kubernetes.default.svc
namespace: cert-manager
syncPolicy: {}

View File

@@ -0,0 +1,24 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: cert-manager
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "-1"
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
repoURL: https://charts.jetstack.io
chart: cert-manager
targetRevision: ">=1.18.0"
helm:
values: |
installCRDs: true
destination:
server: https://kubernetes.default.svc
namespace: cert-manager
syncPolicy:
syncOptions:
- CreateNamespace=true

View File

@@ -0,0 +1,24 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: cnpg-cluster
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "1"
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
repoURL: http://gitea.gitea.svc.cluster.local:3000/admin/main.git
targetRevision: master
path: manifests/cnpg
directory:
recurse: true
include: "*.yaml"
destination:
server: https://kubernetes.default.svc
namespace: cnpg
syncPolicy:
syncOptions:
- CreateNamespace=true

View File

@@ -0,0 +1,20 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: cnpg-operator
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
repoURL: https://cloudnative-pg.github.io/charts
chart: cloudnative-pg
targetRevision: ">=0.23.0"
destination:
server: https://kubernetes.default.svc
namespace: cnpg-system
syncPolicy:
syncOptions:
- CreateNamespace=true
- ServerSideApply=true

92
argocd/apps/loki.yaml Normal file
View File

@@ -0,0 +1,92 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: loki
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "0"
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
repoURL: https://grafana.github.io/helm-charts
chart: loki
targetRevision: ">=6.0.0"
helm:
values: |
deploymentMode: SingleBinary
write:
replicas: 0
read:
replicas: 0
backend:
replicas: 0
loki:
auth_enabled: false
storage:
bucketNames:
chunks: chunks
ruler: ruler
admin: admin
type: filesystem
filesystem:
chunks_directory: /var/loki/chunks
rules_directory: /var/loki/rules
structuredConfig:
auth_enabled: false
server:
http_listen_port: 3100
grpc_listen_port: 9095
common:
path_prefix: /var/loki
replication_factor: 1
schema_config:
configs:
- from: "2025-01-01"
store: tsdb
object_store: filesystem
schema: v13
index:
prefix: index_
period: 24h
limits_config:
retention_period: 30d
reject_old_samples: true
reject_old_samples_max_age: 168h
chunksCache:
enabled: false
resultsCache:
enabled: false
gateway:
enabled: false
test:
enabled: false
lokiCanary:
enabled: false
singleBinary:
replicas: 1
persistence:
enabled: true
size: 20Gi
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 1Gi
destination:
server: https://kubernetes.default.svc
namespace: metrics
syncPolicy:
syncOptions:
- CreateNamespace=true

View File

@@ -0,0 +1,89 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: matrix-mrt0rtikize
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
sources:
- repoURL: http://gitea.gitea.svc.cluster.local:3000/admin/main.git
targetRevision: master
path: manifests/matrix-mrt0rtikize
directory:
recurse: true
include: "*.yaml"
- repoURL: ghcr.io
chart: element-hq/ess-helm/matrix-stack
targetRevision: 26.6.1
helm:
values: |
serverName: mrt0rtikize.ru
certManager:
clusterIssuer: letsencrypt-production
ingress:
className: traefik
postgres:
enabled: false
synapse:
postgres:
host: shared-pg-rw.cnpg.svc.cluster.local
database: synapse_mrt0rtikize
user: synapse_mrt0rtikize
password:
secret: pg-creds
secretKey: synapse
media:
storage:
size: 10Gi
ingress:
host: matrix.mrt0rtikize.ru
matrixAuthenticationService:
postgres:
host: shared-pg-rw.cnpg.svc.cluster.local
database: mas_mrt0rtikize
user: mas_mrt0rtikize
password:
secret: pg-creds
secretKey: mas
ingress:
host: account.mrt0rtikize.ru
elementWeb:
ingress:
host: chat.mrt0rtikize.ru
elementAdmin:
ingress:
host: admin.mrt0rtikize.ru
matrixRTC:
ingress:
host: mrtc.mrt0rtikize.ru
sfu:
manualIP: "81.26.181.240"
useStunToDiscoverPublicIP: false
exposedServices:
rtcTcp:
port: 30009
portType: NodePort
nodePort: ""
rtcMuxedUdp:
port: 30008
portType: NodePort
nodePort: ""
hookshot:
enabled: true
destination:
server: https://kubernetes.default.svc
namespace: matrix-mrt0rtikize
syncPolicy:
syncOptions:
- CreateNamespace=true

View File

@@ -0,0 +1,89 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: matrix-roglog
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
sources:
- repoURL: http://gitea.gitea.svc.cluster.local:3000/admin/main.git
targetRevision: master
path: manifests/matrix-roglog
directory:
recurse: true
include: "*.yaml"
- repoURL: ghcr.io
chart: element-hq/ess-helm/matrix-stack
targetRevision: 26.6.1
helm:
values: |
serverName: roglog.space
certManager:
clusterIssuer: letsencrypt-production
ingress:
className: traefik
postgres:
enabled: false
synapse:
postgres:
host: shared-pg-rw.cnpg.svc.cluster.local
database: synapse_roglog
user: synapse_roglog
password:
secret: pg-creds
secretKey: synapse
media:
storage:
size: 10Gi
ingress:
host: matrix.roglog.space
matrixAuthenticationService:
postgres:
host: shared-pg-rw.cnpg.svc.cluster.local
database: mas_roglog
user: mas_roglog
password:
secret: pg-creds
secretKey: mas
ingress:
host: auth.roglog.space
elementWeb:
ingress:
host: chat.roglog.space
elementAdmin:
ingress:
host: admin.roglog.space
matrixRTC:
ingress:
host: rtc.roglog.space
sfu:
manualIP: "81.26.181.240"
useStunToDiscoverPublicIP: false
exposedServices:
rtcTcp:
port: 30005
portType: NodePort
nodePort: ""
rtcMuxedUdp:
port: 30004
portType: NodePort
nodePort: ""
hookshot:
enabled: true
destination:
server: https://kubernetes.default.svc
namespace: matrix-roglog
syncPolicy:
syncOptions:
- CreateNamespace=true

View File

@@ -0,0 +1,160 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: matrix-t0rt1k
namespace: argocd
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
sources:
- repoURL: http://gitea.gitea.svc.cluster.local:3000/admin/main.git
targetRevision: master
path: manifests/matrix-t0rt1k
directory:
recurse: true
include: "*.yaml"
- repoURL: ghcr.io
chart: element-hq/ess-helm/matrix-stack
targetRevision: 26.6.1
helm:
values: |
serverName: t0rt1k.tech
certManager:
clusterIssuer: letsencrypt-production
ingress:
className: traefik
postgres:
enabled: false
synapse:
postgres:
host: shared-pg-rw.cnpg.svc.cluster.local
database: synapse_t0rt1k
user: synapse_t0rt1k
password:
secret: pg-creds
secretKey: synapse
media:
storage:
size: 10Gi
ingress:
host: matrix.t0rt1k.tech
resources:
requests:
memory: 256Mi
cpu: 100m
limits:
memory: 1.5Gi
workers:
federation-sender:
enabled: true
resources:
requests:
memory: 192Mi
cpu: 50m
limits:
memory: 256Mi
federation-reader:
enabled: true
resources:
requests:
memory: 128Mi
cpu: 50m
limits:
memory: 256Mi
client-reader:
enabled: true
replicas: 1
resources:
requests:
memory: 128Mi
cpu: 50m
limits:
memory: 256Mi
initial-synchrotron:
enabled: true
resources:
requests:
memory: 128Mi
cpu: 50m
limits:
memory: 256Mi
synchrotron:
enabled: true
replicas: 1
resources:
requests:
memory: 128Mi
cpu: 50m
limits:
memory: 256Mi
additional:
0-federation-retry:
config: |
destination_min_retry_interval: "1m"
destination_retry_multiplier: 1.5
destination_max_retry_interval: "1d"
matrixAuthenticationService:
postgres:
host: shared-pg-rw.cnpg.svc.cluster.local
database: mas_t0rt1k
user: mas_t0rt1k
password:
secret: pg-creds
secretKey: mas
ingress:
host: auth.t0rt1k.tech
resources:
limits:
memory: 128Mi
elementWeb:
ingress:
host: chat.t0rt1k.tech
elementAdmin:
ingress:
host: admin.t0rt1k.tech
matrixRTC:
ingress:
host: rtc.t0rt1k.tech
sfu:
manualIP: "81.26.181.240"
useStunToDiscoverPublicIP: false
exposedServices:
rtcTcp:
port: 30007
portType: NodePort
nodePort: ""
rtcMuxedUdp:
port: 30006
portType: NodePort
nodePort: ""
resources:
requests:
memory: 64Mi
cpu: 50m
limits:
memory: 512Mi
hookshot:
enabled: true
resources:
limits:
memory: 256Mi
ingress:
host: hookshot.t0rt1k.tech
className: traefik
tlsEnabled: true
destination:
server: https://kubernetes.default.svc
namespace: matrix-t0rt1k
syncPolicy:
syncOptions:
- CreateNamespace=true

142
argocd/apps/monitoring.yaml Normal file
View File

@@ -0,0 +1,142 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: monitoring
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "0"
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
sources:
- repoURL: http://gitea.gitea.svc.cluster.local:3000/admin/main.git
targetRevision: master
path: manifests/metrics/grafana
directory:
recurse: true
include: "*.yaml"
- repoURL: https://victoriametrics.github.io/helm-charts/
chart: victoria-metrics-k8s-stack
targetRevision: ">=0.30.0"
helm:
values: |
fullnameOverride: vm-k8s-stack
namespaceOverride: metrics
victoria-metrics-operator:
resources:
requests:
memory: 128Mi
cpu: 25m
limits:
memory: 256Mi
defaultDashboards:
dashboards:
node-exporter-full:
enabled: false
vmsingle:
enabled: true
spec:
retentionPeriod: "30d"
replicaCount: 1
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
cpu: 500m
memory: 1Gi
storage:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 30Gi
alertmanager:
enabled: true
spec:
replicaCount: 1
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
cpu: 200m
memory: 512Mi
storage:
volumeClaimTemplate:
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
config:
route:
receiver: blackhole
receivers:
- name: blackhole
grafana:
enabled: true
adminUser: admin
adminPassword: change-me
persistence:
enabled: true
size: 2Gi
resources:
requests:
cpu: 50m
memory: 256Mi
limits:
cpu: 200m
memory: 512Mi
prometheus-node-exporter:
enabled: true
kube-state-metrics:
enabled: true
kubelet:
enabled: true
kubeApiServer:
enabled: false
kubeControllerManager:
enabled: false
kubeScheduler:
enabled: false
kubeProxy:
enabled: false
kubeEtcd:
enabled: false
destination:
server: https://kubernetes.default.svc
namespace: metrics
ignoreDifferences:
- group: operator.victoriametrics.com
kind: VMAlertmanager
jsonPointers:
- /spec/config
- kind: Secret
name: monitoring-victoria-metrics-operator-validation
jsonPointers:
- /data
- kind: ValidatingWebhookConfiguration
name: monitoring-victoria-metrics-operator-admission
jsonPointers:
- /webhooks/0/clientConfig/caBundle
syncPolicy:
syncOptions:
- CreateNamespace=true

139
argocd/apps/traefik.yaml Normal file
View File

@@ -0,0 +1,139 @@
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: traefik
namespace: argocd
annotations:
argocd.argoproj.io/sync-wave: "-2"
finalizers:
- resources-finalizer.argocd.argoproj.io
spec:
project: default
source:
repoURL: https://traefik.github.io/charts
chart: traefik
targetRevision: ">=37.0.0"
helm:
values: |
deployment:
kind: DaemonSet
podAnnotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9100"
ingressClass:
enabled: true
isDefaultClass: true
additionalArguments:
- "--api.dashboard=true"
- "--ping=true"
- "--metrics.prometheus=true"
- "--metrics.prometheus.entrypoint=metrics"
- "--entryPoints.ssh.address=:2222/tcp"
- "--entryPoints.rtc-tcp-mrt0rtikize.address=:30009/tcp"
- "--entryPoints.rtc-udp-mrt0rtikize.address=:30008/udp"
- "--entryPoints.rtc-tcp-t0rt1k.address=:30007/tcp"
- "--entryPoints.rtc-udp-t0rt1k.address=:30006/udp"
- "--entryPoints.rtc-tcp-roglog.address=:30005/tcp"
- "--entryPoints.rtc-udp-roglog.address=:30004/udp"
- "--providers.kubernetesingress.ingressclass=traefik"
- "--providers.kubernetesingress.ingressendpoint.publishedservice=traefik/traefik"
- "--accesslog=true"
- "--log.level=INFO"
ports:
web:
port: 8080
exposedPort: 80
http:
redirections:
entryPoint:
to: websecure
scheme: https
permanent: true
websecure:
port: 8443
exposedPort: 443
ssh:
port: 2222
exposedPort: 22
protocol: TCP
expose:
default: true
rtc-tcp-mrt0rtikize:
port: 30009
exposedPort: 30009
protocol: TCP
expose:
default: true
rtc-udp-mrt0rtikize:
port: 30008
exposedPort: 30008
protocol: UDP
expose:
default: true
rtc-tcp-t0rt1k:
port: 30007
exposedPort: 30007
protocol: TCP
expose:
default: true
rtc-udp-t0rt1k:
port: 30006
exposedPort: 30006
protocol: UDP
expose:
default: true
rtc-tcp-roglog:
port: 30005
exposedPort: 30005
protocol: TCP
expose:
default: true
rtc-udp-roglog:
port: 30004
exposedPort: 30004
protocol: UDP
expose:
default: true
metrics:
port: 9100
expose:
default: false
traefik:
port: 9000
expose:
default: false
service:
type: LoadBalancer
annotations:
service.beta.kubernetes.io/yandex-load-balancer-name: traefik
service.beta.kubernetes.io/yandex-load-balancer-specification: '{"type": "network-load-balancer"}'
service.beta.kubernetes.io/yandex-load-balancer-type: external
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
destination:
server: https://kubernetes.default.svc
namespace: traefik
syncPolicy:
syncOptions:
- CreateNamespace=true