This commit is contained in:
Alexander Rogov
2026-06-12 17:55:07 +03:00
commit 589cadd8fc
25 changed files with 1130 additions and 0 deletions

308
BOOTSTRAP.md Normal file
View File

@@ -0,0 +1,308 @@
# Yandex Cloud Production Cluster — Bootstrap Guide
## Prerequisites
- [ ] `kubeconfig` file placed at `~/infra/yandex-prod/kubeconfig`
- [ ] `kubectl` context pointing to the new `yc-prod` cluster
- [ ] Domain `prod.t01tt.tech` DNS managed (can be updated later in Phase 5)
- [ ] `git` and `helm` installed locally
---
## Phase 0: Verify Cluster Access
```bash
export KUBECONFIG=~/infra/yandex-prod/kubeconfig
kubectl get nodes
# Expected: 3 nodes Ready, 2CPU/8GB each
kubectl get sc
# Expected: yc-network-hdd (default), yc-network-ssd, yc-network-nvme, ...
```
---
## Phase 1: Bootstrap Gitea (internal access only)
Gitea hosts the Git repo that ArgoCD reads. Deploy it first, but without ingress — we access it via port-forward.
```bash
kubectl apply -f bootstrap/gitea/namespace.yaml
kubectl apply -f bootstrap/gitea/pvc.yaml
kubectl apply -f bootstrap/gitea/deployment.yaml
kubectl apply -f bootstrap/gitea/service.yaml
# NOTE: Do NOT apply ingress.yaml yet — no Traefik or cert-manager exists
```
Wait for Gitea to be ready, then port-forward and configure:
```bash
kubectl wait deploy/gitea -n gitea --for=condition=available --timeout=120s
# Port-forward in a separate terminal:
kubectl port-forward svc/gitea 3000:3000 -n gitea
```
1. Open **http://localhost:3000** in a browser
2. Fill out the install form:
- Database: **SQLite3** (default)
- Site Title: **Gitea**
- Domain: **git.prod.t01tt.tech**
- Application URL: **https://git.prod.t01tt.tech**
- Create admin account (username/password/email — save these)
3. Click "Install Gitea"
4. Create a new repository: **`yandex-prod`** (must be **public**, owned by admin)
5. Close the port-forward (Ctrl+C)
---
## Phase 2: Push Repository to Gitea
```bash
cd ~/infra/yandex-prod
git init
git remote add origin http://localhost:3000/<admin-user>/yandex-prod.git
# Or, once Gitea ingress works later, use:
# git remote add origin https://git.prod.t01tt.tech/<admin-user>/yandex-prod.git
git add -A
git commit -m "initial bootstrap: infrastructure manifests"
git push -u origin main
# Enter Gitea admin credentials when prompted
```
---
## Phase 3: Install ArgoCD (internal access only)
```bash
bash bootstrap/argocd/install.sh
# Saves the admin password — copy it
```
Add the Gitea repository to ArgoCD:
```bash
# Via port-forward:
kubectl port-forward svc/argocd-server 8080:80 -n argocd &
sleep 2
# Login and add repo:
ARGOCD_PASS=$(kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d)
argocd login localhost:8080 --username admin --password "${ARGOCD_PASS}" --insecure
argocd repo add http://gitea.gitea.svc.cluster.local:3000/<admin-user>/yandex-prod.git \
--name yandex-prod \
--type git
```
Deploy the root app:
```bash
kubectl apply -f argocd/app-of-apps.yaml
```
ArgoCD will now sync child apps according to their sync waves. You can watch progress:
```bash
argocd app list
```
---
## Phase 4: Let the Sync Waves Run
Sync order (automated by ArgoCD via `argocd.argoproj.io/sync-wave` annotations):
| Wave | App | What happens |
|------|-----|-------------|
| **-2** | `traefik` | DaemonSet deployed on all 3 nodes. NLB created → external IP provisioned |
| **-1** | `cert-manager` | cert-manager operator + CRDs installed |
| **0** | `cert-manager-issuers` | `letsencrypt-production` + `letsencrypt-staging` ClusterIssuers created |
| **0** | `monitoring` | VM k8s-stack (metrics) + Grafana ingress deployed |
| **0** | `loki` | Loki single-binary deployed |
| **0** | `cnpg-operator` | CloudNativePG operator installed |
| **1** | `cnpg-cluster` | `shared-pg` 3-node PostgreSQL cluster + 8 databases created |
**Verify Traefik IP:**
```bash
kubectl get svc traefik -n traefik -w
# Wait for EXTERNAL-IP to appear. Example output:
# traefik LoadBalancer 10.x.x.x <pending> 80:3xxxx/TCP,443:3xxxx/TCP 30s
# traefik LoadBalancer 10.x.x.x 158.160.x.x 80:3xxxx/TCP,443:3xxxx/TCP 60s
```
Take the EXTERNAL-IP — this is your NLB IP. You'll need it in Phase 5.
**Verify state:**
```bash
kubectl get pods -A
# Expected running pods:
# traefik: traefik-xxxxx (3 pods, DaemonSet)
# cert-manager: cert-manager-xxxxx, cert-manager-cainjector-xxxxx, cert-manager-webhook-xxxxx
# metrics: vm-k8s-stack-* pods (vmsingle, alertmanager, grafana, node-exporter, kube-state-metrics, vmagent)
# metrics: loki-0
# cnpg-system: cnpg-operator-xxxxx
# cnpg: shared-pg-1, shared-pg-2, shared-pg-3 (may take a minute to start)
kubectl get clusterissuer
# Expected: letsencrypt-production (True), letsencrypt-staging (True)
kubectl get cluster -n cnpg
# Expected: shared-pg (3/3 instances ready)
```
---
## Phase 5: DNS + Expose Gitea & ArgoCD
Now that Traefik has an external IP and cert-manager is running, we can:
1. Point DNS at the NLB IP
2. Create the Gitea and ArgoCD ingress resources (with TLS)
### 5.1 Update DNS
Point the following records to the Traefik NLB IP (from Phase 4):
```
git.prod.t01tt.tech → <NLB-IP>
argocd.prod.t01tt.tech → <NLB-IP>
grafana.prod.t01tt.tech → <NLB-IP>
```
Also create a wildcard for future hosts:
```
*.prod.t01tt.tech → <NLB-IP>
```
### 5.2 Apply Ingresses
```bash
kubectl apply -f bootstrap/gitea/ingress.yaml
kubectl apply -f bootstrap/argocd/ingress.yaml
```
### 5.3 Wait for TLS Certificates
```bash
kubectl get certificate -A -w
# Wait for all to show Ready=True:
# gitea gitea-tls True
# argocd argocd-tls True
# metrics grafana-tls True
```
**Troubleshooting:** If certificates are stuck in `Pending`:
- Check DNS resolves: `dig git.prod.t01tt.tech` — must return the NLB IP
- Check cert-manager logs: `kubectl logs -n cert-manager deploy/cert-manager`
- Check challenge: `kubectl get challenges -A`
---
## Phase 6: Verify Everything
### Gitea
```
https://git.prod.t01tt.tech
```
Login with the admin credentials from Phase 1. Verify the `yandex-prod` repo exists.
### ArgoCD
```
https://argocd.prod.t01tt.tech
```
Login with `admin` + password from Phase 3. All apps should show green (`Synced` + `Healthy`).
The Ingress health may show `Healthy` immediately (by design — see `values.yaml` customization).
### Grafana
```
https://grafana.prod.t01tt.tech
```
Login with `admin` / `change-me`. Check that VM k8s-stack dashboards are available.
### PostgreSQL
```bash
kubectl get databases -n cnpg
# Expected: 8 Database resources, one per homeserver
kubectl get pods -n cnpg
# Expected: shared-pg-1, shared-pg-2, shared-pg-3 (Running)
```
### ArgoCD Repo Connection
```bash
argocd repo list
# Expected: the Gitea repo with status "Successful"
```
If not connected, re-add via ArgoCD CLI:
```bash
argocd repo add http://gitea.gitea.svc.cluster.local:3000/<admin-user>/yandex-prod.git \
--name yandex-prod \
--type git
```
Or in the ArgoCD UI: Settings → Repositories → Connect repo.
---
## Phase 7: Post-Bootstrap Checklist
- [ ] All ArgoCD apps `Synced` and `Healthy`
- [ ] `https://git.prod.t01tt.tech` — Gitea accessible, SSL valid
- [ ] `https://argocd.prod.t01tt.tech` — ArgoCD accessible, SSL valid
- [ ] `https://grafana.prod.t01tt.tech` — Grafana accessible, SSL valid, datasources working
- [ ] `kubectl get pv` — PVCs bound for all stateful components
- [ ] CNPG `shared-pg` cluster status: `kubectl get cluster -n cnpg` shows 3/3 ready
- [ ] Certificates all `Ready`: `kubectl get certificate -A | grep False` (should return nothing)
---
## Quick Reference: Service URLs
| Service | URL | Auth |
|---------|-----|------|
| Gitea | `https://git.prod.t01tt.tech` | Admin user from Phase 1 |
| ArgoCD | `https://argocd.prod.t01tt.tech` | `admin` / password from Phase 3 |
| Grafana | `https://grafana.prod.t01tt.tech` | `admin` / `change-me` |
| Traefik dashboard | `kubectl port-forward -n traefik daemonset/traefik 9000:9000` | Internal only |
---
## Troubleshooting
### Traefik NLB stuck in `<pending>`
Yandex Cloud NLB provisioning can take a few minutes. Check:
```bash
kubectl describe svc traefik -n traefik
```
If it's stuck for >5 minutes, verify the Yandex annotations are correct.
### Certificates stuck in `Pending`
1. Verify DNS: `dig git.prod.t01tt.tech` → must return the NLB IP
2. Check Traefik is listening: `curl -k https://<NLB-IP> -H "Host: git.prod.t01tt.tech"` → should return 404 (expected, just verifying Traefik responds)
3. Check orders: `kubectl get orders -A`
### CNPG cluster not becoming ready
```bash
kubectl describe cluster shared-pg -n cnpg
kubectl logs -n cnpg-system deploy/cnpg-controller-manager
```
Common issue: pods can't schedule due to `podAntiAffinityType: required`. Ensure all 3 nodes exist and PVCs can bind.
### Gitea UI shows wrong URL after first login
Gitea caches the ROOT_URL from the `deployment.yaml` env vars. If you change the domain, update:
```bash
kubectl set env deploy/gitea -n gitea \
GITEA__server__DOMAIN=git.prod.t01tt.tech \
GITEA__server__ROOT_URL=https://git.prod.t01tt.tech
kubectl rollout restart deploy/gitea -n gitea
```
### ArgoCD apps showing "Unknown" health
This is normal for Ingress resources — the custom health check in `bootstrap/argocd/values.yaml` marks all Ingresses as `Healthy` once synced. For other resources, check the app details in ArgoCD UI for the specific error.

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

@@ -0,0 +1,25 @@
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/gitea/yandex-prod.git
targetRevision: main
path: argocd/apps
directory:
recurse: true
include: "*.yaml"
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true

View File

@@ -0,0 +1,25 @@
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/gitea/yandex-prod.git
targetRevision: main
path: manifests/cert-manager
directory:
recurse: true
include: "*.yaml"
destination:
server: https://kubernetes.default.svc
namespace: cert-manager
syncPolicy:
automated:
prune: true
selfHeal: true

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,27 @@
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/gitea/yandex-prod.git
targetRevision: main
path: manifests/cnpg
directory:
recurse: true
include: "*.yaml"
destination:
server: https://kubernetes.default.svc
namespace: cnpg
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true

View File

@@ -0,0 +1,19 @@
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

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

@@ -0,0 +1,56 @@
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
loki:
auth_enabled: false
commonConfig:
replication_factor: 1
storage:
type: filesystem
schemaConfig:
configs:
- from: "2025-01-01"
store: tsdb
objectStore: filesystem
schema: v13
index:
prefix: index_
period: 24h
limits_config:
retention_period: 30d
reject_old_samples: true
reject_old_samples_max_age: 168h
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

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

@@ -0,0 +1,119 @@
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: https://victoriametrics.github.io/helm-charts/
chart: victoria-metrics-k8s-stack
targetRevision: ">=0.30.0"
helm:
values: |
fullnameOverride: vm-k8s-stack
namespaceOverride: metrics
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
- repoURL: http://gitea.gitea.svc.cluster.local:3000/gitea/yandex-prod.git
targetRevision: main
path: manifests/metrics/grafana
directory:
recurse: true
include: "*.yaml"
destination:
server: https://kubernetes.default.svc
namespace: argocd
syncPolicy:
automated:
prune: true
selfHeal: true
syncOptions:
- CreateNamespace=true

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

@@ -0,0 +1,84 @@
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
ingressClass:
enabled: true
isDefaultClass: true
additionalArguments:
- "--api.dashboard=true"
- "--ping=true"
- "--metrics.prometheus=true"
- "--metrics.prometheus.entrypoint=metrics"
- "--providers.kubernetesingress.ingressclass=traefik"
- "--providers.kubernetesingress.ingressendpoint.publishedservice=traefik/traefik"
- "--accesslog=true"
- "--log.level=INFO"
ports:
web:
port: 8080
exposedPort: 80
redirectTo: websecure
websecure:
port: 8443
exposedPort: 443
metrics:
port: 9100
expose: false
traefik:
port: 9000
expose: 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
podAnnotations:
prometheus.io/scrape: "true"
prometheus.io/port: "9100"
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

View File

@@ -0,0 +1,26 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: argocd
namespace: argocd
annotations:
cert-manager.io/cluster-issuer: letsencrypt-production
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
spec:
ingressClassName: traefik
tls:
- hosts:
- argocd.prod.t01tt.tech
secretName: argocd-tls
rules:
- host: argocd.prod.t01tt.tech
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: argocd-server
port:
number: 80

29
bootstrap/argocd/install.sh Executable file
View File

@@ -0,0 +1,29 @@
#!/bin/bash
set -e
KUBECONFIG="/home/mrt0rtikize/infra/yandex-prod/kubeconfig"
KCTL="kubectl --kubeconfig ${KUBECONFIG}"
echo "=== Installing ArgoCD ==="
helm repo add argo https://argoproj.github.io/argo-helm 2>/dev/null || true
helm repo update
helm upgrade --install argocd argo/argo-cd \
--namespace argocd \
--create-namespace \
--values "$(dirname "$0")/values.yaml" \
--wait \
--timeout 300s
echo ""
echo "=== ArgoCD installed ==="
echo ""
echo "To access ArgoCD UI:"
echo " kubectl --kubeconfig ${KUBECONFIG} port-forward svc/argocd-server -n argocd 8080:80"
echo ""
echo "Admin password:"
kubectl --kubeconfig ${KUBECONFIG} -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
echo ""
echo ""
echo "Login with username: admin"

View File

@@ -0,0 +1,20 @@
server:
extraArgs:
- --insecure
configs:
params:
server.insecure: true
cm:
timeout.reconciliation: 180s
helm.timeoutSeconds: "300"
resource.customizations.health.networking.k8s.io_Ingress: |
hs = {}
hs.status = "Healthy"
hs.message = "Ingress is synced"
return hs
redis:
image:
repository: docker.io/library/redis
tag: 7.4-alpine

View File

@@ -0,0 +1,64 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: gitea
namespace: gitea
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: gitea
template:
metadata:
labels:
app: gitea
spec:
containers:
- name: gitea
image: gitea/gitea:1.24
ports:
- containerPort: 3000
name: http
- containerPort: 22
name: ssh
env:
- name: GITEA__database__DB_TYPE
value: sqlite3
- name: GITEA__server__DOMAIN
value: git.prod.t01tt.tech
- name: GITEA__server__ROOT_URL
value: https://git.prod.t01tt.tech
- name: GITEA__server__HTTP_PORT
value: "3000"
- name: GITEA__server__SSH_PORT
value: "22"
- name: GITEA__service__DISABLE_REGISTRATION
value: "true"
volumeMounts:
- name: data
mountPath: /data
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 500m
memory: 512Mi
livenessProbe:
httpGet:
path: /
port: 3000
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 3000
initialDelaySeconds: 5
periodSeconds: 5
volumes:
- name: data
persistentVolumeClaim:
claimName: gitea-data

View File

@@ -0,0 +1,26 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: gitea
namespace: gitea
annotations:
cert-manager.io/cluster-issuer: letsencrypt-production
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
spec:
ingressClassName: traefik
tls:
- hosts:
- git.prod.t01tt.tech
secretName: gitea-tls
rules:
- host: git.prod.t01tt.tech
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: gitea
port:
number: 3000

View File

@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: gitea

11
bootstrap/gitea/pvc.yaml Normal file
View File

@@ -0,0 +1,11 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: gitea-data
namespace: gitea
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi

View File

@@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: gitea
namespace: gitea
spec:
selector:
app: gitea
ports:
- name: http
port: 3000
targetPort: 3000
- name: ssh
port: 22
targetPort: 22

5
kubeconfig Normal file
View File

@@ -0,0 +1,5 @@
# Placeholder for Yandex Cloud Managed Kubernetes kubeconfig.
# Copy your kubeconfig here before running bootstrap.
#
# Example:
# yc managed-kubernetes cluster get-credentials --id <cluster-id> --external --kubeconfig kubeconfig

View File

@@ -0,0 +1,29 @@
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-production
spec:
acme:
email: i_am@rogov.al
privateKeySecretRef:
name: letsencrypt-production-account-key
server: https://acme-v02.api.letsencrypt.org/directory
solvers:
- http01:
ingress:
class: traefik
---
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
email: i_am@rogov.al
privateKeySecretRef:
name: letsencrypt-staging-account-key
server: https://acme-staging-v02.api.letsencrypt.org/directory
solvers:
- http01:
ingress:
class: traefik

View File

@@ -0,0 +1,30 @@
apiVersion: postgresql.cnpg.io/v1
kind: Cluster
metadata:
name: shared-pg
namespace: cnpg
spec:
instances: 3
imageName: ghcr.io/cloudnative-pg/postgresql:16
storage:
size: 20Gi
storageClass: yc-network-ssd
affinity:
podAntiAffinityType: required
bootstrap:
initdb:
database: postgres
owner: postgres
postgresql:
parameters:
shared_buffers: "256MB"
effective_cache_size: "768MB"
maintenance_work_mem: "64MB"
max_connections: "200"
monitoring:
enablePodMonitor: true

View File

@@ -0,0 +1,87 @@
apiVersion: postgresql.cnpg.io/v1
kind: Database
metadata:
name: synapse-mrt0rtikize
namespace: cnpg
spec:
name: synapse_mrt0rtikize
owner: synapse_mrt0rtikize
clusterRef:
name: shared-pg
---
apiVersion: postgresql.cnpg.io/v1
kind: Database
metadata:
name: mas-mrt0rtikize
namespace: cnpg
spec:
name: mas_mrt0rtikize
owner: mas_mrt0rtikize
clusterRef:
name: shared-pg
---
apiVersion: postgresql.cnpg.io/v1
kind: Database
metadata:
name: synapse-t0rt1k
namespace: cnpg
spec:
name: synapse_t0rt1k
owner: synapse_t0rt1k
clusterRef:
name: shared-pg
---
apiVersion: postgresql.cnpg.io/v1
kind: Database
metadata:
name: mas-t0rt1k
namespace: cnpg
spec:
name: mas_t0rt1k
owner: mas_t0rt1k
clusterRef:
name: shared-pg
---
apiVersion: postgresql.cnpg.io/v1
kind: Database
metadata:
name: synapse-roglog
namespace: cnpg
spec:
name: synapse_roglog
owner: synapse_roglog
clusterRef:
name: shared-pg
---
apiVersion: postgresql.cnpg.io/v1
kind: Database
metadata:
name: mas-roglog
namespace: cnpg
spec:
name: mas_roglog
owner: mas_roglog
clusterRef:
name: shared-pg
---
apiVersion: postgresql.cnpg.io/v1
kind: Database
metadata:
name: synapse-uretra
namespace: cnpg
spec:
name: synapse_uretra
owner: synapse_uretra
clusterRef:
name: shared-pg
---
apiVersion: postgresql.cnpg.io/v1
kind: Database
metadata:
name: mas-uretra
namespace: cnpg
spec:
name: mas_uretra
owner: mas_uretra
clusterRef:
name: shared-pg

View File

@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: cnpg

View File

@@ -0,0 +1,63 @@
apiVersion: v1
kind: Secret
metadata:
name: mrt0rtikize-pg-creds
namespace: cnpg
labels:
cnpg.io/reload: ""
type: kubernetes.io/basic-auth
stringData:
synapse: |
username: synapse_mrt0rtikize
password: change-me-synapse
mas: |
username: mas_mrt0rtikize
password: change-me-mas
---
apiVersion: v1
kind: Secret
metadata:
name: t0rt1k-pg-creds
namespace: cnpg
labels:
cnpg.io/reload: ""
type: kubernetes.io/basic-auth
stringData:
synapse: |
username: synapse_t0rt1k
password: change-me-synapse
mas: |
username: mas_t0rt1k
password: change-me-mas
---
apiVersion: v1
kind: Secret
metadata:
name: roglog-pg-creds
namespace: cnpg
labels:
cnpg.io/reload: ""
type: kubernetes.io/basic-auth
stringData:
synapse: |
username: synapse_roglog
password: change-me-synapse
mas: |
username: mas_roglog
password: change-me-mas
---
apiVersion: v1
kind: Secret
metadata:
name: uretra-pg-creds
namespace: cnpg
labels:
cnpg.io/reload: ""
type: kubernetes.io/basic-auth
stringData:
synapse: |
username: synapse_uretra
password: change-me-synapse
mas: |
username: mas_uretra
password: change-me-mas

View File

@@ -0,0 +1,26 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: grafana
namespace: metrics
annotations:
cert-manager.io/cluster-issuer: letsencrypt-production
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
spec:
ingressClassName: traefik
tls:
- hosts:
- grafana.prod.t01tt.tech
secretName: grafana-tls
rules:
- host: grafana.prod.t01tt.tech
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: vm-k8s-stack-grafana
port:
number: 80

View File

@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: metrics