Kong merupakan sebuah API gateway yang keren sekali. Kong ini sangat berguna untuk kita yang menerapkan microservice pada layanan / apps kita. Kemudian ada juga yang namanya konga, ini adalah GUI / WebUI dari kong namun bukan official dari kong.

Selain kong dan konga, nantinya kita juga membutuhkan DBMS yang berfungsi untuk menyimpan data data dari kong dan konga. Mereka support menggunakan postgresql, jadi kita akan gunakan postgresql untuk DBMS nya.

Sebelumnya tkjpedia pernah membuat postingan tentang bagaimana cara menjalankan kong dan konga di docker pada halaman berikut:

Prasyarat

Untuk mengikuti tutorial ini ada beberapa prasyarat.

  1. Menggunakan kubernetes
  2. Menginstall kubectl
  3. Clusterissuer (menggunakan ssl gratis letsencrypt)

Install Postgresql

Pada kasus ini tkjpedia tidak menggunakan postgresql versi terbaru alih alih menggunakan postgresql versi 9.6. Alasan nya adalah kompatibilitas, dimana kong dan konga saat ini belum support postgresql versi baru.

tkjpedia akan menggukan image postgresql dari bitnami berikut: https://hub.docker.com/r/bitnami/postgresql

Statefulset Postgresql

Gunakan statefulset untuk postgresql pada kubernetes. Sesuaikan storageClassName dengan yang kalian digunakan.

buat file bernama statefulset-postgresql.yml

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: postgresql
  namespace: tkjpedia
spec:
  selector:
    matchLabels:
      name: postgresql
  serviceName: "postgresql"
  replicas: 1
  minReadySeconds: 0
  template:
    metadata:
      labels:
        name: postgresql
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: postgresql
        image: bitnami/postgresql:9.6
        ports:
        - containerPort: 5432
          name: 5432app
        volumeMounts:
        - name: postgresql
          mountPath: /bitnami/postgresql
        env:
            - name: "POSTGRESQL_USERNAME"
              value: "postgres"
            - name: "POSTGRESQL_PASSWORD"
              value: "rahasia"
            - name: "POSTGRESQL_DATABASE"
              value: "kong"
  volumeClaimTemplates:
  - metadata:
      name: postgresql
      namespace: dev
    spec:
      accessModes: [ "ReadWriteOnce" ]
      # storageClassName: "my-storage-class"
      resources:
        requests:
          storage: 1Gi

Kemudian apply postgres dengan perintah berikut:

kubectl apply -f statefulset-postgresql.yml

Service Postgresql

buat file bernama service-postgresql.yml

apiVersion: v1
kind: Service
metadata:
  name: postgresql-service
  namespace: tkjpedia
  labels:
    name: postgresql
spec:
  ports:
  - port: 5432
    name: 5432app
  selector:
    name: postgresql
  type: ClusterIP

Kemudian apply service dengan perintah berikut:

kubectl apply -f service-postgresql.yml

Install Kong

Untuk kong nya tkjpedia menggunakan image official dari kong berikut: https://hub.docker.com/_/kong

Sebelum menjalankan container kong, kita jalankan dulu database migration dari untuk kong tersebut dengan perintah sebagai berikut:

Job Kong Migration

Sebelum digunakan, kong membutuhkan database migration di awal. Untuk penggunaan sekali pakai, di kubernetes kita bisa menggunakan Job.

apiVersion: batch/v1
kind: Job
metadata:
  name: kong-migration
  namespace: tkjpedia
spec:
  template:
    spec:
      containers:
      - name: kong-migration
        image: kong
        command: ["kong", "migrations", "bootstrap"]
        env: 
          - name: "KONG_DATABASE"
            value: "postgres"
          - name: "KONG_PG_HOST"
            value: "postgresql-service"
          - name: "KONG_PG_DATABASE"
            value: "kong"
          - name: "KONG_PG_USER"
            value: "postgres"
          - name: "KONG_PG_PASSWORD"
            value: "rahasia"
          - name: "KONG_PROXY_ACCESS_LOG"
            value: "/dev/stdout"
          - name: "KONG_ADMIN_ACCESS_LOG"
            value: "/dev/stdout"
          - name: "KONG_PROXY_ERROR_LOG"
            value: "/dev/stderr"
          - name: "KONG_ADMIN_ERROR_LOG"
            value: "/dev/stderr"
          - name: "KONG_ADMIN_LISTEN"
            value: "0.0.0.0:8001, 0.0.0.0:8444 ssl"
      restartPolicy: Never
  backoffLimit: 1

Kemudian apply job dengan perintah berikut:

kubectl apply -f job-kong.yml

Deployment Kong

apiVersion: apps/v1
kind: Deployment
metadata:
  name: kong
  namespace: tkjpedia
  labels:
    name: kong
spec:
  replicas: 1
  selector:
    matchLabels:
      name: kong
  template:
    metadata:
      name: kong
      labels:
        name: kong
    spec:
      containers:
        - name: kong
          image: kong
          ports:
            - containerPort: 8000
              name: http
            - containerPort: 8443
              name: https
            - containerPort: 8001
              name: api-http
            - containerPort: 8443
              name: api-https
          resources: 
            limits: 
              cpu: 500m
              memory: 512Mi
            requests: 
              cpu: 250m
              memory: 256Mi
          env: 
          - name: "KONG_DATABASE"
            value: "postgres"
          - name: "KONG_PG_HOST"
            value: "postgresql-service"
          - name: "KONG_PG_DATABASE"
            value: "kong"
          - name: "KONG_PG_USER"
            value: "postgres"
          - name: "KONG_PG_PASSWORD"
            value: "rahasia"
          - name: "KONG_PROXY_ACCESS_LOG"
            value: "/dev/stdout"
          - name: "KONG_ADMIN_ACCESS_LOG"
            value: "/dev/stdout"
          - name: "KONG_PROXY_ERROR_LOG"
            value: "/dev/stderr"
          - name: "KONG_ADMIN_ERROR_LOG"
            value: "/dev/stderr"
          - name: "KONG_ADMIN_LISTEN"
            value: "0.0.0.0:8001, 0.0.0.0:8444 ssl"

Kemudian apply deployment dengan perintah berikut:

kubectl apply -f deployment-kong.yml

HPA Kong

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: kong
  namespace: tkjpedia
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: kong
  minReplicas: 1
  maxReplicas: 4
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 80
  - type: Resource
    resource:
      name: memory
      target:
        type: Utilization
        averageUtilization: 70

Kemudian apply HPA dengan perintah berikut:

kubectl apply -f hpa-kong.yml

Service Kong

apiVersion: v1
kind: Service
metadata:
  name: kong-service
  namespace: tkjpedia
  annotations:
spec:
  ports:
  - name: 8000app
    port: 8000
    protocol: TCP
    targetPort: 8000
  - name: 8443app
    port: 8443
    protocol: TCP
    targetPort: 8443
  - name: 8001app
    port: 8001
    protocol: TCP
    targetPort: 8001
  - name: 8444app
    port: 8444
    protocol: TCP
    targetPort: 8444
  selector:
    name: kong
  type: ClusterIP

Kemudian apply service dengan perintah berikut:

kubectl apply -f service-kong.yml

Ingress Kong

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: kong-ingress
  namespace: tkjpedia
  generation: 1
  annotations:
    nginx.ingress.kubernetes.io/proxy-body-size: "0"
    nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
    nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
    cert-manager.io/cluster-issuer: lets-encrypt
spec:
  tls:
  - hosts: 
    - api.tkjpedia.com
    secretName: api-tkjpedia-com-tls
  ingressClassName: public
  rules:
  - host: api.tkjpedia.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: kong-service
            port:
              number: 8000

Kemudian apply ingress dengan perintah berikut:

kubectl apply -f ingress-kong.yml

Install Konga

Job Konga Migration

apiVersion: batch/v1
kind: Job
metadata:
  name: konga-migration
  namespace: tkjpedia
spec:
  template:
    spec:
      containers:
      - name: konga-migration
        image: pantsel/konga
        command: ["node", "./bin/konga.js", "prepare"]
        env: 
        - name: "TOKEN_SECRET"
          value: "rahasia"
        - name: "NODE_ENV"
          value: "development"
        - name: "KONGA_ENV"
          value: "development"
        - name: "DB_ADAPTER"
          value: "postgres"
        - name: "DB_URI"
          value: "postgresql://postgres:rahasia@postgresql-service:5432/konga"
      restartPolicy: Never
  backoffLimit: 1

Kemudian apply job dengan perintah berikut:

kubectl apply -f job-konga.yml

Deployment Konga

apiVersion: apps/v1
kind: Deployment
metadata:
  name: konga
  namespace: tkjpedia
  labels:
    name: konga
spec:
  replicas: 1
  selector:
    matchLabels:
      name: konga
  template:
    metadata:
      name: konga
      labels:
        name: konga
    spec:
      containers:
        - name: konga
          image: pantsel/konga
          ports:
            - containerPort: 1337
              name: http
          resources: 
            limits: 
              cpu: 500m
              memory: 512Mi
            requests: 
              cpu: 250m
              memory: 256Mi
          env: 
          - name: "TOKEN_SECRET"
            value: "rahasia"
          - name: "NODE_ENV"
            value: "development"
          - name: "DB_ADAPTER"
            value: "postgres"
          - name: "DB_URI"
            value: "postgresql://postgres:rahasia@postgresql-service:5432/konga"

Kemudian apply deployment dengan perintah berikut:

kubectl apply -f deployment-konga.yml

Service Konga

apiVersion: v1
kind: Service
metadata:
  name: konga-service
  namespace: tkjpedia
  annotations:
spec:
  ports:
  - name: 1337app
    port: 1337
    protocol: TCP
    targetPort: 1337
  selector:
    name: konga
  type: ClusterIP

Kemudian apply service dengan perintah berikut:

kubectl apply -f service-konga.yml

Ingress Konga

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: konga-ingress
  namespace: tkjpedia
  generation: 1
  annotations:
    cert-manager.io/cluster-issuer: lets-encrypt
    nginx.ingress.kubernetes.io/whitelist-source-range: <ip>/<prefix> # optional whitelist
spec:
  tls:
  - hosts: 
    - konga.tkjpedia.com
    secretName: konga-tkjpedia-com-tls
  ingressClassName: public
  rules:
  - host: konga.tkjpedia.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: konga-service
            port:
              number: 1337

Kemudian apply ingress dengan perintah berikut:

kubectl apply -f ingress-konga.yml

Konfigurasi Konga

Buka domain yang sudah di atur, tadi saya bikin whitelist IP, maka saya harus menggunakan IP yang ada di whitelist, jika tidak maka hasilnya adalah forbidden seperti ini.

Ketika dibuka menggunakan IP yang di whitelist, maka bisa dan muncul formulir pendaftaran.

Setelah mendaftar dan login. Konfigurasikan konga untuk terhubung ke kong menggunakan http dan arahkan ke service nya kong dengan port 8001

Selamat! kong kalian sudah terinstall di kubernetes.

Uji Coba

Coba kita buat service dan route kemudian mengaksesnya.

Buat service

Buat route

Coba kita akses api nya melalui kong api gateway

Selamat!