Skip to content

Commit

Permalink
Switch to static bash for etcd
Browse files Browse the repository at this point in the history
- use bash-static and avoid dragging in all of debian-base
- use distroless as the base image
- the shell script needs a `cp` utility, add a go based one for just
  files (no support for directories!)
- Rework the calls to `mv` and recursive `cp` in the code
- we don't need to support windows in this container image
- the test case was slightly off as it was assuming that the old
  directory was copied into the new directory, but the desired
  functionality is that all files in the old directory should be in the
  new directory.

Signed-off-by: Davanum Srinivas <[email protected]>
  • Loading branch information
dims committed May 19, 2020
1 parent 0f23eef commit c225d13
Show file tree
Hide file tree
Showing 13 changed files with 232 additions and 35 deletions.
1 change: 1 addition & 0 deletions cluster/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ filegroup(
"//cluster/gce:all-srcs",
"//cluster/images/conformance:all-srcs",
"//cluster/images/etcd-version-monitor:all-srcs",
"//cluster/images/etcd/cp:all-srcs",
"//cluster/images/etcd/migrate:all-srcs",
"//cluster/images/kubemark:all-srcs",
],
Expand Down
14 changes: 13 additions & 1 deletion cluster/images/etcd/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,20 @@
# See the License for the specific language governing permissions and
# limitations under the License.

FROM BASEIMAGE
FROM BASEIMAGE as builder

RUN apt-get update -y \
&& apt-get -yy -q install --no-install-recommends --no-install-suggests --fix-missing \
bash-static

RUN cp /bin/bash-static /sh

FROM RUNNERIMAGE
WORKDIR /

COPY --from=builder /sh /bin/

EXPOSE 2379 2380 4001 7001
COPY etcd* etcdctl* /usr/local/bin/
COPY cp* /bin/
COPY migrate-if-needed.sh migrate /usr/local/bin/
10 changes: 8 additions & 2 deletions cluster/images/etcd/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ LATEST_ETCD_VERSION?=3.4.7
# REVISION provides a version number fo this image and all it's bundled
# artifacts. It should start at zero for each LATEST_ETCD_VERSION and increment
# for each revision of this image at that etcd version.
REVISION?=1
REVISION?=2

# IMAGE_TAG Uniquely identifies k8s.gcr.io/etcd docker image with a tag of the form "<etcd-version>-<revision>".
IMAGE_TAG=$(LATEST_ETCD_VERSION)-$(REVISION)
Expand Down Expand Up @@ -82,6 +82,8 @@ ifeq ($(ARCH),s390x)
BASEIMAGE?=us.gcr.io/k8s-artifacts-prod/build-image/debian-base-s390x:v2.1.0
endif

RUNNERIMAGE?=gcr.io/distroless/static:latest

build:
# Explicitly copy files to the temp directory
$(BIN_INSTALL) migrate-if-needed.sh $(TEMP_DIR)
Expand All @@ -91,7 +93,10 @@ build:
migrate_tmp_dir=$(shell mktemp -d); \
docker run --interactive -v $(shell pwd)/../../../:/go/src/k8s.io/kubernetes$(DOCKER_VOL_OPTS) -v $${migrate_tmp_dir}:/build$(DOCKER_VOL_OPTS) -e GOARCH=$(ARCH) golang:$(GOLANG_VERSION) \
/bin/bash -c "CGO_ENABLED=0 go build -o /build/migrate k8s.io/kubernetes/cluster/images/etcd/migrate"; \
$(BIN_INSTALL) $${migrate_tmp_dir}/migrate $(TEMP_DIR)
$(BIN_INSTALL) $${migrate_tmp_dir}/migrate $(TEMP_DIR); \
docker run --interactive -v $(shell pwd)/../../../:/go/src/k8s.io/kubernetes$(DOCKER_VOL_OPTS) -v $${migrate_tmp_dir}:/build$(DOCKER_VOL_OPTS) -e GOARCH=$(ARCH) golang:$(GOLANG_VERSION) \
/bin/bash -c "CGO_ENABLED=0 go build -o /build/cp k8s.io/kubernetes/cluster/images/etcd/cp"; \
$(BIN_INSTALL) $${migrate_tmp_dir}/cp $(TEMP_DIR);

ifeq ($(ARCH),amd64)

Expand Down Expand Up @@ -140,6 +145,7 @@ endif

# Replace BASEIMAGE with the real base image
cd $(TEMP_DIR) && sed -i.bak 's|BASEIMAGE|$(BASEIMAGE)|g' Dockerfile
cd $(TEMP_DIR) && sed -i.bak 's|RUNNERIMAGE|$(RUNNERIMAGE)|g' Dockerfile

# And build the image
docker build --pull -t $(REGISTRY)/etcd-$(ARCH):$(IMAGE_TAG) $(TEMP_DIR)
Expand Down
28 changes: 28 additions & 0 deletions cluster/images/etcd/cp/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")

go_library(
name = "go_default_library",
srcs = ["cp.go"],
importpath = "k8s.io/kubernetes/cluster/images/etcd/cp",
visibility = ["//visibility:private"],
)

go_binary(
name = "cp",
embed = [":go_default_library"],
visibility = ["//visibility:public"],
)

filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)

filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
visibility = ["//visibility:public"],
)
62 changes: 62 additions & 0 deletions cluster/images/etcd/cp/cp.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
Copyright 2020 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 main

import (
"io"
"log"
"os"
"path/filepath"
)

func main() {
if len(os.Args) != 3 {
log.Fatal("Usage: cp SOURCE DEST")
}

sf, err := os.Open(os.Args[1])
if err != nil {
log.Fatalf("unable to open source file [%s]: %q", os.Args[1], err)
}
defer sf.Close()
fi, err := sf.Stat()
if err != nil {
log.Fatalf("unable to stat source file [%s]: %q", os.Args[1], err)
}

dir := filepath.Dir(os.Args[2])
if err := os.MkdirAll(dir, 0755); err != nil {
log.Fatalf("unable to create directory [%s]: %q", dir, err)
}
df, err := os.Create(os.Args[2])
if err != nil {
log.Fatalf("unable to create destination file [%s]: %q", os.Args[1], err)
}
defer df.Close()

_, err = io.Copy(df, sf)
if err != nil {
log.Fatalf("unable to copy [%s] to [%s]: %q", os.Args[1], os.Args[2], err)
}

if err := df.Close(); err != nil {
log.Fatalf("unable to close destination file: %q", err)
}
if err := os.Chmod(os.Args[2], fi.Mode()); err != nil {
log.Fatalf("unable to close destination file: %q", err)
}
}
7 changes: 4 additions & 3 deletions cluster/images/etcd/migrate-if-needed.sh
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ set -o nounset
# etcd image (to make this script work correctly).
BUNDLED_VERSIONS="3.0.17, 3.1.12, 3.2.24, 3.3.17, 3.4.7"

ETCD_NAME="${ETCD_NAME:-etcd-$(hostname)}"
# shellcheck disable=SC2039
ETCD_NAME="${ETCD_NAME:-etcd-$HOSTNAME}"
if [ -z "${DATA_DIRECTORY:-}" ]; then
echo "DATA_DIRECTORY variable unset - unexpected failure"
exit 1
Expand Down Expand Up @@ -87,8 +88,8 @@ ETCD_CREDS="${ETCD_CREDS:-}"

# Correctly support upgrade and rollback to non-default version.
if [ "${DO_NOT_MOVE_BINARIES:-}" != "true" ]; then
cp "/usr/local/bin/etcd-${TARGET_VERSION}" "/usr/local/bin/etcd"
cp "/usr/local/bin/etcdctl-${TARGET_VERSION}" "/usr/local/bin/etcdctl"
/bin/cp "/usr/local/bin/etcd-${TARGET_VERSION}" "/usr/local/bin/etcd"
/bin/cp "/usr/local/bin/etcdctl-${TARGET_VERSION}" "/usr/local/bin/etcdctl"
fi

/usr/local/bin/migrate \
Expand Down
81 changes: 57 additions & 24 deletions cluster/images/etcd/migrate/BUILD
Original file line number Diff line number Diff line change
@@ -1,16 +1,4 @@
package(default_visibility = ["//visibility:public"])

load(
"@io_bazel_rules_go//go:def.bzl",
"go_binary",
"go_library",
"go_test",
)

go_binary(
name = "migrate",
embed = [":go_default_library"],
)
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test")

go_library(
name = "go_default_library",
Expand All @@ -20,17 +8,72 @@ go_library(
"migrate_client.go",
"migrate_server.go",
"migrator.go",
"util_others.go",
"utils_windows.go",
"versions.go",
],
importpath = "k8s.io/kubernetes/cluster/images/etcd/migrate",
visibility = ["//visibility:private"],
deps = [
"//vendor/github.com/blang/semver:go_default_library",
"//vendor/github.com/spf13/cobra:go_default_library",
"//vendor/go.etcd.io/etcd/client:go_default_library",
"//vendor/go.etcd.io/etcd/clientv3:go_default_library",
"//vendor/google.golang.org/grpc:go_default_library",
"//vendor/k8s.io/klog/v2:go_default_library",
] + select({
"@io_bazel_rules_go//go/platform:android": [
"//vendor/github.com/mrunalp/fileutils:go_default_library",
],
"@io_bazel_rules_go//go/platform:darwin": [
"//vendor/github.com/mrunalp/fileutils:go_default_library",
],
"@io_bazel_rules_go//go/platform:dragonfly": [
"//vendor/github.com/mrunalp/fileutils:go_default_library",
],
"@io_bazel_rules_go//go/platform:freebsd": [
"//vendor/github.com/mrunalp/fileutils:go_default_library",
],
"@io_bazel_rules_go//go/platform:ios": [
"//vendor/github.com/mrunalp/fileutils:go_default_library",
],
"@io_bazel_rules_go//go/platform:linux": [
"//vendor/github.com/mrunalp/fileutils:go_default_library",
],
"@io_bazel_rules_go//go/platform:nacl": [
"//vendor/github.com/mrunalp/fileutils:go_default_library",
],
"@io_bazel_rules_go//go/platform:netbsd": [
"//vendor/github.com/mrunalp/fileutils:go_default_library",
],
"@io_bazel_rules_go//go/platform:openbsd": [
"//vendor/github.com/mrunalp/fileutils:go_default_library",
],
"@io_bazel_rules_go//go/platform:plan9": [
"//vendor/github.com/mrunalp/fileutils:go_default_library",
],
"@io_bazel_rules_go//go/platform:solaris": [
"//vendor/github.com/mrunalp/fileutils:go_default_library",
],
"//conditions:default": [],
}),
)

go_binary(
name = "migrate",
embed = [":go_default_library"],
visibility = ["//visibility:public"],
)

go_test(
name = "go_default_test",
srcs = [
"data_dir_test.go",
"versions_test.go",
],
data = glob(["testdata/**"]),
embed = [":go_default_library"],
deps = ["//vendor/github.com/blang/semver:go_default_library"],
)

filegroup(
Expand All @@ -44,15 +87,5 @@ filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

go_test(
name = "go_default_test",
srcs = [
"data_dir_test.go",
"versions_test.go",
],
data = glob(["testdata/**"]),
embed = [":go_default_library"],
deps = ["//vendor/github.com/blang/semver:go_default_library"],
visibility = ["//visibility:public"],
)
3 changes: 1 addition & 2 deletions cluster/images/etcd/migrate/data_dir.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ import (
"io"
"io/ioutil"
"os"
"os/exec"
"path/filepath"
"strings"

Expand Down Expand Up @@ -88,7 +87,7 @@ func (d *DataDirectory) Backup() error {
if err != nil {
return err
}
err = exec.Command("cp", "-r", d.path, backupDir).Run()
err = copyDirectory(d.path, backupDir)
if err != nil {
return err
}
Expand Down
4 changes: 4 additions & 0 deletions cluster/images/etcd/migrate/data_dir_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ func TestBackup(t *testing.T) {
if err != nil {
t.Fatalf("Failed to open data dir: %v", err)
}
_, err = os.Create(filepath.Join(path, "data-dir", "empty.txt"))
if err != nil {
t.Fatal(err)
}
err = d.Backup()
if err != nil {
t.Fatalf("Failed to backup data directory %s: %v", d.path, err)
Expand Down
3 changes: 1 addition & 2 deletions cluster/images/etcd/migrate/migrator.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ package main
import (
"fmt"
"os"
"os/exec"
"time"

"github.com/blang/semver"
Expand Down Expand Up @@ -159,7 +158,7 @@ func (m *Migrator) rollbackEtcd3MinorVersion(current *EtcdVersionPair, target *E
if err != nil {
return nil, err
}
err = exec.Command("mv", m.dataDirectory.path, backupDir).Run()
err = os.Rename(m.dataDirectory.path, backupDir)
if err != nil {
return nil, err
}
Expand Down
27 changes: 27 additions & 0 deletions cluster/images/etcd/migrate/util_others.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// +build !windows

/*
Copyright 2020 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 main

import (
"github.com/mrunalp/fileutils"
)

func copyDirectory(source string, dest string) error {
return fileutils.CopyDirectory(source, dest)
}
25 changes: 25 additions & 0 deletions cluster/images/etcd/migrate/utils_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// +build windows

/*
Copyright 2020 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 main

import "fmt"

func copyDirectory(source string, dest string) error {
return fmt.Errorf("no support for windows")
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ require (
github.com/miekg/dns v1.1.4
github.com/moby/ipvs v1.0.1
github.com/mohae/deepcopy v0.0.0-20170603005431-491d3605edfb // indirect
github.com/mrunalp/fileutils v0.0.0-20171103030105-7d4729fb3618 // indirect
github.com/mrunalp/fileutils v0.0.0-20171103030105-7d4729fb3618
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822
github.com/mvdan/xurls v1.1.0
github.com/onsi/ginkgo v1.11.0
Expand Down

0 comments on commit c225d13

Please sign in to comment.