Amazon EKS Auto ModeにKong GatewayをデプロイしてKonnectで管理する

Amazon EKS Auto ModeにKong GatewayをデプロイしてKonnectで管理する

Clock Icon2025.02.18

APIの管理を効率化したい えがわ です。

Amazon EKS Auto ModeにKong Gatewayを導入していきます。

KongにはIngress Controller(KIC)もありますが、ブラウザから設定を行えなくなるため、今回はKong Gatewayをデプロイします。

構成図

今回の構成図はこちら

kong_eks_auto_mode_01.png

コントロールプレーンにはKonnectを使用し、EKSにKong Gatewayをデプロイします。

環境

  • Ubuntu 22.04.4 LTS(WSL2)
  • kubectl: v1.31.0
  • eksctl: 0.204.0

やってみる

EKS Auto Modeクラスターを作成

eksctlでEKSクラスターを作成します。

eksctl create cluster --{your-cluster-name} --enable-auto-mode
実行例
egawa@HL01559:kong-o11y$ avp eksctl create cluster --name=kong-demo --enable-auto-mode
2025-02-18 14:30:53 []  eksctl version 0.204.0
2025-02-18 14:30:53 []  using region us-east-1
2025-02-18 14:30:53 []  setting availability zones to [us-east-1b us-east-1d]
... 中略
2025-02-18 14:44:11 []  all EKS cluster resources for "kong-demo" have been created
2025-02-18 14:44:16 []  kubectl command should work with "/home/egawa/.kube/config", try 'kubectl get nodes'
2025-02-18 14:44:16 []  EKS cluster "kong-demo" in "us-east-1" region is ready

※コマンドのavpaws-vaultのエイリアスです。

Kongのネームスペースを作成

これからデプロイするKong GatewayやIngressはKongのNamespaceにデプロイします。

kubectl create namespace kong
実行例
egawa@HL01559:kong-o11y$ avp kubectl create namespace kong
namespace/kong created

Kong Gatewayをデプロイ

今回はKonnect経由にするため、Konnectからデプロイ情報を取得します。

New Data Plane Nodeでデータプレーン作成画面に遷移します。

kong_eks_auto_mode_02.png

PlatformでKubernetesを選択します。

kong_eks_auto_mode_03.png

今回はHelmチャートではデプロイしないため、2 Set up Helmはスキップします。

表示されているシークレットを登録します。

kong_eks_auto_mode_04.png

kubectl create secret tls kong-cluster-cert -n kong --cert=/{PATH_TO_FILE}/tls.crt --key=/{PATH_TO_FILE}/tls.key
egawa@HL01559:kong-o11y$ avp kubectl create secret tls kong-cluster-cert -n kong --cert=./tls.crt --key=./tls.key
secret/kong-cluster-cert created

Kong Gatewayをデプロイします。

kong-gateway.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: kong-gateway
  namespace: kong
  labels:
    app: kong-gateway
spec:
  replicas: 1
  selector:
    matchLabels:
      app: kong-gateway
  template:
    metadata:
      labels:
        app: kong-gateway
    spec:
      containers:
      - name: kong-gateway
        image: kong/kong-gateway:3.9
        env:
        - name: KONG_ROLE
          value: "data_plane"
        - name: KONG_DATABASE
          value: "off"
        - name: KONG_CLUSTER_MTLS
          value: "pki"
        - name: KONG_CLUSTER_CONTROL_PLANE
          value: "df0495f9e9.us.cp0.konghq.com:443"
        - name: KONG_CLUSTER_SERVER_NAME
          value: "df0495f9e9.us.cp0.konghq.com"
        - name: KONG_CLUSTER_TELEMETRY_ENDPOINT
          value: "df0495f9e9.us.tp0.konghq.com:443"
        - name: KONG_CLUSTER_TELEMETRY_SERVER_NAME
          value: "df0495f9e9.us.tp0.konghq.com"
        - name: KONG_CLUSTER_CERT
          value: "/etc/secrets/kong-cluster-cert/tls.crt"
        - name: KONG_CLUSTER_CERT_KEY
          value: "/etc/secrets/kong-cluster-cert/tls.key"
        - name: KONG_LUA_SSL_TRUSTED_CERTIFICATE
          value: "system"
        - name: KONG_KONNECT_MODE
          value: "on"
        - name: KONG_VITALS
          value: "off"
        - name: KONG_NGINX_WORKER_PROCESSES
          value: "1"
        - name: KONG_UPSTREAM_KEEPALIVE_MAX_REQUESTS
          value: "100000"
        - name: KONG_NGINX_HTTP_KEEPALIVE_REQUESTS
          value: "100000"
        - name: KONG_PROXY_ACCESS_LOG
          value: "off"
        - name: KONG_DNS_STALE_TTL
          value: "3600"
        - name: KONG_STATUS_LISTEN
          value: "0.0.0.0:8100"
        ports:
          - name: proxy
            containerPort: 8000
          - name: proxy-ssl
            containerPort: 8443
          - name: kong-cluster
            containerPort: 8005
          - name: status
            containerPort: 8100
        volumeMounts:
        - name: kong-cluster-cert
          mountPath: /etc/secrets/kong-cluster-cert
          readOnly: true
        resources:
          requests:
            cpu: "1"
            memory: "2Gi"
      volumes:
      - name: kong-cluster-cert
        secret:
          secretName: kong-cluster-cert
---
apiVersion: v1
kind: Service
metadata:
  name: kong-gateway
  namespace: kong
  labels:
    app: kong-gateway
spec:
  type: ClusterIP
  selector:
    app: kong-gateway
  ports:
    - name: http
      port: 80
      targetPort: 8000
    - name: https
      port: 443
      targetPort: 8443
    - name: status
      port: 8100
      targetPort: 8100

※エンドポイントは適宜変更してください。
※Kong GatewayのHealth Checkとしてポート:8100を開放しています。

kubectl apply -f kong-gateway.yaml
実行例
egawa@HL01559:kong-o11y$ avp kubectl apply -f kong-gateway.yaml
deployment.apps/kong-gateway created
service/kong-gateway created

Ingressをデプロイ

Kong Gatewayがデプロイできたので、外部から接続するためにIngressをデプロイします。

ALBを使用したいので、IngressClassを作成します。

alb-ingress.yaml
apiVersion: eks.amazonaws.com/v1
kind: IngressClassParams
metadata:
  name: eks-auto-alb
spec:
  scheme: internet-facing
---
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  name: eks-auto-alb
spec:
  controller: eks.amazonaws.com/alb
  parameters:
    apiGroup: eks.amazonaws.com
    kind: IngressClassParams
    name: eks-auto-alb
kubectl apply -f alb-ingress.yaml
実行例
egawa@HL01559:kong-o11y$ avp kubectl apply -f alb-ingress.yaml
ingressclassparams.eks.amazonaws.com/eks-auto-alb created
ingressclass.networking.k8s.io/eks-auto-alb created

Ingressをデプロイします。
ヘルスチェックはこちらを参考に設定しています。

kong-gateway-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: kong-gateway-ingress
  namespace: kong
  annotations:
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTP":80}]'
    alb.ingress.kubernetes.io/healthcheck-path: "/status/ready"
    alb.ingress.kubernetes.io/healthcheck-port: "8100"
    # HTTPS化・証明書を使用したい場合
    # alb.ingress.kubernetes.io/listen-ports: '[{"HTTP":80},{"HTTPS":443}]'
    # alb.ingress.kubernetes.io/certificate-arn: "arn:aws:acm:us-east-1:xxxx:certificate/xxxxxx"
spec:
  ingressClassName: eks-auto-alb
  rules:
    - http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: kong-gateway
                port:
                  number: 80
kubectl apply -f kong-gateway-ingress.yaml
実行例
egawa@HL01559:kong-o11y$ avp kubectl apply -f kong-gateway-ingress.yaml
ingress.networking.k8s.io/kong-gateway-ingress created

このコマンド実行時にALBが作成されます。

いったんテスト

Kong Gatewayの外部公開が完了しているはずなので、確認を行います。

以下でALBのDNSを取得できます。

kubectl get ingress -n kong
実行例
egawa@HL01559:kong-o11y$ avp kubectl get ingress -n kong
NAME                   CLASS          HOSTS   ADDRESS                                                              PORTS   AGE
kong-gateway-ingress   eks-auto-alb   *       k8s-kong-konggate-xxxxxx.us-east-1.elb.amazonaws.com   80      168m

Kong Gatewayにアクセスできていそうです。

実行例
egawa@HL01559:kong-o11y$ curl k8s-kong-konggate-xxxxxx.us-east-1.elb.amazonaws.com
{
  "message":"no Route matched with those values",
  "request_id":"f2f3b70302ef783bf97e784db790ea20"
}

ユーザーサービスをデプロイ

以前作成したユーザーサービスをデプロイしていきます。

user-service.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: user-service
  labels:
    app: user-service
spec:
  replicas: 2
  selector:
    matchLabels:
      app: user-service
  template:
    metadata:
      labels:
        app: user-service
    spec:
      containers:
      - name: user-service
        image: <your-aws-account>.dkr.ecr.us-east-1.amazonaws.com/user-service:latest
        ports:
        - containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
  name: user-service
  labels:
    app: user-service
spec:
  type: ClusterIP
  selector:
    app: user-service
  ports:
    - name: http
      port: 80
      targetPort: 3000
kubectl apply -f user-service.yaml
実行例
egawa@HL01559:kong-o11y$ avp kubectl apply -f user-service.yaml
deployment.apps/user-service created
service/user-service created

ユーザーサービスをデプロイできました。

Konnect側の設定

Kong Gateway -> ユーザーサービスのルートを作成していきます。

Service作成画面に遷移し、UpstreamURLにhttp://user-service.default/usersを設定します。

kong_eks_auto_mode_05.png

Route設定画面に遷移し、Pathsに/usersを設定します。

kong_eks_auto_mode_06.png

動作確認を行います。

egawa@HL01559:kong-o11y$ curl k8s-kong-konggate-xxxxxx.us-east-1.elb.amazonaws.com/users
[{"id":1,"name":"John Doe"},{"id":2,"name":"Tom Jelly"}]

Kong Gateway経由でアクセスできました。

おまけとしてRate Limitプラグインを有効にしてみます。

kong_eks_auto_mode_07.png

指定回数以上アクセスすると制限がかかります。

egawa@HL01559:kong-o11y$ curl k8s-kong-konggate-xxxxxx.us-east-1.elb.amazonaws.com/users
[{"id":1,"name":"John Doe"},{"id":2,"name":"Tom Jelly"}]
egawa@HL01559:kong-o11y$ curl k8s-kong-konggate-xxxxxx.us-east-1.elb.amazonaws.com/users
{
  "message":"API rate limit exceeded",
  "request_id":"cf5906370273a70861765d59a07cfa30"
}

このように簡単にAPIに機能を追加することが可能です。

さいごに

今回はEKS Auto Modeを使用してKonnectで管理するKong Gatewayをデプロイしてみました。
Konnectで管理することで、ブラウザで操作するだけで簡単にAPIの機能拡張を行うことができます。
この記事がどなたかの参考になれば幸いです。

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.