ใครไม่ดี KrakenD API Gateway

API Gateway Jul 07, 2019

เมื่อสัก 2 วันก่อน ผมเห็น KrakenD จากน้องคนนึงโพสต์ใน Facebook บอกว่า มันเร็วกว่า Kong ด้วย ผมตามไปดู เห็นผลการทดสอบ มันเร็วกว่าเยอะเลย จากรูปนี้

https://www.krakend.io/docs/benchmarks/overview/

โห เร็วกว่า Kong และ Tyk ด้วย ผมเลยลองรันเล่นดู แต่ว่า เมื่อ 2 วันก่อนนี้ รันแบบรีบๆ ไม่ได้ตั้งใจอ่านเอกสาร เลยยังรันมาเล่นไม่ผ่าน ก็เลยหยุดเล่น แล้วไปทำงานต่อ...

วันนี้ว่าง เลยลองเล่นดูอีกรอบ เพื่อจะดูว่า มันดียังไง เผื่อว่ามีงานที่มันทำได้ดี จะได้มีตัวเปรียบเทียบกับ Kong ถ้าใครติดตามผมใน Facebook จะเห็นว่า ผมใช้ Kong API Gateway และเขียนบล็อก Kong API Gateway ฉบับรวบรัด สำหรับผู้เริ่มต้น แต่พอเห็นตัวนี้เคลมว่าตัวเองเร็วกว่า Kong ผมก็เลยอยากลองดูว่า มันใช้ยังไง

KrakenD API Gateway เขียนด้วยภาษา Golang เหมือนกับ Tyk แต่ผมลอง Tyk แล้วไม่ผ่าน มัน Deploy ดูยาก ๆ ยุ่ง ๆยังไงไม่รู้ มันเป็น Open Source แต่ เวลาใช้ ต้องไปขอ Key มา -_- ผมเลยไม่ลองต่อ ส่วน KrakenD ผมลองแล้ว Deploy ไมผ่านในครั้งแรก และไม่ค่อยชอบเพราะไปเห็นไฟล์คอนฟิกของมัน ที่เป็น JSON ดูแล้วยุ่งๆ อ่านยาก แล้วเอาคอนฟิกไฟล์ตัวอย่างมาลอง แล้วใช้ยากอีก ลาก่อย

วันนี้นั่งร้านกาแฟ และให้เวลากับมัน 2 ขั่วโมง เผื่อหาว่ามันใช้ยังไง พอได้คอนเซ็ปต์ และกลับมากินเบียร์กระป๋องนึง ลื่นไหลเลยทีนี้ พอจะหาข้อดี และชอบมันได้

ไฟล์คอนฟิก ที่เป็น JSON

{
    "version": 2,
    "name": "KrakenD - API Gateway",
    "port": 8000,
    "endpoints": [{
        "endpoint": "/",
        "method": "GET",
        "backend": [{
            "url_pattern": "/ip",
            "host": [
                "http://httpbin.org/"
            ]
        }]
    }]
}

จริง ๆแล้วไฟล์คอนฟิกตัวอย่าง อ่านยากกว่านี้ อันนี้เลย https://github.com/devopsfaith/krakend-ce/blob/master/krakend.json คือผมคิดว่า ถ้าไฟล์คอนฟิกมันสั้นๆ ดูเข้าใจง่าย ผมคงชอบมันในครั้งแรกเห็น 5555 แต่แม่งยาวเฟี้ย กว่าผมจะลดทอน เหลือ JSON ข้างบน หมดกาแฟไป 1 แก้ว เบียร์ 1 กระป๋องเลย

มา Deploy KrakenD กัน

ใช้ Docker + docker-compose แล้วกัน ใครใช้ไม่เป็น ไปหาอ่าน Docker ก่อน หรือซื้อคอร์สผมก็ได้ที่ ask-me.guru | ถามได้ ถ้าจ่ายตังส์

 สร้างไดเรคทอรีสำหรับคอนฟิกไฟล์ ผมใช้ชื่อ konf.d

mkdir -p konf.d

จากนั้นสร้างไฟล์คอนฟิก แล้วใส่ JSON ไฟล์ข้างบน

touch konf.d/krakend.json

ถ้าขี้เกียจเลื่อนไปข้างบน ก๊อปปี้ไปใส่เลย

{
    "version": 2,
    "name": "KrakenD - API Gateway",
    "port": 8000,
    "endpoints": [{
        "endpoint": "/",
        "method": "GET",
        "backend": [{
            "url_pattern": "/ip",
            "host": [
                "http://httpbin.org/"
            ]
        }]
    }]
}

จากนั้น สร้างไฟล์ docker-compose.yml สำหรับรัน KrakenD ใน Docker

version: '3.7'
services: 
  krakend:
    image: devopsfaith/krakend
    ports: 
      - 80:8000
    volumes: 
      - ./konf.d:/etc/krakend/

ไฟล์จะมีแบบนี้

.
├── docker-compose.yml
└── konf.d
    └── krakend.json

จากนั้นรัน docker-compose เพื่อรัน KrakenD

docker-compose up

จะได้ KranenD รันอยู่ที่ http://127.0.0.1

ใช้ cURL หรือ HTTPie เรียก จะได้ IP ของเครื่องเราเอง เหมือนกับเรียกไปที่ http://httpbin.org/ip

http :80

http http://httpbin.org/ip

เห็นไหม ง่ายนิดเดียว ได้ KrakenD API Gateway แล้ว แต่นอกจากนี้ KrakenD ยังมี Designer ชื่อ KrakenDesigner ใช้สำหรับสร้างไฟล์คอนฟิก ที่มีหน้าเว็บให้ใส่ค่าต่างๆ เพื่อความสะดวกสำหรับการเริ่มต้น แต่ผมเองใช้แล้วรู้สึกยุ่งยาก ไฟล์ที่สร้างมาแล้วรันไม่ผ่าน เลยไปอ่านไฟล์คอนฟิกตัวอย่างใน GitHub แล้วก็ตัดตอนเอาให้เหลือคอนฟิกที่น้อยที่สุดที่มันทำงานได้ จนกลายมาเป็น JSON ด้านบนนู้น -_-

KrakenD Emulator พัง ทำให้ไม่อยากใช้ Designer

ไม่มี Reload config ใน Production!

KrakenD บอกว่า ออกแบบมาคำนึงถึงประสิทธิ์ภาพเป็นเรื่องแรก! เอ้อ การ Reload config อาจทำให้ประสิทธิ์ภาพลดลงเยอะก็ได้ แต่ถ้าจะทำ น่าจะไปทาง Deploy KrakenD เป็นคลัสเตอร์ แล้วใช้ Load Balancer ค่อยๆกระจายโหลดไปโหนดใหม่ ทำ A/B Testing, Canary, Blue/Green อะไรก็ว่าไป ที่มีคอนฟิกใหม่เอาแทน จะเอาคอนฟิกใหม่ ต้อง Restart KrakenD เอา  ดูเพิ่มเติมได้ที่นี้ จิ้มเลย 👉 Reloading the Krakend configuration with Reflex and Docker

เมื่อก่อนผมไม่ชอบ YAML เลย ขี้เกียจจัดการกับ indent หรือย่อหน้า ชอบ JSON มากกว่า พอมาช่วงหลังๆ การเขียนคอนฟิกไฟล์ จะเป็น YAML เป็นส่วนใหญ่ ตั้งแต่ docker-compose, k8s ก็เป็น YAML หมดเลย หลังๆมา เลยชินกับมัน

KrakenD YAML Config

KrakenD รองรับไฟล์คอนฟิกหลายหลายฟอร์แมตมาก คือ

  • .json
  • .toml
  • .yaml
  • .yml
  • .properties
  • .props
  • .prop
  • .hcl

เยอะเลยแต่ KrakenD แนะนำให้ใช้ JSON เพราะมันแก้ไขผ่าน Designer ได้ แต่อันนี้เป็นตัวอย่าง YAML ที่ทำเหมือน JSON ไฟล์ข้างบน

version: 2
name: KrakenD - API Gateway
port: 8000
output_encoding: json
endpoints:
- endpoint: "/"
  method: "GET"
  backend:
  - host:
    - http://httpbin.org
    url_pattern: "/ip"

แก้ docker-compose.yml ให้เรียกไฟล์ตอนฟิก YAML

version: '3.7'
services: 
  krakend:
    image: devopsfaith/krakend
    working_dir: /etc/krakend/
    command: run -c krakend.yml
    ports: 
      - 80:8000
    volumes: 
      - ./konf.d:/etc/krakend/

Hot-Reload, Check Config, Designer

version: '3.7'
services: 
  designer:
    image: devopsfaith/krakendesigner:latest
    ports:
      - 8787:80
  krakend:
    image: devopsfaith/krakend:config-watcher
    working_dir: /etc/krakend/
    environment: 
      KRAKEND_CONFIG: krakend.yml
    ports: 
      - 80:8000
    volumes: 
      - ./konf.d:/etc/krakend/
  check:
    image: devopsfaith/krakend
    working_dir: /etc/krakend/
    command: check -c krakend.yml
    volumes: 
      - ./konf.d:/etc/krakend

Start KrakenDesiner

docker-compose up -d designer

KrakenDesigner จะรันอยู่ที่ http://127.0.0.1:8787

Check config

docker-compose up check

แถม Aggregate API

ผมชอบฟีเจอร์นี้มาก ใน Kong API Gateway มันไม่มีมาให้ คือการเรียกไป 1 enpoint แล้วทำการรวม Response มาจากหลายๆที่ เช่น ผมจะเอา 2 API นี้มารวมกัน ใน 1 enpoint

  • http://httpbin.org/ip
  • http://mockbin.org/status/200/Hello

เขียนไฟล์คอนฟิกได้แบบนี้

version: 2
name: KrakenD - API Gateway
port: 8000
output_encoding: json
endpoints:
- endpoint: "/"
  method: "GET"
  backend:
  - host:
    - http://httpbin.org
    url_pattern: "/ip"
- endpoint: "/aggs"
  method: "GET"
  backend:
  - host:
    - "http://httpbin.org"
    url_pattern: "/ip"
  - host:
    - "http://mockbin.org"
    url_pattern: "/status/200/Hello"

ผลที่ได้

$ http :80/aggs

HTTP/1.1 200 OK
Content-Length: 72
Content-Type: application/json; charset=utf-8
Date: Sun, 07 Jul 2019 16:09:32 GMT
X-Krakend: Version 0.9.0
X-Krakend-Completed: true

{
    "code": "200",
    "message": "Hello",
    "origin": "171.99.165.99, 171.99.165.99"
}
จบแล้วจ้า

ไฟล์คอนฟิกตัวอย่าง https://github.com/narate/krakend-example

Great! You've successfully subscribed.
Great! Next, complete checkout for full access.
Welcome back! You've successfully signed in.
Success! Your account is fully activated, you now have access to all content.