Files
alo-cluster/services/traefik.hcl

217 lines
5.4 KiB
HCL

job "traefik" {
datacenters = ["alo"]
group "lbs" {
network {
port "http" {
static = "80"
}
port "https" {
static = "443"
}
port "admin" {
#host_network = "tailscale"
static = "9002"
}
port "promtail_healthcheck" {}
}
task "traefik" {
driver = "docker"
service {
name = "traefik"
port = "https"
tags = [
"traefik.enable=true",
"traefik.http.routers.api.entryPoints=websecure",
"traefik.http.routers.api.rule=Host(`traefik.v.paler.net`)",
"traefik.http.routers.api.service=api@internal",
]
check {
type = "http"
port = "admin"
path = "/ping"
interval = "10s"
timeout = "2s"
}
}
service {
name = "traefik-admin"
port = "admin"
tags = [
"metrics"
]
}
config {
image = "traefik:latest"
ports = ["http", "https", "admin"]
network_mode = "host"
volumes = [
"local/traefik.yml:/etc/traefik/traefik.yml",
"/data/compute/config/traefik:/config",
]
}
template {
data = <<EOH
#log:
# level: debug
entryPoints:
web:
address: ":{{{ env "NOMAD_PORT_http" }}}"
http:
redirections:
entrypoint:
to: websecure
scheme: https
permanent: true
websecure:
address: ":{{{ env "NOMAD_PORT_https" }}}"
http:
tls:
certResolver: letsencrypt
admin:
address: ":{{{ env "NOMAD_PORT_admin" }}}"
api:
dashboard: true
accessLog: {}
metrics:
prometheus:
entryPoint: admin
manualrouting: true
ping:
entryPoint: admin
serversTransport:
insecureSkipVerify: true
providers:
file:
directory: /config/rules
watch: true
consulcatalog:
exposedByDefault: false
prefix: "traefik"
defaultRule: "Host(`{{ .Name }}.v.paler.net`)"
certificatesResolvers:
letsencrypt:
acme:
email: petru@paler.net
storage: /config/acme/acme.json
tlsChallenge: {}
global:
checkNewVersion: false
sendAnonymousUsage: false
EOH
destination = "local/traefik.yml"
change_mode = "noop"
left_delimiter = "{{{"
right_delimiter = "}}}"
}
resources {
cpu = 100
memory = 512
}
}
task "keepalived" {
driver = "docker"
env {
KEEPALIVED_INTERFACE = "eno1"
KEEPALIVED_VIRTUAL_IPS = "192.168.1.100/24"
KEEPALIVED_UNICAST_PEERS = ""
KEEPALIVED_STATE = "MASTER"
KEEPALIVED_VIRTUAL_ROUTES = ""
}
config {
# 2.2.8 wasn't starting, reason unknown
image = "visibilityspots/keepalived:2.2.7"
network_mode = "host"
privileged = true
cap_add = ["NET_ADMIN", "NET_BROADCAST", "NET_RAW"]
}
}
task "promtail" {
driver = "docker"
config {
image = "grafana/promtail:2.2.0"
args = [
"-config.file",
"local/config.yaml",
"-print-config-stderr",
]
# the only port required is for the healthcheck
ports = ["promtail_healthcheck"]
}
# the template with Promtail's YAML configuration file, configuring the files to scrape,
# the Loki server to send the logs to (based on a registered Consul service, but it could be a fixed URL),
# the regex to parse the Common Log Format (https://en.wikipedia.org/wiki/Common_Log_Format) used for access logs,
# and the labels ( HTTP method and status code)
template {
data = <<EOH
server:
http_listen_port: {{ env "NOMAD_PORT_promtail_healthcheck" }}
grpc_listen_port: 0
positions:
filename: /alloc/positions.yaml
client:
url: http://{{ range service "loki" }}{{ .Address }}:{{ .Port }}{{ end }}/loki/api/v1/push
scrape_configs:
- job_name: local
static_configs:
- targets:
- localhost
labels:
job: traefik
__path__: "/alloc/logs/traefik.std*.0"
pipeline_stages:
- regex:
expression: '^(?P<remote_addr>[\w\.]+) - (?P<remote_user>[^ ]*) \[(?P<time_local>[^\]]+)\] "(?P<method>[^ ]*) (?P<request>[^ ]*) (?P<protocol>[^ ]*)" (?P<status>[\d]+) (?P<body_bytes_sent>[\d]+) "(?P<http_referer>[^"]*)" "(?P<http_user_agent>[^"]*)"? (?P<total_requests>\d+) "(?P<frontend_name>.+)" "(?P<backend_url>.+)" (?P<duration_ms>\d+)ms'
- labels:
method:
status:
frontend_name:
EOH
destination = "local/config.yaml"
}
resources {
cpu = 50
memory = 256
}
# poststart, and sidecar=true, so Promtail will start *after* Traefik ( since it has nothing to do before Traefik isup and running),
# and run for as long as it does
lifecycle {
hook = "poststart"
sidecar = true
}
# a service for a health check to determine the state of Promtail
service {
check {
type = "http"
port = "promtail_healthcheck"
path = "/ready"
interval = "10s"
timeout = "2s"
}
}
}
}
}