Krakend Flexible Configuration

Serdarcan Büyükdereli
Arabam Labs
5 min readOct 6, 2023

--

Makalemizde, Krakend Flexible’ı nasıl yapılandıracağımızı keşfetmeye başlayacağız.

Öncelikle, neden Krakend Flexible yapılandırmasına ihtiyaç duyduğumuza bir göz atalım. Herhangi bir yapılandırmayı tek bir dosya üzerinden yönetmek, büyük projeler için tam bir karmaşa yaratabilir. Bu karmaşadan kaçınmak için yapılandırmayı parçalara ayırmak daha düzenli ve yönetilebilir bir yaklaşım sunar. İşte bu nedenle, bu makalede Helm ve Krakend üzerinde yapılandırma yöntemlerini inceleyeceğiz.

KrakenD de esnek bir konfigürasyon yapmak istersek environment ek olarak ;

  • FC_ENABLE=1 tanımı yapmamız gerekiyor. Bu tanım esnek konfigürasyonu açıyor.
  • FC_TEMPLATES=path/to/templates templates file environment path olarak belirtiliyor..
  • FC_SETTINGS=path/to/settings settings file environment path olarak belirtiliyor..

Bu environmentler eklenmesi gerekmektedir.

.
├── config
│ ├── sample.json
│ ├── settings
│ │ └── service.json
│ └── templates
│ ├── endpoint.tmpl
│ └── proje-1.tmpl
│ └── proje-2.tmpl
│ .
│ .
└── krakend.json

Krakend folder yapısında projeleri teker teker bu şekilde ekleyebilirsiniz.

Sample.json

{
"version": 3,
"name": "api-proxy",
"output_encoding": "json",
"cache_ttl": "0s",
"timeout": "15s",
"port": 80,
"router": {
"return_error_msg": true
},
"extra_config": {
"github_com/devopsfaith/krakend-gologging": {
"level": "DEBUG",
"prefix": "[KRAKEND]",
"syslog": false,
"stdout": true
},
"github_com/devopsfaith/krakend-metrics": {
"collection_time": "60s",
"proxy_disabled": false,
"router_disabled": false,
"backend_disabled": false,
"endpoint_disabled": false,
"listen_address": ":8090"
},
"github_com/devopsfaith/krakend-cors": {
"allow_origins": [ "*" ],
"allow_methods": [ "POST", "GET", "PUT", "DELETE" ],
"allow_headers": [
"Origin",
"Authorization",
"Content-Type",
"Accept",
"X-Auth-Token"
],
"expose_headers": [ "Content-Length" ],
"max_age": "12h"
}
},
"endpoints": [{{ template "Endpoint" .service }}]
}

service.json

{
"proje-1": "<http://proje-1.default.svc.arabam-cluster>",
"proje-2": "<http://proje-2.default.svc.arabam-cluster>"
}

Endpoint.tmpl

{{define "Endpoint"}}

{{$service := .}}

{{ template "proje-1" $service.proje-1 }},
{{ template "proje-2" $service.proje-2 }}

{{end}

project-1.tmpl

{{define "proje-1"}}

{{$host := .}}

{
"method": "GET",
"endpoint": "/project-1/v1/get",
"extra_config": {},
"output_encoding": "no-op",
"concurrent_calls": 1,
"input_query_strings":[
"cityId", "code"
],
"backend": [
{
"method": "GET",
"url_pattern": "/project-1/api/v1/get",
"encoding": "no-op",
"extra_config": {
"telemetry/logging": {
"level": "DEBUG",
"prefix": "[DUMMYTEST1]",
"stdout": true
}
},
"sd": "static",
"host": ["{{ $host }}"],
"disable_host_sanitize": false
}
]
},

{
"method": "GET",
"endpoint": "/project-1/v2/get",
"extra_config": {},
"output_encoding": "no-op",
"concurrent_calls": 1,
"input_query_strings":[
"cityId", "code"
],
"input_headers":[
"*"
],
"backend": [
{
"method": "GET",
"url_pattern": "/project-1/api/v2/get",
"encoding": "no-op",
"extra_config": {
"telemetry/logging": {
"level": "DEBUG",
"prefix": "[DUMMYTEST1]",
"stdout": true
}
},
"sd": "static",
"host": ["{{ $host }}"],
"disable_host_sanitize": false
}
]
}

{{end}}

project-2.tmpl

{{define "proje-2"}}

{{$host := .}}

{
"method": "GET",
"endpoint": "/proje-2/get",
"extra_config": {},
"output_encoding": "json",
"concurrent_calls": 1,
"input_query_strings":[
"id", "name"
],
"input_headers":[
"*"
],
"backend": [
{
"method": "GET",
"url_pattern": "/proje-2/api/v1/get",
"encoding": "json",
"extra_config": {
"telemetry/logging": {
"level": "DEBUG",
"prefix": "[DUMMYTEST1]",
"stdout": true
}
},
"sd": "static",
"host": ["{{ $host }}"],
"disable_host_sanitize": false
}
]
}

{{end}}

Bu senaryoda, tüm yapılandırmaların Sample.json dosyasında toplandığı görülüyor. Ancak projeyi daha geniş bir perspektiften ele aldığımızda, bu yapılandırmaların her birinin ayrı dosyalarda, büyük projeye uygun bir şekilde düzenlendiği gözlemlenmektedir.

service.json dosyası, Kubernetes kümesi içindeki backend hizmetlerimize yönlendirme sağlar. Bu yaklaşım, projeyi proje-1, proje-2 gibi daha fazla projeyle genişletmek veya özelleştirmek için daha uygun bir yapılandırma sağlar.

Helm Entegrasyonu

Helm Chart içerisinde, entegrasyon configmap'leri kullanılarak yapılandırıldı. Dosya yapısının daha okunaklı hale getirilmesi ve daha iyi bir şekilde yapılandırılabilmesi için 'krakend' adlı bir klasör oluşturuldu.

.
├── Chart.yaml
├── krakend
│ ├── backend-services
│ │ ├── endpoint.tmpl
│ │ ├── team-1
│ │ │ └── project-1.tmpl
│ │ └── team-2
│ │ └── project-2.tmpl
│ ├── config
│ │ └── sample.json
│ └── settings
│ └── service.json
├── templates
│ ├── NOTES.txt
│ ├── _helpers.tpl
│ ├── configmap-config.yaml
│ ├── configmap-settings.yaml
│ ├── configmap-templates.yaml
│ ├── configmap.yaml
│ ├── deployment.yaml
│ ├── hpa.yaml
│ ├── ingress.yaml
│ ├── service.yaml
│ ├── serviceaccount.yaml
│ └── tests
│ └── test-connection.yaml
└── values.yaml

backend-services

  • Burada takımları halinde projeler listelendi.
  • Endpointler burada yer almaktadır. Yeni endpoint tanımlamaları burada yapılması gerekmektedir.

config

  • Burası tüm konfigürasyonun endpoint dışındaki yapısı burası . Krakend config file olarak burayı görüyor. Command;
  • krakend run -c /etc/krakend/config/sample.json

settings

  • Service.json içerisinde yönlendirelecek hostları yazıyoruz. Bunuda backend-services içinde çağırıyoruz.

Helm Chart a yeni 3 adet configmap eklendi.

Bu configmap’ler her path için oluşturuldu. config , settings, templates olamak üzere.

Burada aşağıdaki yapı kullanıldı. Bu şekilde pathlerin aşağısındaki fileları kullanabiliyoruz.

configmap-settings.yaml

apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "basic-app.fullname" . }}-settings
data:
{{ (.Files.Glob "krakend/settings/*").AsConfig | indent 2 }}

krakend/settings folder altındaki bütün fileları adı ile ekliyor.

configmap-templates.yaml

apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "basic-app.fullname" . }}-templates-krakend
data:
{{ (.Files.Glob "krakend/backend-services/*").AsConfig | indent 2 }}
{{ (.Files.Glob "krakend/backend-services/project-1/*").AsConfig | indent 2 }}
{{ (.Files.Glob "krakend/backend-services/project-2/*").AsConfig | indent 2 }}

backend-service folder altındaki tüm file ları configmap e ekleniyor.

configmap-config.yaml

apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "basic-app.fullname" . }}-config
data:
{{ (.Files.Glob "krakend/config/*").AsConfig | indent 2 }}

config folderı altındaki tüm filelar configmap’e ekleniyor .

values.yaml

env:
KRAKEND_PORT: "8080"
FC_ENABLE: "1"
FC_TEMPLATES: /etc/krakend/config/templates
FC_SETTINGS: /etc/krakend/config/settings

values.yaml a ek olarak makalemizin en başında dediğimiz environmentlar ekleniyor.

deployment.yaml

volumes:
- name: volume-templates-krakend
configMap:
name: {{ include "basic-app.fullname" . }}-templates-krakend
- name: volume-settings
configMap:
name: {{ include "basic-app.fullname" . }}-settings
- name: volume-sample
configMap:
name: {{ include "basic-app.fullname" . }}-config
volumeMounts:
- name: volume-templates-krakend
mountPath: /etc/krakend/config/templates/
- name: volume-settings
mountPath: /etc/krakend/config/settings/
- name: volume-sample
mountPath: /etc/krakend/config/sample.json
subPath: sample.json
command: ["sh","-c","krakend run -c /etc/krakend/config/sample.json"]

deployment.yaml içerisinde configmap’ler environment belirttiğimiz folderlara eklendi. Başlangıç komutu olarak sample.json seçildi.

References

https://medium.com/@isikakin95/simpleapp-krakend-api-gateway-templates-part-ii-187685599079

https://www.krakend.io/docs/configuration/flexible-config/#flexible-configuration-variables

https://github.com/krakend/krakend-ce

--

--

Serdarcan Büyükdereli
Arabam Labs

Linux ,Bulut sistemleri hayranı paylaşımcı bir Jedi . Docker, Kubernetes , Linux …