环境
AlmaLinux 9.0 Podman
注意事项:
1. podman通过https_proxy 环境变量来设置代理配置
export https_proxy=http://ip:port
2. podman创建容器后会将代理配置带入容器中并将导致应用网络异常,
请先pull镜像后,务必删除代理配置
unset https_proxy
准备工作:
## 代理配置, 如已连通外网,则忽略 export https_proxy=http://ip:port ## 下载镜像 docker pull postgres:9.6 docker pull pantsel/konga docker pull kong ## 解除代理 unset https_proxy ## 建立专用网络, 用于内部的管理 podman network create kong-net ##创建名称为kong-net的内部网络
数据库:PostgreSQL
##数据库存储专用目录,以便于持久化数据,提高性能 podman volume create postgres-vol ##创建postgreSQL数据库,请使用9.6版本, ## network: 内部网络名称(选配),用于docker应用内部互联 ## POSTGRES_DB: 初始化建立的数据库名称 ## POSTGRES_USER: 数据库初始化用户 ## POSTGRES_PASSWORD: 数据库初始密码 podman run -d --name=postgres \ --network=kong-net -p 5432:5432 \ -v postgres-volume:/var/lib/postgresql/data \ -e POSTGRES_PASSWORD=mypwd \ -e POSTGRES_DB=kong \ -e POSTGRES_USER=postgres \ postgres:9.6
Konga
Kong服务的前端管理界面,管理微服务
##运行konga ##DB_HOST: postgres数据库地址,IP或者主机名,postgres 为上一步中kong-net网络的主机名 ##DB_User: postgres数据库用户 ##DB_PASSWORD: postgres数据库密码 podman run -d --name konga \ --network=kong-net -p 1337:1337 \ -e "TOKEN_SECRET=mypwd" \ -e "DB_ADAPTER=postgres" \ -e "DB_HOST=postgres" \ -e "DB_USER=postgres" \ -e "DB_PASSWORD=mypwd" \ pantsel/konga
Kong
Kong 的核心是nginx,通过lua脚本语言来支持其微服务的管理能力和扩展能力,支持了流量管理,身份校验,日志管理等微服务等公共管理特性。
## 初始化kong 数据库结构 ## 环境准备: PostgreSQL数据库已建立kong的数据库对象,不然初始化阶段将报错 ## KONG_DATABASE: 数据库类型 ## KONG_PG_HOST: 数据库地址: IP或者Host ## KONG_PG_USER: 数据库用户 ## KONG_PG_PASSWORD: 数据库密码 docker run --rm \ --network=kong-net \ -e "KONG_DATABASE=postgres" \ -e "KONG_PG_HOST=postgres" \ -e "KONG_PG_USER=postgres" \ -e "KONG_PG_PASSWORD=mypwd" \ kong kong migrations bootstrap ##创建kong实例 ## 服务端口8000 映射到主机80端口 ## kong管理端口8001 不开放至主机网络,仅在kong-net内部网络开放流通, 防止外部非法链接进入 ## 注意:如将8001端口映射至主机端口,firewalld防火墙策略将不能阻止外部非法访问 ## konga 通过内部网络kong-net 连接kong服务,konga则配置了用户名和密码,从而建立基础的安全能力 ## 修改了http-log插件,日志增加了http请求内容和响应内容,详见后文描述 docker run -d --privileged --name kong \ --network=kong-net -p 80:8000 \ -v /home/docker/kong/handler.lua:/usr/local/share/lua/5.1/kong/plugins/http-log/handler.lua \ -e "KONG_DATABASE=postgres" \ -e "KONG_PG_HOST=postgres" \ -e "KONG_PG_USER=postgres" \ -e "KONG_PG_PASSWORD=mypwd" \ -e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \ -e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \ -e "KONG_PROXY_ERROR_LOG=/dev/stderr" \ -e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \ -e "KONG_ADMIN_LISTEN=0.0.0.0:8001, 0.0.0.0:8444 ssl" \ kong:latest
防火墙配置
firewall-cmd --permanent --add-port=5432/tcp firewall-cmd --permanent --add-port=80/tcp firewall-cmd --permanent --add-port=1337/tcp firewall-cmd --reload
Konga使用
创建kong的连接,注意:请使用其kong-net的host名称
具体如何配置相关的service,route等详细参考其他博客
Http-log日志
目前该插件官方不提供http请求和响应报文,导入ELK日志服务缺乏关键信息。在参考http-log-with-body插件(目前最新版本已失效),改造http-log官方插件,在access阶段记录request的请求内容,并开启response的缓存,用于log阶段获取响应报文,同时对gzip压缩过的响应报文进行解压缩。
修改 /usr/local/share/lua/5.1/kong/plugins/http-log/handler.lua
-- gzip local utils = require "kong.tools.utils" local inflate_gzip = utils.inflate_gzip -- 实现access接口,报文请求报文,并开启响应缓存 function HttpLogHandler:access(conf) --缓存响应数据,便于响应内容保存至日志 kong.service.request.enable_buffering() --获取请求内容至当前环境 local ctx = kong.ctx.plugin; ctx.requestBody = kong.request.get_raw_body(); end function HttpLogHandler:log(conf) if conf.custom_fields_by_lua then local set_serialize_value = kong.log.set_serialize_value for key, expression in pairs(conf.custom_fields_by_lua) do set_serialize_value(key, sandbox(expression, sandbox_opts)()) end end -- begin add 增加请求和响应的报文 local responseBody=kong.service.response.get_raw_body() local encoding = kong.response.get_header("Content-Encoding") if encoding == "gzip" then responseBody = inflate_gzip(responseBody) end local ctx = kong.ctx.plugin; local jsonObj=kong.log.serialize() jsonObj.request.body= ctx.requestBody jsonObj.response.body=responseBody local entry = cjson.encode(jsonObj) --end addd local queue_id = get_queue_id(conf) local q = queues[queue_id] if not q then -- batch_max_size <==> conf.queue_size local batch_max_size = conf.queue_size or 1 local process = function(entries) local payload = batch_max_size == 1 and entries[1] or json_array_concat(entries) return send_payload(self, conf, payload) end local opts = { retry_count = conf.retry_count, flush_timeout = conf.flush_timeout, batch_max_size = batch_max_size, process_delay = 0, } local err q, err = BatchQueue.new(process, opts) if not q then kong.log.err("could not create queue: ", err) return end queues[queue_id] = q end q:add(entry) end
ELK日志服务
ElasticSearch: 日志存储和搜索
Kibana: 可视化
Filebeat: http日志收集并上传至ElasticSearch