0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

EKS上にKonnectのDPをGitHub Actions経由で構築する

Last updated at Posted at 2025-05-08

KonnectのData Planeの構築はWebUIから簡単に行えるが、それでもログインしたりクラスタ側でhelmコマンドを叩いたり、ある程度の作業が発生する。
今回はこれを全てGitHub Actionsに落とし込んで1クリックで作成しようと思う。

前提

以下を前提とする。

  • EKSがある
  • 以下のAWSに関する環境変数が設定済み
    • export AWS_REGION=us-east-1
    • export AWS_ACCESS_KEY_ID="ASIAV..."
    • export AWS_SECRET_ACCESS_KEY="Fh4E..."
    • export AWS_SESSION_TOKEN="IQoJ..."
  • Konnectのトークンを発行済

準備

GitHub Actions向け変数の準備

まずはGitHub Actionsで使う変数を用意する。
個人的な好みから、先に環境変数で設定し、それを使ってGitHubのリポジトリに設定するようにする。
ここで設定する環境変数は以下となる。

環境変数 意味
KONNECT_TOKEN Konnectのアクセストークン。CPのIDを取得するためのAPIを発行するのに利用。
EKS_CLUSTER_NAME EKSのクラスタ名
CP_NAME DPを展開するCPの名前
KONG_REPO DPのイメージを格納しているリポジトリ。ここではこの記事で作成したイメージを使いたいので環境変数化している。デフォルトのものを使いたい人はkong/kong-gatewayを指定する
KONG_VER DPのバージョン
GIT_REPO 変数を設定するGitHubのリポジトリ

ということで以下のように設定する。

KONNECT_TOKEN=kpat_sHa...
EKS_CLUSTER_NAME=mycluster
CP_NAME=default
KONG_REPO=ghcr.io/imurata/kong-gateway
KONG_VER=3.10.0.1
GIT_REPO=imurata/hoge

設定後、ghコマンドを使ってSecret、Variablesを設定する。

gh secret set AWS_ACCESS_KEY_ID --body $AWS_ACCESS_KEY_ID --repo $GIT_REPO
gh secret set AWS_SECRET_ACCESS_KEY --body $AWS_SECRET_ACCESS_KEY --repo $GIT_REPO
gh secret set AWS_SESSION_TOKEN --body $AWS_SESSION_TOKEN --repo $GIT_REPO
gh secret set AWS_REGION --body $AWS_REGION --repo $GIT_REPO
gh secret set KONNECT_TOKEN --body $KONNECT_TOKEN --repo $GIT_REPO
gh secret set EKS_CLUSTER_NAME --body $EKS_CLUSTER_NAME --repo $GIT_REPO
gh variable set CP_NAME --body $CP_NAME --repo $GIT_REPO
gh variable set KONG_REPO --body $KONG_REPO --repo $GIT_REPO
gh variable set KONG_VER --body $KONG_VER --repo $GIT_REPO

また、KONG_REPOにアクセスするためのコンテナレジストリ用Secretが必要な場合は作成しておく。
(ここでは事前に作ったが、実際はパイプラインの中で作った方がいいかも)

kubectl create secret docker-registry ghcr-secret --docker-server=ghcr.io --docker-username=imurata --docker-password=$GITHUB_TOKEN -n kong

パイプラインの作成

以下のような感じでパイプラインを作成してGitにPushする。

cat <<'EOF' > ./.github/workflows/deploy_dp.yaml
name: Deploy Kong Data Plane

on:
  workflow_dispatch:

jobs:
  deploy-dp:
    runs-on: ubuntu-latest
    env:
      KONNECT_API: https://us.api.konghq.com/v2

    steps:
      - name: Set up dependencies
        run: |
          sudo apt-get update
          sudo apt-get install -y jq openssl

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-session-token: ${{ secrets.AWS_SESSION_TOKEN }}
          aws-region: ${{ secrets.AWS_REGION }}

      - name: Set up kubeconfig for EKS
        run: |
          aws eks update-kubeconfig --name ${{ secrets.EKS_CLUSTER_NAME }}

      - name: Get Control Plane ID and upload TLS certs
        id: get_cp
        run: |
          CP_ID=$(curl -s -X GET \
            -H "Authorization: Bearer ${{ secrets.KONNECT_TOKEN }}" \
            "${KONNECT_API}/control-planes" \
            | jq -r --arg name "${{ vars.CP_NAME }}" '.data[] | select(.name==$name) | .id')
          mkdir certs
          openssl req -new -x509 -nodes -newkey rsa:2048 \
            -subj "/CN=kongdp/C=US" \
            -keyout ./certs/tls.key -out ./certs/tls.crt -days 3650
          export CERT=$(awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' ./certs/tls.crt)
          curl -sX POST \
            -H "Authorization: Bearer ${{ secrets.KONNECT_TOKEN }}" \
            ${KONNECT_API}/control-planes/${CP_ID}/dp-client-certificates \
            --json '{"cert":"'"$CERT"'"}'
          CP_ENDPOINT=$(curl -s -X GET \
            -H "Authorization: Bearer ${{ secrets.KONNECT_TOKEN }}" \
            "${KONNECT_API}/control-planes/${CP_ID}" \
            | jq -r '.config.control_plane_endpoint')
          CP_ENDPOINT=$(sed "s@https://@@" <<< $CP_ENDPOINT)
          TP_ENDPOINT=$(curl -s -X GET \
            -H "Authorization: Bearer ${{ secrets.KONNECT_TOKEN }}" \
            "${KONNECT_API}/control-planes/${CP_ID}" \
            | jq -r '.config.telemetry_endpoint')
          TP_ENDPOINT=$(sed "s@https://@@" <<< $TP_ENDPOINT)
          echo "tp_endpoint=$TP_ENDPOINT" >> "$GITHUB_OUTPUT"
          echo "cp_endpoint=$CP_ENDPOINT" >> "$GITHUB_OUTPUT"

      - name: Create Kubernetes namespace and TLS secret
        run: |
          kubectl create ns kong || true
          kubectl create secret tls kong-cluster-cert -n kong \
            --cert=./certs/tls.crt \
            --key=./certs/tls.key \
            --dry-run=client -o yaml | kubectl apply -f -

      - name: Generate values.yaml
        run: |
          cat <<EOF > ./values.yaml
          image:
            repository: ${{ vars.KONG_REPO }}
            tag: ${{ vars.KONG_VER }}
            pullSecrets:
              - ghcr-secret

          secretVolumes:
            - kong-cluster-cert

          admin:
            enabled: false

          env:
            role: data_plane
            database: "off"
            cluster_mtls: pki
            cluster_control_plane: ${{ steps.get_cp.outputs.cp_endpoint }}:443
            cluster_server_name: ${{ steps.get_cp.outputs.cp_endpoint }}
            cluster_telemetry_endpoint: ${{ steps.get_cp.outputs.tp_endpoint }}:443
            cluster_telemetry_server_name: ${{ steps.get_cp.outputs.tp_endpoint }}
            cluster_cert: /etc/secrets/kong-cluster-cert/tls.crt
            cluster_cert_key: /etc/secrets/kong-cluster-cert/tls.key
            lua_ssl_trusted_certificate: system
            konnect_mode: "on"
            vitals: "off"
            nginx_worker_processes: "1"
            upstream_keepalive_max_requests: "100000"
            nginx_http_keepalive_requests: "100000"
            proxy_access_log: "off"
            dns_stale_ttl: "3600"
            router_flavor: expressions

          ingressController:
            enabled: false
            installCRDs: false

          resources:
            requests:
              cpu: 1
              memory: "2Gi"
          EOF

      - name: Deploy with Helm
        run: |
          helm repo add kong https://charts.konghq.com
          helm repo update
          helm upgrade -i my-kong kong/kong -n kong --values ./values.yaml --debug --wait

      - name: Upload artifacts
        uses: actions/upload-artifact@v4
        with:
          name: kong-dp-config
          path: |
            ./values.yaml
            ./certs/tls.crt
            ./certs/tls.key
EOF
git add -A 
git commit -m "Initial Commit" 
git push origin main

上記のコードについて、ポイントを絞って説明する。

      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-session-token: ${{ secrets.AWS_SESSION_TOKEN }}
          aws-region: ${{ secrets.AWS_REGION }}

      - name: Set up kubeconfig for EKS
        run: |
          aws eks update-kubeconfig --name ${{ secrets.EKS_CLUSTER_NAME }}

上記についてはEKSを叩くためのkubeconfigを取得するために実行している。
EKSではないクラスタであれば、以下のような感じで取り込むといいと思う。

gh secret set KUBECONFIG_DATA --body $(base64 -w 0 ~/.kube/config) --repo $GIT_REPO

      - name: Set up kubeconfig
        run: |
          echo "${{ secrets.KUBECONFIG_DATA }}" | base64 -d > $HOME/.kube/config

次に以下のstepではCPのIDを取得しTLSの証明書のアップロードやvalues.yamlに設定するためのエンドポイントを取得する。

- name: Get Control Plane ID and upload TLS certs
        id: get_cp
        :(省略)

過去に書いた「Konnectに繋ぐData PlaneをCLIのみで起動する」という記事で実行しているコマンドの詳細を説明しているので、ここでは説明は割愛する。

      - name: Create Kubernetes namespace and TLS secret
        run: |
          kubectl create ns kong || true
          kubectl create secret tls kong-cluster-cert -n kong \
            --cert=./certs/tls.crt \
            --key=./certs/tls.key \
            --dry-run=client -o yaml | kubectl apply -f -

ここではNamespaceを作成し、証明書をSecretに格納する箇所となる。
UIではSecretはkubectl createで作成するが、ここでは既にSecretがある場合を考慮し、--dry-runでYAML形式で吐いた後にkubectl applyで上書きするようにしている。
今回は省略したが、KONG_REPOに対するアクセス用のpullSecretsのためのSecretを作成するならここで作っておくとよい。

      - name: Generate values.yaml
        run: |
          cat <<EOF > ./values.yaml
          image:
            repository: ${{ vars.KONG_REPO }}
            tag: ${{ vars.KONG_VER }}
            pullSecrets:
              - ghcr-secret
          :(省略)

上記以降でHelmのvalues.yamlを作成してDPをデプロイする。
KonnectのUIで提示されるvalues.yamlではpullSecretsの項目はないが、今回は自前のリポジトリ(KONG_REPO)にイメージがあることを想定し、そこからPullするための認証情報を引っ張るために設定する。
cluster_control_planecluster_server_namecluster_telemetry_endpointcluster_telemetry_server_nameに関してはControl Planeがないと値が設定できない部分であり事前に値を設定することが難しい。
そのため、CPのIDを取得した際にそれぞれのエンドポイントの値を覚えておいて、values.yaml作成時に反映させている。

ちなみに今回のパイプラインはHelmのインストールで終了させているが、何だったらPodの起動確認やdeckを使って簡易的な疎通確認まで実装してもよいと思う。
今回は検証目的であり省略した。

動作確認

パイプラインをworkflow_dispatchで作成しているので、GitHub Actionsから手動で実行してDPをデプロイする。
以下のような感じでActionsからRun workflowをクリックして実行する。
Pasted image 20250508152547.png

ジョブの実行が完了するとクラスタ上でPodが立っているのが分かる。

$ kubectl get pod -n kong
NAME                           READY   STATUS    RESTARTS   AGE
my-kong-kong-6898888cb-8cw5l   1/1     Running   0          3m12s

KonnectのUIからも確認できる。
Pasted image 20250508163436.png

以上より、1クリックでKonnectのDPを払い出せる環境が作成できた。
なお、注意点としてhelm uninstallで削除してもKonnect側に作成した証明書は残り続けるので、helm uninstall後は手動で削除する、もしくは削除用にまたパイプラインを用意した方がいい。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?