Closed tsujp closed 2 weeks ago
Thanks for the details!
If you have jq
installed can you paste the output of:
nomad node status -self -json | jq .Resources.Networks
I'm afraid Nomad is scheduling onto the IPv4 address first, although I'm unsure why that address isn't being displayed in the CLI output. Unfortunately you can only specify which network_interface Nomad should schedule on, but not choose which IP address on that interface is preferred.
Luckily Docker is doing the right thing and your service is available on the intended IPv6 address.
The IPv6 address should be advertised in Consul as well. Could you paste the output of:
curl -s localhost:8500/v1/catalog/service/redis-cache | jq -r .[].ServiceAddress
I believe there are 2 things we need to do:
This is related to #5862 and #3285
Sorry I haven't had time to test this yet, so I've held off on replying but I felt I should let you know I still plan to give your steps a run @schmichael I just have another backlog of work to get through – I've had to apply some workarounds as I cannot use Nomad until this works. An alternative might be Podman (with IPv6 of course) but I am unfamiliar with Drivers for Nomad and how to extend them.
@tsujp I'm using the same setup for a while now. The address should be published in consul. It's only a nomad UI issue not showing the IPv6 address, but besides that everything should work.
Thanks for the details!
If you have
jq
installed can you paste the output of:nomad node status -self -json | jq .Resources.Networks
I'm afraid Nomad is scheduling onto the IPv4 address first, although I'm unsure why that address isn't being displayed in the CLI output. Unfortunately you can only specify which network_interface Nomad should schedule on, but not choose which IP address on that interface is preferred.
Luckily Docker is doing the right thing and your service is available on the intended IPv6 address.
The IPv6 address should be advertised in Consul as well. Could you paste the output of:
curl -s localhost:8500/v1/catalog/service/redis-cache | jq -r .[].ServiceAddress
Fixes
I believe there are 2 things we need to do:
1. Fix the address display issue. Not sure what's happening there! 2. Allow selecting specific addresses or address classes for scheduling.
(1)
nomad node status -self -json | jq .Resources.Networks
[
{
"CIDR": "127.0.0.1/32",
"Device": "lo",
"DynamicPorts": null,
"IP": "127.0.0.1",
"MBits": 1000,
"Mode": "",
"ReservedPorts": null
},
{
"CIDR": "::1/128",
"Device": "lo",
"DynamicPorts": null,
"IP": "::1",
"MBits": 1000,
"Mode": "",
"ReservedPorts": null
}
]
(2)
No output.
EDIT: for (2) I didn't have Consul running at all, I quickly skimmed the docs to get something up (for a ninja edit) and the curl command still returns nothing, at it's base it's
$ curl -s localhost:8500
<a href="/ui/">Moved Permanently</a>.
When I view the Consul UI and go to http://localhost:8500/ui/dc1/services/ip6-echo-service
I can see the IPv6 address of the service, yay!
I assume as @42wim states this means everything is working under the hood (as how else is it going to determine the correct address) but that it's just a Nomad UI error in both the Web UI and CLI @schmichael
I have this same issue. Setup: running the dev version of nomad on my local mac laptop.
On some wifi networks, the unique IP address is IPv6
:
When that happens, my tasks fail:
nomad node status -self -json | jq .Resources.Networks
gives:
[
{
"CIDR": "fd67:2a00:1152:1:6a:8c9e:b809:7d5f/128",
"DNS": null,
"Device": "en0",
"DynamicPorts": null,
"Hostname": "",
"IP": "fd67:2a00:1152:1:6a:8c9e:b809:7d5f",
"MBits": 1000,
"Mode": "host",
"ReservedPorts": null
},
{
"CIDR": "2406:5a00:1011:7b00:186b:fea3:d955:36b8/128",
"DNS": null,
"Device": "en0",
"DynamicPorts": null,
"Hostname": "",
"IP": "2406:5a00:1011:7b00:186b:fea3:d955:36b8",
"MBits": 1000,
"Mode": "host",
"ReservedPorts": null
},
{
"CIDR": "2406:5a00:1011:7b00:64a5:2481:bc7e:22b3/128",
"DNS": null,
"Device": "en0",
"DynamicPorts": null,
"Hostname": "",
"IP": "2406:5a00:1011:7b00:64a5:2481:bc7e:22b3",
"MBits": 1000,
"Mode": "host",
"ReservedPorts": null
},
{
"CIDR": "192.168.4.55/32",
"DNS": null,
"Device": "en0",
"DynamicPorts": null,
"Hostname": "",
"IP": "192.168.4.55",
"MBits": 1000,
"Mode": "host",
"ReservedPorts": null
}
]
I would prefer to force the nomad client to use the IPv4
IP address but it is choosing IPv6
Tasks are fine when an IPv4
address is bound.
It looks like part of the issue is that macos
Desktop Docker doesn't support IPv6
, so nomad should be aware of this and bind accordingly: https://github.com/docker/for-mac/issues/1432
Hey all, this has been open a while, and various things have changed over the years. I'll try to summarize them here before closing out the issue.
I can only reproduce this happening one way, which is also today true of IPv4 addresses, with this config:
job "job" {
group "grp" {
task "tsk" {
driver = "docker"
config = {...}
service {
name = "web"
port = 8000
}
}
}
}
Notes: the service{}
must be defined within task{}
and the port
must be a number (which is only allowed in a task.service{}
). Nomad doesn't have an associated group.network.port{}
block to associate the allocation to an IP; it's merely forwarding along service info to the service provider. As with Consul, if the service{ provider = "nomad" }
, then the IPv4/6 address provided by Docker can be seen as a Nomad service, but otherwise it's effectively discarded.
The proper format for this nowadays would be:
job "job" {
group "grp" {
network {
port "http" {
static = 8000
}
}
service {
name = "web"
port = "http"
provider = "nomad" # or default "consul"
}
task "tsk" {
driver = "docker"
config = {
...
ports = ["http"]
}
}
}
}
This makes the static port available to Nomad for scheduling (to prevent port collisions), and it's passed down to service and task by its label "http" rather than number. Both network
and service
are group
-scoped, because that's the unit that gets placed as an allocation, all the tasks together in one network. The main downside here is that it doesn't pay any mind to Docker's assigned IP(s). Instead, a host IP:Port combo will be selected by Nomad, then bound by Docker.
Which brings us to IPv6:
Instead of asking Docker to provide an IPv6, you can now (as of #23388 -> Nomad 1.8.2) set preferred_address_family = "ipv6"
in the client{}
config. That will sort the host's addresses by family and try to choose the configured preference for scheduling and advertising services. This is especially nice because it works for other task drivers, too.
E.g. My laptop has these addresses:
$ nomad node status -json -self | jq -r '.NodeResources.Networks[].CIDR'
192.168.1.201/32
2600:4040:1229:f00:a860:15dd:xx:xx/128
2600:4040:1229:f00:f068:ed9e:xx:xx/128
By default, my services would get that 192...
IPv4 address, just because of how the addresses were sorted:
$ nomad service info web
Job ID Address Tags Node ID Alloc ID
dock 192.168.1.201:8000 [] c9ec5d97 96ecee71
$ nomad alloc status 96ecee71 | grep -B2 http
Allocation Addresses:
Label Dynamic Address
*http yes 192.168.1.201:8000
("web" service and "http" port label are from my example jobspec in part 1 above)
With client { preferred_address_family = "ipv6" }
in my agent config, I get:
$ nomad service info web
Job ID Address Tags Node ID Alloc ID
dock [2600:4040:1229:f00:a860:15dd:xx:xx]:8000 [] c9ec5d97 d13ce1a9
$ nomad alloc status d13ce1a9 | grep -B2 http
Allocation Addresses:
Label Dynamic Address
*http yes 2600:4040:1229:f00:a860:15dd:xx:xx:8000
Note: If you use network { mode = "bridge" }
(the default is "host"), then you will also need to configure Nomad for that (Nomad 1.9+) - see #14101.
Finally, for folks with the opposite issue, to avoid IPv6, you may try setting preferred_address_family = "ipv4"
.
So with all that, I'm closing this out, but please let us know if we missed something important!
Nomad version
Nomad v0.9.5 (1cbb2b9a81b5715be2f201a4650293c9ae517b87)
Docker version
Docker info
Operating system and Environment details
None applicable, nothing but a barebones install of Nomad, Docker, and a basic hello world container.
Issue
Nomad does not show the service IP of the Docker container, yet Docker reports the container IP via direct inspection of the properties the Service stanza should be grabbing the IP from.
Reproduction steps
nomad agent -dev
after fresh install, no other nomad configuration./etc/docker/daemon.json
Addresses
on the CLI or on the Nomad UI.Job file (if appropriate)
Nomad Job Allocation
Host Interfaces from
ip a s
Docker network inspect bridge
Notes
I have tested this works (the Docker container is reachable) via the command
curl -g -6 'http://[2a01:4f8:c2c:bafc::4]:5555/'
being able to be run from anywhere and returninghello world
.The image is a barebones nodejs http server, nothing special
The Dockerfile for the image is
docker ps -a
gives