Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add dns capabilities for Windows CNI plugins #67435

Merged
merged 2 commits into from Nov 6, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
13 changes: 11 additions & 2 deletions pkg/kubelet/dockershim/docker_sandbox.go
Expand Up @@ -18,6 +18,7 @@ package dockershim

import (
"context"
"encoding/json"
"fmt"
"os"
"strings"
Expand All @@ -27,7 +28,6 @@ import (
dockercontainer "github.com/docker/docker/api/types/container"
dockerfilters "github.com/docker/docker/api/types/filters"
"github.com/golang/glog"

utilerrors "k8s.io/apimachinery/pkg/util/errors"
runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
"k8s.io/kubernetes/pkg/kubelet/checkpointmanager"
Expand Down Expand Up @@ -165,7 +165,16 @@ func (ds *dockerService) RunPodSandbox(ctx context.Context, r *runtimeapi.RunPod
// on the host as well, to satisfy parts of the pod spec that aren't
// recognized by the CNI standard yet.
cID := kubecontainer.BuildContainerID(runtimeName, createResp.ID)
err = ds.network.SetUpPod(config.GetMetadata().Namespace, config.GetMetadata().Name, cID, config.Annotations)
networkOptions := make(map[string]string)
if dnsConfig := config.GetDnsConfig(); dnsConfig != nil {
// Build DNS options.
dnsOption, err := json.Marshal(dnsConfig)
if err != nil {
return nil, fmt.Errorf("failed to marshal dns config for pod %q: %v", config.Metadata.Name, err)
}
networkOptions["dns"] = string(dnsOption)
}
err = ds.network.SetUpPod(config.GetMetadata().Namespace, config.GetMetadata().Name, cID, config.Annotations, networkOptions)
if err != nil {
errList := []error{fmt.Errorf("failed to set up sandbox container %q network for pod %q: %v", createResp.ID, config.Metadata.Name, err)}

Expand Down
1 change: 0 additions & 1 deletion pkg/kubelet/dockershim/docker_service_test.go
Expand Up @@ -27,7 +27,6 @@ import (
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

"k8s.io/apimachinery/pkg/util/clock"
runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
"k8s.io/kubernetes/pkg/kubelet/checkpointmanager"
Expand Down
1 change: 1 addition & 0 deletions pkg/kubelet/dockershim/network/cni/BUILD
Expand Up @@ -16,6 +16,7 @@ go_library(
importpath = "k8s.io/kubernetes/pkg/kubelet/dockershim/network/cni",
deps = [
"//pkg/kubelet/apis/config:go_default_library",
"//pkg/kubelet/apis/cri/runtime/v1alpha2:go_default_library",
"//pkg/kubelet/container:go_default_library",
"//pkg/kubelet/dockershim/network:go_default_library",
"//pkg/util/bandwidth:go_default_library",
Expand Down
40 changes: 33 additions & 7 deletions pkg/kubelet/dockershim/network/cni/cni.go
Expand Up @@ -17,6 +17,7 @@ limitations under the License.
package cni

import (
"encoding/json"
"errors"
"fmt"
"sort"
Expand All @@ -27,6 +28,7 @@ import (
cnitypes "github.com/containernetworking/cni/pkg/types"
"github.com/golang/glog"
kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
"k8s.io/kubernetes/pkg/kubelet/dockershim/network"
"k8s.io/kubernetes/pkg/util/bandwidth"
Expand Down Expand Up @@ -89,6 +91,18 @@ type cniIpRange struct {
Subnet string `json:"subnet"`
}

// cniDNSConfig maps to the windows CNI dns Capability.
// see: https://github.com/containernetworking/cni/blob/master/CONVENTIONS.md
// Note that dns capability is only used for Windows containers.
type cniDNSConfig struct {
// List of DNS servers of the cluster.
Servers []string `json:"servers,omitempty"`
// List of DNS search domains of the cluster.
Searches []string `json:"searches,omitempty"`
// List of DNS options.
Options []string `json:"options,omitempty"`
}

func SplitDirs(dirs string) []string {
// Use comma rather than colon to work better with Windows too
return strings.Split(dirs, ",")
Expand Down Expand Up @@ -256,7 +270,7 @@ func (plugin *cniNetworkPlugin) Status() error {
return plugin.checkInitialized()
}

func (plugin *cniNetworkPlugin) SetUpPod(namespace string, name string, id kubecontainer.ContainerID, annotations map[string]string) error {
func (plugin *cniNetworkPlugin) SetUpPod(namespace string, name string, id kubecontainer.ContainerID, annotations, options map[string]string) error {
if err := plugin.checkInitialized(); err != nil {
return err
}
Expand All @@ -267,12 +281,12 @@ func (plugin *cniNetworkPlugin) SetUpPod(namespace string, name string, id kubec

// Windows doesn't have loNetwork. It comes only with Linux
if plugin.loNetwork != nil {
if _, err = plugin.addToNetwork(plugin.loNetwork, name, namespace, id, netnsPath, annotations); err != nil {
if _, err = plugin.addToNetwork(plugin.loNetwork, name, namespace, id, netnsPath, annotations, options); err != nil {
return err
}
}

_, err = plugin.addToNetwork(plugin.getDefaultNetwork(), name, namespace, id, netnsPath, annotations)
_, err = plugin.addToNetwork(plugin.getDefaultNetwork(), name, namespace, id, netnsPath, annotations, options)
return err
}

Expand All @@ -294,8 +308,8 @@ func podDesc(namespace, name string, id kubecontainer.ContainerID) string {
return fmt.Sprintf("%s_%s/%s", namespace, name, id.ID)
}

func (plugin *cniNetworkPlugin) addToNetwork(network *cniNetwork, podName string, podNamespace string, podSandboxID kubecontainer.ContainerID, podNetnsPath string, annotations map[string]string) (cnitypes.Result, error) {
rt, err := plugin.buildCNIRuntimeConf(podName, podNamespace, podSandboxID, podNetnsPath, annotations)
func (plugin *cniNetworkPlugin) addToNetwork(network *cniNetwork, podName string, podNamespace string, podSandboxID kubecontainer.ContainerID, podNetnsPath string, annotations, options map[string]string) (cnitypes.Result, error) {
rt, err := plugin.buildCNIRuntimeConf(podName, podNamespace, podSandboxID, podNetnsPath, annotations, options)
if err != nil {
glog.Errorf("Error adding network when building cni runtime conf: %v", err)
return nil, err
Expand All @@ -314,7 +328,7 @@ func (plugin *cniNetworkPlugin) addToNetwork(network *cniNetwork, podName string
}

func (plugin *cniNetworkPlugin) deleteFromNetwork(network *cniNetwork, podName string, podNamespace string, podSandboxID kubecontainer.ContainerID, podNetnsPath string, annotations map[string]string) error {
rt, err := plugin.buildCNIRuntimeConf(podName, podNamespace, podSandboxID, podNetnsPath, annotations)
rt, err := plugin.buildCNIRuntimeConf(podName, podNamespace, podSandboxID, podNetnsPath, annotations, nil)
if err != nil {
glog.Errorf("Error deleting network when building cni runtime conf: %v", err)
return err
Expand All @@ -334,7 +348,7 @@ func (plugin *cniNetworkPlugin) deleteFromNetwork(network *cniNetwork, podName s
return nil
}

func (plugin *cniNetworkPlugin) buildCNIRuntimeConf(podName string, podNs string, podSandboxID kubecontainer.ContainerID, podNetnsPath string, annotations map[string]string) (*libcni.RuntimeConf, error) {
func (plugin *cniNetworkPlugin) buildCNIRuntimeConf(podName string, podNs string, podSandboxID kubecontainer.ContainerID, podNetnsPath string, annotations, options map[string]string) (*libcni.RuntimeConf, error) {
rt := &libcni.RuntimeConf{
ContainerID: podSandboxID.ID,
NetNS: podNetnsPath,
Expand Down Expand Up @@ -389,5 +403,17 @@ func (plugin *cniNetworkPlugin) buildCNIRuntimeConf(podName string, podNs string
// Set the PodCIDR
rt.CapabilityArgs["ipRanges"] = [][]cniIpRange{{{Subnet: plugin.podCidr}}}

// Set dns capability args.
if dnsOptions, ok := options["dns"]; ok {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

options could be nil, right?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, ok will be false in that case

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought it would panic. surprised it won't.

dnsConfig := runtimeapi.DNSConfig{}
err := json.Unmarshal([]byte(dnsOptions), &dnsConfig)
if err != nil {
return nil, fmt.Errorf("failed to unmarshal dns config %q: %v", dnsOptions, err)
}
if dnsParam := buildDNSCapabilities(&dnsConfig); dnsParam != nil {
rt.CapabilityArgs["dns"] = *dnsParam
}
}

return rt, nil
}
6 changes: 6 additions & 0 deletions pkg/kubelet/dockershim/network/cni/cni_others.go
Expand Up @@ -22,6 +22,7 @@ import (
"fmt"

"github.com/containernetworking/cni/libcni"
runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
"k8s.io/kubernetes/pkg/kubelet/dockershim/network"
)
Expand Down Expand Up @@ -75,3 +76,8 @@ func (plugin *cniNetworkPlugin) GetPodNetworkStatus(namespace string, name strin

return &network.PodNetworkStatus{IP: ip}, nil
}

// buildDNSCapabilities builds cniDNSConfig from runtimeapi.DNSConfig.
func buildDNSCapabilities(dnsConfig *runtimeapi.DNSConfig) *cniDNSConfig {
return nil
}
2 changes: 1 addition & 1 deletion pkg/kubelet/dockershim/network/cni/cni_test.go
Expand Up @@ -254,7 +254,7 @@ func TestCNIPlugin(t *testing.T) {
bandwidthAnnotation["kubernetes.io/egress-bandwidth"] = "1M"

// Set up the pod
err = plug.SetUpPod("podNamespace", "podName", containerID, bandwidthAnnotation)
err = plug.SetUpPod("podNamespace", "podName", containerID, bandwidthAnnotation, nil)
if err != nil {
t.Errorf("Expected nil: %v", err)
}
Expand Down
16 changes: 15 additions & 1 deletion pkg/kubelet/dockershim/network/cni/cni_windows.go
Expand Up @@ -23,6 +23,7 @@ import (

cniTypes020 "github.com/containernetworking/cni/pkg/types/020"
"github.com/golang/glog"
runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
kubecontainer "k8s.io/kubernetes/pkg/kubelet/container"
"k8s.io/kubernetes/pkg/kubelet/dockershim/network"
)
Expand All @@ -42,7 +43,7 @@ func (plugin *cniNetworkPlugin) GetPodNetworkStatus(namespace string, name strin
return nil, fmt.Errorf("CNI failed to retrieve network namespace path: %v", err)
}

result, err := plugin.addToNetwork(plugin.getDefaultNetwork(), name, namespace, id, netnsPath, nil)
result, err := plugin.addToNetwork(plugin.getDefaultNetwork(), name, namespace, id, netnsPath, nil, nil)

glog.V(5).Infof("GetPodNetworkStatus result %+v", result)
if err != nil {
Expand All @@ -59,3 +60,16 @@ func (plugin *cniNetworkPlugin) GetPodNetworkStatus(namespace string, name strin
}
return &network.PodNetworkStatus{IP: result020.IP4.IP.IP}, nil
}

// buildDNSCapabilities builds cniDNSConfig from runtimeapi.DNSConfig.
func buildDNSCapabilities(dnsConfig *runtimeapi.DNSConfig) *cniDNSConfig {
if dnsConfig != nil {
return &cniDNSConfig{
Servers: dnsConfig.Servers,
Searches: dnsConfig.Searches,
Options: dnsConfig.Options,
}
}

return nil
}
2 changes: 1 addition & 1 deletion pkg/kubelet/dockershim/network/kubenet/kubenet_linux.go
Expand Up @@ -379,7 +379,7 @@ func (plugin *kubenetNetworkPlugin) setup(namespace string, name string, id kube
return nil
}

func (plugin *kubenetNetworkPlugin) SetUpPod(namespace string, name string, id kubecontainer.ContainerID, annotations map[string]string) error {
func (plugin *kubenetNetworkPlugin) SetUpPod(namespace string, name string, id kubecontainer.ContainerID, annotations, options map[string]string) error {
plugin.mu.Lock()
defer plugin.mu.Unlock()

Expand Down
Expand Up @@ -42,7 +42,7 @@ func (plugin *kubenetNetworkPlugin) Name() string {
return "kubenet"
}

func (plugin *kubenetNetworkPlugin) SetUpPod(namespace string, name string, id kubecontainer.ContainerID, annotations map[string]string) error {
func (plugin *kubenetNetworkPlugin) SetUpPod(namespace string, name string, id kubecontainer.ContainerID, annotations, options map[string]string) error {
return fmt.Errorf("Kubenet is not supported in this build")
}

Expand Down
8 changes: 4 additions & 4 deletions pkg/kubelet/dockershim/network/plugins.go
Expand Up @@ -63,7 +63,7 @@ type NetworkPlugin interface {
// SetUpPod is the method called after the infra container of
// the pod has been created but before the other containers of the
// pod are launched.
SetUpPod(namespace string, name string, podSandboxID kubecontainer.ContainerID, annotations map[string]string) error
SetUpPod(namespace string, name string, podSandboxID kubecontainer.ContainerID, annotations, options map[string]string) error

// TearDownPod is the method called before a pod's infra container will be deleted
TearDownPod(namespace string, name string, podSandboxID kubecontainer.ContainerID) error
Expand Down Expand Up @@ -207,7 +207,7 @@ func (plugin *NoopNetworkPlugin) Capabilities() utilsets.Int {
return utilsets.NewInt()
}

func (plugin *NoopNetworkPlugin) SetUpPod(namespace string, name string, id kubecontainer.ContainerID, annotations map[string]string) error {
func (plugin *NoopNetworkPlugin) SetUpPod(namespace string, name string, id kubecontainer.ContainerID, annotations, options map[string]string) error {
return nil
}

Expand Down Expand Up @@ -368,14 +368,14 @@ func (pm *PluginManager) GetPodNetworkStatus(podNamespace, podName string, id ku
return netStatus, nil
}

func (pm *PluginManager) SetUpPod(podNamespace, podName string, id kubecontainer.ContainerID, annotations map[string]string) error {
func (pm *PluginManager) SetUpPod(podNamespace, podName string, id kubecontainer.ContainerID, annotations, options map[string]string) error {
defer recordOperation("set_up_pod", time.Now())
fullPodName := kubecontainer.BuildPodFullName(podName, podNamespace)
pm.podLock(fullPodName).Lock()
defer pm.podUnlock(fullPodName)

glog.V(3).Infof("Calling network plugin %s to set up pod %q", pm.plugin.Name(), fullPodName)
if err := pm.plugin.SetUpPod(podNamespace, podName, id, annotations); err != nil {
if err := pm.plugin.SetUpPod(podNamespace, podName, id, annotations, options); err != nil {
return fmt.Errorf("NetworkPlugin %s failed to set up pod %q network: %v", pm.plugin.Name(), fullPodName, err)
}

Expand Down
Expand Up @@ -102,7 +102,7 @@ func (_mr *_MockNetworkPluginRecorder) Name() *gomock.Call {
return _mr.mock.ctrl.RecordCall(_mr.mock, "Name")
}

func (_m *MockNetworkPlugin) SetUpPod(_param0 string, _param1 string, _param2 container.ContainerID, annotations map[string]string) error {
func (_m *MockNetworkPlugin) SetUpPod(_param0 string, _param1 string, _param2 container.ContainerID, annotations, options map[string]string) error {
ret := _m.ctrl.Call(_m, "SetUpPod", _param0, _param1, _param2)
ret0, _ := ret[0].(error)
return ret0
Expand Down
8 changes: 4 additions & 4 deletions pkg/kubelet/dockershim/network/testing/plugins_test.go
Expand Up @@ -108,7 +108,7 @@ func TestPluginManager(t *testing.T) {
// concurrently.
allCreatedWg.Wait()

if err := pm.SetUpPod("", name, id, nil); err != nil {
if err := pm.SetUpPod("", name, id, nil, nil); err != nil {
t.Errorf("Failed to set up pod %q: %v", name, err)
return
}
Expand Down Expand Up @@ -159,7 +159,7 @@ func (p *hookableFakeNetworkPlugin) Capabilities() utilsets.Int {
return utilsets.NewInt()
}

func (p *hookableFakeNetworkPlugin) SetUpPod(namespace string, name string, id kubecontainer.ContainerID, annotations map[string]string) error {
func (p *hookableFakeNetworkPlugin) SetUpPod(namespace string, name string, id kubecontainer.ContainerID, annotations, options map[string]string) error {
if p.setupHook != nil {
p.setupHook(namespace, name, id)
}
Expand Down Expand Up @@ -210,7 +210,7 @@ func TestMultiPodParallelNetworkOps(t *testing.T) {
// Setup will block on the runner pod completing. If network
// operations locking isn't correct (eg pod network operations
// block other pods) setUpPod() will never return.
if err := pm.SetUpPod("", podName, containerID, nil); err != nil {
if err := pm.SetUpPod("", podName, containerID, nil, nil); err != nil {
t.Errorf("Failed to set up waiter pod: %v", err)
return
}
Expand All @@ -230,7 +230,7 @@ func TestMultiPodParallelNetworkOps(t *testing.T) {
podName := "runner"
containerID := kubecontainer.ContainerID{ID: podName}

if err := pm.SetUpPod("", podName, containerID, nil); err != nil {
if err := pm.SetUpPod("", podName, containerID, nil, nil); err != nil {
t.Errorf("Failed to set up runner pod: %v", err)
return
}
Expand Down