use systemd cgroups for kubernetes v1.24.0+

This commit is contained in:
Benjamin Elder
2022-05-03 11:22:46 -07:00
parent 0b55550ecc
commit 90d7770f07
3 changed files with 84 additions and 17 deletions

View File

@@ -113,13 +113,18 @@ func (c *buildContext) buildImage(bits kube.Bits) error {
// write version
// TODO: support grabbing version from a binary instead?
// This may or may not be a good idea ...
if err := createFile(cmder, "/kind/version", bits.Version()); err != nil {
rawVersion := bits.Version()
parsedVersion, err := version.ParseSemantic(rawVersion)
if err != nil {
return errors.Wrap(err, "invalid Kubernetes version")
}
if err := createFile(cmder, "/kind/version", rawVersion); err != nil {
return err
}
// pre-pull images that were not part of the build and write CNI / storage
// manifests
if _, err = c.prePullImagesAndWriteManifests(bits, containerID); err != nil {
if _, err = c.prePullImagesAndWriteManifests(bits, parsedVersion, containerID); err != nil {
c.logger.Errorf("Image build Failed! Failed to pull Images: %v", err)
return err
}
@@ -153,7 +158,7 @@ func (c *buildContext) getBuiltImages(bits kube.Bits) (sets.String, error) {
}
// must be run after kubernetes has been installed on the node
func (c *buildContext) prePullImagesAndWriteManifests(bits kube.Bits, containerID string) ([]string, error) {
func (c *buildContext) prePullImagesAndWriteManifests(bits kube.Bits, parsedVersion *version.Version, containerID string) ([]string, error) {
// first get the images we actually built
builtImages, err := c.getBuiltImages(bits)
if err != nil {
@@ -164,13 +169,6 @@ func (c *buildContext) prePullImagesAndWriteManifests(bits kube.Bits, containerI
// helpers to run things in the build container
cmder := docker.ContainerCmder(containerID)
// parse version for comparison
rawVersion := bits.Version()
ver, err := version.ParseSemantic(rawVersion)
if err != nil {
return nil, err
}
// For kubernetes v1.15+ (actually 1.16 alpha versions) we may need to
// drop the arch suffix from images to get the expected image
archSuffix := "-" + c.arch
@@ -199,18 +197,18 @@ func (c *buildContext) prePullImagesAndWriteManifests(bits kube.Bits, containerI
// gets the list of images required by kubeadm
requiredImages, err := exec.OutputLines(cmder.Command(
"kubeadm", "config", "images", "list", "--kubernetes-version", rawVersion,
"kubeadm", "config", "images", "list", "--kubernetes-version", bits.Version(),
))
if err != nil {
return nil, err
}
// replace pause image with our own
config, err := exec.Output(cmder.Command("cat", "/etc/containerd/config.toml"))
containerdConfig, err := exec.Output(cmder.Command("cat", containerdConfigPath))
if err != nil {
return nil, err
}
pauseImage, err := findSandboxImage(string(config))
pauseImage, err := findSandboxImage(string(containerdConfig))
if err != nil {
return nil, err
}
@@ -223,6 +221,12 @@ func (c *buildContext) prePullImagesAndWriteManifests(bits kube.Bits, containerI
}
requiredImages = append(requiredImages[:n], pauseImage)
if parsedVersion.LessThan(version.MustParseSemantic("v1.24.0")) {
if err := configureContainerdSystemdCgroupFalse(cmder, string(containerdConfig)); err != nil {
return nil, err
}
}
// write the default CNI manifest
if err := createFile(cmder, defaultCNIManifestLocation, defaultCNIManifest); err != nil {
c.logger.Errorf("Image build Failed! Failed write default CNI Manifest: %v", err)
@@ -234,7 +238,7 @@ func (c *buildContext) prePullImagesAndWriteManifests(bits kube.Bits, containerI
// write the default Storage manifest
// in < 1.14 we need to use beta labels
storageManifest := defaultStorageManifest
if ver.LessThan(version.MustParseSemantic("v1.14.0")) {
if parsedVersion.LessThan(version.MustParseSemantic("v1.14.0")) {
storageManifest = strings.ReplaceAll(storageManifest, "kubernetes.io/os", "beta.kubernetes.io/os")
}
if err := createFile(cmder, defaultStorageManifestLocation, storageManifest); err != nil {

View File

@@ -0,0 +1,50 @@
/*
Copyright 2022 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.
*/
package nodeimage
import (
"strings"
"sigs.k8s.io/kind/pkg/errors"
"sigs.k8s.io/kind/pkg/exec"
"sigs.k8s.io/kind/pkg/internal/patch"
)
const containerdConfigPath = "/etc/containerd/config.toml"
const containerdConfigPatchSystemdCgroupFalse = `
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = false
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.test-handler.options]
SystemdCgroup = false
`
func configureContainerdSystemdCgroupFalse(containerCmdr exec.Cmder, config string) error {
patched, err := patch.TOML(config, []string{containerdConfigPatchSystemdCgroupFalse}, []string{})
if err != nil {
return errors.Wrap(err, "failed to configure containerd SystemdCgroup=false")
}
err = containerCmdr.Command(
"cp", "/dev/stdin", containerdConfigPath,
).SetStdin(strings.NewReader(patched)).Run()
if err != nil {
return errors.Wrap(err, "failed to configure containerd SystemdCgroup=false")
}
return nil
}