mirror of
https://github.com/kemko/nomad.git
synced 2026-01-06 18:35:44 +03:00
cni: add DNS set by CNI plugins to task configuration (#20007)
CNI plugins may set DNS configuration, but this isn't threaded through to the task configuration so that we can write it to the `/etc/resolv.conf` file as needed. Add the `AllocNetworkStatus` to the alloc hook resources so they're accessible from the taskrunner. Any DNS entries provided by the user will override these values. Fixes: https://github.com/hashicorp/nomad/issues/11102
This commit is contained in:
@@ -1125,6 +1125,18 @@ func (tr *TaskRunner) buildTaskConfig() *drivers.TaskConfig {
|
||||
defer tr.networkIsolationLock.Unlock()
|
||||
|
||||
var dns *drivers.DNSConfig
|
||||
|
||||
// set DNS from any CNI plugins
|
||||
netStatus := tr.allocHookResources.GetAllocNetworkStatus()
|
||||
if netStatus != nil && netStatus.DNS != nil {
|
||||
dns = &drivers.DNSConfig{
|
||||
Servers: netStatus.DNS.Servers,
|
||||
Searches: netStatus.DNS.Searches,
|
||||
Options: netStatus.DNS.Options,
|
||||
}
|
||||
}
|
||||
|
||||
// override DNS if set by job submitter
|
||||
if alloc.AllocatedResources != nil && len(alloc.AllocatedResources.Shared.Networks) > 0 {
|
||||
allocDNS := alloc.AllocatedResources.Shared.Networks[0].DNS
|
||||
if allocDNS != nil {
|
||||
|
||||
@@ -2931,3 +2931,121 @@ func TestTaskRunner_IdentityHook_Disabled(t *testing.T) {
|
||||
taskEnv := tr.envBuilder.Build()
|
||||
must.MapNotContainsKey(t, taskEnv.EnvMap, "NOMAD_TOKEN")
|
||||
}
|
||||
|
||||
func TestTaskRunner_AllocNetworkStatus(t *testing.T) {
|
||||
ci.Parallel(t)
|
||||
|
||||
// Mock task with group network
|
||||
alloc1 := mock.Alloc()
|
||||
task1 := alloc1.Job.TaskGroups[0].Tasks[0]
|
||||
alloc1.AllocatedResources.Shared.Networks = []*structs.NetworkResource{
|
||||
{
|
||||
Device: "eth0",
|
||||
IP: "192.168.0.100",
|
||||
DNS: &structs.DNSConfig{
|
||||
Servers: []string{"1.1.1.1", "8.8.8.8"},
|
||||
Searches: []string{"test.local"},
|
||||
Options: []string{"ndots:1"},
|
||||
},
|
||||
ReservedPorts: []structs.Port{{Label: "admin", Value: 5000}},
|
||||
DynamicPorts: []structs.Port{{Label: "http", Value: 9876}},
|
||||
}}
|
||||
task1.Driver = "mock_driver"
|
||||
task1.Config = map[string]interface{}{"run_for": "2s"}
|
||||
|
||||
// Mock task with task networking only
|
||||
alloc2 := mock.Alloc()
|
||||
task2 := alloc2.Job.TaskGroups[0].Tasks[0]
|
||||
task2.Driver = "mock_driver"
|
||||
task2.Config = map[string]interface{}{"run_for": "2s"}
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
alloc *structs.Allocation
|
||||
task *structs.Task
|
||||
fromCNI *structs.DNSConfig
|
||||
expect *drivers.DNSConfig
|
||||
}{
|
||||
{
|
||||
name: "task with group networking overrides CNI",
|
||||
alloc: alloc1,
|
||||
task: task1,
|
||||
fromCNI: &structs.DNSConfig{
|
||||
Servers: []string{"10.37.105.17"},
|
||||
Searches: []string{"node.consul"},
|
||||
Options: []string{"ndots:2", "edns0"},
|
||||
},
|
||||
expect: &drivers.DNSConfig{
|
||||
Servers: []string{"1.1.1.1", "8.8.8.8"},
|
||||
Searches: []string{"test.local"},
|
||||
Options: []string{"ndots:1"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "task with CNI alone",
|
||||
alloc: alloc2,
|
||||
task: task1,
|
||||
fromCNI: &structs.DNSConfig{
|
||||
Servers: []string{"10.37.105.17"},
|
||||
Searches: []string{"node.consul"},
|
||||
Options: []string{"ndots:2", "edns0"},
|
||||
},
|
||||
expect: &drivers.DNSConfig{
|
||||
Servers: []string{"10.37.105.17"},
|
||||
Searches: []string{"node.consul"},
|
||||
Options: []string{"ndots:2", "edns0"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "task with group networking alone",
|
||||
alloc: alloc1,
|
||||
task: task1,
|
||||
fromCNI: nil,
|
||||
expect: &drivers.DNSConfig{
|
||||
Servers: []string{"1.1.1.1", "8.8.8.8"},
|
||||
Searches: []string{"test.local"},
|
||||
Options: []string{"ndots:1"},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "task without group networking",
|
||||
alloc: alloc2,
|
||||
task: task2,
|
||||
fromCNI: nil,
|
||||
expect: nil,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
|
||||
conf, cleanup := testTaskRunnerConfig(t, tc.alloc, tc.task.Name, nil)
|
||||
t.Cleanup(cleanup)
|
||||
|
||||
// note this will never actually be set if we don't have group/CNI
|
||||
// networking, but it's a good validation no-group/CNI code path
|
||||
conf.AllocHookResources.SetAllocNetworkStatus(&structs.AllocNetworkStatus{
|
||||
InterfaceName: "",
|
||||
Address: "",
|
||||
DNS: tc.fromCNI,
|
||||
})
|
||||
|
||||
tr, err := NewTaskRunner(conf)
|
||||
must.NoError(t, err)
|
||||
|
||||
// Run the task runner.
|
||||
go tr.Run()
|
||||
t.Cleanup(func() {
|
||||
tr.Kill(context.Background(), structs.NewTaskEvent("cleanup"))
|
||||
})
|
||||
|
||||
// Wait for task to complete.
|
||||
testWaitForTaskToStart(t, tr)
|
||||
|
||||
tr.stateLock.RLock()
|
||||
t.Cleanup(tr.stateLock.RUnlock)
|
||||
|
||||
must.Eq(t, tc.expect, tr.localState.TaskHandle.Config.DNS)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user