Skip to content

Commit d17947e

Browse files
authored
Merge pull request kubernetes#91171 from dims/switch-etcd-to-bash-static
Switch to static bash and distroless image for etcd
2 parents ebcae8f + c1c2b66 commit d17947e

File tree

14 files changed

+257
-35
lines changed

14 files changed

+257
-35
lines changed

cluster/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ filegroup(
1717
"//cluster/gce:all-srcs",
1818
"//cluster/images/conformance:all-srcs",
1919
"//cluster/images/etcd-version-monitor:all-srcs",
20+
"//cluster/images/etcd/cp:all-srcs",
2021
"//cluster/images/etcd/migrate:all-srcs",
2122
"//cluster/images/kubemark:all-srcs",
2223
],

cluster/images/etcd/Dockerfile

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,23 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
FROM BASEIMAGE
15+
FROM BASEIMAGE as builder
16+
17+
# This image needs bash for running "migrate-if-needed.sh". Instead of a full debian image
18+
# we use just the bash-static and we wrap bash-static into a distroless image instead of
19+
# a full debian image
20+
RUN apt-get update -y \
21+
&& apt-get -yy -q install --no-install-recommends --no-install-suggests --fix-missing \
22+
bash-static
23+
24+
RUN cp /bin/bash-static /sh
25+
26+
FROM RUNNERIMAGE
27+
WORKDIR /
28+
29+
COPY --from=builder /sh /bin/
1630

1731
EXPOSE 2379 2380 4001 7001
1832
COPY etcd* etcdctl* /usr/local/bin/
33+
COPY cp* /bin/
1934
COPY migrate-if-needed.sh migrate /usr/local/bin/

cluster/images/etcd/Makefile

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ LATEST_ETCD_VERSION?=3.4.7
3434
# REVISION provides a version number fo this image and all it's bundled
3535
# artifacts. It should start at zero for each LATEST_ETCD_VERSION and increment
3636
# for each revision of this image at that etcd version.
37-
REVISION?=1
37+
REVISION?=2
3838

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

85+
RUNNERIMAGE?=gcr.io/distroless/static:latest
86+
8587
build:
8688
# Explicitly copy files to the temp directory
8789
$(BIN_INSTALL) migrate-if-needed.sh $(TEMP_DIR)
@@ -91,7 +93,10 @@ build:
9193
migrate_tmp_dir=$(shell mktemp -d); \
9294
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) \
9395
/bin/bash -c "CGO_ENABLED=0 go build -o /build/migrate k8s.io/kubernetes/cluster/images/etcd/migrate"; \
94-
$(BIN_INSTALL) $${migrate_tmp_dir}/migrate $(TEMP_DIR)
96+
$(BIN_INSTALL) $${migrate_tmp_dir}/migrate $(TEMP_DIR); \
97+
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) \
98+
/bin/bash -c "CGO_ENABLED=0 go build -o /build/cp k8s.io/kubernetes/cluster/images/etcd/cp"; \
99+
$(BIN_INSTALL) $${migrate_tmp_dir}/cp $(TEMP_DIR);
95100

96101
ifeq ($(ARCH),amd64)
97102

@@ -140,6 +145,7 @@ endif
140145

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

144150
# And build the image
145151
docker build --pull -t $(REGISTRY)/etcd-$(ARCH):$(IMAGE_TAG) $(TEMP_DIR)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# See https://cloud.google.com/cloud-build/docs/build-config
2+
timeout: 1200s
3+
options:
4+
substitution_option: ALLOW_LOOSE
5+
machineType: 'N1_HIGHCPU_8'
6+
steps:
7+
- name: 'gcr.io/k8s-testimages/gcb-docker-gcloud:v20200422-b25d964'
8+
entrypoint: 'bash'
9+
dir: ./cluster/images/etcd
10+
env:
11+
- DOCKER_CLI_EXPERIMENTAL=enabled
12+
- REGISTRY=gcr.io/$PROJECT_ID
13+
- PUSH_REGISTRY=gcr.io/$PROJECT_ID
14+
- IMAGE=gcr.io/$PROJECT_ID/etcd
15+
- BUILD_IMAGE=debian-build
16+
- TMPDIR=/workspace
17+
args:
18+
- '-c'
19+
- |
20+
gcloud auth configure-docker \
21+
&& docker run --rm --privileged linuxkit/binfmt:4ea3b9b0938cbd19834c096aa31ff475cc75d281 \
22+
&& make all-push

cluster/images/etcd/cp/BUILD

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library")
2+
3+
go_library(
4+
name = "go_default_library",
5+
srcs = ["cp.go"],
6+
importpath = "k8s.io/kubernetes/cluster/images/etcd/cp",
7+
visibility = ["//visibility:private"],
8+
)
9+
10+
go_binary(
11+
name = "cp",
12+
embed = [":go_default_library"],
13+
visibility = ["//visibility:public"],
14+
)
15+
16+
filegroup(
17+
name = "package-srcs",
18+
srcs = glob(["**"]),
19+
tags = ["automanaged"],
20+
visibility = ["//visibility:private"],
21+
)
22+
23+
filegroup(
24+
name = "all-srcs",
25+
srcs = [":package-srcs"],
26+
tags = ["automanaged"],
27+
visibility = ["//visibility:public"],
28+
)

cluster/images/etcd/cp/cp.go

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/*
2+
Copyright 2020 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package main
18+
19+
import (
20+
"io"
21+
"log"
22+
"os"
23+
"path/filepath"
24+
)
25+
26+
func main() {
27+
if len(os.Args) != 3 {
28+
log.Fatal("Usage: cp SOURCE DEST")
29+
}
30+
31+
sf, err := os.Open(os.Args[1])
32+
if err != nil {
33+
log.Fatalf("unable to open source file [%s]: %q", os.Args[1], err)
34+
}
35+
defer sf.Close()
36+
fi, err := sf.Stat()
37+
if err != nil {
38+
log.Fatalf("unable to stat source file [%s]: %q", os.Args[1], err)
39+
}
40+
41+
dir := filepath.Dir(os.Args[2])
42+
if err := os.MkdirAll(dir, 0755); err != nil {
43+
log.Fatalf("unable to create directory [%s]: %q", dir, err)
44+
}
45+
df, err := os.Create(os.Args[2])
46+
if err != nil {
47+
log.Fatalf("unable to create destination file [%s]: %q", os.Args[1], err)
48+
}
49+
defer df.Close()
50+
51+
_, err = io.Copy(df, sf)
52+
if err != nil {
53+
log.Fatalf("unable to copy [%s] to [%s]: %q", os.Args[1], os.Args[2], err)
54+
}
55+
56+
if err := df.Close(); err != nil {
57+
log.Fatalf("unable to close destination file: %q", err)
58+
}
59+
if err := os.Chmod(os.Args[2], fi.Mode()); err != nil {
60+
log.Fatalf("unable to close destination file: %q", err)
61+
}
62+
}

cluster/images/etcd/migrate-if-needed.sh

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,8 @@ set -o nounset
4545
# etcd image (to make this script work correctly).
4646
BUNDLED_VERSIONS="3.0.17, 3.1.12, 3.2.24, 3.3.17, 3.4.7"
4747

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

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

9495
/usr/local/bin/migrate \

cluster/images/etcd/migrate/BUILD

Lines changed: 57 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,4 @@
1-
package(default_visibility = ["//visibility:public"])
2-
3-
load(
4-
"@io_bazel_rules_go//go:def.bzl",
5-
"go_binary",
6-
"go_library",
7-
"go_test",
8-
)
9-
10-
go_binary(
11-
name = "migrate",
12-
embed = [":go_default_library"],
13-
)
1+
load("@io_bazel_rules_go//go:def.bzl", "go_binary", "go_library", "go_test")
142

153
go_library(
164
name = "go_default_library",
@@ -20,17 +8,72 @@ go_library(
208
"migrate_client.go",
219
"migrate_server.go",
2210
"migrator.go",
11+
"util_others.go",
12+
"utils_windows.go",
2313
"versions.go",
2414
],
2515
importpath = "k8s.io/kubernetes/cluster/images/etcd/migrate",
16+
visibility = ["//visibility:private"],
2617
deps = [
2718
"//vendor/github.com/blang/semver:go_default_library",
2819
"//vendor/github.com/spf13/cobra:go_default_library",
2920
"//vendor/go.etcd.io/etcd/client:go_default_library",
3021
"//vendor/go.etcd.io/etcd/clientv3:go_default_library",
3122
"//vendor/google.golang.org/grpc:go_default_library",
3223
"//vendor/k8s.io/klog/v2:go_default_library",
24+
] + select({
25+
"@io_bazel_rules_go//go/platform:android": [
26+
"//vendor/github.com/mrunalp/fileutils:go_default_library",
27+
],
28+
"@io_bazel_rules_go//go/platform:darwin": [
29+
"//vendor/github.com/mrunalp/fileutils:go_default_library",
30+
],
31+
"@io_bazel_rules_go//go/platform:dragonfly": [
32+
"//vendor/github.com/mrunalp/fileutils:go_default_library",
33+
],
34+
"@io_bazel_rules_go//go/platform:freebsd": [
35+
"//vendor/github.com/mrunalp/fileutils:go_default_library",
36+
],
37+
"@io_bazel_rules_go//go/platform:ios": [
38+
"//vendor/github.com/mrunalp/fileutils:go_default_library",
39+
],
40+
"@io_bazel_rules_go//go/platform:linux": [
41+
"//vendor/github.com/mrunalp/fileutils:go_default_library",
42+
],
43+
"@io_bazel_rules_go//go/platform:nacl": [
44+
"//vendor/github.com/mrunalp/fileutils:go_default_library",
45+
],
46+
"@io_bazel_rules_go//go/platform:netbsd": [
47+
"//vendor/github.com/mrunalp/fileutils:go_default_library",
48+
],
49+
"@io_bazel_rules_go//go/platform:openbsd": [
50+
"//vendor/github.com/mrunalp/fileutils:go_default_library",
51+
],
52+
"@io_bazel_rules_go//go/platform:plan9": [
53+
"//vendor/github.com/mrunalp/fileutils:go_default_library",
54+
],
55+
"@io_bazel_rules_go//go/platform:solaris": [
56+
"//vendor/github.com/mrunalp/fileutils:go_default_library",
57+
],
58+
"//conditions:default": [],
59+
}),
60+
)
61+
62+
go_binary(
63+
name = "migrate",
64+
embed = [":go_default_library"],
65+
visibility = ["//visibility:public"],
66+
)
67+
68+
go_test(
69+
name = "go_default_test",
70+
srcs = [
71+
"data_dir_test.go",
72+
"versions_test.go",
3373
],
74+
data = glob(["testdata/**"]),
75+
embed = [":go_default_library"],
76+
deps = ["//vendor/github.com/blang/semver:go_default_library"],
3477
)
3578

3679
filegroup(
@@ -44,15 +87,5 @@ filegroup(
4487
name = "all-srcs",
4588
srcs = [":package-srcs"],
4689
tags = ["automanaged"],
47-
)
48-
49-
go_test(
50-
name = "go_default_test",
51-
srcs = [
52-
"data_dir_test.go",
53-
"versions_test.go",
54-
],
55-
data = glob(["testdata/**"]),
56-
embed = [":go_default_library"],
57-
deps = ["//vendor/github.com/blang/semver:go_default_library"],
90+
visibility = ["//visibility:public"],
5891
)

cluster/images/etcd/migrate/data_dir.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ import (
2121
"io"
2222
"io/ioutil"
2323
"os"
24-
"os/exec"
2524
"path/filepath"
2625
"strings"
2726

@@ -88,7 +87,7 @@ func (d *DataDirectory) Backup() error {
8887
if err != nil {
8988
return err
9089
}
91-
err = exec.Command("cp", "-r", d.path, backupDir).Run()
90+
err = copyDirectory(d.path, backupDir)
9291
if err != nil {
9392
return err
9493
}

cluster/images/etcd/migrate/data_dir_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,10 @@ func TestBackup(t *testing.T) {
132132
if err != nil {
133133
t.Fatalf("Failed to open data dir: %v", err)
134134
}
135+
_, err = os.Create(filepath.Join(path, "data-dir", "empty.txt"))
136+
if err != nil {
137+
t.Fatal(err)
138+
}
135139
err = d.Backup()
136140
if err != nil {
137141
t.Fatalf("Failed to backup data directory %s: %v", d.path, err)

0 commit comments

Comments
 (0)