1.0.0 Release IaaS
This commit is contained in:
35
config/services/containers/infra/ca/ca.container.j2
Normal file
35
config/services/containers/infra/ca/ca.container.j2
Normal file
@@ -0,0 +1,35 @@
|
||||
[Quadlet]
|
||||
DefaultDependencies=false
|
||||
|
||||
[Unit]
|
||||
Description=CA
|
||||
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Container]
|
||||
Image=docker.io/smallstep/step-ca:{{ version['containers']['step'] }}
|
||||
|
||||
ContainerName=ca
|
||||
HostName=ca
|
||||
|
||||
PublishPort=9000:9000/tcp
|
||||
|
||||
Volume=%h/containers/ca/certs:/home/step/certs:ro
|
||||
Volume=%h/containers/ca/secrets:/home/step/secrets:ro
|
||||
Volume=%h/containers/ca/config:/home/step/config:rw
|
||||
Volume=%h/containers/ca/db:/home/step/db:rw
|
||||
Volume=%h/containers/ca/templates:/home/step/templates:rw
|
||||
|
||||
Environment="TZ=Asia/Seoul"
|
||||
Environment="PWDPATH=/run/secrets/STEP_CA_PASSWORD"
|
||||
|
||||
Secret=STEP_CA_PASSWORD,target=/run/secrets/STEP_CA_PASSWORD
|
||||
|
||||
[Service]
|
||||
Restart=always
|
||||
RestartSec=10s
|
||||
TimeoutStopSec=120
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
61
config/services/containers/infra/ca/config/ca.json.j2
Normal file
61
config/services/containers/infra/ca/config/ca.json.j2
Normal file
@@ -0,0 +1,61 @@
|
||||
{
|
||||
"root": "/home/step/certs/ilnmors_root_ca.crt",
|
||||
"federatedRoots": null,
|
||||
"crt": "/home/step/certs/ilnmors_intermediate_ca.crt",
|
||||
"key": "/home/step/secrets/ilnmors_intermediate_ca.key",
|
||||
"address": ":9000",
|
||||
"insecureAddress": "",
|
||||
"dnsNames": [
|
||||
"{{ infra_uri['ca']['domain'] }}"
|
||||
],
|
||||
"logger": {
|
||||
"format": "text"
|
||||
},
|
||||
"db": {
|
||||
"type": "badgerv2",
|
||||
"dataSource": "/home/step/db",
|
||||
"badgerFileLoadingMode": ""
|
||||
},
|
||||
"authority": {
|
||||
"policy": {
|
||||
"x509": {
|
||||
"allow": {
|
||||
"dns": [
|
||||
"ilnmors.internal",
|
||||
"*.ilnmors.internal"
|
||||
]
|
||||
},
|
||||
"allowWildcardNames": true
|
||||
}
|
||||
},
|
||||
"provisioners": [
|
||||
{
|
||||
"type": "ACME",
|
||||
"name": "acme@ilnmors.internal",
|
||||
"claims": {
|
||||
"defaultTLSCertDuration": "2160h0m0s",
|
||||
"enableSSHCA": true,
|
||||
"disableRenewal": false,
|
||||
"allowRenewalAfterExpiry": false,
|
||||
"disableSmallstepExtensions": false
|
||||
},
|
||||
"options": {
|
||||
"x509": {},
|
||||
"ssh": {}
|
||||
}
|
||||
}
|
||||
],
|
||||
"template": {},
|
||||
"backdate": "1m0s"
|
||||
},
|
||||
"tls": {
|
||||
"cipherSuites": [
|
||||
"TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256",
|
||||
"TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"
|
||||
],
|
||||
"minVersion": 1.2,
|
||||
"maxVersion": 1.3,
|
||||
"renegotiation": false
|
||||
},
|
||||
"commonName": "ilnmors Online CA"
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"ca-url": "https://{{ infra_uri['ca']['domain'] }}:{{ infra_uri['ca']['ports']['https'] }}",
|
||||
"ca-config": "/home/step/config/ca.json",
|
||||
"fingerprint": "215c851d2d0d2dbf90fc3507425207c29696ffd587c640c94a68dddb1d84d8e8",
|
||||
"root": "/home/step/certs/ilnmors_root_ca.crt"
|
||||
}
|
||||
8
config/services/containers/infra/ca/templates/ca.tpl
Normal file
8
config/services/containers/infra/ca/templates/ca.tpl
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"subject": {{ toJson .Subject }},
|
||||
"keyUsage": ["certSign", "crlSign"],
|
||||
"basicConstraints": {
|
||||
"isCA": true,
|
||||
"maxPathLen": 0
|
||||
}
|
||||
}
|
||||
54
config/services/containers/infra/grafana/etc/grafana.ini.j2
Normal file
54
config/services/containers/infra/grafana/etc/grafana.ini.j2
Normal file
@@ -0,0 +1,54 @@
|
||||
# https://github.com/grafana/grafana/blob/main/conf/defaults.ini
|
||||
[paths]
|
||||
data = /var/lib/grafana
|
||||
logs = /var/log/grafana
|
||||
plugins = /var/lib/grafana/plugins
|
||||
provisioning = /etc/grafana/provisioning
|
||||
|
||||
[server]
|
||||
protocol = http
|
||||
http_port = 3000
|
||||
domain = grafana.ilnmors.internal
|
||||
root_url = http://grafana.ilnmors.internal/
|
||||
router_logging = false
|
||||
|
||||
[database]
|
||||
type = postgres
|
||||
host = {{ infra_uri['postgresql']['domain'] }}:{{ infra_uri['postgresql']['ports']['tcp'] }}
|
||||
name = grafana_db
|
||||
user = grafana
|
||||
password = $__file{/run/secrets/GF_DB_PASSWORD}
|
||||
ssl_mode = verify-full
|
||||
ca_cert_path = /etc/ssl/grafana/ilnmors_root_ca.crt
|
||||
|
||||
[auth.ldap]
|
||||
enabled = true
|
||||
config_file = /etc/grafana/ldap.toml
|
||||
allow_sign_up = true
|
||||
|
||||
[auth]
|
||||
disable_login_form = false
|
||||
allow_anonymous_device_id_auth = false
|
||||
|
||||
[security]
|
||||
# local admin
|
||||
admin_user = local_admin
|
||||
# local password
|
||||
admin_password = $__file{/run/secrets/GF_ADMIN_PASSWORD}
|
||||
cookie_secure = true
|
||||
cookie_samesite = lax
|
||||
allow_embedding = false
|
||||
|
||||
# [smtp]
|
||||
# enabled = true
|
||||
# host = localhost:25
|
||||
# from_address = alert@ilnmors.internal
|
||||
# from_name = Grafana-Infra
|
||||
|
||||
[analytics]
|
||||
reporting_enabled = false
|
||||
check_for_updates = false
|
||||
|
||||
[log]
|
||||
mode = console
|
||||
level = info
|
||||
47
config/services/containers/infra/grafana/etc/ldap.toml.j2
Normal file
47
config/services/containers/infra/grafana/etc/ldap.toml.j2
Normal file
@@ -0,0 +1,47 @@
|
||||
# https://github.com/lldap/lldap/blob/main/example_configs/grafana_ldap_config.toml
|
||||
[[servers]]
|
||||
host = "{{ infra_uri['ldap']['domain'] }}"
|
||||
port = {{ infra_uri['ldap']['ports']['ldaps'] }}
|
||||
# Activate STARTTLS or LDAPS
|
||||
use_ssl = true
|
||||
# true = STARTTLS, false = LDAPS
|
||||
start_tls = false
|
||||
tls_ciphers = []
|
||||
min_tls_version = ""
|
||||
ssl_skip_verify = false
|
||||
root_ca_cert = "/etc/ssl/grafana/ilnmors_root_ca.crt"
|
||||
# mTLS option, it is not needed
|
||||
# client_cert = "/path/to/client.crt"
|
||||
# client_key = "/path/to/client.key"
|
||||
|
||||
bind_dn = "uid=grafana,ou=people,dc=ilnmors,dc=internal"
|
||||
bind_password = "$__file{/run/secrets/LDAP_BIND_PASSWORD}"
|
||||
|
||||
search_filter = "(|(uid=%s)(mail=%s))"
|
||||
search_base_dns = ["dc=ilnmors,dc=internal"]
|
||||
|
||||
[servers.attributes]
|
||||
member_of = "memberOf"
|
||||
email = "mail"
|
||||
name = "displayName"
|
||||
surname = "sn"
|
||||
username = "uid"
|
||||
|
||||
group_search_filter = "(&(objectClass=groupOfUniqueNames)(uniqueMember=%s))"
|
||||
group_search_base_dns = ["ou=groups,dc=ilnmors,dc=internal"]
|
||||
group_search_filter_user_attribute = "uid"
|
||||
|
||||
[[servers.group_mappings]]
|
||||
group_dn = "cn=lldap_admin,ou=groups,dc=ilnmors,dc=internal"
|
||||
org_role = "Admin"
|
||||
grafana_admin = true
|
||||
|
||||
[[servers.group_mappings]]
|
||||
group_dn = "cn=admins,ou=groups,dc=ilnmors,dc=internal"
|
||||
org_role = "Editor"
|
||||
grafana_admin = false
|
||||
|
||||
[[servers.group_mappings]]
|
||||
group_dn = "cn=users,ou=groups,dc=ilnmors,dc=internal"
|
||||
org_role = "Viewer"
|
||||
grafana_admin = false
|
||||
@@ -0,0 +1,29 @@
|
||||
# https://github.com/grafana/grafana/blob/main/conf/provisioning/datasources/sample.yaml
|
||||
apiVersion: 1
|
||||
|
||||
datasources:
|
||||
- name: Prometheus
|
||||
type: prometheus
|
||||
url: https://prometheus.ilnmors.internal:9090
|
||||
access: proxy
|
||||
isDefault: true
|
||||
jsonData:
|
||||
tlsAuth: false
|
||||
tlsAuthWithCACert: true
|
||||
httpMethod: POST
|
||||
secureJsonData:
|
||||
tlsCACert: "$__file{/etc/ssl/grafana/ilnmors_root_ca.crt}"
|
||||
|
||||
- name: Loki
|
||||
type: loki
|
||||
url: https://loki.ilnmors.internal:3100
|
||||
access: proxy
|
||||
jsonData:
|
||||
tlsAuth: false
|
||||
tlsAuthWithCACert: true
|
||||
# Tenent value set "to solve no org id"
|
||||
httpHeaderName1: "X-Scope-OrgID"
|
||||
maxLines: 1000
|
||||
secureJsonData:
|
||||
tlsCACert: "$__file{/etc/ssl/grafana/ilnmors_root_ca.crt}"
|
||||
httpHeaderValue1: "ilnmors.internal"
|
||||
@@ -0,0 +1,43 @@
|
||||
[Quadlet]
|
||||
DefaultDependencies=false
|
||||
|
||||
[Unit]
|
||||
Description=Grafana
|
||||
|
||||
After=postgresql.service ldap.service
|
||||
Requires=postgresql.service ldap.service
|
||||
|
||||
[Container]
|
||||
Image=docker.io/grafana/grafana:{{ version['containers']['grafana'] }}
|
||||
|
||||
ContainerName=grafana
|
||||
HostName=grafana
|
||||
|
||||
AddHost={{ infra_uri['postgresql']['domain'] }}:host-gateway
|
||||
AddHost={{ infra_uri['ldap']['domain'] }}:host-gateway
|
||||
AddHost={{ infra_uri['prometheus']['domain'] }}:host-gateway
|
||||
AddHost={{ infra_uri['loki']['domain'] }}:host-gateway
|
||||
|
||||
PublishPort=3000:3000/tcp
|
||||
|
||||
Volume=%h/containers/grafana/data:/var/lib/grafana:rw
|
||||
Volume=%h/containers/grafana/etc:/etc/grafana:ro
|
||||
Volume=%h/containers/grafana/ssl:/etc/ssl/grafana:ro
|
||||
|
||||
Environment="TZ=Asia/Seoul"
|
||||
Environment="GF_PATHS_CONFIG=/etc/grafana/grafana.ini"
|
||||
# plugin
|
||||
# Environment="GF_INSTALL_PLUGINS=grafana-clock-panel,grafana-simple-json-datasource"
|
||||
Environment="GF_FEATURE_TOGGLES_EXPAND_ENV_VARS=true"
|
||||
|
||||
Secret=GF_DB_PASSWORD,target=/run/secrets/GF_DB_PASSWORD
|
||||
Secret=LDAP_BIND_PASSWORD,target=/run/secrets/LDAP_BIND_PASSWORD
|
||||
Secret=GF_ADMIN_PASSWORD,target=/run/secrets/GF_ADMIN_PASSWORD
|
||||
|
||||
[Service]
|
||||
Restart=always
|
||||
RestartSec=10s
|
||||
TimeoutStopSec=120
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
64
config/services/containers/infra/ldap/ldap.container.j2
Normal file
64
config/services/containers/infra/ldap/ldap.container.j2
Normal file
@@ -0,0 +1,64 @@
|
||||
[Quadlet]
|
||||
DefaultDependencies=false
|
||||
|
||||
[Unit]
|
||||
Description=LDAP
|
||||
|
||||
After=postgresql.service
|
||||
Requires=postgresql.service
|
||||
|
||||
[Container]
|
||||
Image=docker.io/lldap/lldap:{{ version['containers']['ldap'] }}
|
||||
|
||||
ContainerName=ldap
|
||||
HostName=ldap
|
||||
# They are at the same host (for Pasta, it is needed)
|
||||
AddHost={{ infra_uri['postgresql']['domain'] }}:host-gateway
|
||||
# For LDAPS - 636 > 6360 nftables
|
||||
PublishPort=6360:6360/tcp
|
||||
# Web UI
|
||||
PublishPort=17170:17170/tcp
|
||||
|
||||
|
||||
Volume=%h/containers/ldap/data:/data:rw
|
||||
Volume=%h/containers/ldap/ssl:/etc/ssl/ldap:ro
|
||||
|
||||
# Default
|
||||
Environment="TZ=Asia/Seoul"
|
||||
|
||||
# Domain
|
||||
Environment="LLDAP_LDAP_BASE_DN=dc=ilnmors,dc=internal"
|
||||
|
||||
# LDAPS
|
||||
Environment="LLDAP_LDAPS_OPTIONS__ENABLED=true"
|
||||
Environment="LLDAP_LDAPS_OPTIONS__CERT_FILE=/etc/ssl/ldap/ldap.crt"
|
||||
Environment="LLDAP_LDAPS_OPTIONS__KEY_FILE=/etc/ssl/ldap/ldap.key"
|
||||
# Secret files' Path
|
||||
Environment="LLDAP_KEY_SEED_FILE=/run/secrets/LLDAP_KEY_SEED"
|
||||
Environment="LLDAP_JWT_SECRET_FILE=/run/secrets/LLDAP_JWT_SECRET"
|
||||
|
||||
# SMTP options > you can set all of these at the /data/config.toml instead of Environment
|
||||
# Only `LLDAP_SMTP_OPTIONS__PASSWORD` will be injected by secret
|
||||
# LLDAP_SMTP_OPTIONS__ENABLE_PASSWORD_RESET=true
|
||||
# LLDAP_SMTP_OPTIONS__SERVER=smtp.example.com
|
||||
# LLDAP_SMTP_OPTIONS__PORT=465
|
||||
# LLDAP_SMTP_OPTIONS__SMTP_ENCRYPTION=TLS
|
||||
# LLDAP_SMTP_OPTIONS__USER=no-reply@example.com
|
||||
# LLDAP_SMTP_OPTIONS__PASSWORD=PasswordGoesHere
|
||||
# LLDAP_SMTP_OPTIONS__FROM=no-reply <no-reply@example.com>
|
||||
# LLDAP_SMTP_OPTIONS__TO=admin <admin@example.com>
|
||||
|
||||
# Database
|
||||
Secret=LLDAP_DATABASE_URL,type=env
|
||||
|
||||
# Secrets
|
||||
Secret=LLDAP_KEY_SEED,target="/run/secrets/LLDAP_KEY_SEED"
|
||||
Secret=LLDAP_JWT_SECRET,target="/run/secrets/LLDAP_JWT_SECRET"
|
||||
|
||||
[Service]
|
||||
Restart=always
|
||||
RestartSec=10s
|
||||
TimeoutStopSec=120
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
46
config/services/containers/infra/loki/etc/loki.yaml
Normal file
46
config/services/containers/infra/loki/etc/loki.yaml
Normal file
@@ -0,0 +1,46 @@
|
||||
---
|
||||
server:
|
||||
http_listen_address: "::"
|
||||
http_listen_port: 3100
|
||||
http_tls_config:
|
||||
cert_file: /etc/ssl/loki/loki.crt
|
||||
key_file: /etc/ssl/loki/loki.key
|
||||
|
||||
#memberlist:
|
||||
# join_members: ["localhost"]
|
||||
# bind_addr: ['::']
|
||||
# bind_port: 7946
|
||||
|
||||
schema_config:
|
||||
configs:
|
||||
- from: "2023-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
|
||||
|
||||
common:
|
||||
instance_addr: localhost
|
||||
path_prefix: /loki
|
||||
replication_factor: 1
|
||||
storage:
|
||||
filesystem:
|
||||
chunks_directory: /loki/chunks
|
||||
rules_directory: /loki/rules
|
||||
ring:
|
||||
kvstore:
|
||||
store: inmemory
|
||||
|
||||
compactor:
|
||||
working_directory: /loki/compactor
|
||||
delete_request_store: filesystem
|
||||
compaction_interval: 10m
|
||||
retention_enabled: true
|
||||
retention_delete_delay: 2h
|
||||
32
config/services/containers/infra/loki/loki.container.j2
Normal file
32
config/services/containers/infra/loki/loki.container.j2
Normal file
@@ -0,0 +1,32 @@
|
||||
[Quadlet]
|
||||
DefaultDependencies=false
|
||||
|
||||
[Unit]
|
||||
Description=Loki
|
||||
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Container]
|
||||
Image=docker.io/grafana/loki:{{ version['containers']['loki'] }}
|
||||
|
||||
ContainerName=loki
|
||||
HostName=loki
|
||||
|
||||
PublishPort=3100:3100/tcp
|
||||
|
||||
Volume=%h/containers/loki/data:/loki:rw
|
||||
Volume=%h/containers/loki/etc:/etc/loki:ro
|
||||
Volume=%h/containers/loki/ssl:/etc/ssl/loki:ro
|
||||
|
||||
Environment="TZ=Asia/Seoul"
|
||||
|
||||
Exec=--config.file=/etc/loki/loki.yaml
|
||||
|
||||
[Service]
|
||||
Restart=always
|
||||
RestartSec=10s
|
||||
TimeoutStopSec=120
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
@@ -0,0 +1,12 @@
|
||||
ARG PG_VER={{ version['containers']['postgresql'] }}
|
||||
|
||||
FROM docker.io/library/postgres:${PG_VER}
|
||||
|
||||
ARG VECTORCHORD_VER={{ version['containers']['vectorchord'] }}
|
||||
|
||||
RUN apt update && \
|
||||
apt install -y wget postgresql-${PG_MAJOR}-pgvector && \
|
||||
wget -nv -O /tmp/vchord.deb https://github.com/tensorchord/VectorChord/releases/download/${VECTORCHORD_VER}/postgresql-${PG_MAJOR}-vchord_${VECTORCHORD_VER}-1_amd64.deb && \
|
||||
apt install -y /tmp/vchord.deb && \
|
||||
apt purge -y wget && apt autoremove -y && \
|
||||
rm -rf /tmp/vchord.deb /var/lib/apt/lists/*
|
||||
@@ -0,0 +1,28 @@
|
||||
# @authcomment@
|
||||
# TYPE DATABASE USER ADDRESS METHOD
|
||||
# Local host `trust`
|
||||
local all all trust
|
||||
|
||||
# Local monitoring connection (host - infra VM) `trust`
|
||||
hostssl postgres alloy {{ hostvars['fw']['network4']['infra']['server'] }}/32 trust
|
||||
hostssl postgres alloy {{ hostvars['fw']['network6']['infra']['server'] }}/128 trust
|
||||
hostssl postgres alloy {{ hostvars['fw']['network4']['subnet']['lla'] }} trust
|
||||
hostssl postgres alloy {{ hostvars['fw']['network6']['subnet']['lla'] }} trust
|
||||
|
||||
# Local connection (in postgresql container) needs password (127.0.0.1 - container loopback)
|
||||
host all all 127.0.0.1/32 scram-sha-256
|
||||
host all all ::1/128 scram-sha-256
|
||||
|
||||
# Local connection (host - infra VM) needs password (169.254.1.0/24 - link_local subnet for containers in pasta mode)
|
||||
hostssl all all {{ hostvars['fw']['network4']['infra']['server'] }}/32 scram-sha-256
|
||||
hostssl all all {{ hostvars['fw']['network6']['infra']['server'] }}/128 scram-sha-256
|
||||
hostssl all all {{ hostvars['fw']['network4']['subnet']['lla'] }} scram-sha-256
|
||||
hostssl all all {{ hostvars['fw']['network6']['subnet']['lla'] }} scram-sha-256
|
||||
|
||||
# auth VM
|
||||
hostssl all all {{ hostvars['fw']['network4']['auth']['server'] }}/32 scram-sha-256
|
||||
hostssl all all {{ hostvars['fw']['network6']['auth']['server'] }}/128 scram-sha-256
|
||||
|
||||
# app VM (Applications, 192.168.10.13)
|
||||
hostssl all all {{ hostvars['fw']['network4']['app']['server'] }}/32 scram-sha-256
|
||||
hostssl all all {{ hostvars['fw']['network6']['app']['server'] }}/128 scram-sha-256
|
||||
@@ -0,0 +1,41 @@
|
||||
#------------------------------------------------------------------------------
|
||||
# CUSTOMIZED OPTIONS
|
||||
#------------------------------------------------------------------------------
|
||||
|
||||
# Add settings for extensions here
|
||||
# Listen_address
|
||||
listen_addresses = '*'
|
||||
# Max connections
|
||||
max_connections = 250
|
||||
# listen_port
|
||||
port = 5432
|
||||
|
||||
# SSL
|
||||
ssl = on
|
||||
ssl_ca_file = '/etc/ssl/postgresql/ilnmors_root_ca.crt'
|
||||
ssl_cert_file = '/etc/ssl/postgresql/postgresql.crt'
|
||||
ssl_key_file = '/etc/ssl/postgresql/postgresql.key'
|
||||
ssl_ciphers = 'HIGH:!aNULL:!MD5'
|
||||
ssl_prefer_server_ciphers = on
|
||||
|
||||
# log
|
||||
log_destination = 'stderr'
|
||||
log_checkpoints = on
|
||||
log_temp_files = 0
|
||||
log_min_duration_statement = 500
|
||||
|
||||
# IO
|
||||
track_io_timing = on
|
||||
|
||||
## immich_config
|
||||
shared_preload_libraries = 'vchord.so'
|
||||
search_path = '"$user", public'
|
||||
max_wal_size = 5GB
|
||||
shared_buffers = 512MB
|
||||
wal_compression = on
|
||||
work_mem = 16MB
|
||||
autovacuum_vacuum_scale_factor = 0.1
|
||||
autovacuum_analyze_scale_factor = 0.05
|
||||
autovacuum_vacuum_cost_limit = 1000
|
||||
effective_io_concurrency = 200
|
||||
random_page_cost = 1.2
|
||||
@@ -0,0 +1,36 @@
|
||||
[Quadlet]
|
||||
DefaultDependencies=false
|
||||
|
||||
[Unit]
|
||||
Description=PostgreSQL
|
||||
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Container]
|
||||
Image=ilnmors.internal/{{ node['name'] }}/postgres:pg{{ version['containers']['postgresql'] }}-vectorchord{{ version['containers']['vectorchord'] }}
|
||||
|
||||
ContainerName=postgresql
|
||||
HostName=postgresql
|
||||
|
||||
PublishPort=5432:5432/tcp
|
||||
|
||||
Volume=%h/containers/postgresql/data:/var/lib/postgresql:rw
|
||||
Volume=%h/containers/postgresql/config:/config:ro
|
||||
Volume=%h/containers/postgresql/ssl:/etc/ssl/postgresql:ro
|
||||
Volume=%h/containers/postgresql/init:/docker-entrypoint-initdb.d/:ro
|
||||
Volume=%h/containers/postgresql/backups:/backups:rw
|
||||
|
||||
Environment="TZ=Asia/Seoul"
|
||||
# This option is only for init process, after init custom config file `pg_hba.conf` will control this option.
|
||||
Environment="POSTGRES_HOST_AUTH_METHOD=trust"
|
||||
|
||||
Exec=postgres -c 'config_file=/config/postgresql.conf' -c 'hba_file=/config/pg_hba.conf'
|
||||
|
||||
[Service]
|
||||
Restart=always
|
||||
RestartSec=10s
|
||||
TimeoutStopSec=120
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
@@ -0,0 +1,18 @@
|
||||
[Unit]
|
||||
Description=PostgreSQL Cluster Backup Service
|
||||
After=postgresql.service
|
||||
BindsTo=postgresql.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
|
||||
# logging
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
|
||||
ExecStartPre=/usr/bin/podman exec postgresql sh -c "mkdir -p /backups/cluster && chown postgres:root /backups/cluster && chmod 770 /backups/cluster"
|
||||
|
||||
# Run the script
|
||||
ExecStart=/usr/bin/podman exec -u postgres postgresql sh -c 'pg_dumpall -U postgres --schema-only | grep -v -E "CREATE ROLE postgres" > /backups/cluster/pg_cluster_$(date "+%%Y-%%m-%%d").sql'
|
||||
ExecStart=/usr/bin/podman exec -u postgres postgresql sh -c "find /backups/cluster -maxdepth 1 -type f -mtime +7 -delete"
|
||||
ExecStart=/usr/bin/podman exec postgresql sh -c "chown -R postgres:root /backups/cluster && chmod 660 /backups/cluster/*"
|
||||
@@ -0,0 +1,17 @@
|
||||
[Unit]
|
||||
Description=Run PostgreSQL Cluster Backup service every day
|
||||
|
||||
[Timer]
|
||||
# Execute service after 1 min on booting
|
||||
OnBootSec=1min
|
||||
|
||||
# Execute service every day 00:00
|
||||
OnCalendar=*-*-* 00:00:00
|
||||
# Random time to postpone the timer
|
||||
RandomizedDelaySec=15min
|
||||
|
||||
# When timer is activated, Service also starts.
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
@@ -0,0 +1,19 @@
|
||||
[Unit]
|
||||
Description=PostgreSQL Data %i Backup Service
|
||||
After=postgresql.service
|
||||
BindsTo=postgresql.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
|
||||
# logging
|
||||
StandardOutput=journal
|
||||
StandardError=journal
|
||||
|
||||
ExecStartPre=/usr/bin/podman exec postgresql sh -c "mkdir -p /backups/%i && chown postgres:root /backups/%i && chmod 770 /backups/%i"
|
||||
|
||||
# Run the script
|
||||
ExecStart=/usr/bin/podman exec -u postgres postgresql sh -c 'printf "\\connect %i_db\n" > /backups/%i/pg_%i_$(date "+%%Y-%%m-%%d").sql'
|
||||
ExecStart=/usr/bin/podman exec -u postgres postgresql sh -c 'pg_dump -U postgres -d %i_db --data-only >> /backups/%i/pg_%i_$(date "+%%Y-%%m-%%d").sql'
|
||||
ExecStart=/usr/bin/podman exec -u postgres postgresql sh -c "find /backups/%i -maxdepth 1 -type f -mtime +7 -delete"
|
||||
ExecStart=/usr/bin/podman exec postgresql sh -c "chown -R postgres:root /backups/%i && chmod 660 /backups/%i/*"
|
||||
@@ -0,0 +1,17 @@
|
||||
[Unit]
|
||||
Description=Run %i Data Backup service every day
|
||||
|
||||
[Timer]
|
||||
# Execute service after 1 min on booting
|
||||
OnBootSec=1min
|
||||
|
||||
# Execute service every day 00:00
|
||||
OnCalendar=*-*-* 00:00:00
|
||||
# Random time to postpone the timer
|
||||
RandomizedDelaySec=15min
|
||||
|
||||
# When timer is activated, Service also starts.
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
@@ -0,0 +1,32 @@
|
||||
# my global config
|
||||
global:
|
||||
scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
|
||||
evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
|
||||
# scrape_timeout is set to the global default (10s).
|
||||
|
||||
# Alertmanager configuration
|
||||
alerting:
|
||||
alertmanagers:
|
||||
- static_configs:
|
||||
- targets:
|
||||
# - alertmanager:9093
|
||||
|
||||
# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
|
||||
rule_files:
|
||||
- "/etc/prometheus/rules.yaml"
|
||||
|
||||
# A scrape configuration containing exactly one endpoint to scrape:
|
||||
# Here it's Prometheus itself.
|
||||
scrape_configs:
|
||||
# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
|
||||
- job_name: "prometheus"
|
||||
# metrics_path defaults to '/metrics'
|
||||
scheme: "https"
|
||||
tls_config:
|
||||
ca_file: "/etc/ssl/prometheus/ilnmors_root_ca.crt"
|
||||
server_name: "{{ infra_uri['prometheus']['domain'] }}"
|
||||
static_configs:
|
||||
- targets: ["localhost:9090"]
|
||||
# The label name is added as a label `label_name=<label_value>` to any timeseries scraped from this config.
|
||||
labels:
|
||||
instance: "{{ node['name'] }}"
|
||||
@@ -0,0 +1,38 @@
|
||||
groups:
|
||||
- name: node_exporters_heartbeat
|
||||
rules:
|
||||
{% for instance in ['vmm', 'fw', 'infra', 'auth', 'app'] %}
|
||||
- alert: {{ instance }}_node_exporter_down
|
||||
expr: |
|
||||
(present_over_time(up{instance="{{ instance }}"}[5m]) or on() vector(0)) == 0
|
||||
for: 30s
|
||||
labels:
|
||||
severity: critical
|
||||
annotations:
|
||||
summary: "Exporter heartbeat is down: {{ instance }}"
|
||||
description: "{{ instance }} exporter is down for 5 mins"
|
||||
{% endfor %}
|
||||
- name: postgresql_heartbeat
|
||||
rules:
|
||||
- alert: Postgresql_Down
|
||||
expr: |
|
||||
(present_over_time(pg_up{instance="infra", job="postgres"}[5m]) or on() vector(0)) == 0
|
||||
for: 30s
|
||||
labels:
|
||||
severity: critical
|
||||
annotations:
|
||||
summary: "Postgresql Heartbeat Lost: postgresql"
|
||||
description: "postgresql node is down for 5 mins."
|
||||
- name: Certificate_expiry_check
|
||||
rules:
|
||||
{% for filename in ['root.crt', 'intermediate.crt', 'crowdsec.crt', 'blocky.crt', 'postgresql.crt', 'ldap.crt', 'prometheus.crt', 'loki.crt', 'dsm.crt'] %}
|
||||
- alert: {{ filename | replace('.', '_') }}_is_expired_soon
|
||||
expr: |
|
||||
max(x509_cert_not_after{filename="{{ filename }}"}) - time() < 2592000
|
||||
for: 1d
|
||||
labels:
|
||||
severity: critical
|
||||
annotations:
|
||||
summary: "{{ filename }} is expired in 30 days"
|
||||
description: "{{ filename }} is expired in 30 days."
|
||||
{% endfor %}
|
||||
@@ -0,0 +1,9 @@
|
||||
# Additionally, a certificate and a key file are needed.
|
||||
tls_server_config:
|
||||
cert_file: "/etc/ssl/prometheus/prometheus.crt"
|
||||
key_file: "/etc/ssl/prometheus/prometheus.key"
|
||||
|
||||
# Passwords are hashed with bcrypt: https://github.com/prometheus/exporter-toolkit/blob/master/docs/web-configuration.md#about-bcrypt
|
||||
#basic_auth_users:
|
||||
# alice: $2y$10$mDwo.lAisC94iLAyP81MCesa29IzH37oigHC/42V2pdJlUprsJPze
|
||||
# bob: $2y$10$hLqFl9jSjoAAy95Z/zw8Ye8wkdMBM8c5Bn1ptYqP/AXyV0.oy0S8m
|
||||
@@ -0,0 +1,38 @@
|
||||
[Quadlet]
|
||||
DefaultDependencies=false
|
||||
|
||||
[Unit]
|
||||
Description=Prometheus
|
||||
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Container]
|
||||
Image=docker.io/prom/prometheus:{{ version['containers']['prometheus'] }}
|
||||
|
||||
ContainerName=prometheus
|
||||
HostName=prometheus
|
||||
|
||||
PublishPort=9090:9090/tcp
|
||||
|
||||
Volume=%h/containers/prometheus/data:/prometheus:rw
|
||||
Volume=%h/containers/prometheus/etc:/etc/prometheus:ro
|
||||
Volume=%h/containers/prometheus/ssl:/etc/ssl/prometheus:ro
|
||||
|
||||
Environment="TZ=Asia/Seoul"
|
||||
|
||||
Exec=--config.file=/etc/prometheus/prometheus.yaml \
|
||||
--web.config.file=/etc/prometheus/web-config.yaml \
|
||||
--web.enable-remote-write-receiver \
|
||||
--storage.tsdb.path=/prometheus \
|
||||
--storage.tsdb.retention.time=30d \
|
||||
--storage.tsdb.retention.size=15GB \
|
||||
--storage.tsdb.wal-compression
|
||||
|
||||
[Service]
|
||||
Restart=always
|
||||
RestartSec=10s
|
||||
TimeoutStopSec=120
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
@@ -0,0 +1,26 @@
|
||||
[Quadlet]
|
||||
DefaultDependencies=false
|
||||
|
||||
[Unit]
|
||||
Description=x509-Exporter
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Container]
|
||||
Image=docker.io/enix/x509-certificate-exporter:{{ version['containers']['x509-exporter'] }}
|
||||
ContainerName=x509-exporter
|
||||
HostName=X509-exporter
|
||||
|
||||
Volume=%h/containers/x509-exporter/certs:/certs:ro
|
||||
|
||||
PublishPort=9793:9793
|
||||
|
||||
Exec=--listen-address :9793 --watch-dir=/certs
|
||||
|
||||
[Service]
|
||||
Restart=always
|
||||
RestartSec=10s
|
||||
TimeoutStopSec=120
|
||||
|
||||
[Install]
|
||||
WantedBy=default.target
|
||||
Reference in New Issue
Block a user