Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .changelog/25632.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
```release-note:bug
consul: Add AllocIPv6 option to allow IPv6 address being used for service registration
```
14 changes: 13 additions & 1 deletion client/serviceregistration/address.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ func GetAddress(

return driverNet.IP, port, nil

case structs.AddressModeAlloc:
case structs.AddressModeAlloc, structs.AddressModeAllocIPv6:
// Cannot use address mode alloc with custom advertise address.
if address != "" {
return "", 0, fmt.Errorf("cannot use custom advertise address with %q address mode", structs.AddressModeAlloc)
Expand All @@ -147,15 +147,24 @@ func GetAddress(

// If no port label is specified just return the IP
if portLabel == "" {
if addressMode == structs.AddressModeAllocIPv6 {
return netStatus.AddressIPv6, 0, nil
}
return netStatus.Address, 0, nil
}

// If port is a label and is found then return it
if port, ok := ports.Get(portLabel); ok {
// Use port.To value unless not set
if port.To > 0 {
if addressMode == structs.AddressModeAllocIPv6 {
return netStatus.AddressIPv6, port.To, nil
}
return netStatus.Address, port.To, nil
}
if addressMode == structs.AddressModeAllocIPv6 {
return netStatus.AddressIPv6, port.Value, nil
}
return netStatus.Address, port.Value, nil
}

Expand All @@ -168,6 +177,9 @@ func GetAddress(
if port <= 0 {
return "", 0, fmt.Errorf("invalid port: %q: port must be >0", portLabel)
}
if addressMode == structs.AddressModeAllocIPv6 {
return netStatus.AddressIPv6, port, nil
}
return netStatus.Address, port, nil

default:
Expand Down
26 changes: 26 additions & 0 deletions client/serviceregistration/address_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,26 @@ func Test_GetAddress(t *testing.T) {
expIP: "172.26.0.1",
expPort: 6379,
},
{
name: "Alloc",
mode: structs.AddressModeAllocIPv6,
portLabel: "db",
ports: []structs.AllocatedPortMapping{
{
Label: "db",
Value: 12345,
To: 6379,
HostIP: HostIP,
},
},
status: &structs.AllocNetworkStatus{
InterfaceName: "eth0",
Address: "172.26.0.1",
AddressIPv6: "2001:db8::8a2e:370:7334",
},
expIP: "2001:db8::8a2e:370:7334",
expPort: 6379,
},
{
name: "Alloc no to value",
mode: structs.AddressModeAlloc,
Expand Down Expand Up @@ -383,6 +403,12 @@ func Test_GetAddress(t *testing.T) {
advertise: "example.com",
expErr: `cannot use custom advertise address with "alloc" address mode`,
},
{
name: "Address with alloc IPv6 mode",
mode: structs.AddressModeAllocIPv6,
advertise: "example.com",
expErr: `cannot use custom advertise address with "alloc" address mode`,
},
}

for _, tc := range testCases {
Expand Down
2 changes: 1 addition & 1 deletion client/serviceregistration/checks/result.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ type Query struct {

Timeout time.Duration // connection / request timeout

AddressMode string // host, driver, or alloc
AddressMode string // host, driver, alloc or alloc_advertise_ipv6
PortLabel string // label or value

Protocol string // http checks only (http or https)
Expand Down
16 changes: 9 additions & 7 deletions nomad/structs/services.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@

// validate address_mode
switch sc.AddressMode {
case "", AddressModeHost, AddressModeDriver, AddressModeAlloc:
case "", AddressModeHost, AddressModeDriver, AddressModeAlloc, AddressModeAllocIPv6:
// Ok
case AddressModeAuto:
return fmt.Errorf("invalid address_mode %q - %s only valid for services", sc.AddressMode, AddressModeAuto)
Expand Down Expand Up @@ -562,10 +562,11 @@
}

const (
AddressModeAuto = "auto"
AddressModeHost = "host"
AddressModeDriver = "driver"
AddressModeAlloc = "alloc"
AddressModeAuto = "auto"

Check failure on line 565 in nomad/structs/services.go

View workflow job for this annotation

GitHub Actions / checks

File is not properly formatted (gofmt)

Check failure on line 565 in nomad/structs/services.go

View workflow job for this annotation

GitHub Actions / checks / checks

File is not properly formatted (gofmt)
AddressModeHost = "host"
AddressModeDriver = "driver"
AddressModeAlloc = "alloc"
AddressModeAllocIPv6 = "alloc_ipv6"

// ServiceProviderConsul is the default service provider and the way Nomad
// worked before native service discovery.
Expand Down Expand Up @@ -597,7 +598,8 @@
PortLabel string

// AddressMode specifies how the address in service registration is
// determined. Must be "auto" (default), "host", "driver", or "alloc".
// determined. Must be "auto" (default), "host", "driver", "alloc" or
// "alloc_ipv6".
AddressMode string

// Address enables explicitly setting a custom address to use in service
Expand Down Expand Up @@ -768,7 +770,7 @@

switch s.AddressMode {
case "", AddressModeAuto:
case AddressModeHost, AddressModeDriver, AddressModeAlloc:
case AddressModeHost, AddressModeDriver, AddressModeAlloc, AddressModeAllocIPv6:
if s.Address != "" {
mErr.Errors = append(mErr.Errors, fmt.Errorf("Service address_mode must be %q if address is set", AddressModeAuto))
}
Expand Down
8 changes: 8 additions & 0 deletions nomad/structs/structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -8313,6 +8313,10 @@ func validateServices(t *Task, tgNetworks Networks) error {
mErr.Errors = append(mErr.Errors, fmt.Errorf("service %q cannot use address_mode=\"alloc\", only services defined in a \"group\" block can use this mode", service.Name))
}

if service.AddressMode == AddressModeAllocIPv6 {
mErr.Errors = append(mErr.Errors, fmt.Errorf("service %q cannot use address_mode=\"alloc_ipv6\", only services defined in a \"group\" block can use this mode", service.Name))
}

// Ensure that services with the same name are not being registered for
// the same port
if _, ok := knownServices[service.Name+service.PortLabel]; ok {
Expand Down Expand Up @@ -8350,6 +8354,10 @@ func validateServices(t *Task, tgNetworks Networks) error {
mErr.Errors = append(mErr.Errors, fmt.Errorf("check %q cannot use address_mode=\"alloc\", only checks defined in a \"group\" service block can use this mode", service.Name))
}

if check.AddressMode == AddressModeAllocIPv6 {
mErr.Errors = append(mErr.Errors, fmt.Errorf("check %q cannot use address_mode=\"alloc_ipv6\", only checks defined in a \"group\" service block can use this mode", service.Name))
}

if !check.RequiresPort() {
// No need to continue validating check if it doesn't need a port
continue
Expand Down
7 changes: 6 additions & 1 deletion website/content/docs/job-specification/service.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,8 @@ service mesh][connect] integration.
If a `to` value is not set, the port falls back to using the allocated host port. The `port`
field may be a numeric port or a port label specified in the same group's network block.

- `alloc_ipv6` - Same as `alloc` but use the IPv6 address in case of dual-stack or IPv6-only.

- `driver` - Advertise the port determined by the driver (e.g. Docker).
The `port` may be a numeric port or a port label specified in the driver's
`ports` field.
Expand Down Expand Up @@ -190,7 +192,7 @@ service mesh][connect] integration.
- `tagged_addresses` `(map<string|string>` - Specifies custom [tagged addresses][tagged_addresses] to
advertise in the Consul service registration. Only available where `provider = "consul"`.

- `address_mode` `(string: "auto")` - Specifies which address (host, alloc or
- `address_mode` `(string: "auto")` - Specifies which address (host, alloc, alloc_ipv6 or
driver-specific) this service should advertise. See [below for
examples.](#using-driver-address-mode) Valid options are:

Expand All @@ -200,6 +202,9 @@ service mesh][connect] integration.
where no port mapping is necessary. This mode can only be set for services which
are defined in a "group" block.

- `alloc_ipv6` - Identical as `alloc` but will pick the IPv6 address in case of
dual-stack or IPv6 only.

- `auto` - Allows the driver to determine whether the host or driver address
should be used. Defaults to `host` and only implemented by Docker. If you
use a Docker network plugin such as weave, Docker will automatically use
Expand Down
Loading