متعادل کردن بارگذاری و پروکسی بازگشتی به وسیله Traefik

گردآوری و تالیف : علیرضا معمارزاده
تاریخ انتشار : 02 آذر 1398
دسته بندی ها : آموزشی

Traefik یک پروکسی بازگشتی و متعادل‌کننده بارگذاری HTTP مدرن است که توسعه میکروسرویس‌ها را آسان می‌کند.

Traefik  با کامپوننت‌های شما به آسانی سازگار می‌شود (Docker،  Rancher،Amazon ECS  و ...) و به‌صورت خودکار و پویا تنظیم می‌شود. در مرحله تنظیم آن، تنها کاری که شما انجام می‌دهید اشاره کردن به آن است.

متعادل کردن بارگذاری و پروکسی بازگشتی به وسیله Traefik

در این مقاله، من به شما نشان می‌دهم که چگونه می‌توانید Traefik نسخه 1 .7. 12 (نسخه 2 alpha درحال حاضر قابل ‌دسترسی است، در این لینک می‌توانید بیشتر درباره آن بخوانید) را روی زیرساخت Rancher نصب کنید. 

با استفاده از آن، پروسه نمایش برنامه کاربردی شما و همچنین گرفتن گواهی‌های SSL/TLS از خدمات «Let's Encrypt» آسان می‌شود. 

در ادامه این مطالب آموزشی، فرض شده است که شما دانش کلی و اساسی درمورد Docker و Rancher دارید.

ملزومات:

  • Rancher(که نصب‌شده و قابل‌اجرا است)
  • Traefik(نگران نباشید کاملاً رایگان است)
  • تعدادی وب اپلیکیشن برای توسعه

بیایید مبحث را با ایجاد یک فایل تنظیمات آغاز کنیم

چون می‌خواهیم از آن روی Rancher استفاده کنیم، ابتدا نیاز داریم که امکانات Rancher را فعال کنیم:

# Enable Rancher Provider.
[rancher]

  # Default base domain used for the frontend rules.
  domain = "<BASE_DOMAIN>"

  # Expose Rancher services by default in Traefik.
  # If true all services will be accessed on <PROTOCOL>://<SERVICE_NAME>.<STACK_NAME>.<DOMAIN>:<HTTP_PORT>
  exposedByDefault = false

  # Expose only services with a healthy state.
  enableServiceHealthFilter = true

  # Credentials for Rancher API
  [rancher.api]

    # Endpoint to use when connecting to the Rancher API.
    # It is a little bit tricky as we will configure the domain for Rancher later in this article.
    endpoint = "https://<RANCHER_DOMAIN>/v1"

    # Credentials for Rancher API
    accessKey = "<RANCHER_ACCESS_KEY>"
    secretKey = "<RANCHER_SECRET_KEY>"

گواهینامه‌ها می‌توانند در صفحه API/Keys در Rancher ایجاد شوند. 

فقط روی دکمه «Add Environment API Key» کلیک کنید. سپس ما نقاط ورودی برای تمام برنامه‌های کاربردی را تنظیم می‌کنیم.

# Entrypoints to be used by frontends that do not specify any entrypoint.
# Each frontend can specify its own entrypoints.
defaultEntryPoints = ["http", "https"]

# Entrypoints definition.
[entryPoints]

  # HTTP definition.
  [entryPoints.http]
         
    # Default 80 port for HTTP requests.
    address = ":80"

    # Enable gzip compression
    # Responses are compressed when:
    # - The response body is larger than 512 bytes
    # - And the Accept-Encoding request header contains gzip
    # - And the response is not already compressed
    compress: true

  # HTTPS definition.
  [entryPoints.https]

    # Default 443 port for HTTPS requests.
    address = ":443"

    # Enable TLS encryption on HTTPS endpoints.
    [entryPoints.https.tls]

برای گرفتن صحیح گواهینامه‌ها از «Let's encrypt» نیاز به راه‌اندازی پروتکل ACME) Automatic Certificate Management Environment) داریم.

# Enable ACME.
[acme]

# Email address used for registration on Let’s Encrypt.
email = "<EMAIL_ADDRESS>"

# File used for certificate storage.
storage = "/etc/traefik/acme/acme.json"

# Entrypoint to proxy acme apply certificates to.
entryPoint = "https"

# Enable certificate generation on frontend host rules.
onHostRule = true

# Use a HTTP-01 ACME challenge.
[acme.httpChallenge]

  # USE HTTP endpoint for this challenge.
  entrypoint = "http"

الان می‌توانیم دامنه‌ای برای Rancher تنظیم کنیم.

[file]

[backends]

  # Set name of backend describing Rancher. We name it "rancher".
  [backends.rancher]

    [backends.rancher.servers]

      [backends.rancher.servers.server0]

        # URL to Rancher server.
        url = "https://<RANCHER_IP>:<RANCHER_PORT>"
     
        # As this is a single instance Rancher, we can set the weight to 1. All requests will be handled by this server.
        weight = 1

[frontends]

  # Set name of frontend describing Rancher. We use the same name "rancher".
  [frontends.rancher]

    # Backend which will handle requests.
    backend = "rancher"

    # Forward client Host header to the backend.
    passHostHeader = true

      [frontends.rancher.routes]

        [frontends.rancher.routes.route0]

          # Use this frontend only when the request contains Host header with our domain.
          rule = "Host:<RANCHER_DOMAIN>"

درحال حاضر Traefik باید تمام درخواست‌هایی را که به Rancher Server ارسال شده است، به‌درستی مدیریت کند. علاوه بر این باید یک گواهی جدید برای <RANCHER_DOMAIN> بگیرد و ارتباط به آن را از طریق پروتکل امن HTTPS ممکن سازد.

ما همچنین می‌توانیم برای مواقعی که شبکه دچار نقص می‌شود، یک گزینه برای تلاش مجدد درخصوص ارسال درخواست‌ها تعریف کنیم.

ما فایل تنظیمات را به‌صورت مستقیم در سرور در آدرس زیر ذخیره می‌کنیم:

« /home/docker/traefik/traefik.toml »

فایل کلی تنظیمات برای Traefik به‌صورت زیر است:

defaultEntryPoints = ["http", "https"]

[rancher]
  domain = "<BASE_DOMAIN>"
  exposedByDefault = false
  enableServiceHealthFilter = true

  [rancher.api]
    endpoint = "https://<RANCHER_DOMAIN>/v1"
    accessKey = "<RANCHER_ACCESS_KEY>"
    secretKey = "<RANCHER_SECRET_KEY>"

[entryPoints]

  [entryPoints.http]
    address = ":80"

  [entryPoints.https]
    address = ":443"

    [entryPoints.https.tls]

[acme]
  email = "<EMAIL_ADDRESS>"
  storage = "/etc/traefik/acme/acme.json"
  entryPoint = "https"
  onHostRule = true

  [acme.httpChallenge]
    entrypoint = "http"

[retry]

[file]

[backends]
  [backends.rancher]
    [backends.rancher.servers]
      [backends.rancher.servers.server0]
        url = "https://<RANCHER_IP>:<RANCHER_PORT>"
        weight = 1

[frontends]
  [frontends.rancher]
    backend = "rancher"
    passHostHeader = true

      [frontends.rancher.routes]
        [frontends.rancher.routes.route0]
          rule = "Host:<RANCHER_DOMAIN>"

بعد از ذخیره این فایل تنظیمات روی سرور، یک فایل جدید خالی به نام acme.json در کنار آن ایجاد کنید. الان ما آماده ایجاد یک پشته جدید برای Traefik روی Rancher هستیم.

ایجاد یک پشته جدید برای Traefik

نکته مهم: شما باید هر پروکسی بازگشتی عمومی قابل ‌دسترس دیگری را غیرفعال کنید و برای این کار باید با استفاده از آدرس IP، Rancher را باز کنید. 

بعد از توقف کار اولیه پروکسی بازگشتی و اطمینان از اینکه محفظه‌ای با پورت‌های 80 یا 443 قابل‌نمایش برای عموم وجود ندارد، روی دکمه «create a new stack» کلیک کنید. 

فایل docker-compose.yml را آپلود کنید (البته این موارد را مطابق با آدرس مسیری که فایل تنظیمات را ذخیره کردید، بروزرسانی کنید):

version: '2'
services:
  traefik:
    image: traefik:v1.7.12
    stdin_open: true
    volumes:
    - /home/docker/traefik/traefik.toml:/etc/traefik/traefik.toml
    - /home/docker/traefik/acme.json:/etc/traefik/acme/acme.json
    tty: true
    ports:
    - 80:80/tcp
    - 443:443/tcp
    labels:
      io.rancher.container.pull_image: traefik:v1.7.12

بعد از طی این مراحل، آماده استفاده از Traefik برای مدیریت درخواست‌هایی که به‌وسیله وب اپلیکیشن خودمان ساخته‌شده است، هستیم. Rancher هم باید روی URL رمزدار (ایمن) زیر قابل‌دسترسی باشد:

https://<RANCHER_DOMAIN>

از  Traefik روی وب اپلیکیشن خودتان استفاده کنید

در مرحله آخر، به یک وب اپلیکیشن نیاز داریم. من از یک برنامه "Hello World" خیلی پیچیده استفاده می‌کنم. یک پشته جدید برای آن ایجاد می‌کنم. مواردی که برای Traefik مهم هستند، مجموعه برچسب‌ها برای یک مخزن خاص است.

این مخزن را در Traefik فعال کنید:

traefik.enable: 'true'

 نام مخزن را در backend بگذارید:

traefik.backend: node-hello-world

پورت را در وب اپلیکیشنی که فهرست می‌شوند، ثبت کنید (پورت داخلی docker):

traefik.port: '8080'

از این مخزن تنها زمانی استفاده کنید که درخواست، شامل Host اصلی با دامنه ما باشد:

traefik.frontend.rule: Host:<DOMAIN>

دامنه را جاگذاری کنید:

traefik.domain: <DOMAIN>

پروتکل پیشفرض HTTP را لغو کنید:

traefik.frontend.protocol: https

مجدداً از HTTP به پروتکل HTTPS تغییر مسیر دهید:

traefik.frontend.redirect.entryPoint: https

در این تغییر مسیر مجدد، 301 را جایگزین 302 کنید:

traefik.frontend.redirect.permanent: 'true'

بعد از جاگذاری برچسب‌های صحیح روی وب اپلیکیشن ما، دسترسی به آن روی دامنه فراهم‌شده امکانپذیر است. 

فایل docker-compose.yml که من از آن برای وب اپلیکیشنِ خودم به نام «Hello World» استفاده می‌کنم، به‌صورت زیر است:

version: '2'
services:
  node-hello-world:
    image: heroku/nodejs-hello-world
    environment:
      PORT: '8080'
    stdin_open: true
    tty: true
    labels:
      io.rancher.container.pull_image: always
      traefik.enable: 'true'
      traefik.backend: node-hello-world
      traefik.port: '8080'
      traefik.frontend.rule: Host:<DOMAIN>
      traefik.domain: <DOMAIN>
      traefik.frontend.protocol: https
      traefik.frontend.redirect.entryPoint: https
      traefik.frontend.redirect.permanent: 'true'

کلام آخر

در این مقاله به بررسی، Traefik که یک پروکسی بازگشتی است که به توسعه‌دهندگان اجازه می‌دهد، وب اپلیکیشنِ خودشان را به‌آسانی روی دامنه‌ها به نمایش بگذارند، پرداختیم. با پشتیبانی «Let's Encrypt» به‌صورت خودکار سرویس‌های جدید را کشف می‌کند و گواهی‌های SSL/TLS را دریافت می‌کند. 

همچنین به‌طور مداوم تنظیمات خودش را بروزرسانی می‌کند؛ بنابراین نیازی به شروع دوباره ندارد.

اطلاعات بیشتر در مورد Traefik را در این لینک بخوانید.

منبع

مقالات پیشنهادی

  • بهتر کردن تجربه کاربری در ۵ دقیقه

    ما زمان زیادی نداریم. همانطور که شما مشغول خواندن این مطلب هستید، ممکن است کارهای بسیار دیگری داشته باشید که نیاز به انجام دادن دارند؛ پیام‌های شبکه‌ه...

    ارسطو عباسی
  • چگونگی تاثیرگذاری لمس کردن بر UX

    همانند اکثر مردم ، من هم هر روز و هر دقیقه اشیا را با دستانم کنترل می کنم بدون اینکه ذره ای به آن فکر کنم . من برای تایپ کردن این پست از انگشتانم استف...

    مهین کیان