Programming

Apache APISIX Lua 기반 Custom Plugin 작성

ipxy 2025. 3. 31. 15:04
728x90

 

🔁 예시 플로우 (Custom Plugin + Kafka Proxy)

[클라이언트 요청 JSON]
  → [Lua 커스텀 플러그인]
       - JSON 파싱
       - 필요한 필드 추출/변환
       - 새로운 JSON 구성
       - ngx.ctx.kafkavalue에 저장
  → [Kafka Proxy Plugin]
       - 변환된 JSON 값을 Kafka에 전송

🎯 예시 목표

요청 바디:

{
  "user_id": 42,
  "event": "signup",
  "password": "secret"
}

➡️ Kafka로는 아래와 같은 값만 보내고 싶어요:

{
  "event": "signup",
  "user": 42
}

🧩 1. Lua 플러그인 작성 (custom-transform.lua)

local core = require("apisix.core")
local plugin_name = "custom-transform"

local schema = {
    type = "object",
    properties = {},
}

local _M = {
    version = 0.1,
    priority = 1000,
    name = plugin_name,
    schema = schema,
}

function _M.access(conf, ctx)
    local body, err = core.request.get_body()
    if not body then
        core.log.error("failed to get request body: ", err)
        return 400, { message = "Invalid request body" }
    end

    -- 원하는 데이터 추출 및 가공
    local transformed = {
        user = body.user_id,
        event = body.event
    }

    -- Kafka 플러그인이 참조할 값 저장
    ctx.var.kafkavalue = core.json.encode(transformed)
end

return _M

🧩 2. 플러그인 등록 (APISIX 구성에 따라 다름)

conf/config.yaml 또는 conf/apisix.yaml에 아래 추가:

plugins:
  - custom-transform
  - kafka-proxy
  # 기타 플러그인

🧩 3. Route 설정

apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
  name: kafka-transform-route
  namespace: default
spec:
  http:
  - name: custom-kafka-route
    match:
      paths:
        - /send-kafka
    backends:
      - serviceName: dummy
        servicePort: 80
    plugins:
      - name: custom-transform
        enable: true
      - name: kafka-proxy
        enable: true
        config:
          brokers:
            - "kafka.default.svc.cluster.local:9092"
          topic: "log-topic"
          value: "$kafkavalue"

📦 결과

요청  Kafka에 전송
{ "user_id": 42, "event": "signup", "password": "secret" } { "user": 42, "event": "signup" }

✨ 확장 가능 기능 (Lua 플러그인 안에서)

  • 날짜/시간 자동 추가
  • 조건 분기 (이벤트에 따라 토픽 분기)
  • 필드 마스킹 (예: password 제거)
  • IP, 헤더 정보 추가
  • 메시지 필터링 (조건 불일치 시 Kafka 전송 생략 등)

✅ 요약

목적  방법
JSON 필드 추출, 가공 Lua 플러그인에서 처리
Kafka 전송 값 변경 ctx.var.kafkavalue 설정
Kafka Proxy와 연동 value: "$kafkavalue" 사용

 

Apache APISIX에서 Lua 플러그인 샘플 프로젝트와 Helm 차트 기반 배포 방법


🧪 1. Lua 플러그인 테스트용 샘플 프로젝트

📁 디렉터리 구조

apisix-lua-plugin-demo/
├── custom_plugins/
│   └── custom-transform.lua     ← 우리가 작성한 Lua 플러그인
├── config.yaml                  ← APISIX 설정
├── docker-compose.yml          ← 로컬 테스트용
└── README.md

📄 custom-transform.lua (예제 Lua 플러그인)

local core = require("apisix.core")
local plugin_name = "custom-transform"

local _M = {
    version = 0.1,
    priority = 1000,
    name = plugin_name,
}

function _M.access(conf, ctx)
    local body, err = core.request.get_body()
    if not body then
        return 400, { message = "Invalid request body" }
    end

    local transformed = {
        user = body.user_id,
        action = body.event
    }

    ctx.var.kafkavalue = core.json.encode(transformed)
end

return _M

이 플러그인은 JSON 바디를 가공하여 $kafkavalue로 저장합니다. Kafka Proxy Plugin에서 사용할 수 있어요.


🚀 2. Helm Chart 기반 APISIX 배포 (쿠버네티스 환경)

🧾 설치 단계 요약

  1. Helm 저장소 등록 및 업데이트
helm repo add apisix https://charts.apiseven.com
helm repo update
  1. custom plugin을 포함한 values.yaml 생성
apisix:
  enabled_plugins:
    - custom-transform
    - kafka-proxy
  extraVolumeMounts:
    - name: custom-lua
      mountPath: /usr/local/apisix/custom_plugins
  extraVolumes:
    - name: custom-lua
      configMap:
        name: custom-lua-code

configMap:
  customLua:
    custom-transform.lua: |
      -- (위 Lua 코드 붙여넣기)
  1. APISIX 설치 (또는 재배포)
helm install apisix apisix/apisix \
  -n apisix --create-namespace \
  -f values.yaml

📦 3. 테스트 방법

  1. Kafka Proxy Route 생성 (Lua 플러그인 연동)
apiVersion: apisix.apache.org/v2
kind: ApisixRoute
metadata:
  name: custom-kafka
spec:
  http:
    - name: transform-and-send
      match:
        paths:
          - /send-kafka
      backends:
        - serviceName: dummy
          servicePort: 80
      plugins:
        - name: custom-transform
          enable: true
        - name: kafka-proxy
          enable: true
          config:
            brokers:
              - "kafka.default.svc.cluster.local:9092"
            topic: "log-topic"
            value: "$kafkavalue"
  1. 테스트 요청
curl -X POST http://<apisix-ip>/send-kafka \
  -H "Content-Type: application/json" \
  -d '{"user_id": 42, "event": "signup", "password": "1234"}'

 

728x90