记录docker使用kong consul postgresql配置dns异常解决
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 mainimport ("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 stringfor _, addr := range ips {if addr.To4() != nil {ip = addr.String()break}}// 检查是否找到有效IPif 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: truedriver: overlayservices:consul:image: consul:1.15.4restart: alwayscontainer_name: consulnetworks:- base_service_database-netports:- "8500:8500"- "8600:8600/udp"volumes:- /etc/localtime:/etc/localtime- /data/docker/consul/data:/consul/dataenvironment:- TZ=Asia/Shanghaideploy:placement:constraints:- node.hostname == managerkong-database:image: postgres:16container_name: kong-databaserestart: alwaysnetworks:- base_service_database-netenvironment:- POSTGRES_USER=kong- POSTGRES_DB=kong- POSTGRES_PASSWORD=kong- TZ=Asia/Shanghaivolumes:- /data/docker/postgresql/data:/var/lib/postgis/data- /data/docker/postgresql/data:/var/lib/postgresql/dataports:- "5348:5432"deploy:placement:constraints:- node.hostname == manager ##kong数据库的初始化kong-migration:container_name: kong-migrationimage: kong:3.9.1-ubuntunetworks:- base_service_database-netdepends_on:- kong-databaserestart: on-failureenvironment:- KONG_PG_HOST=kong-database- KONG_DATABASE=postgres- KONG_PG_USER=kong- KONG_PG_PASSWORD=kong- KONG_CASSANDRA_CONTACT_POINTS=kong-databasedeploy:placement:constraints:- node.hostname == manager #command: sh -c "kong migrations bootstrap && kong migrations up"kong:container_name: kongimage: kong:3.9.1-ubunturestart: alwaysnetworks:- base_service_database-netvolumes:- /data/docker/kong/get_consul_ip:/get_consul_ip- /data/docker/kong/get_kongdatabase_ip:/get_kongdatabase_ipcommand: 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- consulenvironment:- 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 sslports:- "8000:8000" # Proxy- "8443:8443" # Proxy SSL- "8001:8001" # Admin API- "8444:8444" # Admin API SSL- "8002:8002" # Kong Manager- "8445:8445" # Kong Manager SSLdeploy:placement:constraints:- node.hostname == manager