mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-25 04:33:26 +00:00
Deprecate HostConfig at container start
This commit is contained in:
parent
b2600a65f5
commit
8118092d11
@ -212,15 +212,19 @@ func (p throttledDockerPuller) IsImagePresent(name string) (bool, error) {
|
|||||||
const containerNamePrefix = "k8s"
|
const containerNamePrefix = "k8s"
|
||||||
|
|
||||||
// Creates a name which can be reversed to identify both full pod name and container name.
|
// Creates a name which can be reversed to identify both full pod name and container name.
|
||||||
func BuildDockerName(dockerName KubeletContainerName, container *api.Container) (string, string) {
|
// This function returns stable name, unique name and an unique id.
|
||||||
|
// Although rand.Uint32() is not really unique, but it's enough for us because error will
|
||||||
|
// only occur when instances of the same container in the same pod have the same UID. The
|
||||||
|
// chance is really slim.
|
||||||
|
func BuildDockerName(dockerName KubeletContainerName, container *api.Container) (string, string, string) {
|
||||||
containerName := dockerName.ContainerName + "." + strconv.FormatUint(kubecontainer.HashContainer(container), 16)
|
containerName := dockerName.ContainerName + "." + strconv.FormatUint(kubecontainer.HashContainer(container), 16)
|
||||||
stableName := fmt.Sprintf("%s_%s_%s_%s",
|
stableName := fmt.Sprintf("%s_%s_%s_%s",
|
||||||
containerNamePrefix,
|
containerNamePrefix,
|
||||||
containerName,
|
containerName,
|
||||||
dockerName.PodFullName,
|
dockerName.PodFullName,
|
||||||
dockerName.PodUID)
|
dockerName.PodUID)
|
||||||
|
UID := fmt.Sprintf("%08x", rand.Uint32())
|
||||||
return stableName, fmt.Sprintf("%s_%08x", stableName, rand.Uint32())
|
return stableName, fmt.Sprintf("%s_%s", stableName, UID), UID
|
||||||
}
|
}
|
||||||
|
|
||||||
// Unpacks a container name, returning the pod full name and container name we would have used to
|
// Unpacks a container name, returning the pod full name and container name we would have used to
|
||||||
|
@ -119,7 +119,7 @@ func verifyPackUnpack(t *testing.T, podNamespace, podUID, podName, containerName
|
|||||||
hashutil.DeepHashObject(hasher, *container)
|
hashutil.DeepHashObject(hasher, *container)
|
||||||
computedHash := uint64(hasher.Sum32())
|
computedHash := uint64(hasher.Sum32())
|
||||||
podFullName := fmt.Sprintf("%s_%s", podName, podNamespace)
|
podFullName := fmt.Sprintf("%s_%s", podName, podNamespace)
|
||||||
_, name := BuildDockerName(KubeletContainerName{podFullName, types.UID(podUID), container.Name}, container)
|
_, name, _ := BuildDockerName(KubeletContainerName{podFullName, types.UID(podUID), container.Name}, container)
|
||||||
returned, hash, err := ParseDockerName(name)
|
returned, hash, err := ParseDockerName(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Failed to parse Docker container name %q: %v", name, err)
|
t.Errorf("Failed to parse Docker container name %q: %v", name, err)
|
||||||
|
@ -87,9 +87,6 @@ func (f *FakeDockerClient) SetFakeContainers(containers []*docker.Container) {
|
|||||||
if c.Config == nil {
|
if c.Config == nil {
|
||||||
c.Config = &docker.Config{}
|
c.Config = &docker.Config{}
|
||||||
}
|
}
|
||||||
if c.HostConfig == nil {
|
|
||||||
c.HostConfig = &docker.HostConfig{}
|
|
||||||
}
|
|
||||||
f.ContainerMap[c.ID] = c
|
f.ContainerMap[c.ID] = c
|
||||||
apiContainer := docker.APIContainers{
|
apiContainer := docker.APIContainers{
|
||||||
Names: []string{c.Name},
|
Names: []string{c.Name},
|
||||||
@ -254,7 +251,7 @@ func (f *FakeDockerClient) CreateContainer(c docker.CreateContainerOptions) (*do
|
|||||||
f.ContainerList = append([]docker.APIContainers{
|
f.ContainerList = append([]docker.APIContainers{
|
||||||
{ID: name, Names: []string{name}, Image: c.Config.Image, Labels: c.Config.Labels},
|
{ID: name, Names: []string{name}, Image: c.Config.Image, Labels: c.Config.Labels},
|
||||||
}, f.ContainerList...)
|
}, f.ContainerList...)
|
||||||
container := docker.Container{ID: name, Name: name, Config: c.Config}
|
container := docker.Container{ID: name, Name: name, Config: c.Config, HostConfig: c.HostConfig}
|
||||||
containerCopy := container
|
containerCopy := container
|
||||||
f.ContainerMap[name] = &containerCopy
|
f.ContainerMap[name] = &containerCopy
|
||||||
f.normalSleep(100, 25, 25)
|
f.normalSleep(100, 25, 25)
|
||||||
@ -263,7 +260,11 @@ func (f *FakeDockerClient) CreateContainer(c docker.CreateContainerOptions) (*do
|
|||||||
|
|
||||||
// StartContainer is a test-spy implementation of DockerInterface.StartContainer.
|
// StartContainer is a test-spy implementation of DockerInterface.StartContainer.
|
||||||
// It adds an entry "start" to the internal method call record.
|
// It adds an entry "start" to the internal method call record.
|
||||||
func (f *FakeDockerClient) StartContainer(id string, hostConfig *docker.HostConfig) error {
|
// The HostConfig at StartContainer will be deprecated from docker 1.10. Now in
|
||||||
|
// docker manager the HostConfig is set when CreateContainer().
|
||||||
|
// TODO(random-liu): Remove the HostConfig here when it is completely removed in
|
||||||
|
// docker 1.12.
|
||||||
|
func (f *FakeDockerClient) StartContainer(id string, _ *docker.HostConfig) error {
|
||||||
f.Lock()
|
f.Lock()
|
||||||
defer f.Unlock()
|
defer f.Unlock()
|
||||||
f.called = append(f.called, "start")
|
f.called = append(f.called, "start")
|
||||||
@ -274,7 +275,6 @@ func (f *FakeDockerClient) StartContainer(id string, hostConfig *docker.HostConf
|
|||||||
if !ok {
|
if !ok {
|
||||||
container = &docker.Container{ID: id, Name: id}
|
container = &docker.Container{ID: id, Name: id}
|
||||||
}
|
}
|
||||||
container.HostConfig = hostConfig
|
|
||||||
container.State = docker.State{
|
container.State = docker.State{
|
||||||
Running: true,
|
Running: true,
|
||||||
Pid: os.Getpid(),
|
Pid: os.Getpid(),
|
||||||
|
@ -684,51 +684,17 @@ func (dm *DockerManager) runContainer(
|
|||||||
cpuShares = milliCPUToShares(cpuRequest.MilliValue())
|
cpuShares = milliCPUToShares(cpuRequest.MilliValue())
|
||||||
}
|
}
|
||||||
|
|
||||||
_, containerName := BuildDockerName(dockerName, container)
|
|
||||||
dockerOpts := docker.CreateContainerOptions{
|
|
||||||
Name: containerName,
|
|
||||||
Config: &docker.Config{
|
|
||||||
Env: makeEnvList(opts.Envs),
|
|
||||||
ExposedPorts: exposedPorts,
|
|
||||||
Hostname: containerHostname,
|
|
||||||
Image: container.Image,
|
|
||||||
// Memory and CPU are set here for older versions of Docker (pre-1.6).
|
|
||||||
Memory: memoryLimit,
|
|
||||||
MemorySwap: -1,
|
|
||||||
CPUShares: cpuShares,
|
|
||||||
WorkingDir: container.WorkingDir,
|
|
||||||
Labels: labels,
|
|
||||||
// Interactive containers:
|
|
||||||
OpenStdin: container.Stdin,
|
|
||||||
StdinOnce: container.StdinOnce,
|
|
||||||
Tty: container.TTY,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
setEntrypointAndCommand(container, opts, &dockerOpts)
|
|
||||||
|
|
||||||
glog.V(3).Infof("Container %v/%v/%v: setting entrypoint \"%v\" and command \"%v\"", pod.Namespace, pod.Name, container.Name, dockerOpts.Config.Entrypoint, dockerOpts.Config.Cmd)
|
|
||||||
|
|
||||||
securityContextProvider := securitycontext.NewSimpleSecurityContextProvider()
|
|
||||||
securityContextProvider.ModifyContainerConfig(pod, container, dockerOpts.Config)
|
|
||||||
dockerContainer, err := dm.client.CreateContainer(dockerOpts)
|
|
||||||
if err != nil {
|
|
||||||
dm.recorder.Eventf(ref, api.EventTypeWarning, kubecontainer.FailedToCreateContainer, "Failed to create docker container with error: %v", err)
|
|
||||||
return kubecontainer.ContainerID{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
dm.recorder.Eventf(ref, api.EventTypeNormal, kubecontainer.CreatedContainer, "Created container with docker id %v", utilstrings.ShortenString(dockerContainer.ID, 12))
|
|
||||||
|
|
||||||
podHasSELinuxLabel := pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.SELinuxOptions != nil
|
podHasSELinuxLabel := pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.SELinuxOptions != nil
|
||||||
binds := makeMountBindings(opts.Mounts, podHasSELinuxLabel)
|
binds := makeMountBindings(opts.Mounts, podHasSELinuxLabel)
|
||||||
|
|
||||||
// The reason we create and mount the log file in here (not in kubelet) is because
|
_, containerName, cid := BuildDockerName(dockerName, container)
|
||||||
// the file's location depends on the ID of the container, and we need to create and
|
|
||||||
// mount the file before actually starting the container.
|
|
||||||
// TODO(yifan): Consider to pull this logic out since we might need to reuse it in
|
|
||||||
// other container runtime.
|
|
||||||
if opts.PodContainerDir != "" && len(container.TerminationMessagePath) != 0 {
|
if opts.PodContainerDir != "" && len(container.TerminationMessagePath) != 0 {
|
||||||
containerLogPath := path.Join(opts.PodContainerDir, dockerContainer.ID)
|
// Because the PodContainerDir contains pod uid and container name which is unique enough,
|
||||||
|
// here we just add an unique container id to make the path unique for different instances
|
||||||
|
// of the same container.
|
||||||
|
// Notice that the "container id" is just a unique number generated in BuildDockerName(),
|
||||||
|
// it is not the real docker container id.
|
||||||
|
containerLogPath := path.Join(opts.PodContainerDir, cid)
|
||||||
fs, err := os.Create(containerLogPath)
|
fs, err := os.Create(containerLogPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// TODO: Clean up the previouly created dir? return the error?
|
// TODO: Clean up the previouly created dir? return the error?
|
||||||
@ -739,7 +705,6 @@ func (dm *DockerManager) runContainer(
|
|||||||
binds = append(binds, b)
|
binds = append(binds, b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hc := &docker.HostConfig{
|
hc := &docker.HostConfig{
|
||||||
PortBindings: portBindings,
|
PortBindings: portBindings,
|
||||||
Binds: binds,
|
Binds: binds,
|
||||||
@ -770,9 +735,43 @@ func (dm *DockerManager) runContainer(
|
|||||||
if len(opts.CgroupParent) > 0 {
|
if len(opts.CgroupParent) > 0 {
|
||||||
hc.CgroupParent = opts.CgroupParent
|
hc.CgroupParent = opts.CgroupParent
|
||||||
}
|
}
|
||||||
securityContextProvider.ModifyHostConfig(pod, container, hc)
|
|
||||||
|
|
||||||
if err = dm.client.StartContainer(dockerContainer.ID, hc); err != nil {
|
dockerOpts := docker.CreateContainerOptions{
|
||||||
|
Name: containerName,
|
||||||
|
Config: &docker.Config{
|
||||||
|
Env: makeEnvList(opts.Envs),
|
||||||
|
ExposedPorts: exposedPorts,
|
||||||
|
Hostname: containerHostname,
|
||||||
|
Image: container.Image,
|
||||||
|
// Memory and CPU are set here for older versions of Docker (pre-1.6).
|
||||||
|
Memory: memoryLimit,
|
||||||
|
MemorySwap: -1,
|
||||||
|
CPUShares: cpuShares,
|
||||||
|
WorkingDir: container.WorkingDir,
|
||||||
|
Labels: labels,
|
||||||
|
// Interactive containers:
|
||||||
|
OpenStdin: container.Stdin,
|
||||||
|
StdinOnce: container.StdinOnce,
|
||||||
|
Tty: container.TTY,
|
||||||
|
},
|
||||||
|
HostConfig: hc,
|
||||||
|
}
|
||||||
|
|
||||||
|
setEntrypointAndCommand(container, opts, &dockerOpts)
|
||||||
|
|
||||||
|
glog.V(3).Infof("Container %v/%v/%v: setting entrypoint \"%v\" and command \"%v\"", pod.Namespace, pod.Name, container.Name, dockerOpts.Config.Entrypoint, dockerOpts.Config.Cmd)
|
||||||
|
|
||||||
|
securityContextProvider := securitycontext.NewSimpleSecurityContextProvider()
|
||||||
|
securityContextProvider.ModifyContainerConfig(pod, container, dockerOpts.Config)
|
||||||
|
securityContextProvider.ModifyHostConfig(pod, container, dockerOpts.HostConfig)
|
||||||
|
dockerContainer, err := dm.client.CreateContainer(dockerOpts)
|
||||||
|
if err != nil {
|
||||||
|
dm.recorder.Eventf(ref, api.EventTypeWarning, kubecontainer.FailedToCreateContainer, "Failed to create docker container with error: %v", err)
|
||||||
|
return kubecontainer.ContainerID{}, err
|
||||||
|
}
|
||||||
|
dm.recorder.Eventf(ref, api.EventTypeNormal, kubecontainer.CreatedContainer, "Created container with docker id %v", utilstrings.ShortenString(dockerContainer.ID, 12))
|
||||||
|
|
||||||
|
if err = dm.client.StartContainer(dockerContainer.ID, nil); err != nil {
|
||||||
dm.recorder.Eventf(ref, api.EventTypeWarning, kubecontainer.FailedToStartContainer,
|
dm.recorder.Eventf(ref, api.EventTypeWarning, kubecontainer.FailedToStartContainer,
|
||||||
"Failed to start container with docker id %v with error: %v", utilstrings.ShortenString(dockerContainer.ID, 12), err)
|
"Failed to start container with docker id %v with error: %v", utilstrings.ShortenString(dockerContainer.ID, 12), err)
|
||||||
return kubecontainer.ContainerID{}, err
|
return kubecontainer.ContainerID{}, err
|
||||||
@ -2083,7 +2082,7 @@ func (dm *DockerManager) doBackOff(pod *api.Pod, container *api.Container, podSt
|
|||||||
PodUID: pod.UID,
|
PodUID: pod.UID,
|
||||||
ContainerName: container.Name,
|
ContainerName: container.Name,
|
||||||
}
|
}
|
||||||
stableName, _ := BuildDockerName(dockerName, container)
|
stableName, _, _ := BuildDockerName(dockerName, container)
|
||||||
if backOff.IsInBackOffSince(stableName, ts) {
|
if backOff.IsInBackOffSince(stableName, ts) {
|
||||||
if ref, err := kubecontainer.GenerateContainerRef(pod, container); err == nil {
|
if ref, err := kubecontainer.GenerateContainerRef(pod, container); err == nil {
|
||||||
dm.recorder.Eventf(ref, api.EventTypeWarning, kubecontainer.BackOffStartContainer, "Back-off restarting failed docker container")
|
dm.recorder.Eventf(ref, api.EventTypeWarning, kubecontainer.BackOffStartContainer, "Back-off restarting failed docker container")
|
||||||
|
@ -1628,7 +1628,7 @@ func TestSyncPodWithTerminationLog(t *testing.T) {
|
|||||||
t.Fatalf("unexpected error %v", err)
|
t.Fatalf("unexpected error %v", err)
|
||||||
}
|
}
|
||||||
parts := strings.Split(newContainer.HostConfig.Binds[0], ":")
|
parts := strings.Split(newContainer.HostConfig.Binds[0], ":")
|
||||||
if !matchString(t, testPodContainerDir+"/k8s_bar\\.[a-f0-9]", parts[0]) {
|
if !matchString(t, testPodContainerDir+"/[a-f0-9]", parts[0]) {
|
||||||
t.Errorf("Unexpected host path: %s", parts[0])
|
t.Errorf("Unexpected host path: %s", parts[0])
|
||||||
}
|
}
|
||||||
if parts[1] != "/dev/somepath" {
|
if parts[1] != "/dev/somepath" {
|
||||||
|
@ -28,7 +28,7 @@ type SecurityContextProvider interface {
|
|||||||
// the container is created.
|
// the container is created.
|
||||||
ModifyContainerConfig(pod *api.Pod, container *api.Container, config *docker.Config)
|
ModifyContainerConfig(pod *api.Pod, container *api.Container, config *docker.Config)
|
||||||
|
|
||||||
// ModifyHostConfig is called before the Docker runContainer call.
|
// ModifyHostConfig is called before the Docker createContainer call.
|
||||||
// The security context provider can make changes to the HostConfig, affecting
|
// The security context provider can make changes to the HostConfig, affecting
|
||||||
// security options, whether the container is privileged, volume binds, etc.
|
// security options, whether the container is privileged, volume binds, etc.
|
||||||
// An error is returned if it's not possible to secure the container as requested
|
// An error is returned if it's not possible to secure the container as requested
|
||||||
|
Loading…
Reference in New Issue
Block a user