From b06c4cc231fd6c597c4f1f0dd73cabf1c41c1c06 Mon Sep 17 00:00:00 2001 From: Jinesh Nagori Date: Sun, 18 May 2025 18:48:35 +0530 Subject: [PATCH] feat: add apisix-complete-stack with observability, reverse proxy and ssl - Integrated Apache APISIX with etcd and APISIX Dashboard. - Configured Prometheus for metric scraping. - Integrated Loki and Promtail for log aggregation from NGINX. - Added Grafana with pre-provisioned dashboards for metrics and logs. - Set up NGINX as a reverse proxy with SSL. - Organized configuration files into modular directories for maintainability. --- .../apisix_conf/config.yaml | 52 + .../apisix_dashboard_conf/conf.yaml | 56 + .../apisix-complete-stack/docker-compose.yml | 104 + .../grafana_conf/config/grafana.ini | 756 +++++++ .../dashboards/apisix-loki-dashboard.json | 527 +++++ .../apisix-prometheus-dashboard.json | 1782 +++++++++++++++++ .../provisioning/dashboards/all.yaml | 27 + .../provisioning/datasources/all.yaml | 33 + .../loki_conf/loki-config.yaml | 45 + .../nginx_conf/nginx.conf | 105 + .../prometheus_conf/prometheus.yml | 40 + .../promtail_conf/promtail-config.yaml | 18 + example/apisix-complete-stack/ssl/cert.pem | 3 + example/apisix-complete-stack/ssl/key.pem | 3 + 14 files changed, 3551 insertions(+) create mode 100644 example/apisix-complete-stack/apisix_conf/config.yaml create mode 100644 example/apisix-complete-stack/apisix_dashboard_conf/conf.yaml create mode 100644 example/apisix-complete-stack/docker-compose.yml create mode 100644 example/apisix-complete-stack/grafana_conf/config/grafana.ini create mode 100644 example/apisix-complete-stack/grafana_conf/dashboards/apisix-loki-dashboard.json create mode 100644 example/apisix-complete-stack/grafana_conf/dashboards/apisix-prometheus-dashboard.json create mode 100644 example/apisix-complete-stack/grafana_conf/provisioning/dashboards/all.yaml create mode 100644 example/apisix-complete-stack/grafana_conf/provisioning/datasources/all.yaml create mode 100644 example/apisix-complete-stack/loki_conf/loki-config.yaml create mode 100644 example/apisix-complete-stack/nginx_conf/nginx.conf create mode 100644 example/apisix-complete-stack/prometheus_conf/prometheus.yml create mode 100644 example/apisix-complete-stack/promtail_conf/promtail-config.yaml create mode 100644 example/apisix-complete-stack/ssl/cert.pem create mode 100644 example/apisix-complete-stack/ssl/key.pem diff --git a/example/apisix-complete-stack/apisix_conf/config.yaml b/example/apisix-complete-stack/apisix_conf/config.yaml new file mode 100644 index 00000000..55fff3b1 --- /dev/null +++ b/example/apisix-complete-stack/apisix_conf/config.yaml @@ -0,0 +1,52 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +apisix: + node_listen: 9080 # APISIX listening port + enable_ipv6: false + + enable_control: true + + control: + ip: "0.0.0.0" + port: 9092 + +deployment: + admin: + allow_admin: # https://nginx.org/en/docs/http/ngx_http_access_module.html#allow + - 127.0.0.1 + - ::1 + admin_key: + - name: "admin" + key: edd1c9f034335f136f87ad84b625c8f1 + role: admin # admin: manage all configuration data + + - name: "viewer" + key: 4054f7cf07e344346cd3f287985e76a2 + role: viewer + + etcd: + host: # it's possible to define multiple etcd hosts addresses of the same etcd cluster. + - "http://etcd:2379" # multiple etcd address + prefix: "/apisix" # apisix configurations prefix + timeout: 30 # 30 seconds + +plugin_attr: + prometheus: + export_addr: + ip: "0.0.0.0" + port: 9091 diff --git a/example/apisix-complete-stack/apisix_dashboard_conf/conf.yaml b/example/apisix-complete-stack/apisix_dashboard_conf/conf.yaml new file mode 100644 index 00000000..dde79b9d --- /dev/null +++ b/example/apisix-complete-stack/apisix_dashboard_conf/conf.yaml @@ -0,0 +1,56 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one or more +# contributor license agreements. See the NOTICE file distributed with +# this work for additional information regarding copyright ownership. +# The ASF licenses this file to You under the Apache License, Version 2.0 +# (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +conf: + listen: + host: 0.0.0.0 # `manager api` listening ip or host name + port: 9000 # `manager api` listening port + etcd: + endpoints: # supports defining multiple etcd host addresses for an etcd cluster + - etcd:2379 + + allow_list: + - 127.0.0.1 + - ::1 + + # etcd basic auth info + # username: "root" # ignore etcd username if not enable etcd auth + # password: "123456" # ignore etcd password if not enable etcd auth + + log: + error_log: + level: warn # supports levels, lower to higher: debug, info, warn, error, panic, fatal + file_path: + logs/error.log # supports relative path, absolute path, standard output + # such as: logs/error.log, /tmp/logs/error.log, /dev/stdout, /dev/stderr +authentication: + secret: + secret # secret for jwt token generation. + # NOTE: Highly recommended to modify this value to protect `manager api`. + # if it's default value, when `manager api` start, it will generate a random string to replace it. + expire_time: 3600 # jwt token expire time, in second + users: + - username: admin # username and password for login `manager api` + password: '2]~8+y+T9hEAqCc,3[Ylwf/R-x_' + - username: user + password: user + +plugin_attr: + prometheus: + export_addr: + ip: "0.0.0.0" + port: 9091 diff --git a/example/apisix-complete-stack/docker-compose.yml b/example/apisix-complete-stack/docker-compose.yml new file mode 100644 index 00000000..d1f4d976 --- /dev/null +++ b/example/apisix-complete-stack/docker-compose.yml @@ -0,0 +1,104 @@ +version: "3" + +services: + apisix: + image: apache/apisix:${APISIX_IMAGE_TAG:-3.12.0-debian} + container_name: apisix + restart: always + volumes: + - ./apisix_conf/config.yaml:/usr/local/apisix/conf/config.yaml:ro + depends_on: + - etcd + networks: + apisix: + + etcd: + image: bitnami/etcd:3.5.11 + restart: always + container_name: etcd + volumes: + - etcd_data:/bitnami/etcd + - ./etcd_backup:/backup + environment: + ETCD_ENABLE_V2: "true" + ALLOW_NONE_AUTHENTICATION: "yes" + ETCD_ADVERTISE_CLIENT_URLS: "http://etcd:2379" + ETCD_LISTEN_CLIENT_URLS: "http://0.0.0.0:2379" + networks: + apisix: + + dashboard: + image: apache/apisix-dashboard:3.0.0-centos + container_name: apisix-dashboard + volumes: + - ./apisix_dashboard_conf/conf.yaml:/usr/local/apisix-dashboard/conf/conf.yaml:ro + restart: always + networks: + apisix: + + prometheus: + image: prom/prometheus:v2.25.0 + restart: always + container_name: prometheus + volumes: + - ./prometheus_conf/prometheus.yml:/etc/prometheus/prometheus.yml + networks: + apisix: + + loki: + image: grafana/loki:2.9.4 + container_name: loki + restart: always + volumes: + - ./loki_conf:/etc/loki + command: -config.file=/etc/loki/loki-config.yaml + networks: + apisix: + + promtail: + image: grafana/promtail:2.9.4 + container_name: promtail + restart: always + volumes: + - /var/log/nginx:/var/log/nginx + - ./promtail_conf:/etc/promtail + command: -config.file=/etc/promtail/promtail-config.yaml + depends_on: + - loki + networks: + apisix: + + grafana: + image: grafana/grafana:7.3.7 + restart: always + volumes: + - "./grafana_conf/provisioning:/etc/grafana/provisioning" + - "./grafana_conf/dashboards:/var/lib/grafana/dashboards" + - "./grafana_conf/config/grafana.ini:/etc/grafana/grafana.ini" + networks: + apisix: + + nginx: + image: nginx:latest + container_name: nginx-proxy + restart: always + ports: + - "80:80" + - "443:443" + volumes: + - ./nginx_conf/nginx.conf:/etc/nginx/nginx.conf:ro + - ./ssl/cert.pem:/etc/nginx/cert.pem:ro + - ./ssl/key.pem:/etc/nginx/key.pem:ro + - /var/log/nginx:/var/log/nginx + depends_on: + - apisix + networks: + apisix: + +networks: + apisix: + driver: bridge + +volumes: + etcd_data: + driver: local diff --git a/example/apisix-complete-stack/grafana_conf/config/grafana.ini b/example/apisix-complete-stack/grafana_conf/config/grafana.ini new file mode 100644 index 00000000..cb6a7376 --- /dev/null +++ b/example/apisix-complete-stack/grafana_conf/config/grafana.ini @@ -0,0 +1,756 @@ +##################### Grafana Configuration Example ##################### +# +# Everything has defaults so you only need to uncomment things you want to +# change + +# possible values : production, development +;app_mode = production + +# instance name, defaults to HOSTNAME environment variable value or hostname if HOSTNAME var is empty +;instance_name = ${HOSTNAME} + +#################################### Paths #################################### +[paths] +# Path to where grafana can store temp files, sessions, and the sqlite3 db (if that is used) +;data = /var/lib/grafana + +# Temporary files in `data` directory older than given duration will be removed +;temp_data_lifetime = 24h + +# Directory where grafana can store logs +;logs = /var/log/grafana + +# Directory where grafana will automatically scan and look for plugins +;plugins = /var/lib/grafana/plugins + +# folder that contains provisioning config files that grafana will apply on startup and while running. +;provisioning = conf/provisioning + +#################################### Server #################################### +[server] +# Protocol (http, https, h2, socket) +;protocol = http + +# The ip address to bind to, empty will bind to all interfaces +;http_addr = + +# The http port to use +;http_port = 3000 + +# The public facing domain name used to access grafana from a browser +;domain = localhost + +# Redirect to correct domain if host header does not match domain +# Prevents DNS rebinding attacks +;enforce_domain = false + +# The full public facing url you use in browser, used for redirects and emails +# If you use reverse proxy and sub path specify full url (with sub path) +;root_url = %(protocol)s://%(domain)s:%(http_port)s/ + +# Serve Grafana from subpath specified in `root_url` setting. By default it is set to `false` for compatibility reasons. +;serve_from_sub_path = false + +# Log web requests +;router_logging = false + +# the path relative working path +;static_root_path = public + +# enable gzip +;enable_gzip = false + +# https certs & key file +;cert_file = +;cert_key = + +# Unix socket path +;socket = + +#################################### Database #################################### +[database] +# You can configure the database connection by specifying type, host, name, user and password +# as separate properties or as on string using the url properties. + +# Either "mysql", "postgres" or "sqlite3", it's your choice +;type = sqlite3 +;host = 127.0.0.1:3306 +;name = grafana +;user = root +# If the password contains # or ; you have to wrap it with triple quotes. Ex """#password;""" +;password = + +# Use either URL or the previous fields to configure the database +# Example: mysql://user:secret@host:port/database +;url = + +# For "postgres" only, either "disable", "require" or "verify-full" +;ssl_mode = disable + +;ca_cert_path = +;client_key_path = +;client_cert_path = +;server_cert_name = + +# For "sqlite3" only, path relative to data_path setting +;path = grafana.db + +# Max idle conn setting default is 2 +;max_idle_conn = 2 + +# Max conn setting default is 0 (mean not set) +;max_open_conn = + +# Connection Max Lifetime default is 14400 (means 14400 seconds or 4 hours) +;conn_max_lifetime = 14400 + +# Set to true to log the sql calls and execution times. +;log_queries = + +# For "sqlite3" only. cache mode setting used for connecting to the database. (private, shared) +;cache_mode = private + +#################################### Cache server ############################# +[remote_cache] +# Either "redis", "memcached" or "database" default is "database" +;type = database + +# cache connectionstring options +# database: will use Grafana primary database. +# redis: config like redis server e.g. `addr=127.0.0.1:6379,pool_size=100,db=0,ssl=false`. Only addr is required. ssl may be 'true', 'false', or 'insecure'. +# memcache: 127.0.0.1:11211 +;connstr = + +#################################### Data proxy ########################### +[dataproxy] + +# This enables data proxy logging, default is false +;logging = false + +# How long the data proxy should wait before timing out default is 30 (seconds) +;timeout = 30 + +# If enabled and user is not anonymous, data proxy will add X-Grafana-User header with username into the request, default is false. +;send_user_header = false + +#################################### Analytics #################################### +[analytics] +# Server reporting, sends usage counters to stats.grafana.org every 24 hours. +# No ip addresses are being tracked, only simple counters to track +# running instances, dashboard and error counts. It is very helpful to us. +# Change this option to false to disable reporting. +;reporting_enabled = true + +# Set to false to disable all checks to https://grafana.net +# for new vesions (grafana itself and plugins), check is used +# in some UI views to notify that grafana or plugin update exists +# This option does not cause any auto updates, nor send any information +# only a GET request to http://grafana.com to get latest versions +;check_for_updates = true + +# Google Analytics universal tracking code, only enabled if you specify an id here +;google_analytics_ua_id = + +# Google Tag Manager ID, only enabled if you specify an id here +;google_tag_manager_id = + +#################################### Security #################################### +[security] +# disable creation of admin user on first start of grafana +;disable_initial_admin_creation = false + +# default admin user, created on startup +;admin_user = admin + +# default admin password, can be changed before first start of grafana, or in profile settings +;admin_password = admin + +# used for signing +;secret_key = SW2YcwTIb9zpOOhoPsMm + +# disable gravatar profile images +;disable_gravatar = false + +# data source proxy whitelist (ip_or_domain:port separated by spaces) +;data_source_proxy_whitelist = + +# disable protection against brute force login attempts +;disable_brute_force_login_protection = false + +# set to true if you host Grafana behind HTTPS. default is false. +;cookie_secure = false + +# set cookie SameSite attribute. defaults to `lax`. can be set to "lax", "strict", "none" and "disabled" +;cookie_samesite = none + +# set to true if you want to allow browsers to render Grafana in a ,