Run Kong as Kubernetes Service with IPv6 Support

Hi,
I am trying to run Kong 0.14.1 as a Kubernetes Deployment and access it through the Kubernetes Service using DNS. My cluster uses IPv6 addresses. However, I am having difficulty in running commands like “Kong migrations list”. I am using Cassandra DB and is running as a K8 Service as well and resolves through DNS name.

I see the following error:(when I use IPv6 address instead of DNS name as cassandra_contact_points)

Error:
/usr/local/share/lua/5.1/kong/cmd/migrations.lua:37: [cassandra error] all hosts tried for query failed. 3ffd::9755: host seems unhealthy, considering it down (Address family for hostname not supported)
stack traceback:
[C]: in function ‘assert’
/usr/local/share/lua/5.1/kong/cmd/migrations.lua:37: in function ‘cmd_exec’
/usr/local/share/lua/5.1/kong/cmd/init.lua:87: in function </usr/local/share/lua/5.1/kong/cmd/init.lua:87>
[C]: in function ‘xpcall’
/usr/local/share/lua/5.1/kong/cmd/init.lua:87: in function </usr/local/share/lua/5.1/kong/cmd/init.lua:44>
/usr/local/bin/kong:7: in function ‘file_gen’
init_worker_by_lua:48: in function <init_worker_by_lua:46>
[C]: in function ‘xpcall’
init_worker_by_lua:55: in function <init_worker_by_lua:53>

I see the following error: (when I use DNS name as cassandra_contact_points)

Error:
/usr/local/share/lua/5.1/kong/cmd/migrations.lua:37: [cassandra error] all hosts tried for query failed. cassandra.maglev-system.svc.cluster.local: host seems unhealthy, considering it down (host or service not provided, or not known)
stack traceback:
[C]: in function ‘assert’
/usr/local/share/lua/5.1/kong/cmd/migrations.lua:37: in function ‘cmd_exec’
/usr/local/share/lua/5.1/kong/cmd/init.lua:87: in function </usr/local/share/lua/5.1/kong/cmd/init.lua:87>
[C]: in function ‘xpcall’
/usr/local/share/lua/5.1/kong/cmd/init.lua:87: in function </usr/local/share/lua/5.1/kong/cmd/init.lua:44>
/usr/local/bin/kong:7: in function ‘file_gen’
init_worker_by_lua:48: in function <init_worker_by_lua:46>
[C]: in function ‘xpcall’
init_worker_by_lua:55: in function <init_worker_by_lua:53>

Here is the output from my “netcat” command which resolves the DNS name to the right IPv6 address:

root@maglev-master-20010420:/# nslookup -query=AAAA cassandra.maglev-system.svc.cluster.local
Server: 2001:10::1
Address: 2001:10::1#53

cassandra.maglev-system.svc.cluster.local has AAAA address 3ffd::9755

Am I missing something? Please help!

1 Like

For benefit of others who might be running into similar problem, this is how I was able to resolve:

Modify the cassandra/socket.lua to use tcp6() socket. In my environment, I have an env variable that would help me to identify if the addressing is IPv6 or IPv4 enabled. Hence used the same as shown below (marked with ** below):

do
  local setmetatable = setmetatable

  if ngx then
    local log, WARN, INFO = ngx.log, ngx.WARN, ngx.INFO
    local get_phase = ngx.get_phase

    function _M.tcp(...)
      local phase = get_phase()
      if not forced_luasocket_phases[phase]
         and COSOCKET_PHASES[phase]
         or forbidden_luasocket_phases[phase] then
        return ngx.socket.tcp(...)
      end

      -- LuaSocket
      if phase ~= 'init' then
        if forced_luasocket_phases[phase] then
          log(INFO, 'support for cosocket in this context, but LuaSocket forced')
        else
          log(WARN, 'no support for cosockets in this context, falling back to LuaSocket')
        end
      end

      local socket = require 'socket'
      **if os.getenv("ADDRESS_FAMILY") == "ipv6" then**
**        local sock = socket.tcp6(...)**
        return setmetatable({
          sock = sock
        }, proxy_mt)
      else
        local sock = socket.tcp(...)
        return setmetatable({
          sock = sock
        }, proxy_mt)
      end
    end
  else
    function _M.tcp(...)
      local socket = require 'socket'
      **if os.getenv("ADDRESS_FAMILY") == "ipv6" then**
**        local sock = socket.tcp6(...)**
        return setmetatable({
          sock = sock
        }, proxy_mt)
      else
        local sock = socket.tcp(...)
        return setmetatable({
          sock = sock
        }, proxy_mt)
      end
    end
  end
end

© 2019 Kong Inc.    Terms  •  Privacy  •  FAQ