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

switch off of the bazel debs #335

Merged
merged 1 commit into from
Feb 23, 2019
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 77 additions & 35 deletions pkg/build/kube/bazelbuildbits.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,21 @@ limitations under the License.
package kube

import (
"fmt"
"os"
"path"
"path/filepath"
"runtime"

log "github.com/sirupsen/logrus"
"github.com/pkg/errors"
"sigs.k8s.io/kind/pkg/exec"
)

// BazelBuildBits implements Bits for a local Bazel build
type BazelBuildBits struct {
kubeRoot string
// computed at build time
paths map[string]string
}

var _ Bits = &BazelBuildBits{}
Expand Down Expand Up @@ -56,74 +60,112 @@ func (b *BazelBuildBits) Build() error {
// make sure we cd back when done
defer os.Chdir(cwd)

// TODO(bentheelder): we assume the host arch, but cross compiling should
// be possible now
BenTheElder marked this conversation as resolved.
Show resolved Hide resolved
bazelGoosGoarch := fmt.Sprintf("linux_%s", runtime.GOARCH)

// build artifacts
cmd := exec.Command(
"bazel", "build",
// TODO(bentheelder): we assume linux amd64, but we could select
// this based on Arch etc. throughout, this flag supports GOOS/GOARCH
"--platforms=@io_bazel_rules_go//go/toolchain:linux_amd64",
// we want the debian packages
"//build/debs:debs",
fmt.Sprintf("--platforms=@io_bazel_rules_go//go/toolchain:%s", bazelGoosGoarch),
BenTheElder marked this conversation as resolved.
Show resolved Hide resolved
// node installed binaries
"//cmd/kubeadm:kubeadm", "//cmd/kubectl:kubectl", "//cmd/kubelet:kubelet",
// and the docker images
//"//cluster/images/hyperkube:hyperkube.tar",
"//build:docker-artifacts",
)
exec.InheritOutput(cmd)
if err := cmd.Run(); err != nil {
return err
}

// capture the output paths
b.paths = b.findPaths(bazelGoosGoarch)

// capture version info
return buildVersionFile(b.kubeRoot)
}

// Paths implements Bits.Paths
func (b *BazelBuildBits) Paths() map[string]string {
func (b *BazelBuildBits) findPaths(bazelGoosGoarch string) map[string]string {
// https://docs.bazel.build/versions/master/output_directories.html
binDir := filepath.Join(b.kubeRoot, "bazel-bin")
buildDir := filepath.Join(binDir, "build")
return map[string]string{
// debians
filepath.Join(buildDir, "debs", "kubeadm.deb"): "debs/kubeadm.deb",
filepath.Join(buildDir, "debs", "kubelet.deb"): "debs/kubelet.deb",
filepath.Join(buildDir, "debs", "kubectl.deb"): "debs/kubectl.deb",
filepath.Join(buildDir, "debs", "kubernetes-cni.deb"): "debs/kubernetes-cni.deb",
filepath.Join(buildDir, "debs", "cri-tools.deb"): "debs/cri-tools.deb",
Copy link
Member

Choose a reason for hiding this comment

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

How are cri-tools and kubernetes-cni now installed? Don't see any references to them elsewhere 🙄

Copy link
Member Author

Choose a reason for hiding this comment

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

they're installed in the base image, this is now on par with the make/bash/docker build.

these debs just wrap downloading a copy of a stable release of these based on WORKSPACE, we do ~the same in the base image already.

Copy link
Member Author

Choose a reason for hiding this comment

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

or rather CNI is:

# Install CNI binaries to /opt/cni/bin
# TODO(bentheelder): doc why / what here
ARG CNI_VERSION="0.6.0"
ARG CNI_TARBALL="cni-plugins-${ARCH}-v${CNI_VERSION}.tgz"
ARG CNI_BASE_URL="https://storage.googleapis.com/kubernetes-release/network-plugins/"
ARG CNI_URL="${CNI_BASE_URL}${CNI_TARBALL}"
RUN curl -sSL --retry 5 --output /tmp/cni.tgz "${CNI_URL}" \
&& sha256sum /tmp/cni.tgz \
&& mkdir -p /opt/cni/bin \
&& tar -C /opt/cni/bin -xzf /tmp/cni.tgz \
&& rm -rf /tmp/cni.tgz

but cri-tools was only to satisfy the deb install requirements, we don't use those while we're on the dockershim path.

Copy link
Member Author

@BenTheElder BenTheElder Feb 23, 2019

Choose a reason for hiding this comment

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

if/when we take a poke at CRI path we can install these to the base image, they have stable releases and don't change often in the kubernetes WORKSPACE, and IIRC are backwards/forwards compatible.


// all well-known paths that have not changed
paths := map[string]string{
// docker images
filepath.Join(buildDir, "kube-apiserver.tar"): "images/kube-apiserver.tar",
filepath.Join(buildDir, "kube-controller-manager.tar"): "images/kube-controller-manager.tar",
filepath.Join(buildDir, "kube-scheduler.tar"): "images/kube-scheduler.tar",
filepath.Join(buildDir, "kube-proxy.tar"): "images/kube-proxy.tar",
// version file
filepath.Join(b.kubeRoot, "_output", "git_version"): "version",
// borrow kubelet service files from bazel debians
// TODO(bentheelder): probably we should use our own config instead :-)
filepath.Join(b.kubeRoot, "build", "debs", "kubelet.service"): "systemd/kubelet.service",
filepath.Join(b.kubeRoot, "build", "debs", "10-kubeadm.conf"): "systemd/10-kubeadm.conf",
// binaries
filepath.Join(
binDir, "cmd", "kubeadm",
// pure-go binary
fmt.Sprintf("%s_pure_stripped", bazelGoosGoarch), "kubeadm",
): "bin/kubeadm",
filepath.Join(
binDir, "cmd", "kubectl",
// pure-go binary
fmt.Sprintf("%s_pure_stripped", bazelGoosGoarch), "kubectl",
): "bin/kubectl",
}

// paths that changed: kubelet binary
oldKubeletPath := filepath.Join(
binDir, "cmd", "kubelet",
// cgo binary
fmt.Sprintf("%s_stripped", bazelGoosGoarch), "kubelet",
)
newKubeletPath := filepath.Join(binDir, "cmd", "kubelet", "kubelet")
if _, err := os.Stat(oldKubeletPath); os.IsNotExist(err) {
paths[newKubeletPath] = "bin/kubelet"
} else {
paths[oldKubeletPath] = "bin/kubelet"
}

return paths
}

// Paths implements Bits.Paths
func (b *BazelBuildBits) Paths() map[string]string {
return b.paths
}

// Install implements Bits.Install
func (b *BazelBuildBits) Install(install InstallContext) error {
base := install.BasePath()

// install debians
debs := path.Join(base, "debs", "*.deb")
if err := install.Run("/bin/sh", "-c", "dpkg -i "+debs); err != nil {
log.Errorf("Debian install failed! %v", err)
return err
kindBinDir := path.Join(install.BasePath(), "bin")
Copy link
Member Author

@BenTheElder BenTheElder Feb 23, 2019

Choose a reason for hiding this comment

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

this is the install logic from the make/bash/docker build, they match now


// symlink the kubernetes binaries into $PATH
binaries := []string{"kubeadm", "kubelet", "kubectl"}
for _, binary := range binaries {
if err := install.Run("ln", "-s",
path.Join(kindBinDir, binary),
path.Join("/usr/bin/", binary),
); err != nil {
return errors.Wrap(err, "failed to symlink binaries")
}
}

// clean up after debian install
if err := install.Run("/bin/sh", "-c",
"rm -rf /kind/bits/debs/*.deb"+
" /var/cache/debconf/* /var/lib/apt/lists/* /var/log/*kg",
); err != nil {
log.Errorf("Debian cleanup failed! %v", err)
return err
// enable the kubelet service
kubeletService := path.Join(install.BasePath(), "systemd/kubelet.service")
if err := install.Run("systemctl", "enable", kubeletService); err != nil {
return errors.Wrap(err, "failed to enable kubelet service")
}

// enable kubelet service
if err := install.Run("systemctl", "enable", "kubelet.service"); err != nil {
log.Errorf("Enabling kubelet.service failed! %v", err)
return err
// setup the kubelet dropin
kubeletDropinSource := path.Join(install.BasePath(), "systemd/10-kubeadm.conf")
kubeletDropin := "/etc/systemd/system/kubelet.service.d/10-kubeadm.conf"
if err := install.Run("mkdir", "-p", path.Dir(kubeletDropin)); err != nil {
return errors.Wrap(err, "failed to configure kubelet service")
}
if err := install.Run("cp", kubeletDropinSource, kubeletDropin); err != nil {
return errors.Wrap(err, "failed to configure kubelet service")
}

return nil
}
2 changes: 2 additions & 0 deletions pkg/build/kube/bits.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ type Bits interface {
Paths() map[string]string
// Install should install the built sources on the node, assuming paths
// have been populated
// TODO(bentheelder): eliminate install, make install file-copies only,
// support cross-building
Install(InstallContext) error
}

Expand Down