- 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
Hostheader แต่ใน 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 agentarchive.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
- entrypoint
- 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
- TCP routing แบบ TLS Passthrough สำหรับ
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
Traefik ถือว่าดีทีเดียว แต่เจอปัญหาแย่ ๆ แบบเดียวกับ Ansible คือมีเอกสารและบทความเยอะมาก แต่กลับหาเรื่องที่ต้องการจริง ๆ ไม่เจอ
ใช้มาตั้งแต่ v1 แล้ว แต่ก็ยังหลงทางในเอกสารอยู่บ่อย ๆ และรู้สึกหงุดหงิดมาก สำหรับโปรเจกต์เล็ก ๆ มักจะใช้ Caddy แทน เพราะเอกสารไม่ได้แย่เท่า Traefik
ถ้าจะบอกกับคนเขียนเอกสารทางเทคนิคก็คือ เอกสารแบบเน้นตัวอย่าง ดีแค่สำหรับมือใหม่ที่เปิดไล่ดูเท่านั้น คนที่คุ้นเคยกับผลิตภัณฑ์แล้วต้องการ เอกสารอ้างอิงและรายการที่ครบถ้วน ไม่ใช่คำอธิบายฟิลด์ที่กระจัดกระจายอยู่ตามหน้าทูโทเรียล 10 หน้า อย่าโฟกัสแค่ขั้นตอน onboarding แต่ควรปรับให้เหมาะกับคนที่ใช้ผลิตภัณฑ์ทุกวันด้วย
นี่คือจุดที่กวนใจที่สุด และเป็นเหตุผลที่ทำให้เกลียด Ansible ขนาดนั้น ส่วน Traefik ก็คล้ายกัน แม้จะน้อยกว่าก็ตาม
มักสมมติว่าจะทำงานง่ายมาก ๆ กับโครงสร้างข้อมูลที่แบนมากเท่านั้น แต่ความเป็นจริงส่วนใหญ่ไม่ได้เป็นแบบนั้น ถ้าจะใช้ภาษาเหล่านี้ให้ถูกต้อง ต้องเข้าใจกฎโดยนัยทั้งหมดเกี่ยวกับวิธีใช้ YAML แต่เอกสารแทบไม่แตะเรื่องนี้เลย
มีเอกสารการตั้งค่าเฉพาะของแต่ละโมดูลก็จริง แต่แทบไม่ชัดเจนเลยว่าจะใช้การตั้งค่ามาตรฐานอย่างไร จะจัดการข้อมูลที่คืนกลับมาอย่างไร หรือจะนำไปผสานกับสิ่งที่ซับซ้อนขึ้นอีกนิดอย่างไร เหมือนโยนตัวอย่างย่อหน้าสั้น ๆ เป็นสิบ ๆ อันต่อหนึ่งรายการมาเป็นกองวัตถุดิบ แล้วบอกให้เราอบเค้กเอง
จากระบบตัวแปล YAML หลายตัวที่เคยใช้ ประสบการณ์แทบจะเหมือนกันเสมอ และกว่าจะทำงานได้ก็ต้องผ่าน YAML ไปหลายแสนบรรทัด แต่เอกสารแทบไม่มีคุณค่าเกินกว่ารายการการตั้งค่า
ถึงอย่างนั้นพอใช้
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 ไว้เต็มไปหมด
แน่นอนว่าเป็นโปรเจกต์ของเขาเอง แต่ทุกครั้งที่ต้องการหาเมธอดสักตัวของอ็อบเจ็กต์ ก็ต้องไล่อ่านหน้าข้อความยาว ๆ บางครั้งอ่านซอร์สโค้ดตรง ๆ ยังง่ายกว่า
ใช้ Traefik ในโปรดักชันมา 2 ปีแล้ว ก่อนหน้านี้ใช้ NGINX แต่ตัดสินใจย้ายมา Traefik เพราะ การผสานกับ Let's Encrypt แบบอัตโนมัติ และก็เสียใจกับการตัดสินใจนั้น
เอกสารของ Traefik สื่อสารกับผมและทีมได้ไม่ดีเลย ใช้งานยาก และทำงานแปลก ๆ โดยไม่มี log ที่เหมาะสม
เช่น ถ้าพยายามสร้างใบรับรองใหม่ บางครั้งจะล้มเหลว แล้วทำให้โปรดักชันล่มโดยไม่รู้ว่าจะกลับมาเมื่อไหร่ ตอนนี้กำลังย้ายกลับไป NGINX
configuration.nixก็จะตั้งค่าได้ และภายในใช้lego(1)กับ letsencryptsecurity.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
เป็น registrar โดเมนเดียวกัน, API เดียวกัน, การตั้งค่า Docker เดียวกัน และเปิด log ทั้งหมดแล้ว แต่ไม่มีข้อมูลเลยว่าทำไมใบรับรองถึงไม่ถูกสร้าง มันเหมือนไม่ได้พยายามด้วยซ้ำ แค่ย้อนกลับไปใช้ใบรับรองเริ่มต้นที่สร้างไว้
หลังจากแก้ปัญหาไปสองรอบและค้นหาหลายชั่วโมง สุดท้ายก็ยอมแพ้และต้องใช้ไฟล์ใบรับรอง self-signed แทน น่าหงุดหงิดจริง ๆ ที่ไม่มีข้อมูลเลยว่าทำไมถึงใช้ไม่ได้ แล้วก็ล้มเหลวเงียบ ๆ ก่อนจะไปใช้พฤติกรรมสำรอง
โดยรวมแล้วปัญหาใหญ่ที่สุดของ Traefik สำหรับผมคือเรื่องนี้ ตอนที่มันทำงานก็ดีมาก แต่ตอนที่ไม่ทำงาน การแก้ปัญหาหรือหาข้อมูลที่ต้องการจากเอกสารมักยากเสมอ ที่บริษัทมีแผนจะเริ่มใช้ Traefik ในโปรดักชันช่วงปลายปี เลยหวังว่าจะคุ้นกับ Traefik มากขึ้นก่อนถึงตอนนั้น
จุดที่ดีที่สุดคือไม่มีภาษาสำหรับตั้งค่า แค่ใช้ Go ก็พอ
สิ่งที่มารู้ทีหลังคือ ถ้า 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 ซึ่งทำงานได้ดี
มีฟีเจอร์ที่ต้องการครบ แต่เรียบง่ายกว่ามาก
https://github.com/lucaslorentz/caddy-docker-proxy
เช่น ถ้าใช้ storage ภายนอก ควรจัดการ local storage อย่างไร บอกว่าสามารถถือว่าเป็น stateless ได้ แต่ก็อาจไม่ใช่
สุดท้ายก็ต้องภาวนาให้คนที่ทำโมดูลที่ต้องใช้รู้เรื่องจริง ๆ เพราะฝั่งนั้นก็ไม่มีมาตรฐานเอกสารเช่นกัน ผู้ดูแลควรเบรกโมดูลสุ่ม ๆ ที่ให้ฟีเจอร์หลักแต่เอกสารเป็นศูนย์ เช่น backend storage แบบ S3 บ้าง
ถ้าความต้องการเรียบง่ายแค่มี Docker host ไม่กี่เครื่องกับคอนเทนเนอร์ไม่กี่สิบตัว ก็อดคิดไม่ได้ว่ามีเหตุผลอะไรที่ควรใช้ Traefik แทน nginx ผมใช้ https://github.com/NginxProxyManager/nginx-proxy-manager อยู่ แล้วในสเกลเล็กขนาดนี้ Traefik จะให้ข้อได้เปรียบอะไรไหม?
จริง ๆ ก็มีส่วนที่ผมไม่ชอบไวยากรณ์ของ nginx และ Traefik ดูแวววาวน่าสนใจด้วย เริ่มใช้เพราะการต่ออายุ Let's Encrypt กับคอนเทนเนอร์ แล้วก็ใช้ต่อเพราะวิธีตั้งค่าของมัน
คงจะพิจารณาย้ายก็ต่อเมื่อมีช่วงที่ต้องใช้ฟีเจอร์ที่ Traefik มีแต่ Nginx ไม่มี
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 เองก็ดีจริง ๆ
localtest.meร่วมกับ hostnameคุ้มที่จะลอง ทั้งสองตัวเยี่ยมมากในพื้นที่ที่ต่างกัน
จริง ๆ ไม่ต้องใช้ plugin มี Ansible playbook ตัวหนึ่งที่ตั้งค่าทั้งหมดนี้บน VM และสร้าง template ของ compose file ให้ด้วย และมีอีก playbook ที่ลบทุกอย่างบน server ยกเว้นข้อมูลกับ mount ส่วน backup ใช้ restic ร่วมกับ custom script ที่ backup ไฟล์ DB หลายตัว และอื่น ๆ ไปยังหลาย location ได้
เมื่อก่อนเคย deploy k3s แต่ตระหนักว่ามันเกินจำเป็นและซับซ้อนเกินไปสำหรับ self-hosting ผมแค่อยาก deploy ได้เร็วและไม่ต้องจัดการ certificate เอง
เมื่อกี้ลองเช็กในเครื่อง local แล้ว ก็ทำงานได้ดี
ผมใช้ 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” ไม่ได้
ผมมองว่าการใช้ Traefik ร่วมกับ Docker Compose เป็นจุดที่ดีสำหรับงานเซลฟ์โฮสต์ขนาดเล็กก่อนที่จะโตจนต้องไป k8s โดยเฉพาะเมื่อมีจำนวนเซิร์ฟเวอร์น้อยกว่าที่ control plane แบบ high availability ของ k8s ใช้
จำนวนสีหน้าบึ้งตึงและเสียงหัวเราะจากเพื่อนร่วมงานมีเยอะมาก และเป็นอุปสรรคต่อการนำผลิตภัณฑ์มาใช้และการใช้งาน
เราเรียกว่า “tray-feek” ซึ่งก็ยังพอรับได้ แต่พอคุยกับซัพพอร์ตอย่างเป็นทางการ เขาบอกว่าออกเสียงเหมือน “traffic” ปกติทุกประการ ดังนั้นทุกครั้งที่พูดถึงพร็อกซีนั้น ประโยคจะกลายเป็นประมาณว่า “รับ traffic ผ่าน public load balancer แล้ว native load balancing ของ traffic ส่ง traffic ไปยัง pod ของ traffic” ฟังดูโง่ และในความเป็นจริงมันก็โง่จริง
ถ้าไม่เป็นแบบนั้น ก็น่าจะทำอะไรเจ๋ง ๆ ได้ง่ายขึ้น เช่น หน้า maintenance หรือการสตาร์ตคอนเทนเนอร์ขึ้นมาเมื่อมี request แรกหลังจากไม่ active
เลยกำลังคิดว่าจะทำปลั๊กอินที่รู้ตำแหน่งที่เก็บไฟล์ compose และอ่านจากตรงนั้นโดยตรงได้
aeใกล้เคียงกับyหรือhiที่สุด ดังนั้นผมเดาว่าเป็น Tryfik ไม่งั้นก็ Trayfik ถ้าเป็นfikแบบยุโรป ก็อาจเป็น feek ได้