이어서 Kong API Gateway에 대해 더 알아보자!
여기 를 참고하면 Kong + Konga + Postgresql DB 를 docker 로 설치할 수 있다. 하지만 매번 이렇게 run 명령어를 일일이 칠 수도 없을 뿐더러 잘못해 docker container를 delete 시키게 되면 모든 데이터들이 날아갈 우려가 있다. 따라서 아래와 같이 docker-compose.yml 파일에 한꺼번에 정리하고 docker volume을 마운트해놓으면 좋다.
도커에 대한 설명과 아래에 쓰인 여러 지식들은 여기 에 정리해 두었으니 참고하면 좋다!
docker-compose.yml 을 이용해 여러 컨테이너 run 시키기
기본적으로 kong에 관련된 config 데이터들은 postgresql 서버에 들어가므로 konga(kong을 위한 UI)와 postgre image에만 볼륨 설정을 해두었다.
이미 host 8000 포트를 쓰고 있는 다른 컨테이너가 있어 kong container의 8000 포트는 host의 5005 포트에 연결해주었다. (8000 포트는 upstream을 받아오는 kong 기본 프록시 포트이다.)
또한 container 간 통신을 위해 kong-net으로 docker network를 설정해 Kong + Konga + Postgresql DB를 연결해주었다.
version: '3'
services:
kong-database:
image: postgres:9.6
container_name: kong-database
networks:
- kong-net
environment:
POSTGRES_USER: kong
POSTGRES_DB: kong
POSTGRES_PASSWORD: kong123!!
volumes:
- /data/docker_con_repo/kong_postgredb:/var/lib/postgresql/data
kong:
image: kong:latest
container_name: kong
networks:
- kong-net
environment:
KONG_DATABASE: postgres
KONG_PG_HOST: kong-database
KONG_PG_USER: kong
KONG_PG_PASSWORD: kong123!!
KONG_CASSANDRA_CONTACT_POINTS: kong-database
KONG_PROXY_ACCESS_LOG: /dev/stdout
KONG_ADMIN_ACCESS_LOG: /dev/stdout
KONG_PROXY_ERROR_LOG: /dev/stderr
KONG_ADMIN_ERROR_LOG: /dev/stderr
KONG_ADMIN_LISTEN: "0.0.0.0:8001, 0.0.0.0:8444 ssl"
TZ: Asia/Seoul
ports:
- "5005:8000"
- "8443:8443"
- "127.0.0.1:8001:8001"
- "127.0.0.1:8444:8444"
depends_on:
- kong-database
konga:
image: pantsel/konga:latest
container_name: konga
networks:
- kong-net
environment:
TOKEN_SECRET: test
DB_ADAPTER: postgres
DB_URI: postgresql://kong:kong123!!@kong-database:5432/postgres
NODE_ENV: development
ports:
- "5004:1337"
volumes:
- /data/docker_con_repo/konga:/app/kongadata
depends_on:
- kong-database
- kong
kong-migrations:
image: kong:latest
container_name: kong-migrations
networks:
- kong-net
environment:
KONG_DATABASE: postgres
KONG_PG_HOST: kong-database
KONG_PG_USER: kong
KONG_PG_PASSWORD: kong123!!
KONG_CASSANDRA_CONTACT_POINTS: kong-database
command: kong migrations bootstrap #데이터베이스 스키마를 생성하고 초기화할 때 사용
networks:
kong-net:
위의 yml 파일명은 kong.yml 로 정해두고 경로는 ~/compose/kong 로 하였다.
아래 명령어를 실행해주면 root 경로가 아니더라도, 내가 원하는 곳에 yml 파일을 만들어 손쉽게 docker-compose up 명령어와 동일하게 사용할 수 있다.
docker-compose -f /app/docker/compose/kong/kong.yml up -d
명령어를 실행하면 아래와 같이 이미지들이 모두 run 되는 것을 볼 수 있다 !
Kong Plugins
다음으로는 여러 Kong Plugin 기능들을 추가한 내용들을 정리해 보았다. KONG PLUGIN 기능들은 여기에서 확인해볼 수 있다.
아래와 같이 라우팅 단계에서 여러 Plugin들을 추가할 수 있다.
Kong Authentication
api 엔드포인트에서 여러 형태 중 하나를 취할 수 있다.
- 기본인증 - Proxy-Authorization이나 Authorization 헤더에서 유효한 자격 증명을 확인하고 액세스 요청 승인/거부. http/https 모두 가능
- 키 인증 - API 키를 확인한다. http/https 모두 가능
- OAuth 2.0 인증 - https만 허용된다.
우선 다음과 같이 Consumer를 설정한다. visitor1이라는 이름을 가지는 user를 하나 만들었다.
해당 visitor에 대한 Detail 값이다.
Api Keys를 이용해야만 routing 된 url에 접근할 수 있다.
예를 들어 172.xx.xx.xx:5005/json-server에 접근하고 싶다면 172.xx.xx.xx:5005/json-server?apikey={apikey}로 접근해야 한다.
key 없이 접근하면 아래와 같이 Unauthorized 에러를 뱉는다.
이 외에도 Cors나 Ip Restriction 등 보안 관련 여러 플러그인을 제공하고 있다.
Kong 로드밸런싱
먼저 로드밸런싱에 대해 가볍게 알아보자!
- 로드밸런싱?
로드밸런싱이란 서버에 가해지는 부하(=로드)를 분산(=밸런싱)해주는 장치 또는 기술을 의미한다. 클라이언트와 서버 사이에 위치하며, 여러 개의 서버를 사용할 때 부하가 집중되지 않도록 트래픽을 관리해 각각의 서버가 최적의 퍼포먼스를 보일 수 있도록 한다. 서버 자체의 성능을 확장하는 Scale-up과 달리 Scale-out 방식으로, 여러 대의 서버로 트래픽을 분산해줄 수 있다. - 로드밸런싱 부하 분산 방식에는 여러 알고리즘이 존재한다.
- 라운드로빈 : 서버에 들어온 요청들을 순서대로 돌아가며 배정. 클라이언트의 요청을 순서대로 분배하기 때문에 여러 대의 서버가 동일한 스펙을 갖고 있을 때 유리하다.
- 가중 라운드로빈 방식(Weighted Round Robin Method) 각각의 서버마다 가중치를 매기고 가중치가 높은 서버에 클라이언트 요청을 우선 분배한다. 주로 서버의 트래픽 처리 능력이 상이한 경우 사용되는 분산 방식이다. A에 가중치 5를 부여하고 B에 가중치 2를 부여한다면 A에 5개의 요청, B에 2개의 요청이 전달된다.
Kong에서도 API 요청 트래픽을 여러 업스트림 서비스에 분산시킬 수 있다. 위의 가중 라운드로빈 방식을 사용할 수 있다.
Upstream 속 Target들을 여러 개 지정하고 Weight을 조정하여 서버마다의 가중치를 달리 줄 수 있다.
Rate Limiting
incoming connection에 대한 rate를 제한하는 기능이다.
- Traffic Contol - Rate Limiting
속도 제한 플러그인은 요청이 시간당(초당, 분당, 시간당) 몇 회의 요청을 허용할지 설정할 수있다. 만약 분당 5회 규칙으로 설정했다면 이를 초과할 시 해당 API 서버에 대한 후속 요청을 허용하지 않는다. 대신 429 Too Many Requests 응답을 줄 수 있다. - Traffic Control - Response Rate Limiting
custom하게 속도 제한 사항을 만들 수 있는 플러그인이다. 예를 들어 분당 한도가 있는 '동영상'을 응답으로 받는 경우, 내가 준 limit, 그리고 남아있는 동영상 시간 등을 header에 넣어 전달할 수 있다.
X-RateLimit-Limit-Videos-Second: 5
X-RateLimit-Remaining-Videos-Second: 5
X-RateLimit-Limit-Videos-Minute: 10
X-RateLimit-Remaining-Videos-Minute: 10
만약 요청을 아래와 같이 1분에 3개만 주도록 설정한다면,
아래와 같이 POSTMAN에서 Send 요청을 와다다 눌렀을 때 4번째부터 아래와 같이 API rate limit exceeded로 터지게 된다.
Kong CORS
KONG DOCS를 이용하여 기본적인 Cors 설정을 해줄 필요가 있다.
아무리 DB에서 CORS를 활짝🌞 열어줬어도..
아래와 같이 Global Plugins를 통해 API Gateway에서도 cors를 열어주어야 한다.
origins 는 간단히 말해, "이 리소스를 접근하는 것이 허용된 출처" 이다.
만약 전부 허용하고 싶다면 아래와 같이 "*" 로 표기해주면 된다.
트러블슈팅
- Permission denied
Error: mkdir failed for '/usr/local/kong/logs': Permission denied (code 13)
chmod 777은 파일 또는 디렉토리에 대해 소유자, 그룹 및 다른 모든 사용자에게 읽기, 쓰기 및 실행 권한을 부여하는 것을 의미한다 ! 특정 directory가 Permission denied 되었다면 권한을 부여하자.
- migration 대상 파일 경로 확인
Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "/app/start.sh": stat /app/start.sh: no such file or directory: unknown
마이그레이션 대상 파일이 현 docker container 안에 있는지, 디렉토리/파일 여부를 다시 한 번 파악하자.
- 특정 포트가 listen 가능한지 알고 싶을 때
- in Linux
netstat -an | grep 8000
curl -f http://localhost:8000/json-server
현재 host 서버에서 특정 포트를 사용할 수 있을지(열려 있니? Listen 중?) 알고 싶다면, 또는 이미 사용하고 있는지 유무를 알고 싶다면 위의 명령어를 사용할 수 있다.
- in Windows
로컬 cmd 창에서는 telnet을 이용하면 host 의 특정 포트가 열려 있는지 볼 수 있다. 위의 사진처럼 우선 제어판에서 텔넷 클라이언트를 열어주는 과정이 필요하다. 이후 아래의 명령어를 통해 포트가 열려 있는지 확인할 수 있다.
telnet 172.***.***.***(host 서버 주소) 5005
- 리눅스에서 숨김 처리된 디렉토리까지 전부 보고 싶을 때
ls- ralt
- 특정 프로세스가 돌고 있는지 확인하기
ps aux | grep [프로세스명]
'INFRA' 카테고리의 다른 글
[Docker] Docker image에 https 인증서 적용하기 (2) | 2023.11.09 |
---|---|
[kubernetes] 쿠버네티스 기초 이론 (7) | 2023.11.01 |
[API GATEWAY] KONG API Gateway -1 (0) | 2023.10.23 |
[Docker] 도커를 공부하며.. 🐳 (2) | 2023.10.23 |
[ELK] Elastic Search ILM 정책 (+추가 에러 핸들링) (2) | 2023.09.25 |