2016-11-01 20:01:27 +00:00
|
|
|
// +build windows
|
|
|
|
|
|
|
|
/*
|
|
|
|
Copyright 2015 The Kubernetes Authors.
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2017-05-03 16:34:00 +00:00
|
|
|
package dockershim
|
2016-08-24 14:49:06 +00:00
|
|
|
|
2017-05-25 06:19:27 +00:00
|
|
|
import (
|
2017-05-28 04:06:46 +00:00
|
|
|
"os"
|
|
|
|
|
|
|
|
"github.com/blang/semver"
|
2017-06-29 20:21:17 +00:00
|
|
|
dockertypes "github.com/docker/docker/api/types"
|
|
|
|
dockercontainer "github.com/docker/docker/api/types/container"
|
|
|
|
dockerfilters "github.com/docker/docker/api/types/filters"
|
2017-05-25 06:19:27 +00:00
|
|
|
"github.com/golang/glog"
|
2018-01-30 04:56:31 +00:00
|
|
|
|
2018-02-11 07:00:27 +00:00
|
|
|
kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis"
|
2018-02-06 22:11:09 +00:00
|
|
|
runtimeapi "k8s.io/kubernetes/pkg/kubelet/apis/cri/runtime/v1alpha2"
|
2017-05-25 06:19:27 +00:00
|
|
|
)
|
|
|
|
|
2016-12-20 04:59:46 +00:00
|
|
|
func DefaultMemorySwap() int64 {
|
|
|
|
return 0
|
|
|
|
}
|
2017-05-25 06:19:27 +00:00
|
|
|
|
2017-08-15 15:06:51 +00:00
|
|
|
func (ds *dockerService) getSecurityOpts(seccompProfile string, separator rune) ([]string, error) {
|
|
|
|
if seccompProfile != "" {
|
|
|
|
glog.Warningf("seccomp annotations are not supported on windows")
|
2017-05-25 06:19:27 +00:00
|
|
|
}
|
|
|
|
return nil, nil
|
|
|
|
}
|
2017-05-28 04:06:46 +00:00
|
|
|
|
2018-01-30 01:33:48 +00:00
|
|
|
// applyExperimentalCreateConfig applys experimental configures from sandbox annotations.
|
|
|
|
func applyExperimentalCreateConfig(createConfig *dockertypes.ContainerCreateConfig, annotations map[string]string) {
|
2018-02-11 07:00:27 +00:00
|
|
|
if kubeletapis.ShouldIsolatedByHyperV(annotations) {
|
|
|
|
createConfig.HostConfig.Isolation = kubeletapis.HypervIsolationValue
|
2018-01-30 01:33:48 +00:00
|
|
|
|
|
|
|
if networkMode := os.Getenv("CONTAINER_NETWORK"); networkMode == "" {
|
|
|
|
createConfig.HostConfig.NetworkMode = dockercontainer.NetworkMode("none")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-28 04:06:46 +00:00
|
|
|
func (ds *dockerService) updateCreateConfig(
|
|
|
|
createConfig *dockertypes.ContainerCreateConfig,
|
|
|
|
config *runtimeapi.ContainerConfig,
|
|
|
|
sandboxConfig *runtimeapi.PodSandboxConfig,
|
|
|
|
podSandboxID string, securityOptSep rune, apiVersion *semver.Version) error {
|
|
|
|
if networkMode := os.Getenv("CONTAINER_NETWORK"); networkMode != "" {
|
|
|
|
createConfig.HostConfig.NetworkMode = dockercontainer.NetworkMode(networkMode)
|
2018-02-11 07:00:27 +00:00
|
|
|
} else if !kubeletapis.ShouldIsolatedByHyperV(sandboxConfig.Annotations) {
|
2017-06-14 23:27:39 +00:00
|
|
|
// Todo: Refactor this call in future for calling methods directly in security_context.go
|
2018-01-26 17:35:10 +00:00
|
|
|
modifyHostOptionsForContainer(nil, podSandboxID, createConfig.HostConfig)
|
2017-05-28 04:06:46 +00:00
|
|
|
}
|
|
|
|
|
2018-02-11 07:00:27 +00:00
|
|
|
// Apply Windows-specific options if applicable.
|
|
|
|
if wc := config.GetWindows(); wc != nil {
|
|
|
|
rOpts := wc.GetResources()
|
|
|
|
if rOpts != nil {
|
|
|
|
createConfig.HostConfig.Resources = dockercontainer.Resources{
|
|
|
|
Memory: rOpts.MemoryLimitInBytes,
|
|
|
|
CPUShares: rOpts.CpuShares,
|
|
|
|
CPUCount: rOpts.CpuCount,
|
|
|
|
CPUPercent: rOpts.CpuMaximum,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-01-30 01:33:48 +00:00
|
|
|
applyExperimentalCreateConfig(createConfig, sandboxConfig.Annotations)
|
|
|
|
|
2017-05-28 04:06:46 +00:00
|
|
|
return nil
|
|
|
|
}
|
2017-06-02 12:31:44 +00:00
|
|
|
|
|
|
|
func (ds *dockerService) determinePodIPBySandboxID(sandboxID string) string {
|
|
|
|
opts := dockertypes.ContainerListOptions{
|
2017-07-15 01:15:26 +00:00
|
|
|
All: true,
|
|
|
|
Filters: dockerfilters.NewArgs(),
|
2017-06-02 12:31:44 +00:00
|
|
|
}
|
|
|
|
|
2017-07-15 01:15:26 +00:00
|
|
|
f := newDockerFilter(&opts.Filters)
|
2017-06-02 12:31:44 +00:00
|
|
|
f.AddLabel(containerTypeLabelKey, containerTypeLabelContainer)
|
|
|
|
f.AddLabel(sandboxIDLabelKey, sandboxID)
|
|
|
|
containers, err := ds.client.ListContainers(opts)
|
|
|
|
if err != nil {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, c := range containers {
|
|
|
|
r, err := ds.client.InspectContainer(c.ID)
|
|
|
|
if err != nil {
|
|
|
|
continue
|
|
|
|
}
|
2017-06-14 23:27:39 +00:00
|
|
|
|
|
|
|
// Versions and feature support
|
|
|
|
// ============================
|
|
|
|
// Windows version == Windows Server, Version 1709,, Supports both sandbox and non-sandbox case
|
|
|
|
// Windows version == Windows Server 2016 Support only non-sandbox case
|
|
|
|
// Windows version < Windows Server 2016 is Not Supported
|
|
|
|
|
|
|
|
// Sandbox support in Windows mandates CNI Plugin.
|
2018-02-09 06:53:53 +00:00
|
|
|
// Presence of CONTAINER_NETWORK flag is considered as non-Sandbox cases here
|
2017-06-14 23:27:39 +00:00
|
|
|
|
|
|
|
// Todo: Add a kernel version check for more validation
|
|
|
|
|
|
|
|
if networkMode := os.Getenv("CONTAINER_NETWORK"); networkMode == "" {
|
2018-02-11 07:00:27 +00:00
|
|
|
if r.HostConfig.Isolation == kubeletapis.HypervIsolationValue {
|
2018-01-30 01:33:48 +00:00
|
|
|
// Hyper-V only supports one container per Pod yet and the container will have a different
|
|
|
|
// IP address from sandbox. Return the first non-sandbox container IP as POD IP.
|
|
|
|
// TODO(feiskyer): remove this workaround after Hyper-V supports multiple containers per Pod.
|
|
|
|
if containerIP := ds.getIP(c.ID, r); containerIP != "" {
|
|
|
|
return containerIP
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
// Do not return any IP, so that we would continue and get the IP of the Sandbox
|
|
|
|
ds.getIP(sandboxID, r)
|
|
|
|
}
|
2017-06-14 23:27:39 +00:00
|
|
|
} else {
|
|
|
|
// On Windows, every container that is created in a Sandbox, needs to invoke CNI plugin again for adding the Network,
|
|
|
|
// with the shared container name as NetNS info,
|
|
|
|
// This is passed down to the platform to replicate some necessary information to the new container
|
|
|
|
|
|
|
|
//
|
|
|
|
// This place is chosen as a hack for now, since getContainerIP would end up calling CNI's addToNetwork
|
|
|
|
// That is why addToNetwork is required to be idempotent
|
|
|
|
|
|
|
|
// Instead of relying on this call, an explicit call to addToNetwork should be
|
|
|
|
// done immediately after ContainerCreation, in case of Windows only. TBD Issue # to handle this
|
|
|
|
|
|
|
|
if containerIP := getContainerIP(r); containerIP != "" {
|
|
|
|
return containerIP
|
|
|
|
}
|
2017-06-02 12:31:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
|
2017-06-14 23:27:39 +00:00
|
|
|
func getNetworkNamespace(c *dockertypes.ContainerJSON) (string, error) {
|
|
|
|
// Currently in windows there is no identifier exposed for network namespace
|
|
|
|
// Like docker, the referenced container id is used to figure out the network namespace id internally by the platform
|
|
|
|
// so returning the docker networkMode (which holds container:<ref containerid> for network namespace here
|
|
|
|
return string(c.HostConfig.NetworkMode), nil
|
|
|
|
}
|
|
|
|
|
2017-06-02 12:31:44 +00:00
|
|
|
func getContainerIP(container *dockertypes.ContainerJSON) string {
|
|
|
|
if container.NetworkSettings != nil {
|
|
|
|
for _, network := range container.NetworkSettings.Networks {
|
|
|
|
if network.IPAddress != "" {
|
|
|
|
return network.IPAddress
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ""
|
|
|
|
}
|