mirror of
https://github.com/kemko/nomad.git
synced 2026-01-01 16:05:42 +03:00
by setting bridge_network_subnet_ipv6 in client config Co-authored-by: Martina Santangelo <martina.santangelo@hashicorp.com>
147 lines
4.0 KiB
Go
147 lines
4.0 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
package allocrunner
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
hclog "github.com/hashicorp/go-hclog"
|
|
"github.com/hashicorp/nomad/client/allocrunner/cni"
|
|
"github.com/hashicorp/nomad/nomad/structs"
|
|
"github.com/hashicorp/nomad/plugins/drivers"
|
|
)
|
|
|
|
const (
|
|
// defaultNomadBridgeName is the name of the bridge to use when not set by
|
|
// the client
|
|
defaultNomadBridgeName = "nomad"
|
|
|
|
// bridgeNetworkAllocIfPrefix is the prefix that is used for the interface
|
|
// name created inside of the alloc network which is connected to the bridge
|
|
bridgeNetworkAllocIfPrefix = "eth"
|
|
|
|
// defaultNomadAllocSubnet is the subnet to use for host local ip address
|
|
// allocation when not specified by the client
|
|
defaultNomadAllocSubnet = "172.26.64.0/20" // end 172.26.79.255
|
|
)
|
|
|
|
// bridgeNetworkConfigurator is a NetworkConfigurator which adds the alloc to a
|
|
// shared bridge, configures masquerading for egress traffic and port mapping
|
|
// for ingress
|
|
type bridgeNetworkConfigurator struct {
|
|
cni *cniNetworkConfigurator
|
|
allocSubnetIPv6 string
|
|
allocSubnetIPv4 string
|
|
bridgeName string
|
|
hairpinMode bool
|
|
|
|
newIPTables func(structs.NodeNetworkAF) (IPTablesChain, error)
|
|
|
|
logger hclog.Logger
|
|
}
|
|
|
|
func newBridgeNetworkConfigurator(log hclog.Logger, alloc *structs.Allocation, bridgeName, ipv4Range, ipv6Range, cniPath string, hairpinMode, ignorePortMappingHostIP bool, node *structs.Node) (*bridgeNetworkConfigurator, error) {
|
|
b := &bridgeNetworkConfigurator{
|
|
bridgeName: bridgeName,
|
|
hairpinMode: hairpinMode,
|
|
allocSubnetIPv4: ipv4Range,
|
|
allocSubnetIPv6: ipv6Range,
|
|
newIPTables: newIPTablesChain,
|
|
logger: log,
|
|
}
|
|
|
|
if b.bridgeName == "" {
|
|
b.bridgeName = defaultNomadBridgeName
|
|
}
|
|
|
|
if b.allocSubnetIPv4 == "" {
|
|
b.allocSubnetIPv4 = defaultNomadAllocSubnet
|
|
}
|
|
|
|
var netCfg []byte
|
|
var err error
|
|
|
|
tg := alloc.Job.LookupTaskGroup(alloc.TaskGroup)
|
|
for _, svc := range tg.Services {
|
|
if svc.Connect.HasTransparentProxy() {
|
|
netCfg, err = buildNomadBridgeNetConfig(*b, true)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
break
|
|
}
|
|
}
|
|
if netCfg == nil {
|
|
netCfg, err = buildNomadBridgeNetConfig(*b, false)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
parser := &cniConfParser{
|
|
listBytes: netCfg,
|
|
}
|
|
|
|
c, err := newCNINetworkConfiguratorWithConf(log, cniPath, bridgeNetworkAllocIfPrefix, ignorePortMappingHostIP, parser, node)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
b.cni = c
|
|
|
|
return b, nil
|
|
}
|
|
|
|
// ensureForwardingRules ensures that a forwarding rule is added to iptables
|
|
// to allow traffic inbound to the bridge network
|
|
func (b *bridgeNetworkConfigurator) ensureForwardingRules() error {
|
|
if b.allocSubnetIPv6 != "" {
|
|
ip6t, err := b.newIPTables(structs.NodeNetworkAF_IPv6)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err = ensureChainRule(ip6t, b.bridgeName, b.allocSubnetIPv6); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
ipt, err := b.newIPTables(structs.NodeNetworkAF_IPv4)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err = ensureChainRule(ipt, b.bridgeName, b.allocSubnetIPv4); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Setup calls the CNI plugins with the add action
|
|
func (b *bridgeNetworkConfigurator) Setup(ctx context.Context, alloc *structs.Allocation, spec *drivers.NetworkIsolationSpec) (*structs.AllocNetworkStatus, error) {
|
|
if err := b.ensureForwardingRules(); err != nil {
|
|
return nil, fmt.Errorf("failed to initialize table forwarding rules: %v", err)
|
|
}
|
|
|
|
return b.cni.Setup(ctx, alloc, spec)
|
|
}
|
|
|
|
// Teardown calls the CNI plugins with the delete action
|
|
func (b *bridgeNetworkConfigurator) Teardown(ctx context.Context, alloc *structs.Allocation, spec *drivers.NetworkIsolationSpec) error {
|
|
return b.cni.Teardown(ctx, alloc, spec)
|
|
}
|
|
|
|
func buildNomadBridgeNetConfig(b bridgeNetworkConfigurator, withConsulCNI bool) ([]byte, error) {
|
|
conf := cni.NewNomadBridgeConflist(cni.NomadBridgeConfig{
|
|
BridgeName: b.bridgeName,
|
|
AdminChainName: cniAdminChainName,
|
|
IPv4Subnet: b.allocSubnetIPv4,
|
|
IPv6Subnet: b.allocSubnetIPv6,
|
|
HairpinMode: b.hairpinMode,
|
|
ConsulCNI: withConsulCNI,
|
|
})
|
|
return conf.Json()
|
|
}
|