x

Menü

traefik und Hashorp Consul mit terraform

veröffentlicht in: Infrastructure as a Service DevOps HashiCorp Datum: 27.06.2019
Martin Buchleitner, Senior IT-Consultant

Über den Autor

Martin Buchleitner ist ein Senior IT-Berater für Infralovers und für Commandemy. Twitter github LinkedIn

Alle Artikel von diesem Autor sehen

Traefik und Hashicorp Consul mit Terraform

Wenn man eine Lösung sucht, um einen Reverse Proxy oder Load Balancer aufzusetzen, ohne dafür aber eine sehr lange Konfigurationsdatei schreiben und warten zu müssen, dann ist die Kombination von Traefik mit Consul vielleicht die richtige Lösung.

Traefik implementiert einen Zugriff auf Consul, um von dort seine Konfigurationsdaten zu beziehen. Dies erlaubt einem sämtliche Konfigurationen im Key/Value-Store von Consul abzulegen und Traefik nimmt diese Änderungen wahr und lädt sich selbstständig neu.

logLevel = "INFO"
defaultEntryPoints = ["http", "https"]

[consul]
  endpoint = "${consul_backend}"
  watch = true
  prefix = "${prefix}"

[entryPoints]
  [entryPoints.http]
    address = ":80"
  [entryPoints.https]
    address = ":443"
    [entryPoints.https.tls]

[acme]
  email = "it-is-me@example.com"
  storage = "${prefix}/acme/account"
  entryPoint = "https"
  caServer = "https://acme-staging-v02.api.letsencrypt.org/directory"
  [acme.httpChallenge]
    entryPoint = "http"
  [acme.dnsChallenge]
    provider = "dnsimple"
    delayBeforeCheck = 0
[[acme.domains]]
    main = "*.example.com"
    sans = ["example.com"]

In unserem Beispiel verwenden wir nun ein Docker whoami Image, um die Skalierung und das Loadbalancing im Hintergrund zu veranschaulichen.

Außerden werden wir das ganze auch mittels Terraform ausrollen. Zu allererst definiert man die Variablen, um auf den Hosts dann die Docker Container zu starten. Die beiden Hosts wurden so provisioniert, dass der Docker-Port im lokalen Netz verfügbar ist.

variable "traefik_version" {
  default = "v1.7.11"
}
variable "consul_version" {
  default = "1.5"
}
variable "traefik_host" {
  default = "10.0.0.10"
}
variable "backend_host" {
  default = "10.10.0.20"
}
variable "prefix" {
  default = "traefik"
}
variable "consul_backend" {
  default = "10.10.0.20:8500"
}
variable "domain" {
  default = "example.com"
}

Anschließend muss Consul ausgerollt werden:


provider "docker" {
  host = "tcp://${var.backend_host}:2376/"
}
resource "docker_image" "consul" {
  name = "consul:${var.consul_version}"
}
resource "docker_container" "consul" {

  image    = "${docker_image.consul.latest}"
  name     = "consul"
  must_run = true
  restart  = "always"

  ports {
    internal = 8500
    external = 8500
    protocol = "tcp"
  }
}

Auf diesem Host wird dann auch das whoami Image laufen:

resource "docker_image" "whoami" {
  name = "jwilder/whoami"
}
resource "docker_container" "whoami" {

  image    = "${docker_image.whoami.latest}"
  name     = "whoami"
  must_run = true
  restart  = "always"

  ports {
    internal = 8000
    external = 8000
    protocol = "tcp"
  }
}

Zum Schluss muss Traefik auf seinem eigenen Host definiert und ausgerollt werden:

provider "docker" {
  host = "tcp://${var.traefik_host}:2376/"
}

data "template_file" "traefik_config" {
  template = "${file("templates/traefik.tpl")}"

  vars {
    consul_backend = "${var.consul_backend}"
    prefix         = "${var.prefix}"
  }
}

resource "docker_container" "traefik" {
  depends_on = ["consul_keys.whoami"]

  image    = "${docker_image.traefik.latest}"
  name     = "traefik_proxy"
  must_run = true
  restart  = "always"

  ports {
    internal = 80
    external = 80
    protocol = "tcp"
  }

  ports {
    internal = 443
    external = 443
    protocol = "tcp"
  }

  upload {
    content = "${join(",", data.template_file.traefik_config.*.rendered)}"
    file    = "/etc/traefik/traefik.toml"
  }

  volumes {
    host_path      = "/srv/traefik"
    container_path = "/srv/"
    read_only      = false
  }
}

Damit nun alle Services miteinander reden können, muss diese Information in Consul abgelegt werden. Auch hier wird Terraform dafür verwendet, diese Daten anzulegen und zu warten:

resource "consul_keys" "whoami" {
  key {
    path  = "${var.prefix}/acme/account/"
    value = ""
  }

  key {
    path  = "${var.prefix}/backends/whoami/servers/server1/url"
    value = "http://${var.backend_host}:8000/"
  }

  key {
    path  = "${var.prefix}/backends/whoami/servers/server1/weight"
    value = "10"
  }

  key {
    path  = "${var.prefix}/frontends/frontend1/backend"
    value = "whoami"
  }

  key {
    path  = "${var.prefix}/frontends/frontend1/routes/whoami/rule"
    value = "Host: whoami.${var.domain}"
  }
}

Nach diesem Konfigurationschritt lädt Traefik seine Konfiguation neu. Ein Zugriff auf wird an Traefik und von diesem an einen `whoami` Container mit der entsprechenden ID weitergeleitet.