3 คะแนน โดย GN⁺ 2024-05-06 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • Traefik เป็นที่รู้จักในสภาพแวดล้อมคอนเทนเนอร์ แต่สามารถแจกจ่ายเป็น ไฟล์รันได้เดี่ยวที่เขียนด้วย Go จึงใช้งานเป็นรีเวิร์สพร็อกซีได้โดยไม่ต้องมี container engine
  • มันเป็น พร็อกซีที่ใกล้เคียงกับ HAProxy มากกว่า กลุ่ม nginx/caddy/apache2 ที่เน้นเสิร์ฟไฟล์โดยตรง โดยโฟกัสที่การส่งต่อคำขอ การส่งกลับคำตอบ และการปรับแต่งเฮดเดอร์
  • แม้ไม่ใช้ Docker label ก็สามารถตั้งค่าด้วย configuration file provider ได้ และแยก static config กับ dynamic config เพื่อจัดการ router, service และ middleware
  • รองรับ TLS Passthrough และการรับส่ง PROXY protocol ของ HAProxy แต่บริการปลายทางก็ต้องรองรับ PROXY protocol ด้วย ซึ่ง apache2 และ nginx รองรับ
  • การรวมระบบยืนยันตัวตนและการบล็อก user agent/IP อาจไม่พอด้วยความสามารถพื้นฐานเพียงอย่างเดียว จึงต้องชั่งน้ำหนักภาระในการดูแล ForwardAuth, oauth2-proxy และปลั๊กอินจากภายนอกด้วย

Traefik ที่ใช้ได้นอกคอนเทนเนอร์

  • Traefik ได้รับความนิยมในกลุ่ม home-lab บน YouTube ช่วงไม่กี่ปีที่ผ่านมา และมักถูกแนะนำควบคู่กับ โครงสร้างพื้นฐานคอนเทนเนอร์ อย่าง Docker หรือ Kubernetes
  • ในเชิงลักษณะการทำงาน มันใกล้กับ HAProxy มากกว่า nginx/caddy/apache2
    • ส่งต่อคำขอไปยังบริการและส่งกลับคำตอบ
    • ปรับแต่งเฮดเดอร์และบางส่วนของคำขอ/คำตอบได้
    • ไม่รองรับการเสิร์ฟไฟล์
  • ในสภาพแวดล้อมคอนเทนเนอร์ Traefik มักรันเป็นคอนเทนเนอร์เช่นกัน และสามารถเมานต์ Docker socket เพื่อค้นหาคอนเทนเนอร์อื่นโดยอัตโนมัติ
    • พฤติกรรมของพร็อกซีตั้งค่าได้ผ่าน Docker label ของคอนเทนเนอร์
    • เมื่อตรวจพบคอนเทนเนอร์ใหม่ ก็สามารถขอใบรับรอง TLS จาก Let’s Encrypt อัตโนมัติและเปิดเผยบริการได้

การแจกจ่ายแบบไบนารีเดี่ยวและ systemd

  • Traefik เขียนด้วย Go และคอมไพล์เป็น ไฟล์รันได้เดี่ยว
  • สามารถดาวน์โหลดไบนารีได้จาก เอกสารติดตั้ง Traefik
  • สามารถรันทั้ง Traefik และบริการปลายทางได้โดยไม่ต้องมี container engine
  • ตัวอย่าง systemd service unit อยู่ใน รีโพซิทอรีของ Traefik
  • ในการใช้งานจริง นอกจากไฟล์ตั้งค่าแล้ว ยังต้องสร้างผู้ใช้แยกและตั้งค่าสิทธิ์ของไฟล์ตั้งค่าด้วย

การตั้งค่าแบบอิงไฟล์คอนฟิก

  • หากไม่ใช้คอนเทนเนอร์ ก็จะใช้ Docker label ไม่ได้ แต่ Traefik สามารถตั้งค่าได้ผ่าน file provider
  • โดยหลักแล้วการตั้งค่าจะแบ่งเป็นสองส่วน
    • Static config: กำหนดผู้ให้บริการใบรับรอง เช่น Let’s Encrypt และ entrypoint ซึ่งเป็นพอร์ตที่ Traefik รับคำขอ
    • Dynamic config: กำหนด router, service และ middleware
  • Traefik สามารถตรวจจับ file system event เพื่อทำ hot reload ของ dynamic config ได้
  • เอกสารมีทั้งแนวคิดหลักและตัวอย่างการตั้งค่าตามแต่ละวิธี
  • สามารถดูคำอย่าง certificate provider, entrypoint, router, service, middleware ได้อย่างรวดเร็วใน เอกสารของ Traefik

พฤติกรรมหลังตั้งค่าและการดีบัก

  • เมื่อการตั้งค่าไม่ถูกต้อง Traefik จะแสดงคำเตือน
  • แม้ log เริ่มต้นจะไม่ได้มีมากนัก แต่ก็เข้าใจได้ง่ายว่าคำขอวิ่งผ่านเส้นทางไหน
  • จากประสบการณ์ใช้งาน การตั้งค่าเริ่มต้นเสร็จได้รวดเร็วและไม่เจอปัญหาแปลก ๆ

TLS Passthrough และ PROXY protocol

  • Traefik รองรับ TLS Passthrough
    • พร็อกซีสามารถส่งทราฟฟิกต่อไปยังเว็บเซอร์วิสที่มีใบรับรอง TLS ของตัวเองได้ โดยไม่ต้อง terminate TLS ที่พร็อกซี
    • สามารถจัดให้บริการร้องขอใบรับรอง Let’s Encrypt ได้เองแม้จะวิ่งผ่าน Traefik
    • พร็อกซีจะไม่สามารถเห็นเนื้อหาที่ถูกส่งผ่านได้
  • ปกติการเลือก virtual host จะอาศัย HTTP Host header แต่ใน TLS Passthrough เฮดเดอร์นี้อยู่ในเนื้อหาที่ถูกเข้ารหัส จึงใช้ไม่ได้
  • จึงเลือกโฮสต์ปลายทางด้วย SNI(Server Name Indication) ของ TLS และ Traefik รวมถึงเว็บเซิร์ฟเวอร์/พร็อกซีหลายตัวก็ใช้วิธีนี้
  • ยังรองรับการรับส่ง PROXY protocol ของ HAProxy ด้วย
    • เป็นวิธีส่งต่อข้อมูลที่หายไประหว่างผู้ใช้มาถึงพร็อกซี ไปยังบริการปลายทาง
    • ถูกมองว่าจัดการด้านความปลอดภัยได้ง่ายกว่าเฮดเดอร์ X-Forwarded-... แบบเดิม
    • บริการปลายทางเองก็ต้องรองรับ PROXY protocol
    • apache2 และ nginx รองรับ และรายชื่อบริการที่รองรับก็กำลังเพิ่มขึ้น

จุดที่ยังขาดในการรวมระบบยืนยันตัวตน

  • บน nginx สามารถใช้ Vouch Proxy เพื่อปกป้องบางบริการด้วย Azure AD ซึ่งปัจจุบันคือ Microsoft Entra authentication ได้
  • Traefik รองรับ ForwardAuth ที่คล้ายกับรูปแบบการยืนยันตัวตนของ nginx
  • แต่ Vouch Proxy ยังใช้งานกับ Traefik ไม่ได้ และมี issue ที่เปิดค้างอยู่
  • สามารถรันอินสแตนซ์ Keycloak เองแล้วเชื่อมกับ AAD เพื่อนำมาใช้กับ ForwardAuth ได้ แต่ภาระในการตั้งค่าเริ่มต้น การดูแลความปลอดภัย และการอัปเดตค่อนข้างสูง
  • traefik-forward-auth มักถูกแนะนำบ่อย แต่มีการอัปเดตล่าสุดในเดือนมิถุนายน 2020 และต้องอัปเดต dependency จึงถูกมองว่าใช้งานได้ยาก
  • oauth2-proxy เคยให้ประสบการณ์ไม่ดีในอดีต และการวางพร็อกซีซ้อนพร็อกซีทำให้ต้องตั้งค่า HTTP/2·HTTP/3, timeout, ขนาด body และ WebSocket ให้ตรงกันในพร็อกซีแต่ละชั้น ซึ่งเพิ่มโอกาสเกิดข้อผิดพลาด
  • ตามอัปเดตวันที่ 2024-05-06 oauth2-proxy ยังสามารถรวมระบบผ่าน HTTP API ได้ด้วย
    • รองรับ auth_request ของ nginx
    • รองรับ ForwardAuth ของ Traefik
    • วิธีนี้ดูใกล้เคียงกับตัวเลือกที่ต้องการมากกว่า

การบล็อก user agent และ IP

  • มีกรณีที่ไม่ต้องการให้บริการภายในถูก archive โดย archive.org
  • robots.txt และเฮดเดอร์ลักษณะคล้ายกันไม่ช่วยบล็อก Archive.org โดยวิธีบล็อก crawler คือบล็อก user agent archive.org_bot หรือบล็อกช่วง IP
  • หากต้องการบล็อก user agent หรือ IP address ใน Traefik จะต้องใช้ ปลั๊กอินจากภายนอก ไม่ใช่ความสามารถพื้นฐาน
    • ปลั๊กอินบล็อก user agent
    • ปลั๊กอิน deny IP
  • ปลั๊กอินจากภายนอกต้องคอยดูแลตอนอัปเดต และอาจก่อให้เกิดช่องโหว่ด้านความปลอดภัย จึงไม่นิยมใช้
  • สามารถใช้ IPAllowList middleware ในรูปแบบอนุญาตทุกอย่างยกเว้น IP ที่ต้องการบล็อกได้
    • รองรับการคำนวณช่วง IP ด้วย
    • แม้จะไม่แย่ไปกว่าการบล็อกโดยตรง แต่การมองจาก subnet ที่เหลืออยู่เพียงอย่างเดียวทำให้รู้ได้ยากว่าช่วงใดถูกบล็อก จึงไม่ค่อย elegant นัก

โครงสร้างตัวอย่างการตั้งค่า

  • ตัวอย่างแบ่งเป็น /etc/traefik/traefik.yml และ /etc/traefik/dynamic.yml
  • Static config ตั้งค่าดังนี้
    • entrypoint :80 และ :443
    • รีไดเรกต์ HTTP endpoint ไป HTTPS โดยไม่มีข้อยกเว้น
    • ออกใบรับรอง Let’s Encrypt โดยใช้ TLS challenge
    • เฝ้าดูไฟล์ dynamic config ที่ /etc/traefik/dynamic.yml
  • Dynamic config มีองค์ประกอบดังนี้
    • TCP routing แบบ TLS Passthrough สำหรับ cloud.xx.xyz
    • ส่งต่อไปยังบริการ 10.33.1.2:4433 ของโฮสต์อื่น
    • เปิดใช้ PROXY protocol version 2
    • สำหรับ git.xx.xyz ให้ terminate TLS แล้วพร็อกซีไปยัง http://127.0.0.1:3000
    • middleware สำหรับรีไดเรกต์ https://xx.xyz/redirmepls ไปยัง https://google.com
    • middleware ที่เพิ่มเฮดเดอร์ X-Robots-Tag: noindex, nofollow, nosnippet, noarchive

1 ความคิดเห็น

 
GN⁺ 2024-05-06
ความคิดเห็นจาก Hacker News
  • Traefik ถือว่าดีทีเดียว แต่เจอปัญหาแย่ ๆ แบบเดียวกับ Ansible คือมีเอกสารและบทความเยอะมาก แต่กลับหาเรื่องที่ต้องการจริง ๆ ไม่เจอ
    ใช้มาตั้งแต่ v1 แล้ว แต่ก็ยังหลงทางในเอกสารอยู่บ่อย ๆ และรู้สึกหงุดหงิดมาก สำหรับโปรเจกต์เล็ก ๆ มักจะใช้ Caddy แทน เพราะเอกสารไม่ได้แย่เท่า Traefik
    ถ้าจะบอกกับคนเขียนเอกสารทางเทคนิคก็คือ เอกสารแบบเน้นตัวอย่าง ดีแค่สำหรับมือใหม่ที่เปิดไล่ดูเท่านั้น คนที่คุ้นเคยกับผลิตภัณฑ์แล้วต้องการ เอกสารอ้างอิงและรายการที่ครบถ้วน ไม่ใช่คำอธิบายฟิลด์ที่กระจัดกระจายอยู่ตามหน้าทูโทเรียล 10 หน้า อย่าโฟกัสแค่ขั้นตอน onboarding แต่ควรปรับให้เหมาะกับคนที่ใช้ผลิตภัณฑ์ทุกวันด้วย
    นี่คือจุดที่กวนใจที่สุด และเป็นเหตุผลที่ทำให้เกลียด Ansible ขนาดนั้น ส่วน Traefik ก็คล้ายกัน แม้จะน้อยกว่าก็ตาม

    • เห็นด้วย คิดว่าถ้า framework สำหรับการทำเอกสาร อย่าง https://diataxis.fr เป็นที่รู้จักกว้างขึ้น ก็น่าจะเป็นประโยชน์กับทุกคน
    • สิ่งที่เพิ่งทำให้หงุดหงิดในหมวดนี้คือ OpenTelemetry มีเอกสารเป็นพัน ๆ หน้า แต่แทบไม่มีวิธีทำ workflow พื้นฐานที่พบได้ทั่วไปให้สำเร็จจริง ๆ
    • ปัญหาอย่างหนึ่งของสิ่งที่อาจเรียกได้ว่าเป็นตระกูลภาษาแบบตัวแปล YAML คือ ตัว YAML เองก็เป็นภาษา แต่เอกสารของตัวแปลมักไม่ค่อยอธิบายส่วนนั้น
      มักสมมติว่าจะทำงานง่ายมาก ๆ กับโครงสร้างข้อมูลที่แบนมากเท่านั้น แต่ความเป็นจริงส่วนใหญ่ไม่ได้เป็นแบบนั้น ถ้าจะใช้ภาษาเหล่านี้ให้ถูกต้อง ต้องเข้าใจกฎโดยนัยทั้งหมดเกี่ยวกับวิธีใช้ YAML แต่เอกสารแทบไม่แตะเรื่องนี้เลย
      มีเอกสารการตั้งค่าเฉพาะของแต่ละโมดูลก็จริง แต่แทบไม่ชัดเจนเลยว่าจะใช้การตั้งค่ามาตรฐานอย่างไร จะจัดการข้อมูลที่คืนกลับมาอย่างไร หรือจะนำไปผสานกับสิ่งที่ซับซ้อนขึ้นอีกนิดอย่างไร เหมือนโยนตัวอย่างย่อหน้าสั้น ๆ เป็นสิบ ๆ อันต่อหนึ่งรายการมาเป็นกองวัตถุดิบ แล้วบอกให้เราอบเค้กเอง
      จากระบบตัวแปล YAML หลายตัวที่เคยใช้ ประสบการณ์แทบจะเหมือนกันเสมอ และกว่าจะทำงานได้ก็ต้องผ่าน YAML ไปหลายแสนบรรทัด แต่เอกสารแทบไม่มีคุณค่าเกินกว่ารายการการตั้งค่า
    • Ansible ทำให้ต้องเปิดหาเอกสารอยู่เรื่อย ๆ จริง ๆ
      ถึงอย่างนั้นพอใช้ ansible-doc ก็พบ workflow ที่ค่อนข้างดี โดย alias ที่ใช้บ่อยคือ alias adl='ansible-doc --list', alias adls='ansible-doc --list | less -S', alias ad='ansible-doc'
      เริ่มจากใช้ adls ค้นหาคำสั่งที่เกี่ยวข้องอย่างรวดเร็ว จากนั้นใช้ ad ดูเอกสาร แล้วแทบทุกครั้งจะกระโดดไปท้ายเอกสารทันที (G) เพื่อดูตัวอย่าง ปกติคำตอบที่ต้องการจะอยู่ตรงนั้นพอดี
      การเขียนสคริปต์ Ansible พึ่งพาเอกสารสูงมาก ดังนั้นคิดว่าแม้ในสถานะเริ่มต้นก็ควรรองรับกระบวนการค้นหาแบบนี้ให้ดีกว่านี้ และควรมีอินเทอร์เฟซที่ค้นหาได้รวดเร็วโดยไม่ต้องสร้าง alias ไว้เต็มไปหมด
    • Pydantic ก็อยู่ในหมวดนี้สำหรับผม ผู้ดูแลมองว่าควรมีแหล่งข้อมูลเพียงแหล่งเดียว และปฏิเสธที่จะทำ เอกสารอ้างอิง API
      แน่นอนว่าเป็นโปรเจกต์ของเขาเอง แต่ทุกครั้งที่ต้องการหาเมธอดสักตัวของอ็อบเจ็กต์ ก็ต้องไล่อ่านหน้าข้อความยาว ๆ บางครั้งอ่านซอร์สโค้ดตรง ๆ ยังง่ายกว่า
  • ใช้ Traefik ในโปรดักชันมา 2 ปีแล้ว ก่อนหน้านี้ใช้ NGINX แต่ตัดสินใจย้ายมา Traefik เพราะ การผสานกับ Let's Encrypt แบบอัตโนมัติ และก็เสียใจกับการตัดสินใจนั้น
    เอกสารของ Traefik สื่อสารกับผมและทีมได้ไม่ดีเลย ใช้งานยาก และทำงานแปลก ๆ โดยไม่มี log ที่เหมาะสม
    เช่น ถ้าพยายามสร้างใบรับรองใหม่ บางครั้งจะล้มเหลว แล้วทำให้โปรดักชันล่มโดยไม่รู้ว่าจะกลับมาเมื่อไหร่ ตอนนี้กำลังย้ายกลับไป NGINX

    • ในเรื่องแบบนี้ NixOS ช่วยได้มากจริง ๆ แค่เพิ่มไม่กี่บรรทัดใน configuration.nix ก็จะตั้งค่าได้ และภายในใช้ lego(1) กับ letsencrypt
      security.acme = { acceptTerms = true; defaults.email = "admin-email@provider.net"; certs."mydomain.example.com" = { domain = "*.mydomain.example.com"; dnsProvider = "cloudflare"; environmentFile = "/path/to/cloudflare/password"; }; };
      services.caddy.enable = true;
      services.caddy.virtualHosts."subdomain1.mydomain.example.com" = { extraConfig = '' reverse_proxy 127.0.0.1:1234 ''; useACMEHost = "mydomain.example.com"; };
      การตั้งค่าด้วย nginx ก็น่าจะค่อนข้างคล้ายกัน https://github.com/go-acme/lego
    • ผมก็ย้ายจาก NGINX มา Traefik เพราะรองรับ DNS challenge และใบรับรอง wildcard เป็นพื้นฐานเหมือนกัน ใช้เวลาหลายชั่วโมงเพื่อให้มันใช้กับโดเมนที่บริษัทใช้ และแม้จะใช้การตั้งค่าเดียวกันที่ทำงานได้สมบูรณ์ที่บ้าน แต่ในของจริงกลับไม่ทำอะไรเลย
      เป็น registrar โดเมนเดียวกัน, API เดียวกัน, การตั้งค่า Docker เดียวกัน และเปิด log ทั้งหมดแล้ว แต่ไม่มีข้อมูลเลยว่าทำไมใบรับรองถึงไม่ถูกสร้าง มันเหมือนไม่ได้พยายามด้วยซ้ำ แค่ย้อนกลับไปใช้ใบรับรองเริ่มต้นที่สร้างไว้
      หลังจากแก้ปัญหาไปสองรอบและค้นหาหลายชั่วโมง สุดท้ายก็ยอมแพ้และต้องใช้ไฟล์ใบรับรอง self-signed แทน น่าหงุดหงิดจริง ๆ ที่ไม่มีข้อมูลเลยว่าทำไมถึงใช้ไม่ได้ แล้วก็ล้มเหลวเงียบ ๆ ก่อนจะไปใช้พฤติกรรมสำรอง
      โดยรวมแล้วปัญหาใหญ่ที่สุดของ Traefik สำหรับผมคือเรื่องนี้ ตอนที่มันทำงานก็ดีมาก แต่ตอนที่ไม่ทำงาน การแก้ปัญหาหรือหาข้อมูลที่ต้องการจากเอกสารมักยากเสมอ ที่บริษัทมีแผนจะเริ่มใช้ Traefik ในโปรดักชันช่วงปลายปี เลยหวังว่าจะคุ้นกับ Traefik มากขึ้นก่อนถึงตอนนั้น
    • ถ้าต้องการ API gateway ผมก็ใช้ reverse proxy ในตัวของ Go มาตลอด ปรับให้เป็นรูปแบบที่ต้องการได้ง่าย และก็หาไลบรารีสำหรับงานทั่วไปอย่าง CORS, rate limiting, retry ได้ง่าย
      จุดที่ดีที่สุดคือไม่มีภาษาสำหรับตั้งค่า แค่ใช้ Go ก็พอ
    • คุณอาจรู้อยู่แล้วหรืออาจไม่ตรงกับกรณีนี้ แต่มีคอนเทนเนอร์เสริมของ Docker สำหรับทำใบรับรอง Let's Encrypt ให้ nginx Docker container อัตโนมัติอยู่ค่อนข้างมาก
    • ตอนเริ่มใช้ Traefik แรก ๆ เจอปัญหาคล้ายกันหลายอย่าง เช่น ใช้ การตรวจสอบ TLS-01 แต่ถ้ายังไม่ได้ตั้ง DNS record ไว้ก่อนนำ config ไปใช้ ก็ทำให้เครียดหนัก ปริมาณ log ไม่พอก็น่าหงุดหงิดเหมือนกัน
      สิ่งที่มารู้ทีหลังคือ ถ้า DNS ไม่ได้ตั้งค่าอย่างถูกต้อง ความพยายามตรวจสอบจะล้มเหลว N ครั้ง แล้ว Let's Encrypt จะปฏิเสธการตรวจสอบ TLS-01 ซ้ำไปพักหนึ่ง และปัญหาที่คุณเจอฟังดูเหมือนเป็นประเภทนั้น
      หลังจากย้ายมาใช้ การตรวจสอบ DNS-01 ประสบการณ์ก็ดีขึ้นมากแบบทันที สามารถออกใบรับรองให้บริการที่ไม่ได้เปิดสาธารณะได้ด้วย และต้องการ orchestration น้อยกว่าแบบ TLS-01 มาก
      ถ้า DNS provider ปกติ เวลามีปัญหาก็มีโอกาสสูงที่จะได้ API error ก่อนที่ Let's Encrypt จะตรวจสอบ record และสถานะล้มเหลวจะเกิดขึ้นก่อน backoff จากการตรวจล้มเหลวของ Let's Encrypt ไปไกล ตอนนี้แทบตัดสินใจแล้วว่า ไม่ว่าจะใช้ Traefik, Caddy, Nginx หรือ reverse proxy อื่น ๆ ก็จะใช้ Let's Encrypt แบบ DNS-01 เท่านั้น และถ้าจำเป็นต้องใช้ TLS-01 ก็จะตรวจให้แน่ใจตั้งแต่แรกด้วย Staging API ว่าตั้งค่าถูกต้องแล้ว
      อีกอย่าง ถ้าสร้างใบรับรอง Let's Encrypt Staging ใน Traefik แล้ว ไม่มีวิธีที่ดีในการทำให้ใบรับรองนั้นเป็นโมฆะ ต้องไปแก้ ACME JSON เพื่อลบใบรับรอง แล้วรีสตาร์ต Traefik ถึงจะให้การเปลี่ยนแปลงมีผล SIGHUP อาจใช้ได้ แต่ยังไม่เคยลอง
      โดยรวมมีความล้มเหลวแบบเงียบ ๆ และพฤติกรรมแปลก ๆ เยอะ แต่ความเจ็บปวดที่สุดคือมันทำให้ข้อผิดพลาดจากบริการที่พึ่งพาอยู่ไม่โปร่งใส
  • ใช้ Caddy มากกว่า Traefik สำหรับผม การดูแล Caddyfile ง่ายกว่าการตั้งค่า YAML ของ Traefik มาก และดูแล Caddyfile แยกกันสำหรับ deploy แบบ local, production และ on-premises
    มีปลั๊กอินดี ๆ เยอะด้วย และเราใช้ ปลั๊กอิน coraza WAF สำหรับ Caddy ซึ่งทำงานได้ดี

    • ในชุด self-hosting ย้ายจาก Traefik มาใช้ Caddy กับ caddy-docker-proxy
      มีฟีเจอร์ที่ต้องการครบ แต่เรียบง่ายกว่ามาก
      https://github.com/lucaslorentz/caddy-docker-proxy
    • ชอบ Caddy แต่ก็อยากให้เอกสารสำหรับ deployment ในโปรดักชันดีขึ้นด้วย โดยเฉพาะมีคำถามที่ไม่มีคำตอบเกี่ยวกับ best practice ด้าน storage และการจัดการ configuration มากเกินไป
      เช่น ถ้าใช้ storage ภายนอก ควรจัดการ local storage อย่างไร บอกว่าสามารถถือว่าเป็น stateless ได้ แต่ก็อาจไม่ใช่
      สุดท้ายก็ต้องภาวนาให้คนที่ทำโมดูลที่ต้องใช้รู้เรื่องจริง ๆ เพราะฝั่งนั้นก็ไม่มีมาตรฐานเอกสารเช่นกัน ผู้ดูแลควรเบรกโมดูลสุ่ม ๆ ที่ให้ฟีเจอร์หลักแต่เอกสารเป็นศูนย์ เช่น backend storage แบบ S3 บ้าง
    • ถ้าไม่ต้องการลูกเล่นซับซ้อนอย่าง service discovery หรือ autoscaling หรือคุณรับมือด้วยสคริปต์เองได้ ก็ข้าม Traefik, Docker Swarm, Kubernetes ฯลฯ ไปอย่างสบายใจ แล้วใช้ Caddy ก็พอ Caddy ทำได้แทบทุกอย่างจริง ๆ และทำได้ดี
  • ถ้าความต้องการเรียบง่ายแค่มี Docker host ไม่กี่เครื่องกับคอนเทนเนอร์ไม่กี่สิบตัว ก็อดคิดไม่ได้ว่ามีเหตุผลอะไรที่ควรใช้ Traefik แทน nginx ผมใช้ https://github.com/NginxProxyManager/nginx-proxy-manager อยู่ แล้วในสเกลเล็กขนาดนี้ Traefik จะให้ข้อได้เปรียบอะไรไหม?

    • ในกรณีนี้ผมมองว่า https://github.com/caddyserver ดีที่สุด จัดการใบรับรอง SSL ให้อัตโนมัติ เบามาก และไวยากรณ์การตั้งค่าก็ชัดเจนมาก
    • ผมชอบ hot reload ของ Traefik ถ้าอยากซ่อนบริการ หรือก็คือแอปที่ถูก proxy เพิ่ม route ใหม่ หรือในศัพท์ของ Traefik คือ router หรือเพิ่ม middleware อย่าง basic authentication, HTTPS redirect, การปรับแต่ง header ก็แค่โยนไฟล์ลงไปแล้วมันจะมีผลอัตโนมัติ ไม่ต้อง reload Traefik หรือ virtual host ของมัน
      จริง ๆ ก็มีส่วนที่ผมไม่ชอบไวยากรณ์ของ nginx และ Traefik ดูแวววาวน่าสนใจด้วย เริ่มใช้เพราะการต่ออายุ Let's Encrypt กับคอนเทนเนอร์ แล้วก็ใช้ต่อเพราะวิธีตั้งค่าของมัน
    • ถ้าสิ่งที่มีอยู่แล้วทำงานได้ดี ผมว่าไม่มีประโยชน์อะไรที่จะต้องเปลี่ยน
      คงจะพิจารณาย้ายก็ต่อเมื่อมีช่วงที่ต้องใช้ฟีเจอร์ที่ Traefik มีแต่ Nginx ไม่มี
    • ผมก็ใช้ NginxProxyManager อยู่ มี host 8 ตัว แต่ยังไม่เคยเห็นคำตอบที่อธิบายว่า caddyserver หรือ traefik ให้ข้อได้เปรียบอะไรเหนือ NPM
    • เห็นด้วย การตั้งค่า Nginx ง่าย และพอจัดให้เข้าที่ครั้งหนึ่งแล้วก็ลืมมันไปได้เลย ยังไงส่วนใหญ่ก็เป็นการคัดลอกแล้ววางจาก configuration อื่นที่มีอยู่แล้ว
      Certbot ก็มีอยู่แทบทุกที่และรองรับสถานการณ์ได้มากกว่า การที่ Let's Encrypt อัตโนมัติ ถูกใช้เป็นจุดขายเลยดูแปลกนิดหน่อย จุดขายของ Traefik กับ Caddy ไม่ใช่การทำให้สิ่งที่มีทางเลือกที่รองรับแพร่หลายอยู่แล้วง่ายขึ้น สำหรับผมเลยไม่ค่อยโดนใจ
  • เมื่อไม่กี่สัปดาห์ก่อนผมกำลังเลือก reverse proxy แล้วสุดท้ายเลือก Caddy เพราะความเรียบง่าย อย่างไรก็ตาม การค้นพบคอนเทนเนอร์อัตโนมัติ ของ Traefik กับการอ้างอิงด้วย label ก็ค่อนข้างดี และ Caddy ก็มี plugin ที่ทำแบบเดียวกัน
    อ่านบทความแล้ว แต่ยังไม่มั่นใจว่า Traefik มีจุดไหนดีกว่า Caddy สำหรับผมหรือไม่ สำหรับคนอื่นอาจมี เลยอยากฟังความเห็น

  • อีกจุดที่น่าสังเกตคือ Traefik ถูก ตั้งค่าไว้ใน K3s โดยค่าเริ่มต้น ด้วย ด้วยเหตุนี้ K3s จึงกลายเป็นวิธีที่เร็วที่สุดในการเปิด K8s cluster สำหรับทดสอบ และยังทำให้จัดการ cluster แบบ cattle ได้ด้วย
    แค่เพิ่ม deployment กับ service ที่เกี่ยวข้องเป็น NodePort ก็เข้าถึงแอปได้โดยไม่ต้องกังวลเรื่อง ingress controller
    ผมใช้ shell script เปิด K3s cluster แล้วทดสอบแอปที่ระบุเป็น positional argument เมื่อต้องการ โดยใช้ temporary container registry ของ ttl.sh พอสคริปต์เดียวกันจบ ก็ลบ cluster ทิ้งด้วย

  • กำลังคิดจะย้าย reverse proxy สำหรับ self-hosting ไปเป็น Traefik ต่างจากผู้เขียน ผมรัน workload ที่ containerized ด้วย Docker Compose และตอนนี้ใช้ Caddy ร่วมกับ ปลั๊กอิน caddy-docker-proxy ที่ยอดเยี่ยม อยู่
    สิ่งที่ได้ตอนนี้คือ reverse proxy ที่ตั้งค่าจาก Docker label, การตรวจจับ workload ใหม่อัตโนมัติ, ใบรับรอง TLS, และการตั้งค่า DNS อัตโนมัติผ่านปลั๊กอิน caddy-dynamicdns แม้ ISP จะให้ IP อื่นมาก็ไม่ต้องกังวลมากว่าจะเสียการเข้าถึง
    แต่ทุกครั้งที่เพิ่ม workload ใหม่หรือมีการ restart, Caddy ทั้งตัวจะ restart ทำให้การเข้าถึงขาดช่วงชั่วคราว Caddy ไม่สามารถส่งต่อ connection เดิมไปยัง instance ใหม่ได้
    อีกอย่างคือการใช้ wildcard certificate ยังไม่เรียบง่ายพอ ผมไม่อยากให้ workload ทั้งหมดถูกเปิดเผยต่อโลกผ่าน certificate transparency log เลยใช้ wildcard certificate แต่ถ้าเป็นแบบนั้นก็ใช้ไวยากรณ์ Caddyfile แบบง่าย ๆ ที่ใช้ certificate แยกตาม hostname ไม่ได้ รู้ว่า Caddy กำลังทำเรื่องนี้อยู่ แต่ตอนนี้ยังเป็นแบบนั้น
    อย่างไรก็ดี ผมเคยใช้ Traefik ในสภาพแวดล้อม k8s แล้วค่อนข้างโอเค จึงคิดว่าจะลองใช้กับของส่วนตัวดูด้วย หวังว่าคำพูดนี้จะไม่ทำให้ใครไม่ลอง Caddy เพราะ Caddy เองก็ดีจริง ๆ

    • ผมใช้ Caddy กับเครื่องแบบ single-purpose host อะไรทำนองนั้น แต่สำหรับปัญหาที่คุณอธิบาย ผมจะโยน Traefik ใส่ 100% จริง ๆ ผมใช้มันกับทางเข้าของ k8s cluster และในสภาพแวดล้อมพัฒนาก็รันไว้เพื่อใช้ localtest.me ร่วมกับ hostname
      คุ้มที่จะลอง ทั้งสองตัวเยี่ยมมากในพื้นที่ที่ต่างกัน
    • ผมใช้ rootless Docker Compose + Traefik เพราะ wildcard certificate ทำได้แบบแทบไม่เจ็บปวดเลย แต่ผมใช้ DNS server ของตัวเอง และใช้ RFC2136 DDNS สำหรับ Let's Encrypt DNS challenge
      จริง ๆ ไม่ต้องใช้ plugin มี Ansible playbook ตัวหนึ่งที่ตั้งค่าทั้งหมดนี้บน VM และสร้าง template ของ compose file ให้ด้วย และมีอีก playbook ที่ลบทุกอย่างบน server ยกเว้นข้อมูลกับ mount ส่วน backup ใช้ restic ร่วมกับ custom script ที่ backup ไฟล์ DB หลายตัว และอื่น ๆ ไปยังหลาย location ได้
      เมื่อก่อนเคย deploy k3s แต่ตระหนักว่ามันเกินจำเป็นและซับซ้อนเกินไปสำหรับ self-hosting ผมแค่อยาก deploy ได้เร็วและไม่ต้องจัดการ certificate เอง
    • ผมไม่เคยใช้ Caddy และใช้ Traefik อยู่ โดยให้มันค้นพบและใช้ Docker attribute สำหรับการตั้งค่าและการต่ออายุใบรับรอง TLS อัตโนมัติ Dynamic DNS ไม่ค่อยรู้ และไม่ได้ใช้ใน Traefik เท่าที่จำได้ ต่อให้เพิ่มหรือลบ container ก็ไม่ต้อง restart
    • ผมเคยใช้ caddy-docker-proxy ใน production และตอนโหลด configuration ใหม่ Caddy ไม่ได้ตัด connection
      เมื่อกี้ลองเช็กในเครื่อง local แล้ว ก็ทำงานได้ดี
    • นั่นเป็นข้อจำกัดที่หนักมาก ผมเพิ่งเคยได้ยิน reverse proxy ที่ต้องตัด connection เพราะต้อง restart เพื่ออัปเดต configuration ปกติแล้วในการออกแบบ server แบบนั้น เรื่องนี้เป็นส่วนที่ต้องดูแลเป็นอย่างแรก ๆ และพื้นฐานที่สุด
  • ผมใช้ Traefik มาเยอะ แต่เหนื่อยกับการต้องจัดการ docker-compose label ลำดับชั้น และบรรทัดจำนวนมาก เพียงเพื่อจะมี reverse proxy ตัวเดียว จากนั้นก็พบ Caddy และไม่เคยหันกลับไปอีก
    บางทีผมอาจไม่ใช่กลุ่มผู้ใช้เป้าหมายของ Traefik สิ่งที่ต้องการก็แค่ reverse proxy ที่เปิด HTTPS หรือชั้น basic authentication เท่านั้น ใน Caddy ทั้งสองอย่างทำได้ในบรรทัดเดียว กระชับมาก และไม่มีลำดับชั้นที่ผมยังไม่เข้าใจ

  • ใช้ Traefik กับงานเซลฟ์โฮสต์ทั้งหมดมาหลายปีแล้ว
    แต่ฟีเจอร์ dynamic discovery กับ Docker labels นั้นยุ่งยากเกินไป และดีบักแล้วน่าหงุดหงิด เลยเลิกใช้ไป
    แทนที่จะทำแบบนั้น ผมสร้าง ไฟล์คอนฟิกแบบ static ด้วย template engine แทน แทบทุก service เป็นการจับคู่ host/target/port เลยสร้าง section ที่เกี่ยวข้องได้ง่ายมาก และนอกจากการจัดการ TLS ก็ไม่มี middleware ซับซ้อนอะไร ผู้เขียนบทความที่ลิงก์ไว้ก็ดูเหมือนจะเลือกทางเดียวกัน
    คอนฟิกถูกสร้างด้วยสคริปต์ Ansible แล้วคัดลอกไปยังเครื่องที่รัน Traefik อยู่ จากนั้น Traefik จะคอยเฝ้าดูไดเรกทอรีที่มีไฟล์นั้น และเมื่อมีการเปลี่ยนแปลงก็โหลดใหม่อัตโนมัติ ใช้งานได้ดีมากมาตลอด

  • ใช้ Traefik ร่วมกับคอนเทนเนอร์ในโปรดักชันอยู่ และสิ่งที่ชอบที่สุดคือคอนฟิกถูกใส่มาเป็น container labels ดังนั้นแทบไม่ต้องแก้คอนฟิกของ Traefik เองเลย
    ข้อเสียใหญ่ที่สุดคือการหาว่าควรออกเสียงชื่อมันยังไง ดูเหมือนจะอ่านเหมือน traffic ทั่วไป แต่ก็อดอยากเรียกแบบ “trey-feek” ไม่ได้

    • เห็นด้วยมากกับแนวทาง labels ตอนเขียนครั้งแรกจะยากขึ้นนิดหน่อยเพราะต้อง escape และมัน verbose แต่ขอบเขตที่ต้องคอยไล่ตามลดลงมหาศาล
      ผมมองว่าการใช้ Traefik ร่วมกับ Docker Compose เป็นจุดที่ดีสำหรับงานเซลฟ์โฮสต์ขนาดเล็กก่อนที่จะโตจนต้องไป k8s โดยเฉพาะเมื่อมีจำนวนเซิร์ฟเวอร์น้อยกว่าที่ control plane แบบ high availability ของ k8s ใช้
    • เราก็ใช้ในโปรดักชันเหมือนกัน คนอาจจะหัวเราะ แต่การตั้งชื่อที่บนกระดาษดูเท่และไม่เหมือนใคร แต่ในความเป็นจริงแย่มาก ถือเป็นข้อเสียใหญ่
      จำนวนสีหน้าบึ้งตึงและเสียงหัวเราะจากเพื่อนร่วมงานมีเยอะมาก และเป็นอุปสรรคต่อการนำผลิตภัณฑ์มาใช้และการใช้งาน
      เราเรียกว่า “tray-feek” ซึ่งก็ยังพอรับได้ แต่พอคุยกับซัพพอร์ตอย่างเป็นทางการ เขาบอกว่าออกเสียงเหมือน “traffic” ปกติทุกประการ ดังนั้นทุกครั้งที่พูดถึงพร็อกซีนั้น ประโยคจะกลายเป็นประมาณว่า “รับ traffic ผ่าน public load balancer แล้ว native load balancing ของ traffic ส่ง traffic ไปยัง pod ของ traffic” ฟังดูโง่ และในความเป็นจริงมันก็โง่จริง
    • ก็ออกเสียงว่า “traffic” เฉย ๆ ผมไม่ขอเข้าไปยุ่งกับเกมปั่นหัวบ้า ๆ ของพวกเขา
    • ผมมองว่าข้อเสียใหญ่ที่สุดคือ ถ้าคอนเทนเนอร์ไม่มีอยู่หรือไม่ได้รันอยู่ Traefik ก็จะไม่รู้จักคอนเทนเนอร์หรือ labels ของคอนเทนเนอร์นั้น
      ถ้าไม่เป็นแบบนั้น ก็น่าจะทำอะไรเจ๋ง ๆ ได้ง่ายขึ้น เช่น หน้า maintenance หรือการสตาร์ตคอนเทนเนอร์ขึ้นมาเมื่อมี request แรกหลังจากไม่ active
      เลยกำลังคิดว่าจะทำปลั๊กอินที่รู้ตำแหน่งที่เก็บไฟล์ compose และอ่านจากตรงนั้นโดยตรงได้
    • ae ใกล้เคียงกับ y หรือ hi ที่สุด ดังนั้นผมเดาว่าเป็น Tryfik ไม่งั้นก็ Trayfik ถ้าเป็น fik แบบยุโรป ก็อาจเป็น feek ได้