docker 部署 postgresql、kong、consul,kong 使用postgresql数据库作为数据存储,使用consul 作为服务发现
1 KONG_DNS_RESOLVER 配置问题
想要通过docker 内置的dns可以不需要配置pgsql的ip 和 consul的ip,通过dns服务发现容器名动态获取这两个容器的ip进行连接,需要解决以下两个问题:
1 KONG_DNS_RESOLVER 只能接收ipv4的地址,无法配置dns域名进行服务发现
2 如果KONG_DNS_RESOLVER 配置了consul的dns ip,那么就无法通过dns发现pgsql的地址,出现以下问题:
[lua] balancer.lua:540: could not obtain list of upstreams: [postgres] [cosocket] DNS resolution failed: dns server error: 2 server failure. Tried: ["(short)kong-database:(na) - cache-miss","kong-database:33 - cache-miss/scheduled/querying/dns server error: 2 server failure","kong-database:1 - cache-miss/scheduled/querying/dns server error: 2 server failure","kong-database:5 - cache-miss/scheduled/querying/dns server error: 2 server failure"], context: ngx.timer
并且我们的需要是只配置域名,通过dns进行动态解析ip
2 处理KONG_DNS_RESOLVER 配置
我们可以通过go编写一个可执行程序用来dns获取pgsql的ip和consul的ip配置到环境变量中,然后再进行启动,也可以使用其他方法,只要是在kong启动前将pgsql 和consul的ip配置到环境变量中即可,由于kong容器中缺少一些软件,如dig、ping等,无法直接通过命令行去获取到pgsql 、consul的ip,这里就使用go编译成可执行文件去获取
package main
import (
"fmt"
"net"
"os"
)
func main() {
args := os.Args[1:]
domain := "kong-database"
if len(args) > 0 {
domain = args[0]
}
// 解析域名获取IP地址
ips, err := net.LookupIP(domain)
if err != nil {
fmt.Fprintf(os.Stderr, "解析域名失败: %v\n", err)
os.Exit(1)
}
// 提取第一个IPv4地址(跳过IPv6)
var ip string
for _, addr := range ips {
if addr.To4() != nil {
ip = addr.String()
break
}
}
// 检查是否找到有效IP
if ip == "" {
fmt.Fprintf(os.Stderr, "未找到 %s 的IPv4地址\n", domain)
os.Exit(1)
}
fmt.Printf(ip)
}
docker kong容器yml配置
version: '3.8'
networks:
base_service_database-net:
external: true
driver: overlay
services:
consul:
image: consul:1.15.4
restart: always
container_name: consul
networks:
- base_service_database-net
ports:
- "8500:8500"
- "8600:8600/udp"
volumes:
- /etc/localtime:/etc/localtime
- /data/docker/consul/data:/consul/data
environment:
- TZ=Asia/Shanghai
deploy:
placement:
constraints:
- node.hostname == manager
kong-database:
image: postgres:16
container_name: kong-database
restart: always
networks:
- base_service_database-net
environment:
- POSTGRES_USER=kong
- POSTGRES_DB=kong
- POSTGRES_PASSWORD=kong
- TZ=Asia/Shanghai
volumes:
- /data/docker/postgresql/data:/var/lib/postgis/data
- /data/docker/postgresql/data:/var/lib/postgresql/data
ports:
- "5348:5432"
deploy:
placement:
constraints:
- node.hostname == manager #
#kong数据库的初始化
kong-migration:
container_name: kong-migration
image: kong:3.9.1-ubuntu
networks:
- base_service_database-net
depends_on:
- kong-database
restart: on-failure
environment:
- KONG_PG_HOST=kong-database
- KONG_DATABASE=postgres
- KONG_PG_USER=kong
- KONG_PG_PASSWORD=kong
- KONG_CASSANDRA_CONTACT_POINTS=kong-database
deploy:
placement:
constraints:
- node.hostname == manager #
command: sh -c "kong migrations bootstrap && kong migrations up"
kong:
container_name: kong
image: kong:3.9.1-ubuntu
restart: always
networks:
- base_service_database-net
volumes:
- /data/docker/kong/get_consul_ip:/get_consul_ip
- /data/docker/kong/get_kongdatabase_ip:/get_kongdatabase_ip
command: sh -c "export KONG_DNS_RESOLVER="$$(./get_consul_ip):8600,127.0.0.11:53" && export KONG_PG_HOST="$$(./get_kongdatabase_ip)" && /docker-entrypoint.sh kong docker-start"
depends_on:
- kong-migration
- consul
environment:
- TZ=Asia/Shanghai
- KONG_DATABASE=postgres
# - KONG_PG_HOST=kong-database
- KONG_PG_USER=kong
- KONG_PG_PASSWORD=kong
- 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
- KONG_PROXY_LISTEN=0.0.0.0:8000, 0.0.0.0:8443 ssl
- KONG_ADMIN_GUI_LISTEN=0.0.0.0:8002, 0.0.0.0:8445 ssl
ports:
- "8000:8000" # Proxy
- "8443:8443" # Proxy SSL
- "8001:8001" # Admin API
- "8444:8444" # Admin API SSL
- "8002:8002" # Kong Manager
- "8445:8445" # Kong Manager SSL
deploy:
placement:
constraints:
- node.hostname == manager