- Kong 공식페이지를 보면, Kong은 MSA구성을 가속화하는 가장 유명한 오픈 소스 API Gateway라고 말한다.
- 또한 경량화 된 프록시 환경위에 구축 되어 있어, 어디서든지 모든 마이크로 서비스에 성능 및 확장성을 제공한다.
- 이외에도 가장 큰 특징은, 모든 기능을 Restful Interface로 제공하고 있으며, API Gateway를 구성하는 필수 기능( OAuth 인증, Logging, 유량제어 등)들을 Plugin 기반으로 손쉽게 추가하여 사용할 수 있으며, Platform(런타임)에 구애받지 않고 어디서든지 Kong을 구축할 수 있다.
- kong ingress controller는 kubernetes cluster로 들어오는 트래픽을 프록시하는 것 이상을 수행한다.
- Controller Manager는 kubernetes cluster 내에서 발생하는 변경 사항을 보고 모든 트래픽을 프록시하기 위해 변경 사항에 대응하여 kong을 업데이트한다.
- kong은 kubernetes cluster 내에서 발생하는 확장, 구성 변경, 오류에 대한 변경 사항에 대응하기 위해 동적으로 업데이트됩니다.
- kong은 두 가지 타입으로 설치할 수 있는데, With a Database 와 DB-less Mode가 있다.
- Red Hat Enterprise Linux8
- k8s 1.27.11
- istio 1.17.1
- kong 2.9
- istio 1.17.1 version download
curl -s -L https://istio.io/downloadIstio | ISTIO_VERSION=1.17.1 sh -
- istioctl 추가
export PATH="$PATH:$PWD/istio-1.17.1/bin"
- 정상 작동 확인
istioctl x precheck
- service mesh sample app - bookinfo apply
# namespace create $ kubectl create namespace bookinfo # istio sidecar enabled in namespace $ kubectl label namespace bookinfo istio-injection=enabled # istio sample app - bookinfo apply $ kubectl -n bookinfo apply -f istio-1.17.1/samples/bookinfo/platform/kube/bookinfo.yaml # 이후 사이드카 주입 확인 - container 2/2 확인(1/1 상태면 파드 delete 후 apply) $ kubectl get pod -n bookinfo NAME READY STATUS RESTARTS AGE details-v1-c5b5f496d-9wm29 2/2 Running 0 101s productpage-v1-7d6cfb7dfd-5mc96 2/2 Running 0 100s ratings-v1-f745cf57b-hmkwf 2/2 Running 0 101s reviews-v1-85c474d9b8-kqcpt 2/2 Running 0 101s reviews-v2-ccffdd984-9jnsj 2/2 Running 0 101s reviews-v3-98dc67b68-nzw97 2/2 Running 0 101s - API 게이트웨이(Kong)와 서비스 메쉬(Istio) 모두 로드 밸런싱을 처리할 수 있는데, ingress.kubernetes.io/service-upstream: "true" 주석이 없으면 Kong은 productpage 서비스에서 자체 엔드포인트/대상을 선택하여 부하 분산을 시도한다. - 이로 인해 Envoy는 서비스의 클러스터 IP 대신 해당 포드의 IP를 업스트림 로컬 주소로 수신한다. - 하지만 Envoy가 적절하게 부하를 분산할 수 있도록 서비스의 클러스터 IP가 필요하다. $ kubectl annotate service productpage ingress.kubernetes.io/service-upstream=true - 제품 페이지 접근 확인 $ kubectl exec -it $(kubectl get pod -l app=ratings -o jsonpath='{.items[0].metadata.name}') -c ratings -- curl productpage:9080/productpage | grep -o "<title>.*</title>"
- istio 지원 namespace 생성
kubectl create ns kong-istio
- istio mesh namespace 활성화
kubectl label ns kong-istio istio-injection=enabled
- kong helm repo 구성
helm repo add kong https://charts.konghq.com && helm repo update
- chart 배포
helm install -n kong-istio kong-istio kong/kong
- Kong 컨테이너가 배치되고 Istio 사이드카 컨테이너가 제대로 주입되었는지 확인
kubectl describe pod -n kong-istio -l app.kubernetes.io/instance=kong-istio
- kong gateway를 통해 외부에 bookinfo 노출
# ingress yaml 생성 후 배포 vi bookinfo-ingress.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: productpage namespace: bookinfo spec: ingressClassName: kong rules: - http: paths: - path: / pathType: ImplementationSpecific backend: service: name: productpage port: number: 9080 kubectl apply -f bookinfo-ingress.yaml
- kong gateway를 통해 port 80과 매핑되어 있는 노드포트 확인
kubectl get svc -n kong-istio
- 요청
watch -n 1 curl IP:nodeport(kong gateway svc)
- istio 지원 namespace 생성
kubectl create ns kong
- istio mesh namespace 활성화
kubectl label ns kong istio-injection=enabled
- kong helm repo 구성
helm repo add kong https://charts.konghq.com && helm repo update
- values.yaml 커스터마이징(Postgres subcharts 설치)
vi values.yaml --- deployment: kong: enabled: true serviceAccount: create: true env: nginx_worker_processes: "2" anonymous_reports: "off" database: "postgres" admin: enabled: true type: NodePort annotations: {} http: enabled: true tls: enabled: true parameters: [] proxy: enabled: true type: LoadBalancer labels: enable-metrics: "true" http: enabled: true parameters: [] tls: enabled: true parameters: [] ingressController: enabled: true args: - --anonymous-reports=false admissionWebhook: enabled: false ingressClass: kong ingressClassAnnotations: {} rbac: create: true postgresql: enabled: true
- chart 배포
# istio와 kong의 버전 호환성이 맞지 않으면 kong은 error 상태이다. helm install kong kong/kong --version 2.9 -n kong -f values.yaml
- container 확인
k describe deployment.apps/kong-kong -n kong NAME READY STATUS RESTARTS AGE pod/kong-kong-6b9cd4d94d-qszqk 3/3 Running 2 (4m30s ago) 5m9s # 해당 pod의 container는 아래에 해당한다. - 1. proxy: 모든 트래픽을 처리하는 핵심 프록시 - 2. ingress-controller: Kubernetes에서 Kong으로 구성을 동기화하는 일련의 프로세스 - 3. istio-sidecar container
- Kong 컨테이너가 배치되고 Istio 사이드카 컨테이너가 제대로 주입되었는지 확인
kubectl describe pod -n kong -l app.kubernetes.io/instance=kong
- kong gateway를 통해 외부에 bookinfo 노출
# ingress yaml 생성 후 배포 vi bookinfo-ingress.yaml apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: productpage namespace: bookinfo spec: ingressClassName: kong rules: - http: paths: - path: / pathType: ImplementationSpecific backend: service: name: productpage port: number: 9080 kubectl apply -f bookinfo-ingress.yaml
- kong gateway를 통해 port 80과 매핑되어 있는 노드포트 확인
kubectl get svc -n kong
- 요청
watch -n 1 curl IP:nodeport(kong gateway svc)
- Konga는 kong-admin을 이용해서 연결되기 때문에 kong-admin service를 생성해준다.
- kong-admin을 설치하면 나중에 api를 보낼 때 Kong 리소스를 설치할 때 yml파일을 생성하지 않고도 생성할 수 있다.
kong-admin 생성
- kong-admin 설치
$ kubectl apply -f https://bit.ly/k8s-kong-admin -n kong or $ vi kong-admin.yaml apiVersion: v1 kind: Service metadata: name: kong-admin spec: type: NodePort ports: - name: admin port: 8001 protocol: TCP targetPort: 8001 - name: admin-ssl port: 8444 targetPort: 8444 protocol: TCP selector: app: ingress-kong --- apiVersion: apps/v1 kind: Deployment metadata: labels: app: ingress-kong name: ingress-kong spec: replicas: 1 selector: matchLabels: app: ingress-kong template: metadata: annotations: kuma.io/gateway: enabled traffic.sidecar.istio.io/includeInboundPorts: "" labels: app: ingress-kong spec: containers: - env: - name: KONG_DATABASE value: postgres - name: KONG_PG_HOST value: postgres - name: KONG_PG_PASSWORD value: kong - name: KONG_PROXY_LISTEN value: 0.0.0.0:8000, 0.0.0.0:8443 ssl http2 - name: KONG_PORT_MAPS value: 80:8000, 443:8443 - name: KONG_ADMIN_LISTEN value: 0.0.0.0:8001, 0.0.0.0:8444 ssl - name: KONG_STATUS_LISTEN value: 0.0.0.0:8100 - name: KONG_NGINX_WORKER_PROCESSES value: "2" - name: KONG_ADMIN_ACCESS_LOG value: /dev/stdout - name: KONG_ADMIN_ERROR_LOG value: /dev/stderr - name: KONG_PROXY_ERROR_LOG value: /dev/stderr image: kong:2.5 lifecycle: preStop: exec: command: - /bin/sh - -c - kong quit livenessProbe: failureThreshold: 3 httpGet: path: /status port: 8100 scheme: HTTP initialDelaySeconds: 5 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 1 name: proxy ports: - containerPort: 8001 name: admin protocol: TCP - containerPort: 8444 name: admin-ssl protocol: TCP - containerPort: 8000 name: proxy protocol: TCP - containerPort: 8443 name: proxy-ssl protocol: TCP - containerPort: 8100 name: metrics protocol: TCP readinessProbe: failureThreshold: 3 httpGet: path: /status port: 8100 scheme: HTTP initialDelaySeconds: 5 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 1 - env: - name: CONTROLLER_KONG_ADMIN_URL value: https://127.0.0.1:8444 - name: CONTROLLER_KONG_ADMIN_TLS_SKIP_VERIFY value: "true" - name: CONTROLLER_PUBLISH_SERVICE value: kong/kong-proxy - name: POD_NAME valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: apiVersion: v1 fieldPath: metadata.namespace image: kong/kubernetes-ingress-controller:2.0.5 imagePullPolicy: IfNotPresent livenessProbe: failureThreshold: 3 httpGet: path: /healthz port: 10254 scheme: HTTP initialDelaySeconds: 5 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 1 name: ingress-controller ports: - containerPort: 8080 name: webhook protocol: TCP - containerPort: 10255 name: cmetrics protocol: TCP readinessProbe: failureThreshold: 3 httpGet: path: /readyz port: 10254 scheme: HTTP initialDelaySeconds: 5 periodSeconds: 10 successThreshold: 1 timeoutSeconds: 1 initContainers: - command: - /bin/sh - -c - while true; do kong migrations list; if [[ 0 -eq $? ]]; then exit 0; fi; sleep 2; done; env: - name: KONG_PG_HOST value: postgres - name: KONG_PG_PASSWORD value: kong image: kong:2.9 name: wait-for-migrations serviceAccountName: kong-serviceaccount $ kubectl apply -f kong-admin.yaml -n kong-istio
- kong-admin 설치 확인
# kong-admin 설치 확인 kubectl get svc -n kong kong-admin service/kong-kong-admin NodePort 10.96.15.131 <none> 8001:32080/TCP,8444:31448/TCP 14h
konga service 및 deployment 생성
- konga-service 및 deployment 생성
$ kubectl create -f https://bit.ly/k8s-konga -n kong or $ vi konga.yaml apiVersion: apps/v1 kind: Deployment metadata: name: konga spec: replicas: 1 selector: matchLabels: app: konga name: konga template: metadata: labels: name: konga app: konga spec: containers: - name: konga image: pantsel/konga ports: - containerPort: 1337 env: - name: NO_AUTH value: "true" --- apiVersion: v1 kind: Service metadata: name: konga-svc spec: type: NodePort ports: - name: kong-proxy port: 1337 targetPort: 1337 nodePort: 30331 protocol: TCP selector: app: konga $ kubectl apply -f konga.ayml -n kong-istio
- konga-service 및 deployment 설치 확인
kubectl get svc -n kong konga-svc konga-svc NodePort 10.96.5.131 <none> 1337:30330/TCP 3m19s
접속
# konga-svc nodeport 192.168.60.240:30330
- 접속 정보
Name kong # kong-admin nodeport Kong Admin URL http://192.168.60.240:32080
- monitoring tool - kiali, prometheus, grafana 등 시각화 툴 설치 방법은 아래 공식 문서에 나와 있습니다.
주의 - 학습 목적으로 정리하여 개인적인 견해와 내용이 포함되어 있어 틀린 부분이 많을 수 있습니다.
이런 유용한 정보를 나눠주셔서 감사합니다.