GKE ๊ฒŒ์ดํŠธ์›จ์ด์— ์ •์ฑ… ์ถ”๊ฐ€

์ด ํŽ˜์ด์ง€๋Š” Apigee์— ์ ์šฉ๋˜์ง€๋งŒ Apigee Hybrid์—๋Š” ์ ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

Apigee Edge ๋ฌธ์„œ ๋ณด๊ธฐ

์ด ํŽ˜์ด์ง€์—์„œ๋Š” Kubernetes์šฉ Apigee APIM Operator๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ Google Kubernetes Engine(GKE) ๊ฒŒ์ดํŠธ์›จ์ด์— Apigee ๋Ÿฐํƒ€์ž„ ์ •์ฑ… ๋ฐ Google ํ† ํฐ ์‚ฝ์ž… ์ •์ฑ…์„ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ๊ฒŒ์ดํŠธ์›จ์ด์— ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์ •์ฑ… ์ง‘ํ•ฉ์„ ์ถ”๊ฐ€ํ•˜๋ฉด API ์ œํ’ˆ ์‹œํ–‰์„ ๋„˜์–ด ๋ณด์•ˆ ๋ฐ ๋น„์ฆˆ๋‹ˆ์Šค ๊ทœ์น™์„ ์ถ”๊ฐ€ํ•˜์—ฌ ๊ฒŒ์ดํŠธ์›จ์ด์˜ ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Kubernetes์šฉ Apigee APIM Operator๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒŒ์ดํŠธ์›จ์ด์— ๋‹ค์Œ ์ •์ฑ…์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐœ์š”

๋‹ค์Œ ์„น์…˜์—์„œ๋Š” ์•„๋ž˜ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

์‹œ์ž‘ํ•˜๊ธฐ ์ „์—

์ด ๊ฐ€์ด๋“œ์˜ ์˜ˆ์‹œ๋กœ ์‚ฌ์šฉ๋œ ์ „์ฒด ์ •์ฑ… ์ง‘ํ•ฉ์œผ๋กœ GKE ๊ฒŒ์ดํŠธ์›จ์ด๋ฅผ ์ˆ˜์ •ํ•˜๋ ค๋ฉด Apigee ๋‚ด์—์„œ ํ† ํฐ์„ ๋งŒ๋“ค๊ณ  ํ”„๋ก์‹œ ๋ฐ ํ™•์žฅ ํ”„๋กœ๊ทธ๋žจ์„ ๋ฐฐํฌํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ์—ญํ• ์ด ์žˆ๋Š” ์„œ๋น„์Šค ๊ณ„์ •์ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. Google ํ† ํฐ์„ ๋งŒ๋“ค์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ์„œ๋น„์Šค ๊ณ„์ •์— ์ถ”๊ฐ€ ์—ญํ• ์„ ์ถ”๊ฐ€ํ•  ํ•„์š”๊ฐ€ ์—†์œผ๋ฉฐ ๋‹ค์Œ ์„น์…˜์œผ๋กœ ๊ฑด๋„ˆ๋›ธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•„์š”ํ•œ ๊ถŒํ•œ์ด ์žˆ๋Š” ์„œ๋น„์Šค ๊ณ„์ •์„ ๋งŒ๋“ค๋ ค๋ฉด ๋‹ค์Œ ์•ˆ๋‚ด๋ฅผ ๋”ฐ๋ฅด์„ธ์š”.

  1. Kubernetes์šฉ Apigee APIM Operator ์„ค์น˜ ๊ฐ€์ด๋“œ์—์„œ apigee-apim-gsa๋ผ๋Š” ์„œ๋น„์Šค ๊ณ„์ •์„ ๋งŒ๋“  ๊ฒฝ์šฐ ์ด ๋‹จ๊ณ„๋ฅผ ๊ฑด๋„ˆ๋›ฐ๊ณ  ๋‹ค์Œ ๋‹จ๊ณ„๋กœ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ ์„œ๋น„์Šค ๊ณ„์ •์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
    gcloud iam service-accounts create apigee-apim-gsa --project=$PROJECT_ID
  2. ์„œ๋น„์Šค ๊ณ„์ •์— ํ† ํฐ์„ ๋งŒ๋“œ๋Š” ๋ฐ ํ•„์š”ํ•œ ์—ญํ• ์„ ๋ถ€์—ฌํ•ฉ๋‹ˆ๋‹ค.
    gcloud projects add-iam-policy-binding $PROJECT_ID \
      --member "serviceAccount:apigee-apim-gsa@$PROJECT_ID.iam.gserviceaccount.com" \
      --role "roles/iam.serviceAccountTokenCreator"
  3. apigee-apim-gsa ์„œ๋น„์Šค ๊ณ„์ •์— ํ”„๋ก์‹œ ๋ฐ ํ™•์žฅ ํ”„๋กœ๊ทธ๋žจ์„ ๋ฐฐํฌํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ์—ญํ• ์„ ๋ถ€์—ฌํ•ฉ๋‹ˆ๋‹ค.
    gcloud projects add-iam-policy-binding $PROJECT_ID \
      --member "serviceAccount:apigee-apim-gsa@$PROJECT_ID.iam.gserviceaccount.com" \
      --role "roles/iam.serviceAccountUser"

์ •์ฑ…์œผ๋กœ GKE ๊ฒŒ์ดํŠธ์›จ์ด ์ˆ˜์ •

ํ•˜๋‚˜ ์ด์ƒ์˜ ์ •์ฑ…์œผ๋กœ GKE ๊ฒŒ์ดํŠธ์›จ์ด๋ฅผ ์ˆ˜์ •ํ•˜์—ฌ ๊ธฐ๋Šฅ์„ ํ™•์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์˜ˆ์‹œ ๋‘˜๋Ÿฌ๋ณด๊ธฐ์—์„œ๋Š” ๋‘ ๊ฐœ์˜ Apigee ์ •์ฑ… ๋ฐ Google ํ† ํฐ ์‚ฝ์ž… ์ •์ฑ…์— ๊ด€ํ•œ ์‚ฌ์–‘์ด ํฌํ•จ๋œ yaml ํŒŒ์ผ์„ ๊ฒŒ์ดํŠธ์›จ์ด์— ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.

๋‹ค์Œ yaml ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒŒ์ดํŠธ์›จ์ด์— ์ ์šฉ๋œ ๊ฐ ์ •์ฑ…์€ ๊ฒŒ์ดํŠธ์›จ์ด๋กœ ์ „์†ก๋œ ์š”์ฒญ์„ ํ‰๊ฐ€ํ•  ๋•Œ ์„œ๋กœ ๋‹ค๋ฅธ ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

  • SpikeArrest ์ •์ฑ…์€ ์‹œ๊ฐ„ ๋‹จ์œ„๋‹น ํ—ˆ์šฉ๋˜๋Š” ์ตœ๋Œ€ ์š”์ฒญ ๋น„์œจ์„ ์ •์˜ํ•˜์—ฌ ์ตœ๋Œ€ ๋ฉ”์‹œ์ง€ ๋น„์œจ์„ ์ œ์–ดํ•ฉ๋‹ˆ๋‹ค. ์ด ์˜ˆ์‹œ์—์„œ ์ตœ๋Œ€ ๋น„์œจ์€ ๋ถ„๋‹น 5๋กœ ์„ค์ •๋ฉ๋‹ˆ๋‹ค. SpikeArrest ์ •์ฑ…์„ ์‚ฌ์šฉํ•˜์—ฌ ํŠธ๋ž˜ํ”ฝ์˜ ๊ธ‰์ฆ์„ ์™„ํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๊ด€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ SpikeArrest ์ •์ฑ…์„ ์ฐธ์กฐํ•˜์„ธ์š”.
  • JavaScript ์ •์ฑ…์„ ์‚ฌ์šฉํ•˜๋ฉด ๊ฒŒ์ดํŠธ์›จ์ด ์š”์ฒญ์— ์ปค์Šคํ…€ JavaScript ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์˜ˆ์‹œ์—์„œ๋Š” ์ •์ฑ…์ด ์š”์ฒญ์— ์ปค์Šคํ…€ ํ—ค๋”๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. JavaScript ์ •์ฑ…์„ ์‚ฌ์šฉํ•˜์—ฌ ์ปค์Šคํ…€ ์ฝ”๋“œ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๊ด€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ JavaScript ์ •์ฑ…์„ ์ฐธ์กฐํ•˜์„ธ์š”.
  • Google ํ† ํฐ ์‚ฝ์ž… ์ •์ฑ…์€ AssignMessage ์ •์ฑ…์„ ์‚ฌ์šฉํ•˜์—ฌ Google ์ธ์ฆ ์•ก์„ธ์Šค ํ† ํฐ์„ ๊ฒŒ์ดํŠธ์›จ์ด ์š”์ฒญ์— ์‚ฝ์ž…ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. Apigee์—์„œ๋Š” Google OAuth ํ† ํฐ ๋˜๋Š” OpenID Connect ํ† ํฐ์„ ์‚ฌ์šฉํ•˜์—ฌ Google ์„œ๋น„์Šค๋กœ ์ธ์ฆํ•  ์ˆ˜ ์žˆ๋„๋ก ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์ธ์ฆ ํ† ํฐ์— ๊ด€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ Google ์ธ์ฆ ์‚ฌ์šฉ์„ ์ฐธ์กฐํ•˜์„ธ์š”.

๊ฒŒ์ดํŠธ์›จ์ด์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์ฑ…์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

  1. apim ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— apigee-policies.yaml์ด๋ผ๋Š” ์ƒˆ ํŒŒ์ผ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
  2. ๋‹ค์Œ ํŒŒ์ผ์˜ ์ฝ˜ํ…์ธ ๋ฅผ ์ƒˆ๋กœ ๋งŒ๋“  ํŒŒ์ผ์— ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค.
    # apigee-policies.yaml
    apiVersion: apim.googleapis.com/v1
    kind: SpikeArrest
    metadata:
      name: spike-arrest
      namespace: apim
    spec:
      identifier:
        ref: request.header.name
      useEffectiveCount: true
      peakMessageRate:
        value: "5pm"
    ---
    apiVersion: apim.googleapis.com/v1
    kind: Javascript
    metadata:
      name: js-add-headers
      namespace: apim
    spec:
      timeLimit: 2000
      source: |
        var sum = 1+1;
        context.setVariable("request.header.first", 1);
        context.setVariable("request.header.second", 1);
        context.setVariable("request.header.sum", sum);
    ---
    apiVersion: apim.googleapis.com/v1
    kind: AssignMessage
    metadata:
      name: google-token-policy
      namespace: apim
    spec:
      setActions:
        - authentication:
            googleAccessToken:
              scopes:
                - 'https://www.googleapis.com/auth/cloud-platform'
      AssignTo:
        createNew: false
        type: request
    ---
    apiVersion: apim.googleapis.com/v1
    kind: KVM
    metadata:
      name: kvm-1
      namespace: apim
    spec:
      delete:
      - keys:
        - value: mykey
      description: kvm1
      displayName: kvm1
      exclusiveCache: true
      expiryTimeInSecs: 3600
      get:
      - assignTo: response.header.mykvm
        index: 0
        keys:
        - value: mykey
      initialEntries:
      - keys:s
        - key1
        values:s
        - val1
      - keys:s
        - mykey
        values:
        - initvalue
      isEncrypted: false
      mapIdentifier: mapIdentifier
      mapName:s
        ref: kvm.mapname
        value: kvmname
      put:
      - keys:
        - value: mykey
        values:
        - value: request.header.mykvm
      scope: environment
    ---
    apiVersion: apim.googleapis.com/v1
    kind: OASValidation
    metadata:
      name: oas-validation-1
    spec:
      openApiSpec: |
        openapi: 3.0.4
        info:
          title: Sample API
          description: Optional multi/single line description.
          version: 0.1.9
        servers:
          - url: http://apigee-apim-operator-test.apigee.net
            description: Optional server description, our main host in httproute
        paths:
          /get:
            get:
              summary: just for test
              description: Optional extended description in CommonMark or HTML.
              parameters:
                - name: X-Request-Type
                  in: header
                  description: Must be 'internal' or 'external'.
                  required: true
                  schema:
                    type: string
                    enum:
                      - internal
                      - external
              responses:
                '200': # status code
                  description: A JSON object
                  content:
                    application/json:
                      schema:
                        type: object
                        properties:
                          headers:
                            type: object
      source: request
    ---
    apiVersion: apim.googleapis.com/v1
    kind: ServiceCallout
    metadata:
      name: service-callout-1
      namespace: apim
    spec:
      request:
        clearPayload: true
        variable: myRequest
        ignoreUnresolvedVariables: true
        removeActions:
          - payload: true
          - queryParams:
            - name: rq-param1
            - name: rq-param2
        copyActions:
          - version: true
          - verb: true
        addActions:
          - headers:
            - name: X-header1
              value: value1
            - name: X-header2
              value: value2
          - queryParams:
            - name: q-param1
              value: value1
            - name: q-param2
              value: value2
        setActions:
          - verb: PUT
          - formParams:
            - name: f-param1
              value: value1
            - name: f-param2
              value: value2
      response: calloutResponse
      timeout: 30000
      httpTargetConnection:
        URL: https://httpbin.org/put
        properties:
          - name: success.codes
            value: 1xx,2xx,3xx,400
          - name: supports.http11
            value: "true"
  3. ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒŒ์ดํŠธ์›จ์ด์— yaml ํŒŒ์ผ์„ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.
    kubectl -n apim apply -f apigee-policies.yaml

TemplateRule์„ SharedFlow ํ…œํ”Œ๋ฆฟ์œผ๋กœ ๋งŒ๋“ค๊ธฐ

์ด ๋‹จ๊ณ„์—์„œ๋Š” ๊ฒŒ์ดํŠธ์›จ์ด์— ์ถ”๊ฐ€ํ•œ ์ •์ฑ…์„ ์ ์šฉํ•  TemplateRule์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ํ…œํ”Œ๋ฆฟ ๊ทœ์น™์€ ์„œ๋น„์Šค ๊ฐœ๋ฐœ์ž๊ฐ€ ๊ฒŒ์ดํŠธ์›จ์ด ํŠธ๋ž˜ํ”ฝ์— ์Šน์ธ๋œ ์ •์ฑ…๋งŒ ์ ์šฉํ•˜๋„๋ก ์กฐ์ง ๊ด€๋ฆฌ์ž๊ฐ€ ๋งŒ๋“  SharedFlows์˜ ๊ทœ์น™์ž…๋‹ˆ๋‹ค. ํ…œํ”Œ๋ฆฟ ๊ทœ์น™์„ ์‚ฌ์šฉํ•˜๋ฉด ๊ฐœ๋ฐœ์ž๊ฐ€ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ •์ฑ…, ํŠน์ • ์‚ฌ์šฉ ์‚ฌ๋ก€์— ํ•„์š”ํ•œ ์ •์ฑ…, ์„œ๋น„์Šค ๊ฐœ๋ฐœ์ž๊ฐ€ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š” ์ •์ฑ…์„ ํŒŒ์•…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ…œํ”Œ๋ฆฟ ๊ทœ์น™ ๋งŒ๋“ค๊ธฐ

AssignMessage ์ •์ฑ…์˜ ์‚ฌ์šฉ์„ ์ ์šฉํ•˜๋Š” ํ…œํ”Œ๋ฆฟ ๊ทœ์น™์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

  1. apim ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— template-rule.yaml์ด๋ผ๋Š” ์ƒˆ yaml ํŒŒ์ผ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
  2. ๋‹ค์Œ ํŒŒ์ผ์˜ ์ฝ˜ํ…์ธ ๋ฅผ ์ƒˆ๋กœ ๋งŒ๋“  ํŒŒ์ผ์— ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค.
    # template-rule.yaml
    apiVersion: apim.googleapis.com/v1
    kind: ApimTemplateRule
    metadata:
      name: template-rule
      namespace: apim
    spec:
      allowList: [SpikeArrest, Javascript, GenerateJWT, KVM, OASValidation, OAuthv2, ServiceCallout]
      requiredList: [AssignMessage]
      denyList: []

    ์ด ์˜ˆ์‹œ์—์„œ ํ…œํ”Œ๋ฆฟ ๊ทœ์น™์€ ๊ฐœ๋ฐœ์ž์—๊ฒŒ Google ํ† ํฐ ์‚ฝ์ž… ์ •์ฑ…์„ ์„ค๋ช…ํ•˜๋Š” AssignMessage ์ •์ฑ…์ด ํ•„์š”ํ•˜๋‹ค๊ณ  ์•Œ๋ ค์ค๋‹ˆ๋‹ค. ๋˜ํ•œ ๊ฐœ๋ฐœ์ž์—๊ฒŒ API ๊ด€๋ฆฌ์—์„œ SpikeArrest, JavaScript, GenerateJWT, KVM, OASValidation, OAuthv2, ServiceCallout ์ •์ฑ…์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์•ˆ๋‚ดํ•ฉ๋‹ˆ๋‹ค. ๊ฑฐ๋ถ€ ๋ชฉ๋ก์— ์ง€์ •๋œ ์ •์ฑ…์ด ์—†์Šต๋‹ˆ๋‹ค.

ํ…œํ”Œ๋ฆฟ ๊ทœ์น™ ์ ์šฉ

๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ…œํ”Œ๋ฆฟ ๊ทœ์น™์„ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.

kubectl apply -f template-rule.yaml

ํ…œํ”Œ๋ฆฟ ๊ทœ์น™์„ ์‚ฌ์šฉํ•  Apigee ํ…œํ”Œ๋ฆฟ ๋งŒ๋“ค๊ธฐ

์ด์ „ ์„น์…˜์—์„œ ๋งŒ๋“  ํ…œํ”Œ๋ฆฟ ๊ทœ์น™์„ ํฌํ•จํ•˜๋Š” Apigee ํ…œํ”Œ๋ฆฟ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

  1. apim ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— new-admin-template.yaml์ด๋ผ๋Š” ์ƒˆ yaml ํŒŒ์ผ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
  2. ๋‹ค์Œ ํŒŒ์ผ์˜ ์ฝ˜ํ…์ธ ๋ฅผ ์ƒˆ๋กœ ๋งŒ๋“  ํŒŒ์ผ์— ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค.
    # new-admin-template.yaml
    apiVersion: apim.googleapis.com/v1
    kind: ApimTemplate
    metadata:
      name: new-admin-template
      namespace: apim
    spec:
      apimTemplateRule:
        group: apim.googleapis.com
        kind: ApimTemplateRule
        name: template-rule
        namespace: apim
      templates:
      - mode: REQUEST
        flows:
        - name: preflow
          policies:
          - group: apim.googleapis.com
            kind: OASValidation
            name: oas-validation-1
            namespace: apim
          - group: apim.googleapis.com
            kind: SpikeArrest
            name: spike-arrest
            namespace: apim
        - name: ConditionalGetFlow
          policies:
          - group: apim.googleapis.com
            kind: Javascript
            name: js-add-headers
            namespace: apim
          condition: request.verb="GET"
        - name: postflow
          policies:
          - group: apim.googleapis.com
            kind: AssignMessage
            name: google-token-policy
            namespace: apim
          - group: apim.googleapis.com
            kind: ServiceCallout
            name: service-callout-1
            namespace: apim
      - mode: RESPONSE
        flows:
        - name: postflow
          policies:
          - group: apim.googleapis.com
            kind: KVM
            name: kvm-1
            namespace: apim
  3. ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ƒˆ ํ…œํ”Œ๋ฆฟ์„ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.
    kubectl apply -f new-admin-template.yaml

Apigee ๊ฒŒ์ดํŠธ์›จ์ด ์ •์ฑ… ๋ฐฐํฌ

์ด ๋‹จ๊ณ„์—์„œ๋Š” ApigeeGatewayPolicy ์‚ฌ์–‘์ด ํฌํ•จ๋œ ์ƒˆ ํŒŒ์ผ์„ ๊ฒŒ์ดํŠธ์›จ์ด์— ์ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด ์ •์ฑ…์€ Apigee ํ…œํ”Œ๋ฆฟ์„ ๊ฒŒ์ดํŠธ์›จ์ด์— ๋ฐฐํฌํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

Apigee ๊ฒŒ์ดํŠธ์›จ์ด ์ •์ฑ…์„ ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค.

  1. apim ๋„ค์ž„์ŠคํŽ˜์ด์Šค์— apigee-gateway-policy-withSA.yaml์ด๋ผ๋Š” ์ƒˆ yaml ํŒŒ์ผ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.
  2. ๋‹ค์Œ ํŒŒ์ผ์˜ ์ฝ˜ํ…์ธ ๋ฅผ ์ƒˆ๋กœ ๋งŒ๋“  ํŒŒ์ผ์— ๋ณต์‚ฌํ•ฉ๋‹ˆ๋‹ค.
    # apigee-gateway-policy-withSA.yaml
    apiVersion: apim.googleapis.com/v1
    kind: ApigeeGatewayPolicy
    metadata:
      name: apim-template-injection
      namespace: apim
    spec:
      serviceAccount: apigee-apim-gsa@PROJECT_ID.iam.gserviceaccount.com
      ref:
        group: apim.googleapis.com
        kind: ApimTemplate
        name: new-admin-template
        namespace: apim
      targetRef:
        group: apim.googleapis.com
        kind: APIMExtensionPolicy
        name: global-ext-lb1-apim-policy
        namespace: apim
  3. ์ •์ฑ…์„ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.
    kubectl apply -f apigee-gateway-policy-withSA.yaml
  4. ์ƒˆ ๊ฒŒ์ดํŠธ์›จ์ด ์ •์ฑ…์˜ ๋ฐฐํฌ ์ƒํƒœ๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
    kubectl -n apim get ApigeeGatewayPolicy

    ๋ฐฐํฌํ•˜๋ฉด ์ •์ฑ… STATUS์— CREATED๊ฐ€ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

์ƒˆ ๊ฒŒ์ดํŠธ์›จ์ด ์ •์ฑ…์ด ๋ฐฐํฌ๋˜๋ฉด 2๋ถ„ ์ •๋„ ๊ธฐ๋‹ค๋ฆฐ ํ›„ ๊ฒŒ์ดํŠธ์›จ์ด์— ์š”์ฒญ์„ ์ „์†กํ•˜์—ฌ ์ •์ฑ…์ด ํด๋Ÿฌ์Šคํ„ฐ์— ์ „ํŒŒ๋˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

์ •์ฑ… ์‹œํ–‰ ํ™•์ธ

Apigee ๊ฒŒ์ดํŠธ์›จ์ด ์ •์ฑ…์ด ์˜ˆ์ƒ๋Œ€๋กœ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋ ค๋ฉด ๋‹ค์Œ ์„น์…˜์— ์„ค๋ช…๋œ ๋Œ€๋กœ ๊ฒŒ์ดํŠธ์›จ์ด์— ์š”์ฒญ์„ ์ „์†กํ•ฉ๋‹ˆ๋‹ค.

AssignMessage ์ •์ฑ… ์‹œํ–‰

AssignMessage ์ •์ฑ…์„ ์‚ฌ์šฉํ•˜์—ฌ {company_name} ํ† ํฐ์ด ์š”์ฒญ์— ์‚ฝ์ž…๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜๋ ค๋ฉด ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒŒ์ดํŠธ์›จ์ด์— ์š”์ฒญ์„ ์ „์†กํ•ฉ๋‹ˆ๋‹ค.

curl http://GATEWAY_IP_ADDRESS/get -H "Host: HOST_NAME" -H "x-api-key: API_KEY"

๊ฐ ํ•ญ๋ชฉ์˜ ์˜๋ฏธ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • GATEWAY_IP_ADDRESS๋Š” ๊ฒŒ์ดํŠธ์›จ์ด์˜ IP ์ฃผ์†Œ์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒŒ์ดํŠธ์›จ์ด IP ์ฃผ์†Œ๋ฅผ ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    kubectl get gateway GATEWAY_NAME
  • HOST_NAME์€ ํ˜ธ์ŠคํŠธ์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
  • API_KEY๋Š” API ํ‚ค ๊ฐ’์ž…๋‹ˆ๋‹ค.

์„ฑ๊ณต์ ์ธ ์‘๋‹ต์—๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ƒ์„ฑ๋œ Bearer ํ† ํฐ๊ณผ ํ•จ๊ป˜ Authorization ํ—ค๋”๊ฐ€ ํฌํ•จ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

{
  "args": {},
  "headers": {
    "Accept": "*/*",
    "Authorization": "Bearer ya29.c.c0ASRK0Gbw03y9cfvxL11DxaRYBQUU18SmUP4Vu63OckHI5cX7wJ4DmGMG2vbDDS69HXJHqMj-lak4tcqOsJGmE65crn2gNuJLanXidwM8",
    "First": "1.0",
    "Host": "apigee-apim-operator-test.apigee.net",
    "Second": "1.0",
    "Sum": "2",
    "User-Agent": "curl/8.7.1",
    "X-Api-Key": "McYcHGR3PTSGLXExvKADwQ1JJeCjgPDUvAakCl0rJKCFaX0Y",
    "X-Cloud-Trace-Context": "0fd3dadc2a3c328fa968d5f5f1434c29/18300783092696918345"
  },
  "origin": "34.54.108.129",
  "url": "apigee-apim-operator-test.apigee.net/get"
}

SpikeArrest ์ •์ฑ… ์‹œํ–‰

1๋ถ„ ์ด๋‚ด์— ๊ฒŒ์ดํŠธ์›จ์ด์— ์š”์ฒญ์„ 10๋ฒˆ ์ „์†กํ•˜์—ฌ SpikeArrest ์ •์ฑ…์˜ ์ ์šฉ์„ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค์Œ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ์š”์ฒญ์„ ์ƒ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

#!/bin/sh
for i in $(seq 1 11); do
    curl http://GATEWAY_IP_ADDRESS/get -H "Host: HOST_NAME" -H "x-api-key: API_KEY"
    sleep 1
done

๊ฐ ํ•ญ๋ชฉ์˜ ์˜๋ฏธ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • GATEWAY_IP_ADDRESS๋Š” ๊ฒŒ์ดํŠธ์›จ์ด์˜ IP ์ฃผ์†Œ์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒŒ์ดํŠธ์›จ์ด IP ์ฃผ์†Œ๋ฅผ ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ GATEWAY_NAME์€ ๊ฒŒ์ดํŠธ์›จ์ด ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
    kubectl get gateways.gateway.networking.k8s.io GATEWAY_NAME -o=jsonpath="{.status.addresses[0].value}"
  • HOST_NAME์€ ๊ฒŒ์ดํŠธ์›จ์ด์˜ HTTPRoute์— ์ •์˜๋œ ํ˜ธ์ŠคํŠธ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
  • API_KEY๋Š” ํ…Œ์ŠคํŠธ ์„ค์ •์—์„œ ํš๋“ํ•œ API ํ‚ค ๊ฐ’์ž…๋‹ˆ๋‹ค.

๋‹ค์Œ๊ณผ ๋น„์Šทํ•œ ์‘๋‹ต์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

"fault":{"faultstring":"Spike arrest violation. Allowed rate : MessageRate{capacity=5, period=Minutes}","detail":{"errorcode":"policies.ratelimit.SpikeArrestViolation"}}}

JavaScript ์ •์ฑ… ์‹œํ–‰

JavaScript ์ •์ฑ…์ด ์˜ˆ์ƒ๋Œ€๋กœ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋ ค๋ฉด ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒŒ์ดํŠธ์›จ์ด์— ์š”์ฒญ์„ ์ „์†กํ•ฉ๋‹ˆ๋‹ค.

curl http://GATEWAY_IP_ADDRESS/get \
  -H "Host: HOST_NAME" \
  -H "x-api-key: API_KEY" \
  -H "X-Request-Type: external" -i

๊ฐ ํ•ญ๋ชฉ์˜ ์˜๋ฏธ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • GATEWAY_IP_ADDRESS๋Š” ๊ฒŒ์ดํŠธ์›จ์ด์˜ IP ์ฃผ์†Œ์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒŒ์ดํŠธ์›จ์ด IP ์ฃผ์†Œ๋ฅผ ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ GATEWAY_NAME์€ ๊ฒŒ์ดํŠธ์›จ์ด ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
    kubectl get gateways.gateway.networking.k8s.io GATEWAY_NAME -o=jsonpath="{.status.addresses[0].value}"
  • HOST_NAME์€ ๊ฒŒ์ดํŠธ์›จ์ด์˜ HTTPRoute์— ์ •์˜๋œ ํ˜ธ์ŠคํŠธ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
  • API_KEY๋Š” ํ…Œ์ŠคํŠธ ์„ค์ •์—์„œ ํš๋“ํ•œ API ํ‚ค ๊ฐ’์ž…๋‹ˆ๋‹ค.

JavaScript ์ •์ฑ…์€ ์‘๋‹ต์— ํ‘œ์‹œ๋œ ๋Œ€๋กœ First, Second, Sum์˜ 3๊ฐ€์ง€ ์š”์ฒญ ํ—ค๋”๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค.

HTTP/1.1 200 OK
...
{
  "args": {},
  "headers": {
    ...
    "First": "1.0",
    ...
    "Second": "1.0",
    "Sum": "2",
    ...
  },
  ...
}

OASValidation ์ •์ฑ… ์‹œํ–‰

OASValidation ์ •์ฑ…์ด ์˜ˆ์ƒ๋Œ€๋กœ ์ž‘๋™ํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋ ค๋ฉด ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒŒ์ดํŠธ์›จ์ด์— ์š”์ฒญ์„ ์ „์†กํ•ฉ๋‹ˆ๋‹ค.

curl "http://GATEWAY_IP_ADDRESS/get"  \
  -H "Host: HOST_NAME" \
  -H "x-api-key: API_KEY" \
  -H "X-Request-Type: badvalue"

๊ฐ ํ•ญ๋ชฉ์˜ ์˜๋ฏธ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • GATEWAY_IP_ADDRESS๋Š” ๊ฒŒ์ดํŠธ์›จ์ด์˜ IP ์ฃผ์†Œ์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒŒ์ดํŠธ์›จ์ด IP ์ฃผ์†Œ๋ฅผ ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ GATEWAY_NAME์€ ๊ฒŒ์ดํŠธ์›จ์ด ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
    kubectl get gateways.gateway.networking.k8s.io GATEWAY_NAME -o=jsonpath="{.status.addresses[0].value}"
  • HOST_NAME์€ ๊ฒŒ์ดํŠธ์›จ์ด์˜ HTTPRoute์— ์ •์˜๋œ ํ˜ธ์ŠคํŠธ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
  • API_KEY๋Š” ํ…Œ์ŠคํŠธ ์„ค์ •์—์„œ ํš๋“ํ•œ API ํ‚ค ๊ฐ’์ž…๋‹ˆ๋‹ค.

๋ช…๋ น์–ด์— ์ž˜๋ชป๋œ X-Request-Type ํ—ค๋” ๊ฐ’์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ์œ ์‚ฌํ•œ ์‘๋‹ต์ด ํ‘œ์‹œ๋˜๋ฉด์„œ ์š”์ฒญ์ด ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.

{"fault":{"faultstring":"OASValidation oas-validation-1 with resource \"oas:\/\/oas-validation-1.yaml\": failed with reason: \"[ERROR - Instance value (\"badvalue\") not found in enum (possible values: [\"internal\",\"external\"]): []]\"","detail":{"errorcode":"steps.oasvalidation.Failed"}}}

์œ ํšจํ•œ X-Request-Type ํ—ค๋” ๊ฐ’์„ ์‚ฌ์šฉํ•˜์—ฌ ๋™์ผํ•œ ์š”์ฒญ์„ ์ „์†กํ•˜๋ฉด ์„ฑ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

curl "http://GATEWAY_IP_ADDRESS/get"  \
  -H "Host: HOST_NAME" \
  -H "x-api-key: API_KEY" \
  -H "X-Request-Type: external" -i

๊ฐ ํ•ญ๋ชฉ์˜ ์˜๋ฏธ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • GATEWAY_IP_ADDRESS๋Š” ๊ฒŒ์ดํŠธ์›จ์ด์˜ IP ์ฃผ์†Œ์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒŒ์ดํŠธ์›จ์ด IP ์ฃผ์†Œ๋ฅผ ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ GATEWAY_NAME์€ ๊ฒŒ์ดํŠธ์›จ์ด ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
    kubectl get gateways.gateway.networking.k8s.io GATEWAY_NAME -o=jsonpath="{.status.addresses[0].value}"
  • HOST_NAME์€ ๊ฒŒ์ดํŠธ์›จ์ด์˜ HTTPRoute์— ์ •์˜๋œ ํ˜ธ์ŠคํŠธ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
  • API_KEY๋Š” ํ…Œ์ŠคํŠธ ์„ค์ •์—์„œ ํš๋“ํ•œ API ํ‚ค ๊ฐ’์ž…๋‹ˆ๋‹ค.

ServiceCallout ์ •์ฑ… ์‹œํ–‰

๋””๋ฒ„๊ทธ ์„ธ์…˜์„ ์—ด๊ณ  ํ”„๋ก์‹œ์— ์œ ํšจํ•œ ์š”์ฒญ์„ ๋ช‡ ๊ฐœ ์ „์†กํ•˜์—ฌ ServiceCallout ์ •์ฑ…์˜ ์‹œํ–‰์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋””๋ฒ„๊ทธ ์„ธ์…˜์„ ์—ด๋ ค๋ฉด ๋‹ค์Œ ๋‹จ๊ณ„๋ฅผ ๋”ฐ๋ฅด์„ธ์š”.

  1. Google Cloud ์ฝ˜์†”์—์„œ API ํ”„๋ก์‹œ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

    API ํ”„๋ก์‹œ๋กœ ์ด๋™

  2. Kubernetes์šฉ Apigee APIM Operator๋ฅผ ์œ„ํ•ด ์ƒ์„ฑ๋œ ํ™˜๊ฒฝ์— ๋ฐฐํฌํ•œ global-ext-lb1-apim-policy ํ”„๋ก์‹œ๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
  3. ๋””๋ฒ„๊ทธ ํƒญ์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.
  4. ๋””๋ฒ„๊ทธ ์„ธ์…˜ ์ฐฝ์—์„œ ๋””๋ฒ„๊ทธ ์„ธ์…˜ ์‹œ์ž‘์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.
  5. Debug session ์ฐฝ์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
    • ํ™˜๊ฒฝ: ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ํ™˜๊ฒฝ ๋ชฉ๋ก์—์„œ APIM Operator์šฉ์œผ๋กœ ๋งŒ๋“  ํ™˜๊ฒฝ์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
    • ํ•„ํ„ฐ: ์—†์Œ(๋ชจ๋“  ํŠธ๋žœ์žญ์…˜)์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.
  6. ์‹œ์ž‘์„ ํด๋ฆญํ•ฉ๋‹ˆ๋‹ค.

์„ธ์…˜์ด ์‹œ์ž‘๋˜๋ฉด ์œ ํšจํ•œ ์š”์ฒญ์„ ํ”„๋ก์‹œ์— ๋ณด๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

curl "GATEWAY_IP_ADDRESSget"  \
  -H "Host: HOST_NAME" \
  -H "x-api-key: API_KEY" \
  -H "X-Request-Type: external" -i

๊ฐ ํ•ญ๋ชฉ์˜ ์˜๋ฏธ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • GATEWAY_IP_ADDRESS๋Š” ๊ฒŒ์ดํŠธ์›จ์ด์˜ IP ์ฃผ์†Œ์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒŒ์ดํŠธ์›จ์ด IP ์ฃผ์†Œ๋ฅผ ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ GATEWAY_NAME์€ ๊ฒŒ์ดํŠธ์›จ์ด ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
    kubectl get gateway GATEWAY_NAME
  • HOST_NAME์€ ๊ฒŒ์ดํŠธ์›จ์ด์˜ HTTPRoute์— ์ •์˜๋œ ํ˜ธ์ŠคํŠธ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
  • API_KEY๋Š” ํ…Œ์ŠคํŠธ ์„ค์ •์—์„œ ํš๋“ํ•œ API ํ‚ค ๊ฐ’์ž…๋‹ˆ๋‹ค.

์š”์ฒญ ๋ฐ ์‘๋‹ต ํŠธ๋žœ์žญ์…˜์ด ํŠธ๋žœ์žญ์…˜ ์ฐฝ์— ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ๋ชฉ๋ก์—์„œ ์„ฑ๊ณตํ•œ ํŠธ๋žœ์žญ์…˜์„ ์„ ํƒํ•˜์—ฌ ํ๋ฆ„์„ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ServiceCallout ์ •์ฑ…์ด ์„ฑ๊ณต์ ์œผ๋กœ ์‹คํ–‰๋˜์—ˆ์Œ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

KVM ์ •์ฑ… ์‹œํ–‰

KVM ์ •์ฑ…์ด ์„ฑ๊ณต์ ์œผ๋กœ ์‹คํ–‰๋˜๋ฉด mykey ํ‚ค์˜ ์‹œ์ž‘ ๊ฐ’์œผ๋กœ KVM์„ ์ดˆ๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค. ์‘๋‹ต ํŠธ๋žœ์žญ์…˜์ด ์žˆ์œผ๋ฉด KVM ์ •์ฑ…์ด mykey ๊ฐ’์„ ๊ฒ€์ƒ‰ํ•˜์—ฌ ์‘๋‹ต ํ—ค๋” mykvm์— ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. KVM ์ •์ฑ…์ด ๋‹ค์‹œ ์‹คํ–‰๋˜๋ฉด ์š”์ฒญ ํ—ค๋” mykvm์—์„œ ๊ฐ€์ ธ์˜จ mykey์˜ ์ƒˆ ๊ฐ’์ด ์‚ฝ์ž…๋ฉ๋‹ˆ๋‹ค.

๊ฐ ํŠธ๋žœ์žญ์…˜์˜ ํ—ค๋”๋ฅผ ํ™•์ธํ•˜์—ฌ ์ •์ฑ…์ด ํ•œ ํŠธ๋žœ์žญ์…˜์—์„œ KVM์— ๊ฐ’์„ ์ €์žฅํ•˜๊ณ  ๋‹ค์Œ ํŠธ๋žœ์žญ์…˜์—์„œ ๋™์ผํ•œ ๊ฐ’์„ ๊ฒ€์ƒ‰ํ•˜๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(๋‹ค์Œ ์˜ˆ ์ฐธ๊ณ ).

KVM ์ •์ฑ…์„ ํ…Œ์ŠคํŠธํ•ฉ๋‹ˆ๋‹ค.

  1. ์š”์ฒญ์„ ๊ฒŒ์ดํŠธ์›จ์ด์— ๋ณด๋ƒ…๋‹ˆ๋‹ค.
    curl -i "http://GATEWAY_IP_ADDRESS/get" \
      -H "Host: HOST_NAME" \
      -H "x-api-key: API_KEY" \
      -H "X-Request-Type: external" \
      -H "KVM_NAME: next-value1" -i

    ๊ฐ ํ•ญ๋ชฉ์˜ ์˜๋ฏธ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

    • GATEWAY_IP_ADDRESS๋Š” ๊ฒŒ์ดํŠธ์›จ์ด์˜ IP ์ฃผ์†Œ์ž…๋‹ˆ๋‹ค. ๋‹ค์Œ ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๊ฒŒ์ดํŠธ์›จ์ด IP ์ฃผ์†Œ๋ฅผ ๊ฒ€์ƒ‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ GATEWAY_NAME์€ ๊ฒŒ์ดํŠธ์›จ์ด ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
      kubectl get gateway GATEWAY_NAME
    • HOST_NAME์€ ๊ฒŒ์ดํŠธ์›จ์ด์˜ HTTPRoute์— ์ •์˜๋œ ํ˜ธ์ŠคํŠธ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.
    • API_KEY๋Š” ํ…Œ์ŠคํŠธ ์„ค์ •์—์„œ ํš๋“ํ•œ API ํ‚ค ๊ฐ’์ž…๋‹ˆ๋‹ค.
    • KVM_NAME์€ KVM์˜ ์ด๋ฆ„์ž…๋‹ˆ๋‹ค.

  2. ์‘๋‹ต ํ—ค๋”๋ฅผ ํ™•์ธํ•˜์—ฌ KVM ์ •์ฑ…์ด ์„ฑ๊ณต์ ์œผ๋กœ ์‹คํ–‰๋˜์—ˆ๊ณ  ์ดˆ๊ธฐ ๊ฐ’์ด mykvm์— ์ €์žฅ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๋น„์Šทํ•œ ์‘๋‹ต์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.
    HTTP/1.1 200 OK
    access-control-allow-credentials: true
    access-control-allow-origin: *
    Content-Length: 517
    content-type: application/json
    date: ...
    server: gunicorn/19.9.0
    mykvm: initvalue
    via: 1.1 google
    {
      "args": {
      ...
      "url": "http://apigee-apim-operator-test.apigee.net/get"
      }
    }
  3. ๊ฒŒ์ดํŠธ์›จ์ด์— ๋‹ค๋ฅธ ์š”์ฒญ์„ ๋ณด๋ƒ…๋‹ˆ๋‹ค.
    curl -i "http://GATEWAY_IP_ADDRESS/get" \
      -H "Host: HOST_NAME" \
      -H "x-api-key: API_KEY" \
      -H "mykvm: next"X-Request-Type: external" -H "mykvm: next-value2" -i

    ์‘๋‹ต์€ ๋‹ค์Œ๊ณผ ๋น„์Šทํ•˜๊ฒŒ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

    HTTP/1.1 200 OK
    access-control-allow-credentials: true
    access-control-allow-origin: *
    Content-Length: 517
    content-type: application/json
    date: ...
    server: gunicorn/19.9.0
    mykvm: next-value2
    via: 1.1 google
    {
      "args": {
      ...
      "url": "http://apigee-apim-operator-test.apigee.net/get?rq-param2=rq-val1&x-param1=xval1"
      }
    }

    mykvm ํ—ค๋” ๊ฐ’์ด ์š”์ฒญ ํ—ค๋” mykvm ๊ฐ’์œผ๋กœ ์—…๋ฐ์ดํŠธ๋˜์—ˆ์œผ๋ฏ€๋กœ KVM ์ •์ฑ…์ด ์„ฑ๊ณต์ ์œผ๋กœ ์‹คํ–‰๋˜์—ˆ์Œ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  4. ์š”์ฒญ์„ ํ•œ ๋ฒˆ ๋” ๋ณด๋ƒ…๋‹ˆ๋‹ค.
    curl -i "http://GATEWAY_IP_ADDRESS/get" \
      -H "Host: HOST_NAME" \
      -H "x-api-key: API_KEY" \
      -H "X-Request-Type: external" -H "mykvm: next-value3" -i

    ์‘๋‹ต์€ ๋‹ค์Œ๊ณผ ๋น„์Šทํ•˜๊ฒŒ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

    HTTP/1.1 200 OK
    access-control-allow-credentials: true
    access-control-allow-origin: *
    Content-Length: 517
    content-type: application/json
    date: ...
    server: gunicorn/19.9.0
    mykvm: next-value2
    via: 1.1 google
    {
      "args": {
      ...
      "url": "http://apigee-apim-operator-test.apigee.net/get?rq-param2=rq-val1&x-param1=xval1"
      }
    }

    mykvm ํ—ค๋”์˜ ๊ฐ’์ด ๋‹ค์‹œ ์—…๋ฐ์ดํŠธ๋˜์–ด ์‘๋‹ต์— ํ‘œ์‹œ๋œ ๊ฐ’์ด ์ด์ „ ํŠธ๋žœ์žญ์…˜์— ์ €์žฅ๋œ ๊ฐ’์ž„์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

๋ฌธ์ œ ํ•ด๊ฒฐ

GKE ๊ฒŒ์ดํŠธ์›จ์ด์— ์ •์ฑ…์„ ์ถ”๊ฐ€ํ•  ๋•Œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด APIM Operator ๋ฌธ์ œ ํ•ด๊ฒฐ์—์„œ ์ผ๋ฐ˜์ ์ธ ์˜ค๋ฅ˜์˜ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•์„ ์ฐธ์กฐํ•˜์„ธ์š”.

๋‹ค์Œ ๋‹จ๊ณ„